merge v1.0.4 into master (serbridge buffer overflow fixes)

pull/49/head
Thorsten von Eicken 9 years ago
commit 45d56f2d27
  1. 32
      serial/serbridge.c
  2. 9
      serial/serbridge.h

@ -243,15 +243,14 @@ sendtxbuffer(serbridgeConnData *conn)
{ {
sint8 result = ESPCONN_OK; sint8 result = ESPCONN_OK;
if (conn->txbufferlen != 0) { if (conn->txbufferlen != 0) {
os_printf("TX %p %d\n", conn, conn->txbufferlen); //os_printf("TX %p %d\n", conn, conn->txbufferlen);
conn->readytosend = false; conn->readytosend = false;
result = espconn_sent(conn->conn, (uint8_t*)conn->txbuffer, conn->txbufferlen); result = espconn_sent(conn->conn, (uint8_t*)conn->txbuffer, conn->txbufferlen);
conn->txbufferlen = 0; conn->txbufferlen = 0;
if (result != ESPCONN_OK) { if (result != ESPCONN_OK) {
#ifdef SERBR_DBG
os_printf("sendtxbuffer: espconn_sent error %d on conn %p\n", result, conn); os_printf("sendtxbuffer: espconn_sent error %d on conn %p\n", result, conn);
#endif
conn->txbufferlen = 0; conn->txbufferlen = 0;
if (!conn->txoverflow_at) conn->txoverflow_at = system_get_time();
} else { } else {
conn->sentbuffer = conn->txbuffer; conn->sentbuffer = conn->txbuffer;
conn->txbuffer = NULL; conn->txbuffer = NULL;
@ -269,12 +268,7 @@ sendtxbuffer(serbridgeConnData *conn)
static sint8 ICACHE_FLASH_ATTR static sint8 ICACHE_FLASH_ATTR
espbuffsend(serbridgeConnData *conn, const char *data, uint16 len) espbuffsend(serbridgeConnData *conn, const char *data, uint16 len)
{ {
if (conn->txbufferlen >= MAX_TXBUFFER) { if (conn->txbufferlen >= MAX_TXBUFFER) goto overflow;
#ifdef SERBR_DBG
os_printf("espbuffsend: txbuffer full on conn %p\n", conn);
#endif
return -128;
}
// make sure we indeed have a buffer // make sure we indeed have a buffer
if (conn->txbuffer == NULL) conn->txbuffer = os_zalloc(MAX_TXBUFFER); if (conn->txbuffer == NULL) conn->txbuffer = os_zalloc(MAX_TXBUFFER);
@ -298,10 +292,25 @@ espbuffsend(serbridgeConnData *conn, const char *data, uint16 len)
// we sent the prior buffer, so try again // we sent the prior buffer, so try again
return espbuffsend(conn, data+avail, len-avail); return espbuffsend(conn, data+avail, len-avail);
} }
os_printf("espbuffsend: txbuffer full on conn %p\n", conn); goto overflow;
return -128;
} }
return result; return result;
overflow:
if (conn->txoverflow_at) {
// we've already been overflowing
if (system_get_time() - conn->txoverflow_at > 10*1000*1000) {
// no progress in 10 seconds, kill the connection
os_printf("serbridge: killing overlowing stuck conn %p\n", conn);
espconn_disconnect(conn->conn);
}
// else be silent, we already printed an error
} else {
// print 1-time message and take timestamp
os_printf("serbridge: txbuffer full, conn %p\n", conn);
conn->txoverflow_at = system_get_time();
}
return -128;
} }
//callback after the data are sent //callback after the data are sent
@ -315,6 +324,7 @@ serbridgeSentCb(void *arg)
if (conn->sentbuffer != NULL) os_free(conn->sentbuffer); if (conn->sentbuffer != NULL) os_free(conn->sentbuffer);
conn->sentbuffer = NULL; conn->sentbuffer = NULL;
conn->readytosend = true; conn->readytosend = true;
conn->txoverflow_at = 0;
sendtxbuffer(conn); // send possible new data in txbuffer sendtxbuffer(conn); // send possible new data in txbuffer
} }

@ -6,10 +6,10 @@
#include <espconn.h> #include <espconn.h>
#define MAX_CONN 4 #define MAX_CONN 4
#define SER_BRIDGE_TIMEOUT 28799 #define SER_BRIDGE_TIMEOUT 300 // 300 seconds = 5 minutes
// Send buffer size // Send buffer size
#define MAX_TXBUFFER 2048 #define MAX_TXBUFFER (2*1460)
enum connModes { enum connModes {
cmInit = 0, // initialization mode: nothing received yet cmInit = 0, // initialization mode: nothing received yet
@ -22,11 +22,12 @@ enum connModes {
typedef struct serbridgeConnData { typedef struct serbridgeConnData {
struct espconn *conn; struct espconn *conn;
enum connModes conn_mode; // connection mode enum connModes conn_mode; // connection mode
char *txbuffer; // buffer for the data to send uint8_t telnet_state;
uint16 txbufferlen; // length of data in txbuffer uint16 txbufferlen; // length of data in txbuffer
char *txbuffer; // buffer for the data to send
char *sentbuffer; // buffer sent, awaiting callback to get freed char *sentbuffer; // buffer sent, awaiting callback to get freed
uint32_t txoverflow_at; // when the transmitter started to overflow
bool readytosend; // true, if txbuffer can be sent by espconn_sent bool readytosend; // true, if txbuffer can be sent by espconn_sent
uint8_t telnet_state;
} serbridgeConnData; } serbridgeConnData;
// port1 is transparent&programming, second port is programming only // port1 is transparent&programming, second port is programming only

Loading…
Cancel
Save