Make isotptun more robust when starting up and handling errors

pull/494/head
David Shepherd 2024-02-01 23:52:39 -05:00
parent 3615bac17e
commit cb1a73b795
1 changed files with 56 additions and 23 deletions

View File

@ -368,35 +368,68 @@ int main(int argc, char **argv)
nbytes = read(s, buffer, BUF_LEN); nbytes = read(s, buffer, BUF_LEN);
if (nbytes < 0) { if (nbytes < 0) {
perror_syslog("read isotp socket"); perror_syslog("read isotp socket");
return -1; // Handle/ignore various RX/TX errors from isotp.
} //
if (nbytes > MAX_PDU_LENGTH) // Note, we must handle both RX and TX, since the RX path initiates TX flow control to the sender.
return -1; switch(errno) {
ret = write(t, buffer, nbytes); // Need to read again on next pass
if (verbose) { case EAGAIN:
if (ret < 0 && errno == EAGAIN) // RX path timeout of data reception leads to -ETIMEDOUT
printf(";"); case ETIMEDOUT:
else // TX path flowcontrol reception timeout leads to -ECOMM
printf(","); case ECOMM:
fflush(stdout); // RX path SN mismatch leads to -EILSEQ
case EILSEQ:
// TX path flowcontrol reception with wrong layout/padding leads to -EBADMSG
// RX path data reception with wrong padding leads to -EBADMSG
case EBADMSG:
// TX path flowcontrol reception overflow leads to -EMSGSIZE
case EMSGSIZE:
perror_syslog("read isotp socket ignore errno");
// ignore the above errors as they are recoverable
break;
default:
// otherwise, its an error we cannot recover from so exit
return nbytes;
}
} else {
if (nbytes > MAX_PDU_LENGTH) {
syslogger(LOG_WARNING, "isotp received too many bytes %d for max PDU length %d\n",
nbytes, MAX_PDU_LENGTH);
} else {
ret = write(t, buffer, nbytes);
if (verbose) {
if (ret < 0 && errno == EAGAIN)
printf(";");
else
printf(",");
fflush(stdout);
}
}
} }
} }
if (FD_ISSET(t, &rdfs)) { if (FD_ISSET(t, &rdfs)) {
nbytes = read(t, buffer, BUF_LEN); nbytes = read(t, buffer, BUF_LEN);
if (nbytes < 0) { if (nbytes < 0) {
perror_syslog("read tunfd"); if (errno != EAGAIN) {
return -1; perror_syslog("read tunfd");
} return nbytes;
if (nbytes > MAX_PDU_LENGTH) }
return -1; } else {
ret = write(s, buffer, nbytes); if (nbytes > MAX_PDU_LENGTH) {
if (verbose) { syslogger(LOG_WARNING, "tun received too many bytes %d for max PDU length %d\n",
if (ret < 0 && errno == EAGAIN) nbytes, MAX_PDU_LENGTH);
printf(":"); } else {
else ret = write(s, buffer, nbytes);
printf("."); if (verbose) {
fflush(stdout); if (ret < 0 && errno == EAGAIN)
printf(":");
else
printf(".");
fflush(stdout);
}
}
} }
} }
} }