Make isotptun more robust when starting up and handling errors
parent
3615bac17e
commit
cb1a73b795
45
isotptun.c
45
isotptun.c
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue