int net_listen(spdid_t spdid, net_connection_t nc, int queue) { struct tcp_pcb *tp, *new_tp; struct intern_connection *ic; int ret = 0; spdid_t si; //NET_LOCK_TAKE(); ic = net_verify_tcp_connection(nc, &ret); if (NULL == ic) { ret = -EINVAL; goto done; } tp = ic->conn.tp; si = ic->spdid; assert(NULL != tp); new_tp = tcp_listen_with_backlog(tp, queue); if (NULL == new_tp) { ret = -ENOMEM; goto done; } ic->conn.tp = new_tp; tcp_arg(new_tp, ic); tcp_accept(new_tp, cos_net_lwip_tcp_accept); //if (0 > __net_create_tcp_connection(si, new_tp)) BUG(); done: //NET_LOCK_RELEASE(); return ret; }
NetTcpSocketErr LwipNetTcpSocket::listen() { if(!m_pPcb) return NETTCPSOCKET_MEM; //NetTcpSocket was not properly initialised, should destroy it & retry /* From doc/rawapi.txt : The tcp_listen() function returns a new connection identifier, and the one passed as an argument to the function will be deallocated. The reason for this behavior is that less memory is needed for a connection that is listening, so tcp_listen() will reclaim the memory needed for the original connection and allocate a new smaller memory block for the listening connection. */ // tcp_pcb* pNewPcb = tcp_listen(m_pPcb); tcp_pcb* pNewPcb = tcp_listen_with_backlog((tcp_pcb*)m_pPcb, 5); if( !pNewPcb ) //Not enough memory to create the listening pcb return NETTCPSOCKET_MEM; m_pPcb = pNewPcb; tcp_accept( (tcp_pcb*) m_pPcb, LwipNetTcpSocket::sAcceptCb ); return NETTCPSOCKET_OK; }
static void tcp_op_listen(struct socket * sock, message * m) { int backlog, err; struct tcp_pcb * new_pcb; debug_tcp_print("socket num %ld", get_sock_num(sock)); err = copy_from_user(m->m_source, &backlog, sizeof(backlog), (cp_grant_id_t) m->IO_GRANT, 0); new_pcb = tcp_listen_with_backlog((struct tcp_pcb *) sock->pcb, (u8_t) backlog); debug_tcp_print("listening pcb %p", new_pcb); if (!new_pcb) { debug_tcp_print("Cannot listen on socket %ld", get_sock_num(sock)); sock_reply(sock, EGENERIC); return; } /* advertise that this socket is willing to accept connections */ tcp_accept(new_pcb, tcp_accept_callback); sock->flags |= SOCK_FLG_OP_LISTENING; sock->pcb = new_pcb; sock_reply(sock, OK); }
/** * Set a TCP pcb contained in a netconn into listen mode * Called from netconn_listen. * * @param msg the api_msg_msg pointing to the connection */ void lwip_netconn_do_listen(struct api_msg_msg *msg) { if (ERR_IS_FATAL(msg->conn->last_err)) { msg->err = msg->conn->last_err; } else { msg->err = ERR_CONN; if (msg->conn->pcb.tcp != NULL) { if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { if (msg->conn->state == NETCONN_NONE) { struct tcp_pcb* lpcb; #if LWIP_IPV6 if ((msg->conn->flags & NETCONN_FLAG_IPV6_V6ONLY) == 0) { #if TCP_LISTEN_BACKLOG lpcb = tcp_listen_dual_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog); #else /* TCP_LISTEN_BACKLOG */ lpcb = tcp_listen_dual(msg->conn->pcb.tcp); #endif /* TCP_LISTEN_BACKLOG */ } else #endif /* LWIP_IPV6 */ { #if TCP_LISTEN_BACKLOG lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog); #else /* TCP_LISTEN_BACKLOG */ lpcb = tcp_listen(msg->conn->pcb.tcp); #endif /* TCP_LISTEN_BACKLOG */ } if (lpcb == NULL) { /* in this case, the old pcb is still allocated */ msg->err = ERR_MEM; } else { /* delete the recvmbox and allocate the acceptmbox */ if (sys_mbox_valid(&msg->conn->recvmbox)) { /** @todo: should we drain the recvmbox here? */ sys_mbox_free(&msg->conn->recvmbox); sys_mbox_set_invalid(&msg->conn->recvmbox); } msg->err = ERR_OK; if (!sys_mbox_valid(&msg->conn->acceptmbox)) { msg->err = sys_mbox_new(&msg->conn->acceptmbox, DEFAULT_ACCEPTMBOX_SIZE); } if (msg->err == ERR_OK) { msg->conn->state = NETCONN_LISTEN; msg->conn->pcb.tcp = lpcb; tcp_arg(msg->conn->pcb.tcp, msg->conn); tcp_accept(msg->conn->pcb.tcp, accept_function); } else { /* since the old pcb is already deallocated, free lpcb now */ tcp_close(lpcb); msg->conn->pcb.tcp = NULL; } } } } else { msg->err = ERR_ARG; } } } TCPIP_APIMSG_ACK(msg); }
static void tcp_listen_cb(void *ctx_p) { struct socket_t *socket_p = ctx_p; int *backlog_p; backlog_p = socket_p->input.cb.args_p; socket_p->pcb_p = tcp_listen_with_backlog(socket_p->pcb_p, *backlog_p); socket_p->input.u.accept.left = 0; socket_p->input.u.accept.pcb_p = NULL; tcp_accept(socket_p->pcb_p, on_tcp_accept); resume_thrd(socket_p->input.cb.thrd_p, 0); }
/** * @ingroup iperf * Start a TCP iperf server on a specific IP address and port and listen for * incoming connections from iperf clients. * * @returns a connection handle that can be used to abort the server * by calling @ref lwiperf_abort() */ void* lwiperf_start_tcp_server(const ip_addr_t* local_addr, u16_t local_port, lwiperf_report_fn report_fn, void* report_arg) { err_t err; struct tcp_pcb* pcb; lwiperf_state_tcp_t* s; if (local_addr == NULL) { return NULL; } s = (lwiperf_state_tcp_t*)LWIPERF_ALLOC(lwiperf_state_tcp_t); if (s == NULL) { return NULL; } memset(s, 0, sizeof(lwiperf_state_tcp_t)); s->base.tcp = 1; s->base.server = 1; s->report_fn = report_fn; s->report_arg = report_arg; pcb = tcp_new(); if (pcb != NULL) { err = tcp_bind(pcb, local_addr, local_port); if (err == ERR_OK) { s->server_pcb = tcp_listen_with_backlog(pcb, 1); } } if (s->server_pcb == NULL) { if (pcb != NULL) { tcp_close(pcb); } LWIPERF_FREE(lwiperf_state_tcp_t, s); return NULL; } pcb = NULL; tcp_arg(s->server_pcb, s); tcp_accept(s->server_pcb, lwiperf_tcp_accept); lwiperf_list_add(&s->base); return s; }
/** * Set a TCP pcb contained in a netconn into listen mode * Called from netconn_listen. * * @param msg the api_msg_msg pointing to the connection */ void do_listen(struct api_msg_msg *msg) { #if LWIP_TCP if (!ERR_IS_FATAL(msg->conn->err)) { if (msg->conn->pcb.tcp != NULL) { if (msg->conn->type == NETCONN_TCP) { if (msg->conn->pcb.tcp->state == CLOSED) { #if TCP_LISTEN_BACKLOG struct tcp_pcb* lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog); #else /* TCP_LISTEN_BACKLOG */ struct tcp_pcb* lpcb = tcp_listen(msg->conn->pcb.tcp); #endif /* TCP_LISTEN_BACKLOG */ if (lpcb == NULL) { msg->conn->err = ERR_MEM; } else { /* delete the recvmbox and allocate the acceptmbox */ if (msg->conn->recvmbox != SYS_MBOX_NULL) { /** @todo: should we drain the recvmbox here? */ sys_mbox_free(msg->conn->recvmbox); msg->conn->recvmbox = SYS_MBOX_NULL; } if (msg->conn->acceptmbox == SYS_MBOX_NULL) { if ((msg->conn->acceptmbox = sys_mbox_new(DEFAULT_ACCEPTMBOX_SIZE)) == SYS_MBOX_NULL) { msg->conn->err = ERR_MEM; } } if (msg->conn->err == ERR_OK) { msg->conn->state = NETCONN_LISTEN; msg->conn->pcb.tcp = lpcb; tcp_arg(msg->conn->pcb.tcp, msg->conn); tcp_accept(msg->conn->pcb.tcp, accept_function); } } } else { msg->conn->err = ERR_CONN; } } } } #endif /* LWIP_TCP */ TCPIP_APIMSG_ACK(msg); }
STATIC mp_obj_t lwip_socket_listen(mp_obj_t self_in, mp_obj_t backlog_in) { lwip_socket_obj_t *socket = self_in; mp_int_t backlog = mp_obj_get_int(backlog_in); if (socket->pcb == NULL) { nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EBADF))); } if (socket->type != MOD_NETWORK_SOCK_STREAM) { nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(EOPNOTSUPP))); } struct tcp_pcb *new_pcb = tcp_listen_with_backlog((struct tcp_pcb*)socket->pcb, (u8_t)backlog); if (new_pcb == NULL) { nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(ENOMEM))); } socket->pcb = (void*)new_pcb; tcp_accept(new_pcb, _lwip_tcp_accept); return mp_const_none; }
STATIC mp_obj_t lwip_socket_listen(mp_obj_t self_in, mp_obj_t backlog_in) { lwip_socket_obj_t *socket = self_in; mp_int_t backlog = mp_obj_get_int(backlog_in); if (socket->pcb.tcp == NULL) { mp_raise_OSError(MP_EBADF); } if (socket->type != MOD_NETWORK_SOCK_STREAM) { mp_raise_OSError(MP_EOPNOTSUPP); } struct tcp_pcb *new_pcb = tcp_listen_with_backlog(socket->pcb.tcp, (u8_t)backlog); if (new_pcb == NULL) { mp_raise_OSError(MP_ENOMEM); } socket->pcb.tcp = new_pcb; tcp_accept(new_pcb, _lwip_tcp_accept); // Socket is no longer considered "new" for purposes of polling socket->state = STATE_CONNECTING; return mp_const_none; }
static void LibTCPListenCallback(void *arg) { struct lwip_callback_msg *msg = arg; ASSERT(msg); if (!msg->Input.Listen.Connection->SocketContext) { msg->Output.Listen.NewPcb = NULL; goto done; } msg->Output.Listen.NewPcb = tcp_listen_with_backlog((PTCP_PCB)msg->Input.Listen.Connection->SocketContext, msg->Input.Listen.Backlog); if (msg->Output.Listen.NewPcb) { tcp_accept(msg->Output.Listen.NewPcb, InternalAcceptEventHandler); } done: KeSetEvent(&msg->Event, IO_NO_INCREMENT, FALSE); }
static err_t _tcp_listen_api(struct tcpip_api_call *api_call_msg){ tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; msg->err = 0; msg->pcb = tcp_listen_with_backlog(msg->pcb, msg->backlog); return msg->err; }