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,10 +368,35 @@ 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.
//
// Note, we must handle both RX and TX, since the RX path initiates TX flow control to the sender.
switch(errno) {
// Need to read again on next pass
case EAGAIN:
// RX path timeout of data reception leads to -ETIMEDOUT
case ETIMEDOUT:
// TX path flowcontrol reception timeout leads to -ECOMM
case ECOMM:
// 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;
} }
if (nbytes > MAX_PDU_LENGTH) } else {
return -1; 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); ret = write(t, buffer, nbytes);
if (verbose) { if (verbose) {
if (ret < 0 && errno == EAGAIN) if (ret < 0 && errno == EAGAIN)
@ -381,15 +406,21 @@ int main(int argc, char **argv)
fflush(stdout); 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) {
if (errno != EAGAIN) {
perror_syslog("read tunfd"); perror_syslog("read tunfd");
return -1; return nbytes;
} }
if (nbytes > MAX_PDU_LENGTH) } else {
return -1; if (nbytes > MAX_PDU_LENGTH) {
syslogger(LOG_WARNING, "tun received too many bytes %d for max PDU length %d\n",
nbytes, MAX_PDU_LENGTH);
} else {
ret = write(s, buffer, nbytes); ret = write(s, buffer, nbytes);
if (verbose) { if (verbose) {
if (ret < 0 && errno == EAGAIN) if (ret < 0 && errno == EAGAIN)
@ -400,6 +431,8 @@ int main(int argc, char **argv)
} }
} }
} }
}
}
close(s); close(s);
close(t); close(t);