Better error handling for network clients.
This commit is contained in:
parent
e1d3724271
commit
0bf65d8646
57
dump1090.c
57
dump1090.c
|
@ -1737,8 +1737,12 @@ int hexDigitVal(int c) {
|
||||||
* The message is passed to the higher level layers, so it feeds
|
* The message is passed to the higher level layers, so it feeds
|
||||||
* the selected screen output, the network output and so forth.
|
* the selected screen output, the network output and so forth.
|
||||||
*
|
*
|
||||||
* If the message looks invalid is silently discarded. */
|
* If the message looks invalid is silently discarded.
|
||||||
void decodeHexMessage(struct client *c) {
|
*
|
||||||
|
* The function always returns 0 (success) to the caller as there is
|
||||||
|
* no case where we want broken messages here to close the client
|
||||||
|
* connection. */
|
||||||
|
int decodeHexMessage(struct client *c) {
|
||||||
char *hex = c->buf;
|
char *hex = c->buf;
|
||||||
int l = strlen(hex), j;
|
int l = strlen(hex), j;
|
||||||
unsigned char msg[MODES_LONG_MSG_BYTES];
|
unsigned char msg[MODES_LONG_MSG_BYTES];
|
||||||
|
@ -1755,18 +1759,19 @@ void decodeHexMessage(struct client *c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Turn the message into binary. */
|
/* Turn the message into binary. */
|
||||||
if (l < 2 || hex[0] != '*' || hex[l-1] != ';') return;
|
if (l < 2 || hex[0] != '*' || hex[l-1] != ';') return 0;
|
||||||
hex++; l-=2; /* Skip * and ; */
|
hex++; l-=2; /* Skip * and ; */
|
||||||
if (l > MODES_LONG_MSG_BYTES*2) return; /* Too long message... broken. */
|
if (l > MODES_LONG_MSG_BYTES*2) return 0; /* Too long message... broken. */
|
||||||
for (j = 0; j < l; j += 2) {
|
for (j = 0; j < l; j += 2) {
|
||||||
int high = hexDigitVal(hex[j]);
|
int high = hexDigitVal(hex[j]);
|
||||||
int low = hexDigitVal(hex[j+1]);
|
int low = hexDigitVal(hex[j+1]);
|
||||||
|
|
||||||
if (high == -1 || low == -1) return;
|
if (high == -1 || low == -1) return 0;
|
||||||
msg[j/2] = (high<<4) | low;
|
msg[j/2] = (high<<4) | low;
|
||||||
}
|
}
|
||||||
decodeModesMessage(&mm,msg);
|
decodeModesMessage(&mm,msg);
|
||||||
useModesMessage(&mm);
|
useModesMessage(&mm);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return a description of planes in json. */
|
/* Return a description of planes in json. */
|
||||||
|
@ -1820,8 +1825,11 @@ char *aircraftsToJson(int *len) {
|
||||||
|
|
||||||
/* Get an HTTP request header and write the response to the client.
|
/* Get an HTTP request header and write the response to the client.
|
||||||
* Again here we assume that the socket buffer is enough without doing
|
* Again here we assume that the socket buffer is enough without doing
|
||||||
* any kind of userspace buffering. */
|
* any kind of userspace buffering.
|
||||||
void handleHTTPRequest(struct client *c) {
|
*
|
||||||
|
* Returns 1 on error to signal the caller the client connection should
|
||||||
|
* be closed. */
|
||||||
|
int handleHTTPRequest(struct client *c) {
|
||||||
char hdr[512];
|
char hdr[512];
|
||||||
int clen, hdrlen;
|
int clen, hdrlen;
|
||||||
int keepalive;
|
int keepalive;
|
||||||
|
@ -1833,10 +1841,10 @@ void handleHTTPRequest(struct client *c) {
|
||||||
/* Minimally parse the request. */
|
/* Minimally parse the request. */
|
||||||
keepalive = strstr(c->buf, "keep-alive") != NULL;
|
keepalive = strstr(c->buf, "keep-alive") != NULL;
|
||||||
p = strchr(c->buf,' ');
|
p = strchr(c->buf,' ');
|
||||||
if (!p) return; /* There should be the method and a space... */
|
if (!p) return 1; /* There should be the method and a space... */
|
||||||
url = ++p; /* Now this should point to the requested URL. */
|
url = ++p; /* Now this should point to the requested URL. */
|
||||||
p = strchr(p, ' ');
|
p = strchr(p, ' ');
|
||||||
if (!p) return; /* There should be a space before HTTP/... */
|
if (!p) return 1; /* There should be a space before HTTP/... */
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
/* printf("URL: %s\n", url); */
|
/* printf("URL: %s\n", url); */
|
||||||
|
|
||||||
|
@ -1854,7 +1862,10 @@ void handleHTTPRequest(struct client *c) {
|
||||||
(fd = open("gmap.html",O_RDONLY)) != -1)
|
(fd = open("gmap.html",O_RDONLY)) != -1)
|
||||||
{
|
{
|
||||||
content = malloc(sbuf.st_size);
|
content = malloc(sbuf.st_size);
|
||||||
read(fd,content,sbuf.st_size);
|
if (read(fd,content,sbuf.st_size) == -1) {
|
||||||
|
snprintf(content,sbuf.st_size,"Error reading from file: %s",
|
||||||
|
strerror(errno));
|
||||||
|
}
|
||||||
clen = sbuf.st_size;
|
clen = sbuf.st_size;
|
||||||
} else {
|
} else {
|
||||||
char buf[128];
|
char buf[128];
|
||||||
|
@ -1878,12 +1889,17 @@ void handleHTTPRequest(struct client *c) {
|
||||||
ctype,
|
ctype,
|
||||||
keepalive ? "keep-alive" : "close",
|
keepalive ? "keep-alive" : "close",
|
||||||
clen);
|
clen);
|
||||||
write(c->fd, hdr, hdrlen);
|
|
||||||
|
|
||||||
/* Send the actual content. */
|
/* Send header and content. */
|
||||||
write(c->fd, content, clen);
|
if (write(c->fd, hdr, hdrlen) == -1 ||
|
||||||
|
write(c->fd, content, clen) == -1)
|
||||||
|
{
|
||||||
|
free(content);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
free(content);
|
free(content);
|
||||||
Modes.stat_http_requests++;
|
Modes.stat_http_requests++;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function polls the clients using read() in order to receive new
|
/* This function polls the clients using read() in order to receive new
|
||||||
|
@ -1893,9 +1909,13 @@ void handleHTTPRequest(struct client *c) {
|
||||||
* separator 'sep', that is a null-terminated C string.
|
* separator 'sep', that is a null-terminated C string.
|
||||||
*
|
*
|
||||||
* Every full message received is decoded and passed to the higher layers
|
* Every full message received is decoded and passed to the higher layers
|
||||||
* calling the function 'handler'. */
|
* calling the function 'handler'.
|
||||||
|
*
|
||||||
|
* The handelr returns 0 on success, or 1 to signal this function we
|
||||||
|
* should close the connection with the client in case of non-recoverable
|
||||||
|
* errors. */
|
||||||
void modesReadFromClient(struct client *c, char *sep,
|
void modesReadFromClient(struct client *c, char *sep,
|
||||||
void(*handler)(struct client *))
|
int(*handler)(struct client *))
|
||||||
{
|
{
|
||||||
while(1) {
|
while(1) {
|
||||||
int left = sizeof(c->buf) - c->buflen;
|
int left = sizeof(c->buf) - c->buflen;
|
||||||
|
@ -1919,7 +1939,12 @@ void modesReadFromClient(struct client *c, char *sep,
|
||||||
if ((p = strstr(c->buf, sep)) != NULL) {
|
if ((p = strstr(c->buf, sep)) != NULL) {
|
||||||
i = p - c->buf; /* Turn it as an index inside the buffer. */
|
i = p - c->buf; /* Turn it as an index inside the buffer. */
|
||||||
c->buf[i] = '\0'; /* Te handler expects null terminated strings. */
|
c->buf[i] = '\0'; /* Te handler expects null terminated strings. */
|
||||||
handler(c); /* Call the function to process the message. */
|
/* Call the function to process the message. It returns 1
|
||||||
|
* on error to signal we should close the client connection. */
|
||||||
|
if (handler(c)) {
|
||||||
|
modesFreeClient(c->fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
/* Move what's left at the start of the buffer. */
|
/* Move what's left at the start of the buffer. */
|
||||||
i += strlen(sep); /* The separator is part of the previous msg. */
|
i += strlen(sep); /* The separator is part of the previous msg. */
|
||||||
memmove(c->buf,c->buf+i,c->buflen-i);
|
memmove(c->buf,c->buf+i,c->buflen-i);
|
||||||
|
|
Loading…
Reference in a new issue