Esempio n. 1
0
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;
      }
    }
  }
}
Esempio n. 2
0
static void mg_ssl_begin(struct mg_connection *nc) {
  int server_side = (nc->listener != NULL);
  enum mg_ssl_if_result res = mg_ssl_if_handshake(nc);
  DBG(("%p %d res %d", nc, server_side, res));

  if (res == MG_SSL_OK) {
    nc->flags |= MG_F_SSL_HANDSHAKE_DONE;
    nc->flags &= ~(MG_F_WANT_READ | MG_F_WANT_WRITE);

    if (server_side) {
      union socket_address sa;
      socklen_t sa_len = sizeof(sa);
      (void) getpeername(nc->sock, &sa.sa, &sa_len);
      mg_if_accept_tcp_cb(nc, &sa, sa_len);
    } else {
      mg_if_connect_cb(nc, 0);
    }
  } else if (res != MG_SSL_WANT_READ && res != MG_SSL_WANT_WRITE) {
    if (!server_side) {
      mg_if_connect_cb(nc, res);
    }
    nc->flags |= MG_F_CLOSE_IMMEDIATELY;
  }
}
Esempio n. 3
0
static void mg_lwip_task(os_event_t *e) {
  struct mg_mgr *mgr = NULL;
  DBG(("sig %d", e->sig));
  poll_scheduled = 0;
  switch ((enum mg_sig_type) e->sig) {
    case MG_SIG_TOMBSTONE:
      break;
    case MG_SIG_POLL: {
      mgr = (struct mg_mgr *) e->par;
      break;
    }
    case MG_SIG_CONNECT_RESULT: {
      struct mg_connection *nc = (struct mg_connection *) e->par;
      mgr = nc->mgr;
      mg_if_connect_cb(nc, nc->err);
      break;
    }
    case MG_SIG_CLOSE_CONN: {
      struct mg_connection *nc = (struct mg_connection *) e->par;
      mgr = nc->mgr;
      nc->flags |= MG_F_CLOSE_IMMEDIATELY;
      mg_close_conn(nc);
      break;
    }
    case MG_SIG_SENT_CB: {
      struct mg_connection *nc = (struct mg_connection *) e->par;
      mgr = nc->mgr;
      mg_if_sent_cb(nc, nc->err);
      break;
    }
    case MG_SIG_V7_CALLBACK: {
#ifndef NO_V7
      struct v7_callback_args *cba = (struct v7_callback_args *) e->par;
      _sj_invoke_cb(cba->v7, cba->func, cba->this_obj, cba->args);
      v7_disown(cba->v7, &cba->func);
      v7_disown(cba->v7, &cba->this_obj);
      v7_disown(cba->v7, &cba->args);
      free(cba);
#endif
      break;
    }
  }
  if (mgr != NULL) {
    mg_mgr_poll(mgr, 0);
  }
}
Esempio n. 4
0
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) {
    struct mg_connection *nc = md->sig_queue[md->start_index].nc;
    struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
    switch (md->sig_queue[md->start_index].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_CLOSE_IMMEDIATELY;
        mg_close_conn(nc);
        break;
      }
      case MG_SIG_RECV: {
        mg_lwip_handle_recv(nc);
        break;
      }
      case MG_SIG_SENT_CB: {
        if (cs->num_sent > 0) mg_if_sent_cb(nc, cs->num_sent);
        cs->num_sent = 0;
        break;
      }
      case MG_SIG_TOMBSTONE: {
        break;
      }
    }
    md->start_index = (md->start_index + 1) % MG_SIG_QUEUE_LEN;
    md->sig_queue_len--;
  }
}
Esempio n. 5
0
static void mg_lwip_task(os_event_t *e) {
  struct mg_mgr *mgr = NULL;
  poll_scheduled = 0;
  switch ((enum mg_sig_type) e->sig) {
    case MG_SIG_TOMBSTONE:
      break;
    case MG_SIG_POLL: {
      mgr = (struct mg_mgr *) e->par;
      break;
    }
    case MG_SIG_CONNECT_RESULT: {
      struct mg_connection *nc = (struct mg_connection *) e->par;
      struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
      mgr = nc->mgr;
      mg_if_connect_cb(nc, cs->err);
      break;
    }
    case MG_SIG_CLOSE_CONN: {
      struct mg_connection *nc = (struct mg_connection *) e->par;
      mgr = nc->mgr;
      nc->flags |= MG_F_CLOSE_IMMEDIATELY;
      mg_close_conn(nc);
      break;
    }
    case MG_SIG_SENT_CB: {
      struct mg_connection *nc = (struct mg_connection *) e->par;
      struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
      mgr = nc->mgr;
      if (cs->num_sent > 0) mg_if_sent_cb(nc, cs->num_sent);
      cs->num_sent = 0;
      break;
    }
    case MG_SIG_V7_CALLBACK: {
#ifndef NO_V7
      struct v7_callback_args *cba = (struct v7_callback_args *) e->par;
      _sj_invoke_cb(cba->v7, cba->func, cba->this_obj, cba->args);
      v7_disown(cba->v7, &cba->func);
      v7_disown(cba->v7, &cba->this_obj);
      v7_disown(cba->v7, &cba->args);
      free(cba);
#endif
      break;
    }
  }
  if (mgr != NULL) {
    mg_mgr_poll(mgr, 0);
    if (s_suspended) {
      int can_suspend = 1;
      struct mg_connection *nc;
      /* Looking for data to send and if there isn't any - suspending */
      for (nc = mgr->active_connections; nc != NULL; nc = nc->next) {
        if (nc->send_mbuf.len > 0) {
          can_suspend = 0;
          break;
        }
      }

      if (can_suspend) {
        os_timer_disarm(&s_poll_tmr);
#if MG_LWIP_REXMIT_INTERVAL_MS > 0
        os_timer_disarm(&s_rexmit_tmr);
#endif
      }
    }
  }
}
Esempio n. 6
0
void mg_mgr_handle_conn(struct mg_connection *nc, int fd_flags, double now) {
  int worth_logging =
      fd_flags != 0 || (nc->flags & (MG_F_WANT_READ | MG_F_WANT_WRITE));
  if (worth_logging) {
    DBG(("%p fd=%d fd_flags=%d nc_flags=%lu rmbl=%d smbl=%d", nc, nc->sock,
         fd_flags, nc->flags, (int) nc->recv_mbuf.len,
         (int) nc->send_mbuf.len));
  }

  if (nc->flags & MG_F_CONNECTING) {
    if (fd_flags != 0) {
      int err = 0;
#if !defined(MG_ESP8266)
      if (!(nc->flags & MG_F_UDP)) {
        socklen_t len = sizeof(err);
        int ret =
            getsockopt(nc->sock, SOL_SOCKET, SO_ERROR, (char *) &err, &len);
        if (ret != 0) {
          err = 1;
        } else if (err == EAGAIN || err == EWOULDBLOCK) {
          err = 0;
        }
      }
#else
      /*
       * On ESP8266 we use blocking connect.
       */
      err = nc->err;
#endif
#if MG_ENABLE_SSL
      if ((nc->flags & MG_F_SSL) && err == 0) {
        mg_ssl_begin(nc);
      } else {
        mg_if_connect_cb(nc, err);
      }
#else
      mg_if_connect_cb(nc, err);
#endif
    } else if (nc->err != 0) {
      mg_if_connect_cb(nc, nc->err);
    }
  }

  if (fd_flags & _MG_F_FD_CAN_READ) {
    if (nc->flags & MG_F_UDP) {
      mg_handle_udp_read(nc);
    } else {
      if (nc->flags & MG_F_LISTENING) {
        /*
         * We're not looping here, and accepting just one connection at
         * a time. The reason is that eCos does not respect non-blocking
         * flag on a listening socket and hangs in a loop.
         */
        mg_accept_conn(nc);
      } else {
        mg_handle_tcp_read(nc);
      }
    }
  }

  if (!(nc->flags & MG_F_CLOSE_IMMEDIATELY)) {
    if ((fd_flags & _MG_F_FD_CAN_WRITE) && nc->send_mbuf.len > 0) {
      mg_write_to_socket(nc);
    }
    mg_if_poll(nc, (time_t) now);
    mg_if_timer(nc, now);
  }

  if (worth_logging) {
    DBG(("%p after fd=%d nc_flags=%lu rmbl=%d smbl=%d", nc, nc->sock, nc->flags,
         (int) nc->recv_mbuf.len, (int) nc->send_mbuf.len));
  }
}