Beispiel #1
0
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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);
}
Beispiel #4
0
/**
 * 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);
}
Beispiel #5
0
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);
}
Beispiel #6
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;
}
Beispiel #7
0
/**
 * 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);
}
Beispiel #8
0
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;
}
Beispiel #9
0
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;
}
Beispiel #10
0
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);
}
Beispiel #11
0
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;
}