Binkp receiver supports CRC

This commit is contained in:
Michiel Broek 2002-06-16 16:44:38 +00:00
parent 2af1d25bdf
commit c01b504c27
2 changed files with 814 additions and 761 deletions

View File

@ -4,6 +4,8 @@ $Id$
v0.35.01 05-Jun-2002 v0.35.01 05-Jun-2002
DO NOT USE THIS VERSION, IT WON'T WORK !!!!!!
general: general:
Added structures for netmail routing file. Added structures for netmail routing file.
Expanded nodes structures for FTP and Directory transfers. Expanded nodes structures for FTP and Directory transfers.
@ -23,6 +25,8 @@ v0.35.01 05-Jun-2002
The binkd version string now includes the OS and CPU type. The binkd version string now includes the OS and CPU type.
If a transmitted file via binkp is skipped by the remote it If a transmitted file via binkp is skipped by the remote it
will stay in the queue for the next session. will stay in the queue for the next session.
The binkp receiver now supports the CRC option.
The binkp transmitter doesn't right now, sessions will fail!!!!!
mbfile: mbfile:
Added -v commandline switch to supress virus checking for the Added -v commandline switch to supress virus checking for the

View File

@ -87,7 +87,7 @@ static int CRAMflag = FALSE;
static int CRCflag = FALSE; static int CRCflag = FALSE;
unsigned long nethold, mailhold; unsigned long nethold, mailhold;
int transferred = FALSE; int transferred = FALSE;
int batchnr = 0; int batchnr = 0, crc_errors = 0;
@ -371,8 +371,10 @@ void b_nul(char *msg)
CRYPTflag = TRUE; CRYPTflag = TRUE;
if (strstr(msg, (char *)"CRAM-") != NULL) if (strstr(msg, (char *)"CRAM-") != NULL)
CRAMflag = TRUE; CRAMflag = TRUE;
if (strstr(msg, (char *)"CRC") != NULL) if (strstr(msg, (char *)"CRC") != NULL) {
CRCflag = TRUE; CRCflag = TRUE;
Syslog('b', "Switching to CRC32 mode");
}
} else } else
Syslog('+', "M_NUL \"%s\"", msg); Syslog('+', "M_NUL \"%s\"", msg);
} }
@ -410,8 +412,7 @@ SM_STATE(waitconn)
Loaded = FALSE; Loaded = FALSE;
Syslog('+', "Start binkp session with %s", ascfnode(remote->addr, 0x1f)); Syslog('+', "Start binkp session with %s", ascfnode(remote->addr, 0x1f));
b_banner(TRUE); b_banner(TRUE);
// binkp_send_control(MM_NUL,"OPT NR"); binkp_send_control(MM_NUL,"OPT MB CRC");
binkp_send_control(MM_NUL,"OPT MB");
/* /*
* Build a list of aka's to send, the primary aka first. * Build a list of aka's to send, the primary aka first.
@ -520,10 +521,8 @@ SM_STATE(authremote)
rc = 0; rc = 0;
for (tmpa = remote; tmpa; tmpa = tmpa->next) { for (tmpa = remote; tmpa; tmpa = tmpa->next) {
if ((tmpa->addr->zone == ra.zone) && if ((tmpa->addr->zone == ra.zone) && (tmpa->addr->net == ra.net) &&
(tmpa->addr->net == ra.net) && (tmpa->addr->node == ra.node) && (tmpa->addr->point == ra.point)) {
(tmpa->addr->node == ra.node) &&
(tmpa->addr->point == ra.point)) {
rc = 1; rc = 1;
} }
} }
@ -654,8 +653,7 @@ SM_STATE(waitaddr)
} }
for (tmpa = remote; tmpa; tmpa = tmpa->next) { for (tmpa = remote; tmpa; tmpa = tmpa->next) {
if (((nlent = getnlent(tmpa->addr))) && if (((nlent = getnlent(tmpa->addr))) && (nlent->pflag != NL_DUMMY)) {
(nlent->pflag != NL_DUMMY)) {
Syslog('+', "Remote is a listed system"); Syslog('+', "Remote is a listed system");
if (inbound) if (inbound)
free(inbound); free(inbound);
@ -670,6 +668,10 @@ SM_STATE(waitaddr)
Syslog('b', "Remote supports MB"); Syslog('b', "Remote supports MB");
binkp_send_control(MM_NUL,"OPT MB"); binkp_send_control(MM_NUL,"OPT MB");
} }
if (CRCflag) {
Syslog('b', "Remote supports CRC32");
binkp_send_control(MM_NUL,"OPT CRC");
}
history.aka.zone = remote->addr->zone; history.aka.zone = remote->addr->zone;
history.aka.net = remote->addr->net; history.aka.net = remote->addr->net;
@ -712,6 +714,7 @@ SM_STATE(waitpwd)
} }
SM_STATE(pwdack) SM_STATE(pwdack)
if ((strcmp(&rbuf[1], "-") == 0) && !Loaded) { if ((strcmp(&rbuf[1], "-") == 0) && !Loaded) {
Syslog('+', "Node not in setup, unprotected BINKP session"); Syslog('+', "Node not in setup, unprotected BINKP session");
binkp_send_control(MM_OK, ""); binkp_send_control(MM_OK, "");
@ -791,21 +794,16 @@ void debug_binkp_list(binkp_list **bll)
int binkp_batch(file_list *to_send) int binkp_batch(file_list *to_send)
{ {
int rc = 0, NotDone; int rc = 0, NotDone, rxlen = 0, txlen = 0, rxerror = FALSE;
static char *txbuf, *rxbuf; static char *txbuf, *rxbuf;
FILE *txfp = NULL; FILE *txfp = NULL, *rxfp = NULL;
FILE *rxfp = NULL; long txpos = 0, rxpos = 0, stxpos = 0, written, rsize, roffs, lsize, gsize, goffset;
int rxlen = 0, txlen = 0; int sverr, cmd = FALSE, GotFrame = FALSE, blklen = 0, c, Found = FALSE;
long txpos = 0, rxpos = 0;
long stxpos = 0;
int sverr, cmd = FALSE, GotFrame = FALSE;
int blklen = 0, c, Found = FALSE;
unsigned short header = 0; unsigned short header = 0;
char *rname, *lname, *gname, *rcrc; char *rname, *lname, *gname;
long rsize, roffs, lsize, gsize, goffset;
time_t rtime, ltime, gtime; time_t rtime, ltime, gtime;
unsigned long rcrc = 0, tcrc = 0, rxcrc = 0;
off_t rxbytes; off_t rxbytes;
long written;
binkp_list *bll = NULL, *tmp, *tmpg, *cursend = NULL; binkp_list *bll = NULL, *tmp, *tmpg, *cursend = NULL;
file_list *tsl; file_list *tsl;
struct timeval rxtvstart, rxtvend; struct timeval rxtvstart, rxtvend;
@ -823,7 +821,6 @@ int binkp_batch(file_list *to_send)
txbuf = calloc(MAX_BLKSIZE + 3, sizeof(unsigned char)); txbuf = calloc(MAX_BLKSIZE + 3, sizeof(unsigned char));
rxbuf = calloc(MAX_BLKSIZE + 3, sizeof(unsigned char)); rxbuf = calloc(MAX_BLKSIZE + 3, sizeof(unsigned char));
rname = calloc(512, sizeof(char)); rname = calloc(512, sizeof(char));
rcrc = calloc(512, sizeof(char));
lname = calloc(512, sizeof(char)); lname = calloc(512, sizeof(char));
gname = calloc(512, sizeof(char)); gname = calloc(512, sizeof(char));
TfState = Switch; TfState = Switch;
@ -919,6 +916,12 @@ int binkp_batch(file_list *to_send)
txflock.l_start = 0L; txflock.l_start = 0L;
txflock.l_len = 0L; txflock.l_len = 0L;
if (CRCflag)
tcrc = file_crc(tmp->local, FALSE);
else
tcrc = 0;
Syslog('b', "File CRC is %lx", tcrc);
txfp = fopen(tmp->local, "r"); txfp = fopen(tmp->local, "r");
if (txfp == NULL) { if (txfp == NULL) {
sverr = errno; sverr = errno;
@ -941,9 +944,15 @@ int binkp_batch(file_list *to_send)
txpos = stxpos = tmp->offset; txpos = stxpos = tmp->offset;
Syslog('+', "Binkp: send \"%s\" as \"%s\"", MBSE_SS(tmp->local), MBSE_SS(tmp->remote)); Syslog('+', "Binkp: send \"%s\" as \"%s\"", MBSE_SS(tmp->local), MBSE_SS(tmp->remote));
if (CRCflag && tcrc) {
Syslog('+', "Binkp: size %lu bytes, dated %s, crc %lx", (unsigned long)tmp->size, date(tmp->date), tcrc +5);
binkp_send_control(MM_FILE, "%s %lu %ld %ld %lx", MBSE_SS(tmp->remote),
(unsigned long)tmp->size, (long)tmp->date, (unsigned long)tmp->offset), tcrc;
} else {
Syslog('+', "Binkp: size %lu bytes, dated %s", (unsigned long)tmp->size, date(tmp->date)); Syslog('+', "Binkp: size %lu bytes, dated %s", (unsigned long)tmp->size, date(tmp->date));
binkp_send_control(MM_FILE, "%s %lu %ld %ld", MBSE_SS(tmp->remote), binkp_send_control(MM_FILE, "%s %lu %ld %ld", MBSE_SS(tmp->remote),
(unsigned long)tmp->size, (long)tmp->date, (unsigned long)tmp->offset); (unsigned long)tmp->size, (long)tmp->date, (unsigned long)tmp->offset);
}
gettimeofday(&txtvstart, &tz); gettimeofday(&txtvstart, &tz);
tmp->state = Sending; tmp->state = Sending;
cursend = tmp; cursend = tmp;
@ -1003,8 +1012,7 @@ int binkp_batch(file_list *to_send)
stxpos = txpos - stxpos; stxpos = txpos - stxpos;
Syslog('+', "Binkp: OK %s", transfertime(txtvstart, txtvend, stxpos, TRUE)); Syslog('+', "Binkp: OK %s", transfertime(txtvstart, txtvend, stxpos, TRUE));
} else { } else {
Syslog('+', "Binkp: transmitter skipped file after %ld seconds", Syslog('+', "Binkp: transmitter skipped file after %ld seconds", txtvend.tv_sec - txtvstart.tv_sec);
txtvend.tv_sec - txtvstart.tv_sec);
} }
cursend->state = IsSent; cursend->state = IsSent;
@ -1073,8 +1081,7 @@ int binkp_batch(file_list *to_send)
case MM_GOT: sscanf(rxbuf+1, "%s %ld %ld", lname, &lsize, &ltime); case MM_GOT: sscanf(rxbuf+1, "%s %ld %ld", lname, &lsize, &ltime);
Found = FALSE; Found = FALSE;
for (tmp = bll; tmp; tmp = tmp->next) for (tmp = bll; tmp; tmp = tmp->next)
if ((strcmp(lname, tmp->remote) == 0) && if ((strcmp(lname, tmp->remote) == 0) && (lsize == tmp->size) && (ltime == tmp->date)) {
(lsize == tmp->size) && (ltime == tmp->date)) {
Syslog('+', "Binkp: remote GOT \"%s\"", tmp->remote); Syslog('+', "Binkp: remote GOT \"%s\"", tmp->remote);
tmp->state = Got; tmp->state = Got;
Found = TRUE; Found = TRUE;
@ -1098,10 +1105,13 @@ int binkp_batch(file_list *to_send)
/* /*
* Check against buffer overflow * Check against buffer overflow
*/ */
if (CRCflag) rcrc = 0;
sscanf(rxbuf+1, "%s %ld %ld %ld %s", rname, &rsize, &rtime, &roffs, rcrc); if (CRCflag) {
else sscanf(rxbuf+1, "%s %ld %ld %ld %lx", rname, &rsize, &rtime, &roffs, &rcrc);
} else {
sscanf(rxbuf+1, "%s %ld %ld %ld", rname, &rsize, &rtime, &roffs); sscanf(rxbuf+1, "%s %ld %ld %ld", rname, &rsize, &rtime, &roffs);
}
Syslog('b', "Expecting CRC %lx", rcrc);
} else { } else {
Syslog('+', "Got corrupted FILE frame, size %d bytes", strlen(rxbuf)); Syslog('+', "Got corrupted FILE frame, size %d bytes", strlen(rxbuf));
} }
@ -1116,17 +1126,41 @@ int binkp_batch(file_list *to_send)
if (blklen) { if (blklen) {
if (RxState == RxReceData) { if (RxState == RxReceData) {
written = fwrite(rxbuf, 1, blklen, rxfp); written = fwrite(rxbuf, 1, blklen, rxfp);
if (CRCflag)
rxcrc = upd_crc32(rxbuf, rxcrc, blklen);
if (!written && blklen) { if (!written && blklen) {
Syslog('+', "Binkp: file write error"); Syslog('+', "Binkp: file write error");
RxState = RxDone; RxState = RxDone;
} }
rxpos += written; rxpos += written;
if (rxpos == rsize) { if (rxpos == rsize) {
if (CRCflag && rcrc) {
rxcrc = rxcrc ^ 0xffffffff;
Syslog('b', "File received crc %lx, expected %lx", rxcrc, rcrc);
if (rcrc == rxcrc) {
binkp_send_control(MM_GOT, "%s %ld %ld %lx", rname, rsize, rtime, rcrc);
} else {
rxerror = TRUE;
crc_errors++;
if (crc_errors < 3) {
binkp_send_control(MM_SKIP, "%s %ld %ld %lx", rname, rsize, rtime, rcrc);
WriteError("File CRC error nr %d, sending SKIP frame", crc_errors);
} else {
WriteError("File CRC error nr %d, aborting session", crc_errors);
binkp_send_control(MM_ERR, "Too much CRC errors, aborting session");
RxState = RxDone;
}
}
} else {
/*
* ACK without CRC check
*/
binkp_send_control(MM_GOT, "%s %ld %ld", rname, rsize, rtime); binkp_send_control(MM_GOT, "%s %ld %ld", rname, rsize, rtime);
}
closefile(TRUE); closefile(TRUE);
rxpos = rxpos - rxbytes; rxpos = rxpos - rxbytes;
gettimeofday(&rxtvend, &tz); gettimeofday(&rxtvend, &tz);
Syslog('+', "Binkp: OK %s", transfertime(rxtvstart, rxtvend, rxpos, FALSE)); Syslog('+', "Binkp: %s %s", rxerror?"ERROR":"OK", transfertime(rxtvstart, rxtvend, rxpos, FALSE));
rcvdbytes += rxpos; rcvdbytes += rxpos;
RxState = RxWaitFile; RxState = RxWaitFile;
transferred = TRUE; transferred = TRUE;
@ -1142,15 +1176,25 @@ int binkp_batch(file_list *to_send)
blklen = 0; blklen = 0;
} }
/*
* Receiver state machine
*/
switch (RxState) { switch (RxState) {
case RxWaitFile: case RxWaitFile:
break; break;
case RxAcceptFile: case RxAcceptFile:
Syslog('+', "Binkp: receive file \"%s\" date %s size %ld offset %ld", rname, date(rtime), rsize, roffs); if (CRCflag)
Syslog('+', "Binkp: receive file \"%s\" date %s size %ld offset %ld crc %lx",
rname, date(rtime), rsize, roffs, rcrc);
else
Syslog('+', "Binkp: receive file \"%s\" date %s size %ld offset %ld",
rname, date(rtime), rsize, roffs);
rxfp = openfile(rname, rtime, rsize, &rxbytes, resync); rxfp = openfile(rname, rtime, rsize, &rxbytes, resync);
gettimeofday(&rxtvstart, &tz); gettimeofday(&rxtvstart, &tz);
rxpos = 0; rxpos = 0;
rxcrc = 0xffffffff;
rxerror = FALSE;
if (!diskfree(CFG.freespace)) { if (!diskfree(CFG.freespace)) {
Syslog('+', "Binkp: low diskspace, sending BSY"); Syslog('+', "Binkp: low diskspace, sending BSY");
@ -1166,6 +1210,9 @@ int binkp_batch(file_list *to_send)
* be deleted at the remote. * be deleted at the remote.
*/ */
Syslog('+', "Binkp: already got %s, sending GOT", rname); Syslog('+', "Binkp: already got %s, sending GOT", rname);
if (CRCflag &rcrc)
binkp_send_control(MM_GOT, "%s %ld %ld %lx", rname, rsize, rtime, rcrc);
else
binkp_send_control(MM_GOT, "%s %ld %ld", rname, rsize, rtime); binkp_send_control(MM_GOT, "%s %ld %ld", rname, rsize, rtime);
RxState = RxWaitFile; RxState = RxWaitFile;
rxfp = NULL; rxfp = NULL;
@ -1174,6 +1221,9 @@ int binkp_batch(file_list *to_send)
* Some error, request to skip it * Some error, request to skip it
*/ */
Syslog('+', "Binkp: error file %s, sending SKIP", rname); Syslog('+', "Binkp: error file %s, sending SKIP", rname);
if (CRCflag && rcrc)
binkp_send_control(MM_SKIP, "%s %ld %ld %lx", rname, rsize, rtime, rcrc);
else
binkp_send_control(MM_SKIP, "%s %ld %ld", rname, rsize, rtime); binkp_send_control(MM_SKIP, "%s %ld %ld", rname, rsize, rtime);
RxState = RxWaitFile; RxState = RxWaitFile;
} else { } else {
@ -1223,7 +1273,6 @@ int binkp_batch(file_list *to_send)
free(txbuf); free(txbuf);
free(rxbuf); free(rxbuf);
free(rname); free(rname);
free(rcrc);
free(lname); free(lname);
free(gname); free(gname);
Syslog('+', "Binkp: batch %d completed rc=%d", batchnr, rc); Syslog('+', "Binkp: batch %d completed rc=%d", batchnr, rc);