diff --git a/examples/mip-pcap/main.c b/examples/mip-pcap/main.c index 2861745a..44c50218 100644 --- a/examples/mip-pcap/main.c +++ b/examples/mip-pcap/main.c @@ -9,6 +9,10 @@ #define MQTT_URL "mqtt://broker.hivemq.com:1883" // MQTT broker to connect to #define MQTT_TOPIC "t/123" // Topic to subscribe to +#if MG_ARCH == MG_ARCH_WIN32 +#define usleep(x) Sleep((x) / 1000) +#endif + static int s_signo; void signal_handler(int signo) { s_signo = signo; @@ -30,7 +34,7 @@ static size_t pcap_rx(void *buf, size_t len, void *userdata) { size_t received = 0; struct pcap_pkthdr *hdr = NULL; const unsigned char *pkt = NULL; - usleep(1); // This is to avoid 100% CPU + usleep(1000); // Sleep 1 millisecond. This is to avoid 100% CPU if (pcap_next_ex((pcap_t *) userdata, &hdr, &pkt) == 1) { // Yes, read received = hdr->len < len ? hdr->len : len; memcpy(buf, pkt, received); @@ -53,7 +57,7 @@ int main(int argc, char *argv[]) { } else if (strcmp(argv[i], "-bpf") == 0 && i + 1 < argc) { bpf = argv[++i]; } else if (strcmp(argv[i], "-v") == 0 && i + 1 < argc) { - mg_log_set(atoi(argv[++i])); + mg_log_set(atoi(argv[++i])); } else { MG_ERROR(("unknown option %s", argv[i])); return EXIT_FAILURE; @@ -88,8 +92,8 @@ int main(int argc, char *argv[]) { signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); - struct mg_mgr mgr; // Event manager - mg_mgr_init(&mgr); // Initialise event manager + struct mg_mgr mgr; // Event manager + mg_mgr_init(&mgr); // Initialise event manager struct mip_cfg c = {.ip = 0, .mask = 0, .gw = 0}; sscanf(mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &c.mac[0], &c.mac[1], &c.mac[2], diff --git a/mip/mip.c b/mip/mip.c index be3dbaff..77487da1 100644 --- a/mip/mip.c +++ b/mip/mip.c @@ -28,6 +28,7 @@ struct connstate { uint8_t ttype; // Timer type. 0: ack, 1: keep-alive #define MIP_TTYPE_KEEPALIVE 0 // Connection is idle for long, send keepalive #define MIP_TTYPE_ACK 1 // Peer sent us data, we have to ack it soon + uint8_t tmiss; // Number of keep-alive misses struct mg_iobuf raw; // For TLS only. Incoming raw data }; @@ -319,7 +320,7 @@ static void onstatechange(struct mip_if *ifp) { if (ifp->state == MIP_STATE_READY) { MG_INFO(("READY, IP: %M", mg_print_ipv4, ifp->ip)); MG_INFO((" GW: %M", mg_print_ipv4, ifp->gw)); - MG_INFO((" Lease: %lld sec", (ifp->lease_expire - ifp->now)/1000)); + MG_INFO((" Lease: %lld sec", (ifp->lease_expire - ifp->now) / 1000)); arp_ask(ifp, ifp->gw); } else if (ifp->state == MIP_STATE_UP) { MG_ERROR(("Link up")); @@ -660,7 +661,8 @@ static void rx_tcp(struct mip_if *ifp, struct pkt *pkt) { struct connstate *s = (struct connstate *) (c + 1); if (c != NULL && s->ttype == MIP_TTYPE_KEEPALIVE) { - settmout(c, MIP_TTYPE_KEEPALIVE); + s->tmiss = 0; // Reset missed keep-alive counter + settmout(c, MIP_TTYPE_KEEPALIVE); // Advance keep-alive timer } #if 0 MG_INFO(("%lu %hhu %d", c ? c->id : 0, pkt->tcp->flags, (int) pkt->pay.len)); @@ -827,6 +829,7 @@ static void mip_poll(struct mip_if *ifp, uint64_t uptime_ms) { MG_DEBUG(("%lu keepalive", c->id)); tx_tcp(ifp, c->rem.ip, TH_ACK, c->loc.port, c->rem.port, mg_htonl(s->seq - 1), mg_htonl(s->ack), "", 0); + if (s->tmiss++ > 2) mg_error(c, "keepalive"); } settmout(c, MIP_TTYPE_KEEPALIVE); } diff --git a/mongoose.c b/mongoose.c index 2c0249ee..f606da31 100644 --- a/mongoose.c +++ b/mongoose.c @@ -2357,7 +2357,7 @@ int mg_iobuf_resize(struct mg_iobuf *io, size_t new_size) { void *p = calloc(1, new_size); if (p != NULL) { size_t len = new_size < io->len ? new_size : io->len; - if (len > 0) memmove(p, io->buf, len); + if (len > 0 && io->buf != NULL) memmove(p, io->buf, len); zeromem(io->buf, io->size); free(io->buf); io->buf = (unsigned char *) p; @@ -6317,6 +6317,7 @@ struct connstate { uint8_t ttype; // Timer type. 0: ack, 1: keep-alive #define MIP_TTYPE_KEEPALIVE 0 // Connection is idle for long, send keepalive #define MIP_TTYPE_ACK 1 // Peer sent us data, we have to ack it soon + uint8_t tmiss; // Number of keep-alive misses struct mg_iobuf raw; // For TLS only. Incoming raw data }; @@ -6608,7 +6609,7 @@ static void onstatechange(struct mip_if *ifp) { if (ifp->state == MIP_STATE_READY) { MG_INFO(("READY, IP: %M", mg_print_ipv4, ifp->ip)); MG_INFO((" GW: %M", mg_print_ipv4, ifp->gw)); - MG_INFO((" Lease: %lld sec", (ifp->lease_expire - ifp->now)/1000)); + MG_INFO((" Lease: %lld sec", (ifp->lease_expire - ifp->now) / 1000)); arp_ask(ifp, ifp->gw); } else if (ifp->state == MIP_STATE_UP) { MG_ERROR(("Link up")); @@ -6949,7 +6950,8 @@ static void rx_tcp(struct mip_if *ifp, struct pkt *pkt) { struct connstate *s = (struct connstate *) (c + 1); if (c != NULL && s->ttype == MIP_TTYPE_KEEPALIVE) { - settmout(c, MIP_TTYPE_KEEPALIVE); + s->tmiss = 0; // Reset missed keep-alive counter + settmout(c, MIP_TTYPE_KEEPALIVE); // Advance keep-alive timer } #if 0 MG_INFO(("%lu %hhu %d", c ? c->id : 0, pkt->tcp->flags, (int) pkt->pay.len)); @@ -7116,6 +7118,7 @@ static void mip_poll(struct mip_if *ifp, uint64_t uptime_ms) { MG_DEBUG(("%lu keepalive", c->id)); tx_tcp(ifp, c->rem.ip, TH_ACK, c->loc.port, c->rem.port, mg_htonl(s->seq - 1), mg_htonl(s->ack), "", 0); + if (s->tmiss++ > 2) mg_error(c, "keepalive"); } settmout(c, MIP_TTYPE_KEEPALIVE); }