Пример #1
0
static int tcp_do_accept(struct socket * listen_sock,
			message * m,
			struct tcp_pcb * newpcb)
{
	struct socket * newsock;
	unsigned sock_num;
	int ret;

	debug_tcp_print("socket num %ld", get_sock_num(listen_sock));

	if ((ret = copy_from_user(m->m_source, &sock_num, sizeof(sock_num),
				(cp_grant_id_t) m->IO_GRANT, 0)) != OK)
		return EFAULT;
	if (!is_valid_sock_num(sock_num))
		return EBADF;

	newsock = get_sock(sock_num);
	assert(newsock->pcb); /* because of previous open() */
	
	/* we really want to forget about this socket */
	tcp_err((struct tcp_pcb *)newsock->pcb, NULL);
	tcp_abandon((struct tcp_pcb *)newsock->pcb, 0);
	
	tcp_arg(newpcb, newsock);
	tcp_err(newpcb, tcp_error_callback);
	tcp_sent(newpcb, tcp_sent_callback);
	tcp_recv(newpcb, tcp_recv_callback);
	tcp_nagle_disable(newpcb);
	tcp_accepted(((struct tcp_pcb *)(listen_sock->pcb)));
	newsock->pcb = newpcb;

	debug_tcp_print("Accepted new connection using socket %d\n", sock_num);

	return OK;
}
Пример #2
0
//*****************************************************************************
//
// Finalizes the TCP connection in client mode.
//
// \param pvArg is the state data for this connection.
// \param psPcb is the pointer to the TCP control structure.
// \param iErr is not used in this implementation.
//
// This function is called when the lwIP TCP/IP stack has completed a TCP
// connection.
//
// \return This function will return an lwIP defined error code.
//
//*****************************************************************************
static err_t
TCPConnected(void *pvArg, struct tcp_pcb *psPcb, err_t iErr)
{
    //
    // Check if there was a TCP error.
    //
    if(iErr != ERR_OK)
    {
        //
        // Clear out all of the TCP callbacks.
        //
        tcp_sent(psPcb, NULL);
        tcp_recv(psPcb, NULL);
        tcp_err(psPcb, NULL);

        //
        // Close the TCP connection.
        //
        tcp_close(psPcb);

        if(psPcb == g_sEnet.psTCP)
        {
            g_sEnet.psTCP = 0;
        }

        //
        // And return.
        //
        return (ERR_OK);
    }

    //
    // Setup the TCP receive function.
    //
    tcp_recv(psPcb, TCPReceive);

    //
    // Setup the TCP error function.
    //
    tcp_err(psPcb, TCPError);

    //
    // Setup the TCP sent callback function.
    //
    tcp_sent(psPcb, TCPSent);

    //
    // Connection is complete.
    //
    g_sEnet.eState = iEthTCPConnectComplete;

    //
    // Return a success code.
    //
    return(ERR_OK);
}
Пример #3
0
/**
 * Internal helper function to close a TCP netconn: since this sometimes
 * doesn't work at the first attempt, this function is called from multiple
 * places.
 *
 * @param conn the TCP netconn to close
 */
