void mg_lwip_post_signal(enum mg_sig_type sig, struct mg_connection *nc) { struct mg_ev_mgr_lwip_data *md = (struct mg_ev_mgr_lwip_data *) nc->iface->data; mgos_lock(); if (md->sig_queue_len >= MG_SIG_QUEUE_LEN) { mgos_unlock(); return; } int end_index = (md->start_index + md->sig_queue_len) % MG_SIG_QUEUE_LEN; md->sig_queue[end_index].sig = sig; md->sig_queue[end_index].nc = nc; md->sig_queue_len++; mg_lwip_mgr_schedule_poll(nc->mgr); mgos_unlock(); }
int ssl_socket_recv(void *ctx, unsigned char *buf, size_t len) { struct mg_connection *nc = (struct mg_connection *) ctx; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; struct pbuf *seg = cs->rx_chain; if (seg == NULL) { DBG(("%u - nothing to read", len)); return MBEDTLS_ERR_SSL_WANT_READ; } size_t seg_len = (seg->len - cs->rx_offset); DBG(("%u %u %u %u", len, cs->rx_chain->len, seg_len, cs->rx_chain->tot_len)); mgos_lock(); len = MIN(len, seg_len); pbuf_copy_partial(seg, buf, len, cs->rx_offset); cs->rx_offset += len; /* TCP PCB may be NULL if connection has already been closed * but we still have data to deliver to SSL. */ if (cs->pcb.tcp != NULL) tcp_recved(cs->pcb.tcp, len); if (cs->rx_offset == cs->rx_chain->len) { cs->rx_chain = pbuf_dechain(cs->rx_chain); pbuf_free(seg); cs->rx_offset = 0; } mgos_unlock(); LOG(LL_DEBUG, ("%p <- %d", nc, (int) len)); return len; }
void mg_ev_mgr_lwip_process_signals(struct mg_mgr *mgr) { struct mg_ev_mgr_lwip_data *md = (struct mg_ev_mgr_lwip_data *) mgr->ifaces[MG_MAIN_IFACE]->data; while (md->sig_queue_len > 0) { mgos_lock(); int sig = md->sig_queue[md->start_index].sig; struct mg_connection *nc = md->sig_queue[md->start_index].nc; struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock; md->start_index = (md->start_index + 1) % MG_SIG_QUEUE_LEN; md->sig_queue_len--; mgos_unlock(); if (nc->iface == NULL || nc->mgr == NULL) continue; switch (sig) { case MG_SIG_CONNECT_RESULT: { #if MG_ENABLE_SSL if (cs->err == 0 && (nc->flags & MG_F_SSL) && !(nc->flags & MG_F_SSL_HANDSHAKE_DONE)) { mg_lwip_ssl_do_hs(nc); } else #endif { mg_if_connect_cb(nc, cs->err); } break; } case MG_SIG_CLOSE_CONN: { nc->flags |= MG_F_SEND_AND_CLOSE; mg_close_conn(nc); break; } case MG_SIG_RECV: { cs->recv_pending = 0; if (nc->flags & MG_F_UDP) { mg_lwip_handle_recv_udp(nc); } else { mg_lwip_handle_recv_tcp(nc); } break; } case MG_SIG_TOMBSTONE: { break; } case MG_SIG_ACCEPT: { mg_lwip_handle_accept(nc); break; } } } }