Example #1
0
static err_t mg_lwip_accept_cb(void *arg, struct tcp_pcb *newtpcb, err_t err) {
  struct mg_connection *lc = (struct mg_connection *) arg;
  (void) err;
  DBG(("%p conn %p from %s:%u", lc, newtpcb, ipaddr_ntoa(&newtpcb->remote_ip),
       newtpcb->remote_port));
  struct mg_connection *nc = mg_if_accept_new_conn(lc);
  if (nc == NULL) {
    tcp_abort(newtpcb);
    return ERR_ABRT;
  }
  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
  cs->pcb.tcp = newtpcb;
  tcp_arg(newtpcb, nc);
  tcp_err(newtpcb, mg_lwip_tcp_error_cb);
  tcp_sent(newtpcb, mg_lwip_tcp_sent_cb);
  tcp_recv(newtpcb, mg_lwip_tcp_recv_cb);
#ifdef SSL_KRYPTON
  if (lc->ssl_ctx != NULL) {
    nc->ssl = SSL_new(lc->ssl_ctx);
    if (nc->ssl == NULL || SSL_set_fd(nc->ssl, (intptr_t) nc) != 1) {
      LOG(LL_ERROR, ("SSL error"));
      tcp_close(newtpcb);
    }
  } else
#endif
  {
    mg_lwip_accept_conn(nc, newtpcb);
  }
  return ERR_OK;
}
Example #2
0
static void mg_lwip_ssl_do_hs(struct mg_connection *nc) {
  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
  int server_side = (nc->listener != NULL);
  int ret = server_side ? SSL_accept(nc->ssl) : SSL_connect(nc->ssl);
  int err = SSL_get_error(nc->ssl, ret);
  DBG(("%s %d %d", (server_side ? "SSL_accept" : "SSL_connect"), ret, err));
  if (ret <= 0) {
    if (err == SSL_ERROR_WANT_WRITE) {
      nc->flags |= MG_F_WANT_WRITE;
      cs->err = 0;
    } else if (err == SSL_ERROR_WANT_READ) {
      /* Nothing, we are callback-driven. */
      cs->err = 0;
    } else {
      cs->err = err;
      LOG(LL_ERROR, ("SSL handshake error: %d", cs->err));
      if (server_side) {
        system_os_post(MG_TASK_PRIORITY, MG_SIG_CLOSE_CONN, (uint32_t) nc);
      } else {
        system_os_post(MG_TASK_PRIORITY, MG_SIG_CONNECT_RESULT, (uint32_t) nc);
      }
    }
  } else {
    cs->err = 0;
    nc->flags &= ~MG_F_WANT_WRITE;
    nc->flags |= MG_F_SSL_HANDSHAKE_DONE;
    if (server_side) {
      mg_lwip_accept_conn(nc, cs->pcb.tcp);
    } else {
      system_os_post(MG_TASK_PRIORITY, MG_SIG_CONNECT_RESULT, (uint32_t) nc);
    }
  }
}
Example #3
0
void mg_lwip_ssl_do_hs(struct mg_connection *nc) {
  struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
  int server_side = (nc->listener != NULL);
  enum mg_ssl_if_result res;
  if (nc->flags & MG_F_CLOSE_IMMEDIATELY) return;
  res = mg_ssl_if_handshake(nc);
  DBG(("%p %lu %d %d", nc, nc->flags, server_side, res));
  if (res != MG_SSL_OK) {
    if (res == MG_SSL_WANT_WRITE) {
      nc->flags |= MG_F_WANT_WRITE;
      cs->err = 0;
    } else if (res == MG_SSL_WANT_READ) {
      /*
       * Nothing to do in particular, we are callback-driven.
       * What we definitely do not need anymore is SSL reading (nothing left).
       */
      nc->flags &= ~MG_F_WANT_READ;
      cs->err = 0;
    } else {
      cs->err = res;
      if (server_side) {
        mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);
      } else {
        mg_lwip_post_signal(MG_SIG_CONNECT_RESULT, nc);
      }
    }
  } else {
    cs->err = 0;
    nc->flags &= ~MG_F_WANT_WRITE;
    /*
     * Handshake is done. Schedule a read immediately to consume app data
     * which may already be waiting.
     */
    nc->flags |= (MG_F_SSL_HANDSHAKE_DONE | MG_F_WANT_READ);
    if (server_side) {
      mg_lwip_accept_conn(nc, cs->pcb.tcp);
    } else {
      mg_lwip_post_signal(MG_SIG_CONNECT_RESULT, nc);
    }
  }
}