static void
do_close_internal(struct netconn *conn)
{
  err_t err;

  LWIP_ASSERT("invalid conn", (conn != NULL));
  LWIP_ASSERT("this is for tcp netconns only", (conn->type == NETCONN_TCP));
  LWIP_ASSERT("conn must be in state NETCONN_CLOSE", (conn->state == NETCONN_CLOSE));
  LWIP_ASSERT("pcb already closed", (conn->pcb.tcp != NULL));

  /* Set back some callback pointers */
  tcp_arg(conn->pcb.tcp, NULL);
  if (conn->pcb.tcp->state == LISTEN) {
    tcp_accept(conn->pcb.tcp, NULL);
  } else {
    tcp_recv(conn->pcb.tcp, NULL);
    tcp_accept(conn->pcb.tcp, NULL);
    /* some callbacks have to be reset if tcp_close is not successful */
    tcp_sent(conn->pcb.tcp, NULL);
    tcp_poll(conn->pcb.tcp, NULL, 4);
    tcp_err(conn->pcb.tcp, NULL);
  }
  /* Try to close the connection */
  err = tcp_close(conn->pcb.tcp);
  if (err == ERR_OK) {
    /* Closing succeeded */
    conn->state = NETCONN_NONE;
    /* Set back some callback pointers as conn is going away */
    conn->pcb.tcp = NULL;
    conn->err = ERR_OK;
    /* Trigger select() in socket layer. This send should something else so the
       errorfd is set, not the read and write fd! */
    API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
    API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
    /* wake up the application task */
    sys_sem_signal(conn->op_completed);
  } else {
    /* Closing failed, restore some of the callbacks */
    /* Closing of listen pcb will never fail! */
    LWIP_ASSERT("Closing a listen pcb may not fail!", (conn->pcb.tcp->state != LISTEN));
    tcp_sent(conn->pcb.tcp, sent_tcp);
    tcp_poll(conn->pcb.tcp, poll_tcp, 4);
    tcp_err(conn->pcb.tcp, err_tcp);
    tcp_arg(conn->pcb.tcp, conn);
  }
  /* If closing didn't succeed, we get called again either
     from poll_tcp or from sent_tcp */
}
Пример #4
0
void EthernetClient::stop()
{
	if(cpcb == NULL)
		return;

	_connected = false;
	/* Stop frees any resources including any unread buffers */
	err_t err;

	if(cpcb) {
		tcp_err(cpcb, NULL);

		if(cs->p) {
			tcp_recved(cpcb, cs->p->tot_len);
			pbuf_free(cs->p);
			cs->p = NULL;
		}

		err = tcp_close(cpcb);
	}

	if (err != ERR_OK) {
		/* Error closing, try again later in poll (every 2 sec) */
		tcp_poll(cpcb, do_poll, 4);
	} else {
		cpcb = NULL;
	}
}
Пример #5
0
/******************************************************************************
 * FunctionName : espconn_client_close
 * Description  : The connection shall be actively closed.
 * Parameters   : pcb -- Additional argument to pass to the callback function
 *                pcb -- the pcb to close
 * Returns      : none
*******************************************************************************/
static void ICACHE_FLASH_ATTR
espconn_client_close(void *arg, struct tcp_pcb *pcb, uint8 type)
{
    err_t err;
    espconn_msg *pclose = arg;

	pclose->pcommon.pcb = pcb;
	/*avoid recalling the disconnect function*/
	tcp_recv(pcb, NULL);

	if(type == 0)
		err = tcp_close(pcb);
	else
		{tcp_abort(pcb); err = ERR_OK;}

	if (err != ERR_OK) {
		/* closing failed, try again later */
		tcp_recv(pcb, espconn_client_recv);
	} else {
		/* closing succeeded */
		tcp_sent(pcb, NULL);
		tcp_err(pcb, NULL);
		/*switch the state of espconn for application process*/
		pclose->pespconn->state = ESPCONN_CLOSE;
		ets_post(espconn_TaskPrio, SIG_ESPCONN_CLOSE, (uint32_t)pclose);
		printf("ets_post close\n");
	}
}
AsyncClient::AsyncClient(tcp_pcb* pcb):
  _connect_cb(0)
  , _connect_cb_arg(0)
  , _discard_cb(0)
  , _discard_cb_arg(0)
  , _sent_cb(0)
  , _sent_cb_arg(0)
  , _error_cb(0)
  , _error_cb_arg(0)
  , _recv_cb(0)
  , _recv_cb_arg(0)
  , _timeout_cb(0)
  , _timeout_cb_arg(0)
  , _refcnt(0)
  , _pcb_busy(false)
  , _pcb_sent_at(0)
  , _close_pcb(false)
  , _rx_last_packet(0)
  , _rx_since_timeout(0)
  , prev(NULL)
  , next(NULL)
{
  _pcb = pcb;
  if(pcb){
    tcp_setprio(_pcb, TCP_PRIO_MIN);
    tcp_arg(_pcb, this);
    tcp_recv(_pcb, (tcp_recv_fn) &_s_recv);
    tcp_sent(_pcb, &_s_sent);
    tcp_err(_pcb, &_s_error);
    tcp_poll(_pcb, &_s_poll, 1);
  }
}
Пример #7
0
static err_t lwip_accept_cb(void *arg, struct tcp_pcb *newpcb, err_t err)
{
	phase_expected(PHASE_EVENTS);

	debug("<--- %s(arg 0x%pp, newpcb 0x%pp, err %d)\n",
	      __FUNCTION__, arg, newpcb, err);
	outlet_t *ol = (outlet_t *)arg;
	assert(ol != 0);
	assert(err == ERR_OK);

	acc_pend_t *pend = get_free_pending(ol);
	if (pend == 0)
	{
		tcp_abort(newpcb);
		return ERR_ABRT;
	}

	pend->pcb = newpcb;
	pend->ante = 0;

	// The newpcb is being enqueued into
	// Data may be received for the newpcb while
	// it is still on the queue. Such data is handled by a *temporary* recevive
	// callback accept_recv_cb.

	tcp_arg(newpcb, pend);
	tcp_recv(newpcb, accept_recv_cb);
	tcp_err(newpcb, accept_error_cb);

	return try_to_bake(ol, pend);
}
Пример #8
0
/** Close an iperf tcp session */
static void
lwiperf_tcp_close(lwiperf_state_tcp_t* conn, enum lwiperf_report_type report_type)
{
  err_t err;

  lwip_tcp_conn_report(conn, report_type);
  lwiperf_list_remove(&conn->base);
  if (conn->conn_pcb != NULL) {
    tcp_arg(conn->conn_pcb, NULL);
    tcp_poll(conn->conn_pcb, NULL, 0);
    tcp_sent(conn->conn_pcb, NULL);
    tcp_recv(conn->conn_pcb, NULL);
    tcp_err(conn->conn_pcb, NULL);
    err = tcp_close(conn->conn_pcb);
    if (err != ERR_OK) {
      /* don't want to wait for free memory here... */
      tcp_abort(conn->conn_pcb);
    }
  } else {
    /* no conn pcb, this is the server pcb */
    err = tcp_close(conn->server_pcb);
    LWIP_ASSERT("error", err != ERR_OK);
  }
  LWIPERF_FREE(lwiperf_state_tcp_t, conn);
}
Пример #9
0
void EthernetClient::stop() {
	/* Stop frees any resources including any unread buffers */
	err_t err;

	INT_PROTECT_INIT(oldLevel);

	/* protect the code from preemption of the ethernet interrupt servicing */
	INT_PROTECT(oldLevel);

	struct tcp_pcb * cpcb_copy = (tcp_pcb *) SYNC_FETCH_AND_NULL(&cs->cpcb);
	struct pbuf * p_copy = (pbuf *) SYNC_FETCH_AND_NULL(&cs->p);
	_connected = false;
	cs->port = 0;

	if (cpcb_copy) {
		tcp_err(cpcb_copy, NULL);

		if (p_copy) {
			tcp_recved(cpcb_copy, p_copy->tot_len);
			pbuf_free(p_copy);
		}

		err = tcp_close(cpcb_copy);

		if (err != ERR_OK) {
			/* Error closing, try again later in poll (every 2 sec) */
			tcp_poll(cpcb_copy, do_poll, 4);
		}
	}

	INT_UNPROTECT(oldLevel);
}
Пример #10
0
void ol_tcp_animate(outlet_t *new_ol, struct tcp_pcb *pcb, struct pbuf *ante)
{
	//
	// lwIP tries hard to allocate a new PCB. If there is not enough memory it
	// first kills TIME-WAIT connections and then active connections. The
	// error_cb callback is used along the way. The callback may sent an exit
	// signal to an outlet and the chain of exit signal may reach the current
	// outlet. To avoid this the priority of all PCBs is set to TCP_PRIO_MAX+1.
	//

	tcp_setprio(pcb, TCP_PRIO_MAX +1);

	tcp_arg(pcb, new_ol);	// callback arg
	tcp_recv(pcb, recv_cb);
	tcp_sent(pcb, sent_cb);
	tcp_err(pcb, error_cb);

	new_ol->tcp = pcb;
	if (ante != 0)	// data receive while enqueued
	{
		uint16_t len = ante->tot_len;
		if (len > new_ol->recv_bufsize)
		{
			debug("ol_tcp_animate: tot_len=%d, recv_bufsize=%d, truncating\n",
				  ante->tot_len, new_ol->recv_bufsize);
			len = new_ol->recv_bufsize;	
		}
		pbuf_copy_partial(ante, new_ol->recv_buffer, len, 0);
		new_ol->recv_buf_off = len;
		pbuf_free(ante);
	}
}
Пример #11
0
static err_t ftpd_dataaccept(void *arg, struct tcp_pcb *pcb, err_t err)
{
	struct ftpd_datastate *fsd = arg;

	fsd->msgfs->datapcb = pcb;
	fsd->connected = 1;

	/* Tell TCP that we wish to be informed of incoming data by a call
	   to the http_recv() function. */
	tcp_recv(pcb, ftpd_datarecv);

	/* Tell TCP that we wish be to informed of data that has been
	   successfully sent by a call to the ftpd_sent() function. */
	tcp_sent(pcb, ftpd_datasent);

	tcp_err(pcb, ftpd_dataerr);

	switch (fsd->msgfs->state) {
	case FTPD_LIST:
		send_next_directory(fsd, pcb, 0);
		break;
	case FTPD_NLST:
		send_next_directory(fsd, pcb, 1);
		break;
	case FTPD_RETR:
		send_file(fsd, pcb);
		break;
	default:
		break;
	}

	return ERR_OK;
}
Пример #12
0
/*-----------------------------------------------------------------------------------*/
static err_t
ident_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{
  struct ident_state *hs;

  /* Allocate memory for the structure that holds the state of the
     connection. */
  hs = mem_malloc(sizeof(struct ident_state));

  if(hs == NULL) {
    printf("ident_accept: Out of memory\n");
    return ERR_MEM;
  }
  
  /* Initialize the structure. */
  memset (hs, 0, sizeof (*hs));
  if (sizeof (hs->remote) != sizeof (pcb->remote_ip))
    die ("sizeof (hs.remote) != sizeof (pcb->remote_ip)");
  memcpy (&hs->remote, &pcb->remote_ip, sizeof (hs->remote));

  /* Tell TCP that this is the structure we wish to be passed for our
     callbacks. */
  tcp_arg(pcb, hs);

  /* Tell TCP that we wish to be informed of incoming data by a call
     to the ident_recv() function. */
  tcp_recv(pcb, ident_recv);

  tcp_err(pcb, conn_err);
  
  tcp_poll(pcb, ident_poll, 10);
  return ERR_OK;
}
Пример #13
0
/**
 * Clean up and free the ttcp structure
 */
static void ard_tcp_abort(struct ttcp* ttcp) {

	INFO_TCP("Abort ttcb:%p tpcb:%p lpcb:%p\n", ttcp, ttcp->tpcb, ttcp->lpcb);
	if (ttcp->tpcb) {
		tcp_arg(ttcp->tpcb, NULL);
		tcp_sent(ttcp->tpcb, NULL);
		tcp_recv(ttcp->tpcb, NULL);
		tcp_err(ttcp->tpcb, NULL);
		tcp_abort(ttcp->tpcb);
	}

	if (ttcp->lpcb) {
		tcp_arg(ttcp->lpcb, NULL);
		tcp_accept(ttcp->lpcb, NULL);
		tcp_abort(ttcp->lpcb);
	}

	if (ttcp->upcb) {
		udp_disconnect(ttcp->upcb);
		udp_remove(ttcp->upcb);
	}

	if (ttcp->payload)
		free(ttcp->payload);

	free(ttcp);
}
Пример #14
0
/**
 * Clean up and free the ttcp structure
 */
static void ard_tcp_destroy(struct ttcp* ttcp) {
	err_t err = ERR_OK;
	DUMP_TCP_STATE(ttcp);

	if (getSock(ttcp)==-1)
		WARN("ttcp already deallocated!\n");

	if (ttcp->tpcb) {
		tcp_arg(ttcp->tpcb, NULL);
		tcp_sent(ttcp->tpcb, NULL);
		tcp_recv(ttcp->tpcb, NULL);
		tcp_err(ttcp->tpcb, NULL);
		//TEMPORAQARY
		//err = tcp_close(ttcp->tpcb);
		INFO_TCP("Closing tpcb: state:0x%x err:%d\n", ttcp->tpcb->state, err);
	}

	if (ttcp->lpcb) {
		tcp_arg(ttcp->lpcb, NULL);
		tcp_accept(ttcp->lpcb, NULL);
		err = tcp_close(ttcp->lpcb);
		INFO_TCP("Closing lpcb: state:0x%x err:%d\n", ttcp->lpcb->state, err);
	}

	if (ttcp->upcb) {
		udp_disconnect(ttcp->upcb);
		udp_remove(ttcp->upcb);
	}

	if (ttcp->payload)
		free(ttcp->payload);

	free(ttcp);
}
Пример #15
0
static socket_error_t accept_v2(struct socket *listener, struct socket *sock, socket_api_handler_t handler) {
    if (sock == NULL || sock->impl == NULL)
        return SOCKET_ERROR_NULL_PTR;
    switch (sock->family) {
    case SOCKET_DGRAM:
        return SOCKET_ERROR_UNIMPLEMENTED;
    case SOCKET_STREAM:
    {
      struct tcp_pcb *tcp = (struct tcp_pcb *)sock->impl;
      struct tcp_pcb *lpcb = (struct tcp_pcb *)listener->impl;
      /* NOTE: tcp_accepted() is replaced with an empty statement in release,
       * so we need a cast-to-void to remove the unused variable warning */
      (void) lpcb;
      tcp_accepted(lpcb);
      tcp_arg(tcp, (void*) sock);
      tcp_err(tcp, tcp_error_handler);
      tcp_sent(tcp, irqTCPSent);
      tcp_recv(tcp, irqTCPRecv);
      break;
    }
    default:
        return SOCKET_ERROR_BAD_FAMILY;
    }
    sock->handler = (void*)handler;
    sock->rxBufChain = NULL;
    return SOCKET_ERROR_NONE;
}
Пример #16
0
//lwIP tcp_accept()的回调函数
err_t tcp_server_accept(void *arg,struct tcp_pcb *newpcb,err_t err)
{
	err_t ret_err;
	struct tcp_server_struct *es; 
 	LWIP_UNUSED_ARG(arg);
	LWIP_UNUSED_ARG(err);
	tcp_setprio(newpcb,TCP_PRIO_MIN);//设置新创建的pcb优先级
	es=(struct tcp_server_struct*)mem_malloc(sizeof(struct tcp_server_struct)); //分配内存
 	if(es!=NULL) //内存分配成功
	{
		es->state=ES_TCPSERVER_ACCEPTED;  	//接收连接
		es->pcb=newpcb;
		es->p=NULL;
		
		tcp_arg(newpcb,es);
		tcp_recv(newpcb,tcp_server_recv);	//初始化tcp_recv()的回调函数
		tcp_err(newpcb,tcp_server_error); 	//初始化tcp_err()回调函数
		tcp_poll(newpcb,tcp_server_poll,1);	//初始化tcp_poll回调函数
		tcp_sent(newpcb,tcp_server_sent);  	//初始化发送回调函数
		  
		tcp_server_flag|=1<<5;				//标记有客户端连上了
		lwipdev.remoteip[0]=newpcb->remote_ip.addr&0xff; 		//IADDR4
		lwipdev.remoteip[1]=(newpcb->remote_ip.addr>>8)&0xff;  	//IADDR3
		lwipdev.remoteip[2]=(newpcb->remote_ip.addr>>16)&0xff; 	//IADDR2
		lwipdev.remoteip[3]=(newpcb->remote_ip.addr>>24)&0xff; 	//IADDR1 
		ret_err=ERR_OK;
	}else ret_err=ERR_MEM;
Пример #17
0
/*-----------------------------------------------------------------------------------*/
static err_t
http_accept(void *arg, struct tcp_pcb *pcb, err_t err)
{
    struct http_state *hs;

    /* Allocate memory for the structure that holds the state of the
       connection. */
    hs = mem_malloc(sizeof(struct http_state));

    if (hs == NULL)
    {
        return ERR_MEM;
    }

    /* Initialize the structure. */
    hs->file = NULL;
    hs->left = 0;

    /* Tell TCP that this is the structure we wish to be passed for our
       callbacks. */
    tcp_arg(pcb, hs);

    /* Tell TCP that we wish to be informed of incoming data by a call
       to the http_recv() function. */
    tcp_recv(pcb, http_recv);

    tcp_err(pcb, conn_err);

    tcp_poll(pcb, http_poll, 10);
    return ERR_OK;
}
Пример #18
0
static err_t
tcpecho_raw_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
{
  err_t ret_err;
  struct tcpecho_raw_state *es;

  LWIP_UNUSED_ARG(arg);
  if ((err != ERR_OK) || (newpcb == NULL)) {
    return ERR_VAL;
  }

  /* Unless this pcb should have NORMAL priority, set its priority now.
     When running out of pcbs, low priority pcbs can be aborted to create
     new pcbs of higher priority. */
  tcp_setprio(newpcb, TCP_PRIO_MIN);

  es = (struct tcpecho_raw_state *)mem_malloc(sizeof(struct tcpecho_raw_state));
  if (es != NULL) {
    es->state = ES_ACCEPTED;
    es->pcb = newpcb;
    es->retries = 0;
    es->p = NULL;
    /* pass newly allocated es to our callbacks */
    tcp_arg(newpcb, es);
    tcp_recv(newpcb, tcpecho_raw_recv);
    tcp_err(newpcb, tcpecho_raw_error);
    tcp_poll(newpcb, tcpecho_raw_poll, 0);
    tcp_sent(newpcb, tcpecho_raw_sent);
    ret_err = ERR_OK;
  } else {
    ret_err = ERR_MEM;
  }
  return ret_err;
}
Пример #19
0
/**
  * @brief  This function is the implementation of tcp_accept LwIP callback
  * @param  arg: not used
  * @param  newpcb: pointer on tcp_pcb struct for the newly created tcp connection
  * @param  err: not used 
  * @retval err_t: error status
  */
static err_t	
	TCP_accept(void *arg, struct tcp_pcb *newpcb, err_t err) {
		err_t ret_err;
		TCP *es;
		
		LWIP_UNUSED_ARG(arg);
		LWIP_UNUSED_ARG(err);
		tcp_setprio(newpcb, TCP_PRIO_MIN);					/* set priority for the newly accepted tcp connection newpcb */
		es = (TCP *)mem_malloc(sizeof(TCP));				/* allocate structure es to maintain tcp connection informations */
		if (es != NULL) {
			es->state = ES_ACCEPTED;
			es->pcb = newpcb;
			es->tx = NULL;
			es->rx = NULL;
			tcp_arg(newpcb, es);											/* pass newly allocated es structure as argument to newpcb */
			tcp_recv(newpcb, TCP_recv);								/* initialize lwip tcp_recv callback function for newpcb  */ 
			tcp_err(newpcb, TCP_error);								/* initialize lwip tcp_err callback function for newpcb  */
			tcp_poll(newpcb, TCP_poll, 1);						/* initialize lwip tcp_poll callback function for newpcb */

			es->io=((func*)arg)(NULL);								// prvi klic
			if(es->io) {															// tole je lahko tut drugace
				es->f=(func *)arg;
				_thread_add(es->f,es->io,"user app.",0);
				_thread_add(_tcp_flush,es,"tcp flush",0);
			}
			
			ret_err = ERR_OK;
		} else {
			ret_err = ERR_MEM;												/* return memory error */
		}
		return ret_err;  
	}
Пример #20
0
void
socks_tcp_connect(struct socks_data *data)
{
	struct tcp_pcb *pcb;
	err_t ret;

	bufferevent_disable(data->bev, EV_READ);

	LWIP_DEBUGF(SOCKS_DEBUG, ("%s: %s:%d\n", __func__,
				ipaddr_ntoa(&data->ipaddr), data->port));

	pcb = tcp_new();
	if (!pcb)
		data->connect_failed(data);

	pcb->flags |= TF_NODELAY;
	if (data->keep_alive) {
		pcb->so_options |= SOF_KEEPALIVE;
		pcb->keep_intvl = data->keep_alive;
		pcb->keep_idle = data->keep_alive;
	}

	ret = tcp_connect(pcb, &data->ipaddr, data->port, socks_tcp_connect_ok);
	if (ret < 0) {
		tcp_abort(pcb);
		data->connect_failed(data);
	} else {
		data->pcb = pcb;
		tcp_arg(pcb, data);
		tcp_err(pcb, socks_tcp_connect_err);
	}
}
Пример #21
0
static void net_tcp_err_cb(void *arg, err_t err)
{
    struct tls_netconn *conn = (struct tls_netconn *)arg;
    struct tcp_pcb *pcb = conn->pcb.tcp;  
    u8 event = NET_EVENT_TCP_CONNECT_FAILED;
    TLS_DBGPRT_INFO("tcp err = %d\n", err);

    if (pcb) {
        tcp_arg(pcb, NULL);
        tcp_sent(pcb, NULL);
        tcp_recv(pcb, NULL);
        tcp_err(pcb, NULL);
		if (!conn->client) {
		    tcp_accept(pcb, NULL);
		}
		if(err == ERR_OK)
		{
	      tcp_close(pcb);
		}
		
		if(conn->state != NETCONN_STATE_NONE)
		{
           conn->state = NETCONN_STATE_NONE;
           event = NET_EVENT_TCP_DISCONNECT;
		}

		net_send_event_to_hostif(conn, event);
		if(conn->skd->errf != NULL)
		{
			conn->skd->errf(conn->skt_num, err);
		}
		conn->pcb.tcp = NULL;
        net_free_socket(conn);
    }
}
Пример #22
0
int lwip_bind(int s, struct sockaddr *name, socklen_t namelen) {
	sockfd_t	* fd;
	struct ip_addr	ip;
	int		port, rv = 0;

	s = sock_for_fd(s);
	if (s < 0) {
		errno = EBADF;
		return -1;
	}
	fd = fds + s;

	// Make sure it's an internet address we understand.
	if (namelen != sizeof(struct sockaddr_in)) {
		errno = ENAMETOOLONG;
		return -1;
	}

	// Get access
	mutex_lock(fd->mutex);

	// Copy it over
	memcpy(&fd->name, name, namelen);

	// Convert this to an lwIP-happy format
	ip.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr;
	port = ((struct sockaddr_in *)name)->sin_port;

	// Are we TCP or UDP?
	switch (fd->type) {
	case SOCK_STREAM:
		fd->tcppcb = tcp_new();
		tcp_arg(fd->tcppcb, (void *)s);
		tcp_recv(fd->tcppcb, recv_tcp);
		tcp_sent(fd->tcppcb, sent_tcp);
		tcp_poll(fd->tcppcb, poll_tcp, 4);	// 4 == 4 TCP timer intervals
		tcp_err(fd->tcppcb, err_tcp);
		if (tcp_bind(fd->tcppcb, &ip, ntohs(port)) != ERR_OK) {
			if (tcp_close(fd->tcppcb) != ERR_OK)
				tcp_abort(fd->tcppcb);
			fd->tcppcb = NULL;
			errno = EINVAL;
			rv = -1; goto out;
		}
		break;
	case SOCK_DGRAM:
		fd->udppcb = udp_new();
		udp_recv(fd->udppcb, recv_udp, (void *)s);
		udp_bind(fd->udppcb, &ip, ntohs(port));
		break;
	default:
		assert( 0 );
		errno = EINVAL;
		rv = -1; goto out;
	}

out:
	mutex_unlock(fd->mutex);
	return rv;
}
Пример #23
0
/** This is called when a new client connects for an iperf tcp session */
static err_t
lwiperf_tcp_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
{
  lwiperf_state_tcp_t *s, *conn;
  if ((err != ERR_OK)  || (newpcb == NULL) || (arg == NULL)) {
    return ERR_VAL;
  }

  s = (lwiperf_state_tcp_t*)arg;
  conn = (lwiperf_state_tcp_t*)LWIPERF_ALLOC(lwiperf_state_tcp_t);
  if (conn == NULL) {
    return ERR_MEM;
  }
  memset(conn, 0, sizeof(lwiperf_state_tcp_t));
  conn->base.tcp = 1;
  conn->base.server = 1;
  conn->base.related_server_state = &s->base;
  conn->server_pcb = s->server_pcb;
  conn->conn_pcb = newpcb;
  conn->time_started = sys_now();
  conn->report_fn = s->report_fn;
  conn->report_arg = s->report_arg;

  /* setup the tcp rx connection */
  tcp_arg(newpcb, conn);
  tcp_recv(newpcb, lwiperf_tcp_recv);
  tcp_poll(newpcb, lwiperf_tcp_poll, 2U);
  tcp_err(conn->conn_pcb, lwiperf_tcp_err);

  lwiperf_list_add(&conn->base);
  return ERR_OK;
}
Пример #24
0
static err_t net_accept_cb(void *arg, struct tcp_pcb *newpcb, err_t err) {
  lnet_userdata *ud = (lnet_userdata*)arg;
  if (!ud || ud->type != TYPE_TCP_SERVER || !ud->pcb) return ERR_ABRT;
  if (ud->self_ref == LUA_NOREF || ud->server.cb_accept_ref == LUA_NOREF) return ERR_ABRT;

  lua_State *L = lua_getstate();
  lua_rawgeti(L, LUA_REGISTRYINDEX, ud->server.cb_accept_ref);

  lnet_userdata *nud = net_create(L, TYPE_TCP_CLIENT);
  lua_pushvalue(L, 2);
  nud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  nud->tcp_pcb = newpcb;
  tcp_arg(nud->tcp_pcb, nud);
  tcp_err(nud->tcp_pcb, net_err_cb);
  tcp_recv(nud->tcp_pcb, net_tcp_recv_cb);
  tcp_sent(nud->tcp_pcb, net_sent_cb);
  nud->tcp_pcb->so_options |= SOF_KEEPALIVE;
  nud->tcp_pcb->keep_idle = ud->server.timeout * 1000;
  nud->tcp_pcb->keep_cnt = 1;
  tcp_accepted(ud->tcp_pcb);

  lua_call(L, 1, 0);

  return net_connected_cb(nud, nud->tcp_pcb, ERR_OK);
}
Пример #25
0
static err_t http_accept(void *arg, tcp_pcb *pcb, err_t err)
{
  LWIP_UNUSED_ARG(arg);
  LWIP_UNUSED_ARG(err);

  tcp_setprio(pcb, TCP_PRIO_MIN);

  //RepRapNetworkMessage("http_accept\n");

  HttpState *hs = (HttpState*)mem_malloc(sizeof(HttpState));
  if (hs == NULL)
  {
	  RepRapNetworkMessage("Out of memory!\n");
	  return ERR_MEM;
  }

  /* Initialize the structure. */
  hs->pcb = pcb;
  hs->file = NULL;
  hs->left = 0;
  hs->retries = 0;
  hs->sendingRs = NULL;

  tcp_accepted(listening_pcb);	// tell TCP to accept further connections
  tcp_arg(pcb, hs);				// tell TCP that this is the structure we wish to be passed for our callbacks
  tcp_recv(pcb, http_recv);		// tell TCP that we wish to be informed of incoming data by a call to the http_recv() function
  tcp_err(pcb, conn_err);
  tcp_poll(pcb, http_poll, 4);
  return ERR_OK;
}
Пример #26
0
/**
 * Clean up and free the ttcp structure
 */
static void
ttcp_destroy(struct ttcp* ttcp)
{
        if (ttcp->tpcb) {
                tcp_arg(ttcp->tpcb, NULL);
                tcp_sent(ttcp->tpcb, NULL);
                tcp_recv(ttcp->tpcb, NULL);
                tcp_err(ttcp->tpcb, NULL);
                tcp_close(ttcp->tpcb);
        }

        if (ttcp->lpcb) {
                tcp_arg(ttcp->lpcb, NULL);
                tcp_accept(ttcp->lpcb, NULL);
                tcp_close(ttcp->lpcb);
        }

        if (ttcp->upcb) {
                udp_disconnect(ttcp->upcb);
                udp_remove(ttcp->upcb);
        }

        if (ttcp->payload)
                free(ttcp->payload);
        timer_cancel_timeout(ttcp->tid);
        free(ttcp);
}
Пример #27
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;
}
Пример #28
0
/**
 * Callback function called when Server (THIS) receives a valid connection from a client
 *  or a server connects to this client in CLIENT mode
 *
 * @param argument sent by lwIP
 * @param tcp connection descriptor
 * @param reception error flag
 * @return error type on callback to be processed by lwIP
 */
static err_t
BRIDGE_UART_Accept(void *arg, struct tcp_pcb *pcb, err_t err)
{
  struct bridge_state *hs;
  
  /* Allocate memory for the structure that holds the state of the connection */
  hs = mem_malloc(sizeof(struct bridge_state));  

  if (hs == NULL) 
  {
    return ERR_MEM;
  }

  /* Initialize the structure. */
  hs->data = NULL;
  hs->left = 0;
  hs->retries = 0;

  /*uart structure*/
  p_uart_tx_state.tx_pcb = pcb;
  p_uart_tx_state.p_bridge_state = hs;

  /* Tell TCP that this is the structure we wish to be passed for our callbacks */
  tcp_arg(pcb, hs);

  /*called function when RX*/
  tcp_recv(pcb, BRIDGE_UART_ETH_RX);

  tcp_err(pcb, BRIDGE_UART_ETH_ERROR);

  tcp_setprio(pcb,TCP_PRIO_MAX);
  
  return ERR_OK;
}
Пример #29
0
err_t
iperfserver_accept(void *arg, struct tcp_pcb *newpcb, err_t err)
{
  err_t ret_err;
  struct iperfserver_state *es;

  LWIP_UNUSED_ARG(arg);
  LWIP_UNUSED_ARG(err);

  /* commonly observed practive to call tcp_setprio(), why? */
  tcp_setprio(newpcb, TCP_PRIO_MIN);

  es = (struct iperfserver_state *)mem_malloc(sizeof(struct iperfserver_state));
  if (es != NULL)
  {
    es->state = ES_ACCEPTED;
    es->pcb = newpcb;
    es->retries = 0;
    es->p = NULL;
    /* pass newly allocated es to our callbacks */
    tcp_arg(newpcb, es);
    tcp_recv(newpcb, iperfserver_recv);
    tcp_err(newpcb, iperfserver_error);
  
    ret_err = ERR_OK;
  }
  else
  {
    ret_err = ERR_MEM;
  }
  return ret_err;  
}
Пример #30
0
bool AsyncClient::connect(IPAddress ip, uint16_t port){
    if (_pcb){
        log_w("already connected, state %d", _pcb->state);
        return false;
    }
    if(!_start_async_task()){
        log_e("failed to start task");
        return false;
    }

    ip_addr_t addr;
    addr.type = IPADDR_TYPE_V4;
    addr.u_addr.ip4.addr = ip;

    tcp_pcb* pcb = tcp_new_ip_type(IPADDR_TYPE_V4);
    if (!pcb){
        log_e("pcb == NULL");
        return false;
    }

    tcp_arg(pcb, this);
    tcp_err(pcb, &_tcp_error);
    if(_in_lwip_thread){
        tcp_connect(pcb, &addr, port,(tcp_connected_fn)&_s_connected);
    } else {
        _tcp_connect(pcb, &addr, port,(tcp_connected_fn)&_s_connected);
    }
    return true;
}