Beispiel #1
0
int Socket::WaitForConnect()
{
    lwip_fd_set fds;
    struct timeval tmo;
    int error;
    socklen_t len = sizeof(error);

    LWIP_FD_ZERO(&fds);
    LWIP_FD_SET(socket_->fd, &fds);
    tmo.tv_sec = 5;
    tmo.tv_usec = 0;

    //log(LOG_WARN) << "waiting";

    if ( lwip_select(socket_->fd+1, NULL, &fds, NULL, &tmo) <= 0)
    {
        return -1;
    }

    if ( lwip_getsockopt(socket_->fd, SOL_SOCKET, SO_ERROR, &error, &len) < 0 ||
         error > 0 )
    {
        return -1;
    }

    return 0;
}
Beispiel #2
0
// return: 0  timeout.
//         >0 length
//         <0 socket error
    int
blocking_lwip_recv(int s, void *mem, size_t len, int timeout) // the len param here is the length to recv.
{
    int readlen, offset = 0;
    fd_set fds;
    int ret;
    struct timeval to;

    to.tv_sec = timeout/1000;
    to.tv_usec = (timeout%1000)*1000;

    while(1)
    {
        FD_ZERO(&fds);
        FD_SET(s,&fds);
        ret = lwip_select(s+1,&fds,0,0,&to);
        if( ret == 0 )
            break;
        else if( ret < 0 )
            return ret;

        readlen = lwip_recvfrom(s, ((char*)mem)+offset, len-offset, 0, NULL, NULL);
        if( readlen == 0 ) // select is ok and readlen == 0 means connection lost.
            return -1;
        else if( readlen < 0 )
            return readlen;
        if( readlen == (len-offset) )
        {
            offset = len;
            break;
        }
        offset += readlen;
    }
    return offset;
}
Beispiel #3
0
int
mc_event_main(xsMachine *the, mc_event_shutdown_callback_t *cb)
{
	struct timeval tv;
	fd_set rs, ws;
	int n = -1, i;
	unsigned int flags;
	uint64_t timeInterval;
	struct sockaddr_in sin;
	int localevent_sock;

	mc_shutdown_callback = cb;
	g_status = -1;	/* not ready yet */
	if ((localevent_sock = lwip_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
		return -1;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(MC_LOCAL_EVENT_PORT);
	sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
	lwip_bind(localevent_sock, (struct sockaddr *)&sin, sizeof(sin));
	mc_event_register(localevent_sock, MC_SOCK_READ, mc_event_local_callback, the);
	mc_event_delegation_init();
	g_status = 0;	/* running */
	while (!g_status) {
		timeInterval = mc_event_process_timeout(the);
		if (timeInterval != 0) {
			tv.tv_sec = timeInterval / 1000;
			tv.tv_usec = (timeInterval % 1000) * 1000;
		}
		if (maxfd < 0) {	/* @@ what if only timer is running?? */
			mc_log_debug("event: no one is waiting!\n");
			break;	/* no one is waiting for anything! will be blocked forever unless break */
		}
		rs = reads;
		ws = writes;
		n = lwip_select(maxfd + 1, &rs, &ws, NULL, timeInterval > 0 ? &tv : NULL);
		if (mc_event_callback_any.callback != NULL)
			(*mc_event_callback_any.callback)(mc_event_callback_any.fd, (unsigned int)n, mc_event_callback_any.closure);
		if (n > 0) {
			for (i = 0; i <= maxfd; i++) {
				flags = 0;
				if (FD_ISSET(i, &rs))
					flags |= MC_SOCK_READ;
				if (FD_ISSET(i, &ws))
					flags |= MC_SOCK_WRITE;
				if (flags) {
					if (mc_event_callbacks[i].callback == NULL) {
						mc_log_error("event: %s ready for closed socket(%d)!?\n", flags & MC_SOCK_WRITE ? "write" : "read", i);
						continue;
					}
					(*mc_event_callbacks[i].callback)(i, flags, mc_event_callbacks[i].closure);
				}
			}
		}
	}
	mc_event_delegation_fin();
	lwip_close(localevent_sock);
	return g_exit_status;
}
static void   SC_Select(__SYSCALL_PARAM_BLOCK*  pspb)
{
	pspb->lpRetValue = (LPVOID)lwip_select(
		(INT)PARAM(0),
		(fd_set*)PARAM(1),
		(fd_set*)PARAM(2),
		(fd_set*)PARAM(3),
		(struct timeval*)PARAM(4)
		);
}
int socket_select(struct mySocket *sock, struct timeval *timeout, int read, int write) {
    fd_set fdSet;
    FD_ZERO(&fdSet);
    FD_SET(sock->_sock_fd, &fdSet);
    
    fd_set* readset  = (read ) ? (&fdSet) : (NULL);
    fd_set* writeset = (write) ? (&fdSet) : (NULL);
    
    int ret = lwip_select(FD_SETSIZE, readset, writeset, NULL, timeout);
    return (ret <= 0 || !FD_ISSET(sock->_sock_fd, &fdSet)) ? (-1) : (0);
}
Beispiel #6
0
/** helper thread to wait for socket events using select */
static void
sockex_select_waiter(void *arg)
{
  struct sockex_select_helper *helper = (struct sockex_select_helper *)arg;
  int ret;
  fd_set readset;
  fd_set writeset;
  fd_set errset;
  struct timeval tv;

  LWIP_ASSERT("helper != NULL", helper != NULL);

  FD_ZERO(&readset);
  FD_ZERO(&writeset);
  FD_ZERO(&errset);
  if (helper->wait_read) {
    FD_SET(helper->socket, &readset);
  }
  if (helper->wait_write) {
    FD_SET(helper->socket, &writeset);
  }
  if (helper->wait_err) {
    FD_SET(helper->socket, &errset);
  }

  tv.tv_sec = helper->wait_ms / 1000;
  tv.tv_usec = (helper->wait_ms % 1000) * 1000;

  ret = lwip_select(helper->socket, &readset, &writeset, &errset, &tv);
  if (helper->expect_read || helper->expect_write || helper->expect_err) {
    LWIP_ASSERT("ret > 0", ret > 0);
  } else {
    LWIP_ASSERT("ret == 0", ret == 0);
  }
  if (helper->expect_read) {
    LWIP_ASSERT("FD_ISSET(helper->socket, &readset)", FD_ISSET(helper->socket, &readset));
  } else {
    LWIP_ASSERT("!FD_ISSET(helper->socket, &readset)", !FD_ISSET(helper->socket, &readset));
  }
  if (helper->expect_write) {
    LWIP_ASSERT("FD_ISSET(helper->socket, &writeset)", FD_ISSET(helper->socket, &writeset));
  } else {
    LWIP_ASSERT("!FD_ISSET(helper->socket, &writeset)", !FD_ISSET(helper->socket, &writeset));
  }
  if (helper->expect_err) {
    LWIP_ASSERT("FD_ISSET(helper->socket, &errset)", FD_ISSET(helper->socket, &errset));
  } else {
    LWIP_ASSERT("!FD_ISSET(helper->socket, &errset)", !FD_ISSET(helper->socket, &errset));
  }
  sys_sem_signal(&helper->sem);
}
int LWIP_SOCKETS_Driver::Select( int nfds, SOCK_fd_set* readfds, SOCK_fd_set* writefds, SOCK_fd_set* exceptfds, const SOCK_timeval* timeout )
{
    NATIVE_PROFILE_PAL_NETWORK();
    int ret = 0;

    fd_set read;
    fd_set write;
    fd_set excpt;

    fd_set* pR = (readfds   != NULL) ? &read  : NULL;
    fd_set* pW = (writefds  != NULL) ? &write : NULL;
    fd_set* pE = (exceptfds != NULL) ? &excpt : NULL;

    // If the network goes down then we should alert any pending socket actions
    if(exceptfds != NULL && exceptfds->fd_count > 0)
    {
        struct netif *pNetIf = netif_find_interface(g_LWIP_SOCKETS_Driver.m_interfaces[0].m_interfaceNumber);

        if(pNetIf != NULL)
        {
            if(!netif_is_up(pNetIf))
            {
                if(readfds  != NULL) readfds->fd_count = 0;
                if(writefds != NULL) writefds->fd_count = 0;

                errno = ENETDOWN;

                return exceptfds->fd_count;
            }
        }
    }

    MARSHAL_SOCK_FDSET_TO_FDSET(readfds  , pR);
    MARSHAL_SOCK_FDSET_TO_FDSET(writefds , pW);
    MARSHAL_SOCK_FDSET_TO_FDSET(exceptfds, pE);

    ret = lwip_select(MEMP_NUM_NETCONN, pR, pW, pE, (struct timeval *)timeout);

    MARSHAL_FDSET_TO_SOCK_FDSET(readfds  , pR);
    MARSHAL_FDSET_TO_SOCK_FDSET(writefds , pW);
    MARSHAL_FDSET_TO_SOCK_FDSET(exceptfds, pE);

    return ret;
}
Beispiel #8
0
//--------------------------------------------------------------
int recv_noblock(int sock, u8 *buf, int bsize)
{
	int r;
	fd_set rfd;

	FD_ZERO(&rfd);
	FD_SET(sock, &rfd);

	r = lwip_select(sock+1, &rfd, NULL, NULL, NULL);
	if (r < 0)
		return -1;

	// receive the packet
	r = lwip_recv(sock, buf, bsize, 0);
	if (r < 0)
		return -2;

    return r;
}
static int sendCallback(WOLFSSL* ssl, char *buf, int sz, void *ctx)
{
    int fd = *(int*)ctx;
	int result;

	(void)ssl;

    fd_set wfds;
    FD_ZERO(&wfds);
    FD_SET(fd, &wfds);
    
	if (lwip_select(FD_SETSIZE, NULL, &wfds, NULL, NULL) < 0)
	{
		return -1;
	}
	else
	{
		result = lwip_send(fd, buf, sz, 0);
	}

	return result;
}
Beispiel #10
0
END_TEST

START_TEST(test_sockets_select)
{
#if LWIP_SOCKET_SELECT
  int s;
  int ret;
  fd_set readset;
  fd_set writeset;
  fd_set errset;
  struct timeval tv;

  fail_unless(test_sockets_get_used_count() == 0);

  s = lwip_socket(AF_INET, SOCK_STREAM, 0);
  fail_unless(s >= 0);
  fail_unless(test_sockets_get_used_count() == 0);

  FD_ZERO(&readset);
  FD_SET(s, &readset);
  FD_ZERO(&writeset);
  FD_SET(s, &writeset);
  FD_ZERO(&errset);
  FD_SET(s, &errset);

  tv.tv_sec = tv.tv_usec = 0;
  ret = lwip_select(s + 1, &readset, &writeset, &errset, &tv);
  fail_unless(ret == 0);
  fail_unless(test_sockets_get_used_count() == 0);

  ret = lwip_close(s);
  fail_unless(ret == 0);

#endif
  LWIP_UNUSED_ARG(_i);
}
Beispiel #11
0
void net_listen_thread_entry(void *p)
{
    int listenfd;
    struct sockaddr_in saddr;
    fd_set readset;

    // check mode first.
    if( !((getWorkingMode() == TCP_SERVER) || (getWorkingMode() == TCP_AUTO)) )
        return;
    // Acquire our socket for listening for connections
    listenfd = lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if( listenfd == -1 )
    {
        rt_kprintf("Can not create socket!\n");
        return;
    }

    memset(&saddr, 0, sizeof(saddr));
    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr = htonl(INADDR_ANY);
    saddr.sin_port = htons(getListenPort());     //server port

    if (lwip_bind(listenfd, (struct sockaddr *) &saddr, sizeof(saddr)) == -1)
    {
        lwip_close(listenfd);
        rt_kprintf("Socket bind failed!\n");
        return;
    }

    /* Put socket into listening mode */
    if (lwip_listen(listenfd, MAX_LISTEN_SOCK) == -1)
    {
        lwip_close(listenfd);
        rt_kprintf("Listen failed.\n");
        return;
    }

    /* Wait for data or a new connection */
    while(1)
    {
        /* Determine what sockets need to be in readset */
        FD_ZERO(&readset);
        FD_SET(listenfd, &readset);

        // wait forever.
        if( lwip_select(listenfd+1, &readset, 0, 0, 0) == 0 )
            continue;

        if (FD_ISSET(listenfd, &readset))
        {
            int i;
            socklen_t clilen = sizeof(struct sockaddr_in);

            for( i = 0 ; i < SOCKET_LIST_SIZE ; i++ )
            {
                // we don't block here.
                rt_err_t ret = rt_mutex_take(&(socket_list[i].mu_sock),RT_WAITING_NO);
                if( ret == -RT_ETIMEOUT )
                    continue;

                // we already took the mutex here.
                if( socket_list[i].used )
                {
                    rt_mutex_release(&(socket_list[i].mu_sock));
                    continue;
                }

                // it's an empty slot.
                socket_list[i].socket = lwip_accept(listenfd,
                        (struct sockaddr *)&(socket_list[i].cliaddr),&clilen);
                // if accept failed.
                if( socket_list[i].socket < 0 )
                {
                    rt_kprintf("Accept failed!\n");
                }
                // accept successfully.
                else
                {
                    int optval = 1;
                    // set keepalive.
                    lwip_setsockopt(socket_list[i].socket,SOL_SOCKET,SO_KEEPALIVE,&optval,sizeof(optval));
                    // set used flag.
                    socket_list[i].used = 1;
                    rt_kprintf("Accept connection.\n");
                }
                rt_mutex_release(&(socket_list[i].mu_sock));
                break;
            }

            // check if not enough slot.
            if( i == SOCKET_LIST_SIZE )
            {
                // just accept and disconnect.
                int sock;
                struct sockaddr cliaddr;
                socklen_t clilen;
                sock = lwip_accept(listenfd, &cliaddr, &clilen);
                if (sock >= 0)
                    lwip_close(sock);
                rt_kprintf("Not enough slot, accept and close connection.\n");
            }
        }
        else
        {
            rt_kprintf("ERROR,should not reach here!\n");
        }
    }
}
Beispiel #12
0
void usart_tx_thread_entry(void *p)
{
    fd_set readset;
    struct timeval timeout;
    int fd_max;

    timeout.tv_sec = 0; // second.
    timeout.tv_usec = 100*1000; //wait micro second.


    while( 1 )
    {
        int i;
        // prepare select fd.
        FD_ZERO(&readset);
        fd_max = 0;
        for( i = 0 ; i < SOCKET_LIST_SIZE ; i++ )
        {
            if( socket_list[i].used )
            {
                if( fd_max < socket_list[i].socket )
                    fd_max = socket_list[i].socket;
                FD_SET(socket_list[i].socket,&readset);
            }
        }
        // no connection.
        if( fd_max == 0 )
        {
            rt_thread_delay(1); // delay 10ms.
            continue;
        }

        if( lwip_select(fd_max+1,&readset,NULL,0,&timeout) == 0 )
            continue;

        for( i = 0 ; i < SOCKET_LIST_SIZE ; i++ )
        {
            rt_err_t ret;
            // NOTE: we can take tx semaphore here means that the DMA buffer is not in use.
            // We must NOT write the DMA buffer until notified to be used.
            rt_sem_take(&tx1_sem,RT_WAITING_FOREVER);
            rt_sem_take(&tx2_sem,RT_WAITING_FOREVER);
            // Timeout 100ms.
            ret = rt_mutex_take(&(socket_list[i].mu_sock),10);
            if( ret == -RT_ETIMEOUT )
            {
                rt_kprintf("Taking mu_sock timeout.\n");
                rt_sem_release(&tx2_sem);
                rt_sem_release(&tx1_sem);
                continue;
            }
            if( socket_list[i].used && FD_ISSET(socket_list[i].socket,&readset) )
            {
                unsigned short dataLen = lwip_recv(socket_list[i].socket,tx_buf,TX_BUF_SIZE,MSG_DONTWAIT);
                if( dataLen > 0 )
                {
                    usart_bytes_sent += dataLen;
                    usart_led_flash();
                    dev_uart1->write(dev_uart1,0,tx_buf,dataLen);
                    dev_uart2->write(dev_uart2,0,tx_buf,dataLen);
                    // we have sent data to usart.
                    rt_mutex_release(&(socket_list[i].mu_sock));
                    continue;
                }
                else
                {
                    lwip_close(socket_list[i].socket);
                    socket_list[i].used = 0;
                    rt_kprintf("recv failed or FIN recv, close socket.\n");
                }
            }
            rt_mutex_release(&(socket_list[i].mu_sock));
            rt_sem_release(&tx2_sem);
            rt_sem_release(&tx1_sem);
        }
    }
}
Beispiel #13
0
void udp_setup_thread_entry(void *p)
{
    int sock;
    int bytes_read;
    struct sockaddr_in server_addr , client_addr;
    int optval  = 1;
    fd_set readset;

    /* create socket */
    if ((sock = lwip_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
    {
        rt_kprintf("Can not create udp setup socket.\n");
        return;
    }

    lwip_setsockopt(sock,SOL_SOCKET,SO_BROADCAST,&optval ,sizeof(optval));

    /* init server socket address */
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SETUP_UDP_PORT);
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    rt_memset(&(server_addr.sin_zero),0, sizeof(server_addr.sin_zero));

    if (lwip_bind(sock,(struct sockaddr *)&server_addr,
                sizeof(struct sockaddr)) == -1)
    {
        rt_kprintf("Bind error\n");
        return;
    }

    rt_kprintf("UDPServer Waiting for client on port %d \n",SETUP_UDP_PORT);

    while (1)
    {
        int bytes_ret;
        rt_uint32_t addr_len = sizeof(struct sockaddr_in);

        FD_ZERO(&readset);
        FD_SET(sock, &readset);
        if( lwip_select(sock+1, &readset, 0, 0, 0) == 0 )
            continue;
        rt_mutex_take(&setup_data_buf_mutex,RT_WAITING_FOREVER);
        bytes_read = lwip_recvfrom(sock, setup_data_buf, DATA_BUF_SIZE, MSG_DONTWAIT,
                (struct sockaddr *)&client_addr, &addr_len);
        rt_mutex_release(&setup_data_buf_mutex);
        if( bytes_read < 0 )
        {
            continue;
        }
        rt_mutex_take(&setup_data_buf_mutex,RT_WAITING_FOREVER);
        setup_data_buf[bytes_read] = 0;
        bytes_ret = processCMD(setup_data_buf,bytes_read);
        rt_mutex_release(&setup_data_buf_mutex);
        if( bytes_ret > 0 )
        {
            // command execute success, send reply in buffer.
            client_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
            rt_mutex_take(&setup_data_buf_mutex,RT_WAITING_FOREVER);
            lwip_sendto(sock,setup_data_buf,bytes_ret,0,(struct sockaddr*)&client_addr, sizeof(struct sockaddr));
            rt_mutex_release(&setup_data_buf_mutex);
        }
    }
    // Should not reach here!.
}
Beispiel #14
0
/** This is an example function that tests
    the recv function (timeout etc.). */
static void
sockex_testrecv(void *arg)
{
  int s;
  int ret;
  int err;
  int opt;
  struct sockaddr_in addr;
  size_t len;
  char rxbuf[1024];
  fd_set readset;
  fd_set errset;
  struct timeval tv;

  LWIP_UNUSED_ARG(arg);
  /* set up address to connect to */
  memset(&addr, 0, sizeof(addr));
  addr.sin_len = sizeof(addr);
  addr.sin_family = AF_INET;
  addr.sin_port = PP_HTONS(SOCK_TARGET_PORT);
  addr.sin_addr.s_addr = inet_addr(SOCK_TARGET_HOST);

  /* first try blocking: */

  /* create the socket */
  s = lwip_socket(AF_INET, SOCK_STREAM, 0);
  LWIP_ASSERT("s >= 0", s >= 0);

  /* connect */
  ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr));
  /* should succeed */
  LWIP_ASSERT("ret == 0", ret == 0);

  /* set recv timeout (100 ms) */
  opt = 100;
  ret = lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &opt, sizeof(int));
  LWIP_ASSERT("ret == 0", ret == 0);

  /* write the start of a GET request */
#define SNDSTR1 "G"
  len = strlen(SNDSTR1);
  ret = lwip_write(s, SNDSTR1, len);
  LWIP_ASSERT("ret == len", ret == (int)len);

  /* should time out if the other side is a good HTTP server */
  ret = lwip_read(s, rxbuf, 1);
  LWIP_ASSERT("ret == -1", ret == -1);
  err = errno;
  LWIP_ASSERT("errno == EAGAIN", err == EAGAIN);

  /* write the rest of a GET request */
#define SNDSTR2 "ET / HTTP_1.1\r\n\r\n"
  len = strlen(SNDSTR2);
  ret = lwip_write(s, SNDSTR2, len);
  LWIP_ASSERT("ret == len", ret == (int)len);

  /* wait a while: should be enough for the server to send a response */
  sys_msleep(1000);

  /* should not time out but receive a response */
  ret = lwip_read(s, rxbuf, 1024);
  LWIP_ASSERT("ret > 0", ret > 0);

  /* now select should directly return because the socket is readable */
  FD_ZERO(&readset);
  FD_ZERO(&errset);
  FD_SET(s, &readset);
  FD_SET(s, &errset);
  tv.tv_sec = 10;
  tv.tv_usec = 0;
  ret = lwip_select(s + 1, &readset, NULL, &errset, &tv);
  LWIP_ASSERT("ret == 1", ret == 1);
  LWIP_ASSERT("!FD_ISSET(s, &errset)", !FD_ISSET(s, &errset));
  LWIP_ASSERT("FD_ISSET(s, &readset)", FD_ISSET(s, &readset));

  /* should not time out but receive a response */
  ret = lwip_read(s, rxbuf, 1024);
  /* might receive a second packet for HTTP/1.1 servers */
  if (ret > 0) {
    /* should return 0: closed */
    ret = lwip_read(s, rxbuf, 1024);
    LWIP_ASSERT("ret == 0", ret == 0);
  }

  /* close */
  ret = lwip_close(s);
  LWIP_ASSERT("ret == 0", ret == 0);

  printf("sockex_testrecv finished successfully\n");
}
Beispiel #15
0
/** This is an example function that tests
    blocking- and nonblocking connect. */
static void
sockex_nonblocking_connect(void *arg)
{
  int s;
  int ret;
  u32_t opt;
  struct sockaddr_in addr;
  fd_set readset;
  fd_set writeset;
  fd_set errset;
  struct timeval tv;
  u32_t ticks_a, ticks_b;
  int err;

  LWIP_UNUSED_ARG(arg);
  /* set up address to connect to */
  memset(&addr, 0, sizeof(addr));
  addr.sin_len = sizeof(addr);
  addr.sin_family = AF_INET;
  addr.sin_port = PP_HTONS(SOCK_TARGET_PORT);
  addr.sin_addr.s_addr = inet_addr(SOCK_TARGET_HOST);

  /* first try blocking: */

  /* create the socket */
  s = lwip_socket(AF_INET, SOCK_STREAM, 0);
  LWIP_ASSERT("s >= 0", s >= 0);

  /* connect */
  ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr));
  /* should succeed */
  LWIP_ASSERT("ret == 0", ret == 0);

  /* write something */
  ret = lwip_write(s, "test", 4);
  LWIP_ASSERT("ret == 4", ret == 4);

  /* close */
  ret = lwip_close(s);
  LWIP_ASSERT("ret == 0", ret == 0);

  /* now try nonblocking and close before being connected */

  /* create the socket */
  s = lwip_socket(AF_INET, SOCK_STREAM, 0);
  LWIP_ASSERT("s >= 0", s >= 0);
  /* nonblocking */
  opt = lwip_fcntl(s, F_GETFL, 0);
  LWIP_ASSERT("ret != -1", ret != -1);
  opt |= O_NONBLOCK;
  ret = lwip_fcntl(s, F_SETFL, opt);
  LWIP_ASSERT("ret != -1", ret != -1);
  /* connect */
  ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr));
  /* should have an error: "inprogress" */
  LWIP_ASSERT("ret == -1", ret == -1);
  err = errno;
  LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS);
  /* close */
  ret = lwip_close(s);
  LWIP_ASSERT("ret == 0", ret == 0);
  /* try to close again, should fail with EBADF */
  ret = lwip_close(s);
  LWIP_ASSERT("ret == -1", ret == -1);
  err = errno;
  LWIP_ASSERT("errno == EBADF", err == EBADF);
  printf("closing socket in nonblocking connect succeeded\n");

  /* now try nonblocking, connect should succeed:
     this test only works if it is fast enough, i.e. no breakpoints, please! */

  /* create the socket */
  s = lwip_socket(AF_INET, SOCK_STREAM, 0);
  LWIP_ASSERT("s >= 0", s >= 0);

  /* nonblocking */
  opt = 1;
  ret = lwip_ioctl(s, FIONBIO, &opt);
  LWIP_ASSERT("ret == 0", ret == 0);

  /* connect */
  ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr));
  /* should have an error: "inprogress" */
  LWIP_ASSERT("ret == -1", ret == -1);
  err = errno;
  LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS);

  /* write should fail, too */
  ret = lwip_write(s, "test", 4);
  LWIP_ASSERT("ret == -1", ret == -1);
  err = errno;
  LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS);

  FD_ZERO(&readset);
  FD_SET(s, &readset);
  FD_ZERO(&writeset);
  FD_SET(s, &writeset);
  FD_ZERO(&errset);
  FD_SET(s, &errset);
  tv.tv_sec = 0;
  tv.tv_usec = 0;
  /* select without waiting should fail */
  ret = lwip_select(s + 1, &readset, &writeset, &errset, &tv);
  LWIP_ASSERT("ret == 0", ret == 0);
  LWIP_ASSERT("!FD_ISSET(s, &writeset)", !FD_ISSET(s, &writeset));
  LWIP_ASSERT("!FD_ISSET(s, &readset)", !FD_ISSET(s, &readset));
  LWIP_ASSERT("!FD_ISSET(s, &errset)", !FD_ISSET(s, &errset));

  FD_ZERO(&readset);
  FD_SET(s, &readset);
  FD_ZERO(&writeset);
  FD_SET(s, &writeset);
  FD_ZERO(&errset);
  FD_SET(s, &errset);
  ticks_a = sys_now();
  /* select with waiting should succeed */
  ret = lwip_select(s + 1, &readset, &writeset, &errset, NULL);
  ticks_b = sys_now();
  LWIP_ASSERT("ret == 1", ret == 1);
  LWIP_ASSERT("FD_ISSET(s, &writeset)", FD_ISSET(s, &writeset));
  LWIP_ASSERT("!FD_ISSET(s, &readset)", !FD_ISSET(s, &readset));
  LWIP_ASSERT("!FD_ISSET(s, &errset)", !FD_ISSET(s, &errset));

  /* now write should succeed */
  ret = lwip_write(s, "test", 4);
  LWIP_ASSERT("ret == 4", ret == 4);

  /* close */
  ret = lwip_close(s);
  LWIP_ASSERT("ret == 0", ret == 0);

  printf("select() needed %d ticks to return writable\n", ticks_b - ticks_a);


  /* now try nonblocking to invalid address:
     this test only works if it is fast enough, i.e. no breakpoints, please! */

  /* create the socket */
  s = lwip_socket(AF_INET, SOCK_STREAM, 0);
  LWIP_ASSERT("s >= 0", s >= 0);

  /* nonblocking */
  opt = 1;
  ret = lwip_ioctl(s, FIONBIO, &opt);
  LWIP_ASSERT("ret == 0", ret == 0);

  addr.sin_addr.s_addr++;

  /* connect */
  ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr));
  /* should have an error: "inprogress" */
  LWIP_ASSERT("ret == -1", ret == -1);
  err = errno;
  LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS);

  /* write should fail, too */
  ret = lwip_write(s, "test", 4);
  LWIP_ASSERT("ret == -1", ret == -1);
  err = errno;
  LWIP_ASSERT("errno == EINPROGRESS", err == EINPROGRESS);

  FD_ZERO(&readset);
  FD_SET(s, &readset);
  FD_ZERO(&writeset);
  FD_SET(s, &writeset);
  FD_ZERO(&errset);
  FD_SET(s, &errset);
  tv.tv_sec = 0;
  tv.tv_usec = 0;
  /* select without waiting should fail */
  ret = lwip_select(s + 1, &readset, &writeset, &errset, &tv);
  LWIP_ASSERT("ret == 0", ret == 0);

  FD_ZERO(&readset);
  FD_SET(s, &readset);
  FD_ZERO(&writeset);
  FD_SET(s, &writeset);
  FD_ZERO(&errset);
  FD_SET(s, &errset);
  ticks_a = sys_now();
  /* select with waiting should eventually succeed and return errset! */
  ret = lwip_select(s + 1, &readset, &writeset, &errset, NULL);
  ticks_b = sys_now();
  LWIP_ASSERT("ret > 0", ret > 0);
  LWIP_ASSERT("FD_ISSET(s, &errset)", FD_ISSET(s, &errset));
  LWIP_ASSERT("!FD_ISSET(s, &readset)", !FD_ISSET(s, &readset));
  LWIP_ASSERT("!FD_ISSET(s, &writeset)", !FD_ISSET(s, &writeset));

  /* close */
  ret = lwip_close(s);
  LWIP_ASSERT("ret == 0", ret == 0);

  printf("select() needed %d ticks to return error\n", ticks_b - ticks_a);
  printf("all tests done, thread ending\n");
}
Beispiel #16
0
//
// Receive a file from the client
//
static void
tftpd_write_file(struct tftphdr *hdr,
                 struct sockaddr_in *from_addr, int from_len)
{

    struct tftphdr *reply = (struct tftphdr *)data_out;
    struct tftphdr *response = (struct tftphdr *)data_in;
    int fd, len, ok, tries, closed, data_len, s;
    unsigned short block;
    struct timeval timeout;
    fd_set fds;
    int total_timeouts = 0;
    struct sockaddr_in client_addr, local_addr;
    socklen_t client_len;


    s = socket(AF_INET, SOCK_DGRAM, 0);
    if (s < 0) {
        return;
    }

    memset((char *)&local_addr, 0, sizeof(local_addr));
    local_addr.sin_family = AF_INET;
    local_addr.sin_len = sizeof(local_addr);
    local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    local_addr.sin_port = htons(INADDR_ANY);

    if (bind(s, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0) {
        // Problem setting up my end
        close(s);
        return;
    }

    if ((fd = tftpd_open_data_file((int)hdr->th_stuff, O_WRONLY)) < 0) {
        tftpd_send_error(s,reply,TFTP_ENOTFOUND,from_addr, from_len);
        close(s);
        return;
    }

    ok = pdTRUE;
    closed = pdFALSE;
    block = 0;
    while (ok) {
        // Send ACK telling client he can send data
        reply->th_opcode = htons(ACK);
        reply->th_block = htons(block++); // postincrement
        for (tries = 0;  tries < TFTP_RETRIES_MAX;  tries++) {
            sendto(s, reply, 4, 0, (struct sockaddr *)from_addr, from_len);
repeat_select:
            timeout.tv_sec = TFTP_TIMEOUT_PERIOD;
            timeout.tv_usec = 0;
            FD_ZERO(&fds);
            FD_SET(s, &fds);
            vParTestToggleLED( TFTP_LED );
            if (lwip_select(s+1, &fds, 0, 0, &timeout) <= 0) {
                if (++total_timeouts > TFTP_TIMEOUT_MAX) {
                    tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len);
                    ok = pdFALSE;
                    break;
                }
                continue; // retry the send, using up one retry.
            }
            vParTestToggleLED( TFTP_LED );
            // Some data has arrived
            data_len = sizeof(data_in);
            client_len = sizeof(client_addr);
            if ((data_len = recvfrom(s, data_in, data_len, 0,
                                     (struct sockaddr *)&client_addr, &client_len)) < 0) {
                // What happened?  No data here!
                continue; // retry the send, using up one retry.
            }
            if (ntohs(response->th_opcode) == DATA &&
                    ntohs(response->th_block) < block) {
                // Then it is repeat DATA with an old block; listen again,
                // but do not repeat sending the current ack, and do not
                // use up a retry count.  (we do re-send the ack if
                // subsequently we time out)
                goto repeat_select;
            }
            if (ntohs(response->th_opcode) == DATA &&
                    ntohs(response->th_block) == block) {
                // Good data - write to file
                len = tftpd_write_data_file(fd, response->th_data, data_len-4);
                if (len < (data_len-4)) {
                    // File is "full"
                    tftpd_send_error(s,reply,TFTP_ENOSPACE,
                                     from_addr, from_len);
                    ok = pdFALSE;  // Give up
                    break; // out of the retries loop
                }
                if (data_len < (SEGSIZE+4)) {
                    // End of file
                    closed = pdTRUE;
                    ok = pdFALSE;
                    vParTestSetLED( 0 , 0 );

                    if (tftpd_close_data_file(fd) == -1) {
                        tftpd_send_error(s,reply,TFTP_EACCESS,
                                         from_addr, from_len);

                        break;  // out of the retries loop
                    }
                    // Exception to the loop structure: we must ACK the last
                    // packet, the one that implied EOF:
                    reply->th_opcode = htons(ACK);
                    reply->th_block = htons(block++); // postincrement
                    sendto(s, reply, 4, 0, (struct sockaddr *)from_addr, from_len);
                    break; // out of the retries loop
                }
                // Happy!  Break out of the retries loop.
                break;
            }
        } // End of the retries loop.
        if (TFTP_RETRIES_MAX <= tries) {
            tftpd_send_error(s,reply,TFTP_EBADOP,from_addr, from_len);
            ok = pdFALSE;
        }
    }
    close(s);
    if (!closed) {
        tftpd_close_data_file(fd);
    }
}
Beispiel #17
0
int
select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
            struct timeval *timeout)
{
    int index, result;
    int sock, maxfd;

    fd_set sock_readset;
    fd_set sock_writeset;
    fd_set sock_exceptset;

    FD_ZERO(&sock_readset);
    FD_ZERO(&sock_writeset);
    FD_ZERO(&sock_exceptset);

    maxfd = 0;
    for (index = 0; index < maxfdp1; index ++)
    {
        /* convert fd to sock */
        sock = dfs_lwip_getsocket(index);
        if (sock == -1) continue;

        if (sock > maxfd) maxfd = sock;

        /* if FD is set, set the socket set */
        if (readset && FD_ISSET(index, readset))
        {
            FD_SET(sock, &sock_readset);
        }
        if (writeset && FD_ISSET(index, writeset))
        {
            FD_SET(sock, &sock_writeset);
        }
        if (exceptset && FD_ISSET(index, exceptset))
        {
            FD_SET(sock, &sock_exceptset);
        }
    }

    /* no socket found, return bad file descriptor */
    if (maxfd == 0) return -EBADF;
    maxfd += 1;
    
    result = lwip_select(maxfd, &sock_readset, &sock_writeset, &sock_exceptset, timeout);
    
    if (readset)   FD_ZERO(readset);
    if (writeset)  FD_ZERO(writeset);
    if (exceptset) FD_ZERO(exceptset);

    if (result != -1)
    {
        for (index = 0; index < maxfd; index ++)
        {
            /* check each socket */
            if ((FD_ISSET(index, &sock_readset))  ||
                (FD_ISSET(index, &sock_writeset)) ||
                (FD_ISSET(index, &sock_exceptset)))
            {
                int fd_index;
                
                /* Because we can not get the corresponding fd, we have to search it one by one */
                for (fd_index = 0; fd_index < maxfdp1; fd_index ++)
                {
                    sock = dfs_lwip_getsocket(fd_index);
                    if (sock == index) /* found it */
                    {
                        if (readset && FD_ISSET(index, &sock_readset))
                        {
                            FD_SET(sock, readset);
                        }
                        if (writeset && FD_ISSET(index, &sock_writeset))
                        {
                            FD_SET(sock, writeset);
                        }
                        if (exceptset && FD_ISSET(index, &sock_exceptset))
                        {
                            FD_SET(sock, exceptset);
                        }
                        
                        /* end of search */
                        break;
                    }
                }
            }
        }
    }
    
    return result;
}
Beispiel #18
0
int dump_data(UrlResource *rsrc, int sock, FILE *out, libnet_callback notify)
{
	Progress *p = NULL;
	int bytes_read   = 0;
	ssize_t written	   = 0;
	char *buf = NULL;
	int lenth, final, final2 = 0;
	int buflen;
	if ((out == NULL) && (rsrc->buffer == NULL) && (NULL == rsrc->strfile_handle))
		return 0;

	/* if we already have all of it */
	if ( !(rsrc->options ) )
	{
		if ( rsrc->outfile_size &&(rsrc->outfile_offset >= rsrc->outfile_size) )
		{
			LIBNET_DEBUG( "you already have all of `%s', skipping", rsrc->outfile);
			//S_CLOSE(sock);
			return 0;
		}
	}

	p = progress_new();
	p->tranfer_callback = notify;
	if(NULL == rsrc->strfile_handle)
	{
		progress_init(p, rsrc, rsrc->outfile_size);
		progress_update(p, rsrc->outfile_offset);
		buflen = BUFSIZE;
	}else
	{
		progress_init(p, rsrc, rsrc->outfile_size);
		buflen = BUFSIZE * 3;
	}
	p->offset = rsrc->outfile_offset;

	if ( out && (rsrc->outfile_offset > 0) && (rsrc->options & OPT_RESUME))
	{
		fseek(out, rsrc->outfile_offset, SEEK_SET);
		LIBNET_DEBUG("ftell = %d \n", ftell(out));
	}
	buf = MALLOC(buflen);
	if(rsrc->strfile_handle)
	{
		fd_set set;
		struct timeval tv = {30, 0};
		FD_ZERO(&set);
		FD_SET(sock, &set);
		while (lwip_select(sock + 1, &set, NULL, NULL, &tv) > 0 && (rsrc->running))
		{
			bytes_read = S_READ(sock, buf, buflen);
			if(0 >= bytes_read)
				break;
			lenth = bytes_read;
			final += bytes_read;
			final2 += bytes_read;
			while(lenth)
			{
				written = httpstrfile_writedatatobuff(rsrc->strfile_handle, buf + (bytes_read - lenth), (UINT32)lenth);
				lenth -= written;
				osal_task_sleep(1);
			}
			if(0x20000 <= final2)
			{
//				libc_printf("final = %d/%d\n", final, rsrc->outfile_size);
				progress_update(p, final2);
				final2 = 0;
			}			
		}
BST_IP_ERR_T BST_IP_SslReceive( BST_FD_T fd, BST_UINT8* pData, BST_UINT16 usLength )
{
    SSL                *pstSsl;
    BST_UINT8          *pucTmpBuf;
    BST_INT32           lRtnVal;
    BST_INT32           lCopyedLen;
    BST_INT32           lSelect;
    BST_INT32           lSockFd;
    fd_set              stRdFds;
    timeval             stTval;
    stTval.tv_sec       = 0;
    stTval.tv_usec      = 0;
    if ( BST_NULL_PTR == fd.pFd )
    {
        return BST_IP_ERR_ARG;
    }
    if ( BST_NULL_PTR == pData )
    {
        return BST_IP_ERR_ARG;
    }

    lCopyedLen          = 0;
    pstSsl              = (SSL *)fd.pFd;
    lSockFd             = SSL_get_fd( pstSsl );

    pucTmpBuf           = (BST_UINT8 *)BST_OS_MALLOC( usLength );

    if ( BST_NULL_PTR == pucTmpBuf )
    {
        return BST_IP_ERR_MEM;
    }
    
    do {
        FD_ZERO( &stRdFds );
        FD_SET( lSockFd, &stRdFds );

        lRtnVal         = SSL_read( pstSsl, pucTmpBuf, usLength );

        
        if ( lRtnVal <= 0 )
        {
            BST_RLS_LOG( "BST_IP_SslReceive SSL_read error" );
            break;
        }
        if ( 0 == lCopyedLen )
        {
            BST_OS_MEMCPY( pData, pucTmpBuf, lRtnVal );
            lCopyedLen  = lRtnVal;
            BST_DBG_LOG1( "BST_IP_SslReceive lCopyedLen", lCopyedLen );
        }
        /*如果ssl内部缓冲区没有数据可读,则判断IP协议栈是否有数据可读*/
        if ( !SSL_pending( pstSsl ) )
        {
            lSelect     = lwip_select( lSockFd + 1, &stRdFds, NULL, NULL, &stTval );
            if ( lSelect < 0)
            {
                BST_RLS_LOG( "BST_IP_SslReceive lwip_select error" );
                break;
            }

            /*如果协议栈也没有数据可读,则说明这次读取完毕,退出*/
            if ( !FD_ISSET( lSockFd,&stRdFds ) )
            {
                BST_DBG_LOG( "BST_IP_SslReceive socket is not data" );
                break;
            }
        }
    } while( 1 );

    BST_OS_FREE( pucTmpBuf );
    return lCopyedLen;
}
Beispiel #20
0
int poll(struct pollfd *fds, unsigned long nfds, int timeout)
{
    int i,err;
    fd_set rfd, wfd, efd, ifd;
    struct timeval timebuf;
    struct timeval *tbuf = (struct timeval *)0;
    int n = 0;
    int count;
    
    FD_ZERO(&ifd);
    FD_ZERO(&rfd);
    FD_ZERO(&wfd);
    FD_ZERO(&efd);

    for (i = 0; i < nfds; i++) {
		int events = fds[i].events;
		int fd = fds[i].fd;

		fds[i].revents = 0;

		if ((fd < 0) || (FD_ISSET(fd, &ifd)))
	   		continue;

		if (fd > n)
	    	n = fd;

		if (events & POLL_CAN_READ)
	    	FD_SET(fd, &rfd);

		if (events & POLL_CAN_WRITE)
	    	FD_SET(fd, &wfd);

		if (events & POLL_HAS_EXCP)
	    	FD_SET(fd, &efd);
    }

    if (timeout >= 0) {
		timebuf.tv_sec = timeout / 1000;
		timebuf.tv_usec = (timeout % 1000) * 1000;
		tbuf = &timebuf;
    }

    err = lwip_select(n+1, &rfd, &wfd, &efd, tbuf);

    if (err < 0)
		return err;
  
   	count = 0;
   	
   	for (i = 0; i < nfds; i++) {
		int revents = (fds[i].events & POLL_EVENTS_MASK);
		int fd = fds[i].fd;

		if (fd < 0)
	   		continue;

		if (FD_ISSET(fd, &ifd))
	   		revents = POLLNVAL;
		else {
	   		if (!FD_ISSET(fd, &rfd))
	       		revents &= ~POLL_CAN_READ;

	   		if (!FD_ISSET(fd, &wfd))
	       		revents &= ~POLL_CAN_WRITE;

	   		if (!FD_ISSET(fd, &efd))
	       		revents &= ~POLL_HAS_EXCP;
		}

		if ((fds[i].revents = revents) != 0)
	   		count++;
    }
    
    return count; 
}
Beispiel #21
0
/* Just poll without blocking */
static int select_poll(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds)
{
    int i, n = 0;
#ifdef HAVE_LWIP
    int sock_n = 0, sock_nfds = 0;
    fd_set sock_readfds, sock_writefds, sock_exceptfds;
    struct timeval timeout = { .tv_sec = 0, .tv_usec = 0};
#endif

#ifdef LIBC_VERBOSE
    static int nb;
    static int nbread[NOFILE], nbwrite[NOFILE], nbexcept[NOFILE];
    static s_time_t lastshown;

    nb++;
#endif

#ifdef HAVE_LWIP
    /* first poll network */
    FD_ZERO(&sock_readfds);
    FD_ZERO(&sock_writefds);
    FD_ZERO(&sock_exceptfds);
    for (i = 0; i < nfds; i++) {
	if (files[i].type == FTYPE_SOCKET) {
	    if (FD_ISSET(i, readfds)) {
		FD_SET(files[i].socket.fd, &sock_readfds);
		sock_nfds = i+1;
	    }
	    if (FD_ISSET(i, writefds)) {
		FD_SET(files[i].socket.fd, &sock_writefds);
		sock_nfds = i+1;
	    }
	    if (FD_ISSET(i, exceptfds)) {
		FD_SET(files[i].socket.fd, &sock_exceptfds);
		sock_nfds = i+1;
	    }
	}
    }
    if (sock_nfds > 0) {
        DEBUG("lwip_select(");
        dump_set(nfds, &sock_readfds, &sock_writefds, &sock_exceptfds, &timeout);
        DEBUG("); -> ");
        sock_n = lwip_select(sock_nfds, &sock_readfds, &sock_writefds, &sock_exceptfds, &timeout);
        dump_set(nfds, &sock_readfds, &sock_writefds, &sock_exceptfds, &timeout);
        DEBUG("\n");
    }
#endif

    /* Then see others as well. */
    for (i = 0; i < nfds; i++) {
	switch(files[i].type) {
	default:
	    if (FD_ISSET(i, readfds) || FD_ISSET(i, writefds) || FD_ISSET(i, exceptfds))
		printk("bogus fd %d in select\n", i);
	    /* Fallthrough.  */
	case FTYPE_CONSOLE:
	    if (FD_ISSET(i, readfds)) {
                if (xencons_ring_avail(files[i].cons.dev))
		    n++;
		else
		    FD_CLR(i, readfds);
            }
	    if (FD_ISSET(i, writefds))
                n++;
	    FD_CLR(i, exceptfds);
	    break;
#ifdef CONFIG_XENBUS
	case FTYPE_XENBUS:
	    if (FD_ISSET(i, readfds)) {
                if (files[i].xenbus.events)
		    n++;
		else
		    FD_CLR(i, readfds);
	    }
	    FD_CLR(i, writefds);
	    FD_CLR(i, exceptfds);
	    break;
#endif
	case FTYPE_EVTCHN:
	case FTYPE_TAP:
	case FTYPE_BLK:
	case FTYPE_KBD:
	case FTYPE_FB:
	    if (FD_ISSET(i, readfds)) {
		if (files[i].read)
		    n++;
		else
		    FD_CLR(i, readfds);
	    }
	    FD_CLR(i, writefds);
	    FD_CLR(i, exceptfds);
	    break;
#ifdef HAVE_LWIP
	case FTYPE_SOCKET:
	    if (FD_ISSET(i, readfds)) {
	        /* Optimize no-network-packet case.  */
		if (sock_n && FD_ISSET(files[i].socket.fd, &sock_readfds))
		    n++;
		else
		    FD_CLR(i, readfds);
	    }
            if (FD_ISSET(i, writefds)) {
		if (sock_n && FD_ISSET(files[i].socket.fd, &sock_writefds))
		    n++;
		else
		    FD_CLR(i, writefds);
            }
            if (FD_ISSET(i, exceptfds)) {
		if (sock_n && FD_ISSET(files[i].socket.fd, &sock_exceptfds))
		    n++;
		else
		    FD_CLR(i, exceptfds);
            }
	    break;
#endif
	}
#ifdef LIBC_VERBOSE
	if (FD_ISSET(i, readfds))
	    nbread[i]++;
	if (FD_ISSET(i, writefds))
	    nbwrite[i]++;
	if (FD_ISSET(i, exceptfds))
	    nbexcept[i]++;
#endif
    }
#ifdef LIBC_VERBOSE
    if (NOW() > lastshown + 1000000000ull) {
	lastshown = NOW();
	printk("%lu MB free, ", num_free_pages() / ((1 << 20) / PAGE_SIZE));
	printk("%d(%d): ", nb, sock_n);
	for (i = 0; i < nfds; i++) {
	    if (nbread[i] || nbwrite[i] || nbexcept[i])
		printk(" %d(%c):", i, file_types[files[i].type]);
	    if (nbread[i])
	    	printk(" %dR", nbread[i]);
	    if (nbwrite[i])
		printk(" %dW", nbwrite[i]);
	    if (nbexcept[i])
		printk(" %dE", nbexcept[i]);
	}
	printk("\n");
	memset(nbread, 0, sizeof(nbread));
	memset(nbwrite, 0, sizeof(nbwrite));
	memset(nbexcept, 0, sizeof(nbexcept));
	nb = 0;
    }
#endif
    return n;
}

/* The strategy is to
 * - announce that we will maybe sleep
 * - poll a bit ; if successful, return
 * - if timeout, return
 * - really sleep (except if somebody woke us in the meanwhile) */
int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
	struct timeval *timeout)
{
    int n, ret;
    fd_set myread, mywrite, myexcept;
    struct thread *thread = get_current();
    s_time_t start = NOW(), stop;
#ifdef CONFIG_NETFRONT
    DEFINE_WAIT(netfront_w);
#endif
    DEFINE_WAIT(event_w);
#ifdef CONFIG_BLKFRONT
    DEFINE_WAIT(blkfront_w);
#endif
#ifdef CONFIG_XENBUS
    DEFINE_WAIT(xenbus_watch_w);
#endif
#ifdef CONFIG_KBDFRONT
    DEFINE_WAIT(kbdfront_w);
#endif
    DEFINE_WAIT(console_w);

    assert(thread == main_thread);

    DEBUG("select(%d, ", nfds);
    dump_set(nfds, readfds, writefds, exceptfds, timeout);
    DEBUG(");\n");

    if (timeout)
	stop = start + SECONDS(timeout->tv_sec) + timeout->tv_usec * 1000;
    else
	/* just make gcc happy */
	stop = start;

    /* Tell people we're going to sleep before looking at what they are
     * saying, hence letting them wake us if events happen between here and
     * schedule() */
#ifdef CONFIG_NETFRONT
    add_waiter(netfront_w, netfront_queue);
#endif
    add_waiter(event_w, event_queue);
#ifdef CONFIG_BLKFRONT
    add_waiter(blkfront_w, blkfront_queue);
#endif
#ifdef CONFIG_XENBUS
    add_waiter(xenbus_watch_w, xenbus_watch_queue);
#endif
#ifdef CONFIG_KBDFRONT
    add_waiter(kbdfront_w, kbdfront_queue);
#endif
    add_waiter(console_w, console_queue);

    if (readfds)
        myread = *readfds;
    else
        FD_ZERO(&myread);
    if (writefds)
        mywrite = *writefds;
    else
        FD_ZERO(&mywrite);
    if (exceptfds)
        myexcept = *exceptfds;
    else
        FD_ZERO(&myexcept);

    DEBUG("polling ");
    dump_set(nfds, &myread, &mywrite, &myexcept, timeout);
    DEBUG("\n");
    n = select_poll(nfds, &myread, &mywrite, &myexcept);

    if (n) {
	dump_set(nfds, readfds, writefds, exceptfds, timeout);
	if (readfds)
	    *readfds = myread;
	if (writefds)
	    *writefds = mywrite;
	if (exceptfds)
	    *exceptfds = myexcept;
	DEBUG(" -> ");
	dump_set(nfds, readfds, writefds, exceptfds, timeout);
	DEBUG("\n");
	wake(thread);
	ret = n;
	goto out;
    }
    if (timeout && NOW() >= stop) {
	if (readfds)
	    FD_ZERO(readfds);
	if (writefds)
	    FD_ZERO(writefds);
	if (exceptfds)
	    FD_ZERO(exceptfds);
	timeout->tv_sec = 0;
	timeout->tv_usec = 0;
	wake(thread);
	ret = 0;
	goto out;
    }

    if (timeout)
	thread->wakeup_time = stop;
    schedule();

    if (readfds)
        myread = *readfds;
    else
        FD_ZERO(&myread);
    if (writefds)
        mywrite = *writefds;
    else
        FD_ZERO(&mywrite);
    if (exceptfds)
        myexcept = *exceptfds;
    else
        FD_ZERO(&myexcept);

    n = select_poll(nfds, &myread, &mywrite, &myexcept);

    if (n) {
	if (readfds)
	    *readfds = myread;
	if (writefds)
	    *writefds = mywrite;
	if (exceptfds)
	    *exceptfds = myexcept;
	ret = n;
	goto out;
    }
    errno = EINTR;
    ret = -1;

out:
#ifdef CONFIG_NETFRONT
    remove_waiter(netfront_w, netfront_queue);
#endif
    remove_waiter(event_w, event_queue);
#ifdef CONFIG_BLKFRONT
    remove_waiter(blkfront_w, blkfront_queue);
#endif
#ifdef CONFIG_XENBUS
    remove_waiter(xenbus_watch_w, xenbus_watch_queue);
#endif
#ifdef CONFIG_KBDFRONT
    remove_waiter(kbdfront_w, kbdfront_queue);
#endif
    remove_waiter(console_w, console_queue);
    return ret;
}
Beispiel #22
0
/* ------------------------------------------------------------------------------------------------------
 *									   sockex_nonblocking_connect()
 *
 * Description : tests socket blocking and nonblocking connect.
 *
 * Argument(s) : none.
 *
 */
void sockex_nonblocking_connect(void *arg)
{
	int ret;
	struct sockaddr_in addr;
	fd_set readset;
	fd_set writeset;
	fd_set errset;
	struct timeval tv;
	
	LWIP_UNUSED_ARG(arg);

	memset(&addr, 0, sizeof(addr));									/* set up address to connect to */
	addr.sin_len = sizeof(addr);
	addr.sin_family = AF_INET;
	addr.sin_port = PP_HTONS(SOCK_TARGET_PORT);
	addr.sin_addr.s_addr = inet_addr(SOCK_TARGET_HOST);
	
	socket_state = SOCKET_NEW;
	
	for(;;)
	{
		if(g_bNetStatus == NETS_LOCIP)								/* IP is setted.*/
		{
			switch(socket_state)
			{
				case SOCKET_NEW:
				{
					s = lwip_socket(AF_INET, SOCK_STREAM, 0);
					
					socket_state = SOCKET_CON;
					break;
				}

				case SOCKET_CON:
				{
					unsigned int ip;
					ret = lwip_connect(s, (struct sockaddr*)&addr, sizeof(addr));
					
					LWIP_ASSERT("ret == 0", ret == 0);
					if(ret < 0)
					{
						lwip_close(s);
						socket_state = SOCKET_NEW;
						OSTimeDly(2);
						RS232printf("socket connect failed.\n");
						break;
					}
					ip = lwIPLocalIPAddrGet();
					NetDisplayIPAddress(ip);						/* Socket updata IP address.*/
					socket_state = SOCKET_IDIE;
				}
				
				case SOCKET_IDIE:
				{
					INT8U *msg;
					INT8U err;
					
					msg = (INT8U *)OSMboxPend(NET_RfMbox, 0, &err);	/* Waiting socket writing data.*/			
					
					if(err != OS_ERR_NONE)
						break;
					
					ret = lwip_write(s, msg, 6);				
					if(ret < 0)
					{
						lwip_close(s);
						socket_state = SOCKET_CON;	
					}
				}
				break;
				
				case SOCKET_CHECK:
					// TODO: Check socket connecting.
				
					FD_ZERO(&readset);
					FD_SET(s, &readset);
					FD_ZERO(&writeset);
					FD_SET(s, &writeset);
					FD_ZERO(&errset);
					FD_SET(s, &errset);
				
					tv.tv_sec = 3;
					tv.tv_usec = 0;									/* Set time out 3s, 函数立即返回*/
					ret = lwip_select(s+1, &readset, &writeset, &errset, &tv);
					
					if(ret == 0)
					{
						RS232printf("socket check timeout.\n");
						lwip_close(s);
						socket_state = SOCKET_CON;					/* Reconnect socket.*/
					}
					
					if(FD_ISSET(s, &writeset) == 0)					/* If socket couldn't write.*/
					{
						RS232printf("socket write test error.\n");
						lwip_close(s);
						socket_state = SOCKET_CON;					/* Reconnect socket.*/
					}
					
					ret = lwip_write(s, "test", 6);
					if(ret < 0)
					{
						lwip_close(s);
						socket_state = SOCKET_CON;	
					}
					OSTimeDly(2000);
					break;
				
				default:
					break;
			}
		}
		OSTimeDly(2);
	}
}
Beispiel #23
0
/* ------------------------------------------------------------------------------------------------------
 *									      sockex_selects()
 *
 * Description : socket selects test.
 *
 * Argument(s) : none.
 *
 */
void sockex_selects(void *arg)
{
	int sock_fd, new_fd;
	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	socklen_t sin_size;
	int yes;
	INT8U buf[BUF_SIZE];
	int ret;
	int i;
	
	fd_set fdsr;													/* Create file descriptor.*/
	int maxsock;
	struct timeval tv;
	
	conn_amount = 0;
	LWIP_UNUSED_ARG(arg);
	
	sock_fd = lwip_socket(AF_INET, SOCK_STREAM, 0);
	
	yes = 1;
	ret = lwip_setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));
	if(ret == -1)
	{
		return;
	}
	
	memset(&server_addr, 0, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_len = sizeof(server_addr);
	server_addr.sin_port = PP_HTONS(SOCK_HOSR_PORT);
	server_addr.sin_addr.s_addr = lwIPLocalIPAddrGet();				/* IP_ADDR_ANY is '0.0.0.0'.*/
	
	lwip_bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr));
	lwip_listen(sock_fd, BACKLOG + 1);								/* MAX TCP client is BACKLOG.*/
	
	sin_size = sizeof(client_addr);
	maxsock = sock_fd;
	

	
	while(1)
	{
		FD_ZERO(&fdsr);												/* Initialize file descriptor set.*/
		FD_SET(sock_fd, &fdsr);

		tv.tv_sec = 10;												/* Timeout setting.*/
		tv.tv_usec = 0;
		
		for (i = 0; i < BACKLOG; i++)								/* Add active connection to fd set.*/
		{								
			if (fd_A[i] != 0) {
				FD_SET(fd_A[i], &fdsr);
			}
		}
		
		ret = lwip_select(maxsock + 1, &fdsr, NULL, NULL, &tv);
		if(ret < 0)
		{
			break;
		}
		else if(ret == 0)
		{
			continue;
		}
		
		for (i = 0; i < conn_amount; i++)							/* Check every fd in the set.*/
		{
			if (FD_ISSET(fd_A[i], &fdsr))
			{
				int opt = 100;										/* set recv timeout (100 ms) */
				lwip_setsockopt(fd_A[i], SOL_SOCKET, SO_RCVTIMEO, &opt, sizeof(int));

				ret = lwip_read(fd_A[i], buf, 8);
				if (ret <= 0)
				{
// 					lwip_close(fd_A[i]);
// 					FD_CLR(fd_A[i], &fdsr);
// 					fd_A[i] = 0;
				}
				else        										/* receive data.*/
				{
					if((buf[0] == 'C')&&(buf[1] == 'o'))
					{
// 						address_t addr;
// 						INT8U mac[8] = {0x00, 0x12, 0x4B, 0x00, 0x01, 0xC0, 0xB7, 0xE0};
// 						addr.mode = LONG_ADDR;
// 						utilReverseBuf(mac, 8);
// 						memcpy(addr.long_addr, mac, 8);
// 						mac_tx_handle(&addr, &buf[7], 1, MAC_DATA);
					}
					if (ret < BUF_SIZE)
						memset(&buf[ret], '\0', 1);
				}
			}
		}

		if(FD_ISSET(sock_fd, &fdsr))								/* Check whether a new connection comes.*/
		{
			new_fd = lwip_accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size);
			if(new_fd <= 0)
			{
				continue;
			}
//			lwip_send(new_fd, "con", 4, 0);
			if(conn_amount < BACKLOG)								/* Add to fd queue.*/
			{
				fd_A[conn_amount++] = new_fd;
				
				if(new_fd > maxsock)
					maxsock = new_fd;
			}
			else
			{
//				conn_amount = 0;
				lwip_close(fd_A[conn_amount-1]);
				fd_A[conn_amount-1] = new_fd;
				if(new_fd > maxsock)
					maxsock = new_fd;
//				lwip_send(new_fd, "bye", 4, 0);
//				lwip_close(new_fd);									/* Close larger than 5 socket.*/
			}
		}
		
// 		for (i = 0; i < BACKLOG; i++)								/* Close other connections.*/
// 		{
// 			if (fd_A[i] != 0) {
// 				lwip_close(fd_A[i]);
// 			}
// 		}
	}
}
Beispiel #24
0
static int local_select(THandle aHandle, int aMode, uint32_t aTimeoutMs)
{
    OsNetworkHandle* h = (OsNetworkHandle*) aHandle;
    
    LOGFUNCIN();
    
    fd_set read_set;
    fd_set write_set;
    
    FD_ZERO(&read_set);
    FD_ZERO(&write_set);
    
    if ( aMode == LS_READ )
        FD_SET(h->iSocket, &read_set);
    else
        FD_SET(h->iSocket, &write_set);
    
#if INT_ENABLED
    FD_SET(h->iIntSocket, &read_set);
#endif
    
    struct timeval t, *t_ptr = NULL;
    
    if ( aTimeoutMs != LS_FOREVER )
    {
        t.tv_sec  = aTimeoutMs / 1000;
        t.tv_usec = 1000 * (aTimeoutMs % 1000);
        t_ptr = &t;
    }
    
    int nfds = 1 + ( h->iSocket > h->iIntSocket ? h->iSocket : h->iIntSocket );

    int fd = lwip_select(nfds, &read_set, &write_set, NULL, t_ptr);

    if ( fd == 0 )
        return -2;

    if ( fd == -1 )
        exit(-1);
    
#if INT_ENABLED
    if ( FD_ISSET(h->iIntSocket, &read_set) )
    {
        LOG("local_select - interrupted %d", h->iSocket);
        return -1;
    }
#endif

    if ( (aMode == LS_READ) && FD_ISSET(h->iSocket, &read_set) )
    {
        LOGFUNCOUT();
        return h->iSocket;
    }
    
    if ( (aMode != LS_READ) && FD_ISSET(h->iSocket, &write_set) )
    {
        LOGFUNCOUT();
        return h->iSocket;
    }
    
    exit(-1);
}
Beispiel #25
0
int select(std::set<Socket*>* readsockets, std::set<Socket*>* writesockets, std::set<Socket*>* errsockets, int timeout)
{
    int maxfd = 0;
    int rc;
    lwip_fd_set readfds, writefds, errfds;
    std::set<Socket*>::iterator it;
    struct timeval tmo;

    LWIP_FD_ZERO(&readfds);
    LWIP_FD_ZERO(&writefds);
    LWIP_FD_ZERO(&errfds);

    if (readsockets)
    {
        for (it = readsockets->begin(); it != readsockets->end(); it++)
        {
            LWIP_FD_SET((*it)->socket_->fd, &readfds);
            if ((*it)->socket_->fd > maxfd) maxfd = (*it)->socket_->fd;
        }
    }

    if (writesockets)
    {
        for (it = writesockets->begin(); it != writesockets->end(); it++)
        {
            LWIP_FD_SET((*it)->socket_->fd, &writefds);
            if ((*it)->socket_->fd > maxfd) maxfd = (*it)->socket_->fd;
        }
    }

    if (errsockets)
    {
        for (it = errsockets->begin(); it != errsockets->end(); it++)
        {
            LWIP_FD_SET((*it)->socket_->fd, &errfds);
            if ((*it)->socket_->fd > maxfd) maxfd = (*it)->socket_->fd;
        }
    }

    tmo.tv_sec = timeout/1000;
    tmo.tv_usec = (timeout % 1000) * 1000;

    if ( (rc = lwip_select(maxfd+1, &readfds, &writefds, &errfds, &tmo) ) < 0 )
    {
        log(LOG_WARN) << "select() failed";
        return rc;
    }

    if (readsockets)
    {
        it = readsockets->begin();
        while (it != readsockets->end())
        {
            if (!LWIP_FD_ISSET((*it)->socket_->fd, &readfds))
                readsockets->erase(it++);
            else
                it++;
        }
    }

    if (writesockets)
    {
        it = writesockets->begin();
        while (it != writesockets->end())
        {
            if (!LWIP_FD_ISSET((*it)->socket_->fd, &writefds))
            {
                writesockets->erase(it++);
            }
            else
                it++;
        }
    }

    if (errsockets)
    {
        it = errsockets->begin();
        while (it != errsockets->end())
        {
            if (!LWIP_FD_ISSET((*it)->socket_->fd, &errfds))
                errsockets->erase(it++);
            else
                it++;
        }
    }

    return rc;
}
LOCAL int openssl_thread_LWIP_CONNECTION(TLS_IO_INSTANCE* p)
{
    //LogInfo("openssl_thread_LWIP_CONNECTION begin: %d", system_get_free_heap_size());
    //system_show_malloc();

    int result = 0;
    int ret = 0;
    int sock;

    struct sockaddr_in sock_addr;
    fd_set readset;
    fd_set writeset;
    fd_set errset;
    SSL_CTX *ctx;
    SSL *ssl;

    TLS_IO_INSTANCE* tls_io_instance = p;

    LogInfo("OpenSSL thread start...");

    {
        LogInfo("create SSL context");
        /* Codes_SRS_TLSIO_SSL_ESP8266_99_085: [ If SSL_CTX_new failed, the tlsio_openssl_open shall return __LINE__. ] */
        ctx = SSL_CTX_new(TLSv1_client_method());
        if (ctx == NULL) {
            result = __LINE__;
            LogError("create new SSL CTX failed");
        }
        else
        {
            tls_io_instance->ssl_context = ctx;
            LogInfo("set SSL context read buffer size");
            SSL_CTX_set_default_read_buffer_len(ctx, OPENSSL_FRAGMENT_SIZE);
            // LogInfo("create socket ......");
            // LogInfo("size before creating socket: %d", system_get_free_heap_size());
            /* Codes_SRS_TLSIO_SSL_ESP8266_99_080: [ If socket failed, the tlsio_openssl_open shall return __LINE__. ] */
            sock = socket(AF_INET, SOCK_STREAM, 0);
            if (sock < 0) {
                result = __LINE__;
                LogError("create socket failed");
            }
            else
            {
                int keepAlive = 1; //enable keepalive
                int keepIdle = 20; //20s
                int keepInterval = 2; //2s
                int keepCount = 3; //retry # of times

                tls_io_instance->sock = sock;
                LogInfo("sock: %d", sock);
                LogInfo("create socket OK");

                LogInfo("set socket keep-alive ");

                ret = 0;
                ret = ret || setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepAlive, sizeof(keepAlive));
                ret = ret || setsockopt(sock, IPPROTO_TCP, TCP_KEEPIDLE, (void *)&keepIdle, sizeof(keepIdle));
                ret = ret || setsockopt(sock, IPPROTO_TCP, TCP_KEEPINTVL, (void *)&keepInterval, sizeof(keepInterval));
                ret = ret || setsockopt(sock, IPPROTO_TCP, TCP_KEEPCNT, (void *)&keepCount, sizeof(keepCount));

                if (ret != 0){
                    result = __LINE__;
                    LogError("set socket keep-alive failed, ret = %d ", ret);
                }
                else
                {
                    LogInfo("set socket keep-alive OK");

                    lwip_set_non_block(sock);

                    LogInfo("bind socket ......");
                    memset(&sock_addr, 0, sizeof(sock_addr));
                    sock_addr.sin_family = AF_INET;
                    sock_addr.sin_addr.s_addr = 0;
                    sock_addr.sin_port = 0; // random local port
                    /* Codes_SRS_TLSIO_SSL_ESP8266_99_082: [ If bind failed, the tlsio_openssl_open shall return __LINE__. ] */
                    ret = bind(sock, (struct sockaddr*)&sock_addr, sizeof(sock_addr));

                    // LogInfo("bind return: %d", ret);
                    if (ret != 0) {
                        result = __LINE__;
                        LogError("bind socket failed");
                    }
                    else
                    {
                        LogInfo("bind socket OK");

                        memset(&sock_addr, 0, sizeof(sock_addr));
                        sock_addr.sin_family = AF_INET;
                        sock_addr.sin_addr.s_addr = tls_io_instance->target_ip.addr;
                        sock_addr.sin_port = (in_port_t)htons(tls_io_instance->port);

                        ret = connect(sock, (struct sockaddr*)&sock_addr, sizeof(sock_addr));
                        //LogInfo("connect return: %d %s", ret, ip_ntoa(&tls_io_instance->target_ip));
                        //LogInfo("EINPROGRESS: %d", EINPROGRESS);
                        if (ret == -1) {
                            ret = lwip_net_errno(sock);
                            LogInfo("lwip_net_errno ret: %d", ret);
                            /* Codes_SRS_TLSIO_SSL_ESP8266_99_083: [ If connect and getsockopt failed, the tlsio_openssl_open shall return __LINE__. ] */
                            if (ret != 115) { // EINPROGRESS
                                result = __LINE__;
                                ret = -1;
                                LogError("socket connect failed, not EINPROGRESS %s", tls_io_instance->hostname);
                            }
                        }

                        if(ret != -1)
                        {
                            FD_ZERO(&readset);
                            FD_ZERO(&writeset);
                            FD_ZERO(&errset);

                            FD_SET(sock, &readset);
                            FD_SET(sock, &writeset);
                            FD_SET(sock, &errset);

                            ret = lwip_select(sock + 1, NULL, &writeset, &errset, NULL);
                            if (ret <= 0) {
                                result = __LINE__;
                                LogError("select failed: %d", lwip_net_errno(sock));
                            } else
                            {
                                if (!FD_ISSET(sock, &writeset) || FD_ISSET(sock, &errset)) {
                                    result = __LINE__;
                                    LogError("socket Error: %d", lwip_net_errno(sock));
                                }else
                                {
                                    {
                                        LogInfo("Socket Connect OK");
                                        /* Codes_SRS_TLSIO_SSL_ESP8266_99_087: [ If SSL_new failed, the tlsio_openssl_open shall return __LINE__. ] */
                                        ssl = SSL_new(ctx);
                                        //LogInfo("after ssl new");
                                        if (ssl == NULL) {
                                            result = __LINE__;
                                            LogError("create ssl failed");
                                        }
                                        else
                                        {

                                            tls_io_instance->ssl = ssl;
                                            // LogInfo("SSL set fd");
                                            /* Codes_SRS_TLSIO_SSL_ESP8266_99_088: [ If SSL_set_fd failed, the tlsio_openssl_open shall return __LINE__. ] */
                                            ret = SSL_set_fd(ssl, sock);
                                            LogInfo("SSL_set_fd ret:%d", ret);
                                            if (ret != 1){
                                                result = __LINE__;
                                                LogError("SSL_set_fd failed");
                                            }
                                            else{
                                                int retry_connect = 0;
                                                int connect_succeeded = false;

                                                LogInfo("SSL connect... ");

                                                FD_ZERO(&readset);
                                                FD_SET(sock, &readset);
                                                FD_ZERO(&writeset);
                                                FD_SET(sock, &writeset);
                                                FD_ZERO(&errset);
                                                FD_SET(sock, &errset);

                                                /* Codes_SRS_TLSIO_SSL_ESP8266_99_027: [ The tlsio_openssl_open shall set the tlsio to try to open the connection for MAX_RETRY times before assuming that connection failed. ]*/
                                                while (retry_connect < MAX_RETRY)
                                                {
                                                    int ssl_state;

                                                    ret = lwip_select(sock + 1, &readset, &writeset, &errset, &timeout);

                                                    if (ret == 0) {
                                                        result = __LINE__;
                                                        LogInfo("SSL connect timeout");
                                                        break;
                                                    }
                                                    if (FD_ISSET(sock, &errset)) {
                                                        unsigned int len;
                                                        result = __LINE__;
                                                        LogInfo("error return : %d", lwip_net_errno(sock));
                                                        len = (unsigned int) sizeof( int );
                                                        if (0 != getsockopt (sock, SOL_SOCKET, SO_ERROR, &ret, &len))
                                                            LogInfo("SSL error ret : %d", ret);   // socket is in error state
                                                        break;
                                                    }

                                                    ret = SSL_connect(ssl);
                                                    if (ret == 1) { // ssl connect success
                                                        connect_succeeded = true;
                                                        break;
                                                    }

                                                    FD_ZERO(&readset);
                                                    FD_ZERO(&writeset);
                                                    FD_ZERO(&errset);
                                                    FD_SET(sock, &errset);

                                                    ssl_state = SSL_get_error(ssl, ret);
                                                    if (ssl_state == SSL_ERROR_WANT_READ) {
                                                        FD_SET(sock, &readset);
                                                    } else if(ssl_state == SSL_ERROR_WANT_WRITE) {
                                                        FD_SET(sock, &writeset);
                                                    } else {
                                                        LogInfo("SSL state:%d", ssl_state);
                                                        result = __LINE__;
                                                        break;
                                                    }

                                                    retry_connect = retry_connect + 1;
                                                    //LogInfo("SSL connect retry: %d", retry_connect);
                                                    os_delay_us(RETRY_DELAY);
                                                }

                                                /* Codes_SRS_TLSIO_SSL_ESP8266_99_089: [ If SSL_connect failed, the tlsio_openssl_open shall return __LINE__. ] */
                                                if (connect_succeeded == false)
                                                {
                                                    /* Codes_SRS_TLSIO_SSL_ESP8266_99_042: [ If the tlsio_openssl_open retry SSL_connect to open more than MAX_RETRY times without success, it shall return __LINE__. ]*/
                                                    result = __LINE__;
                                                    LogError("SSL_connect failed");
                                                }else{
                                                    LogInfo("SSL connect ok");
                                                    result = 0;
                                                }
                                            }
                                        }
                                    }

                                }
                            }
                        }
                    }

                }
            }

        }
    }
    //LogInfo("openssl_thread_LWIP_CONNECTION end: %d", system_get_free_heap_size());

    if(result!=0){
        tls_io_instance->tlsio_state = TLSIO_STATE_ERROR;
    }
    return result;
}
Beispiel #27
0
void tcp_setup_thread_entry(void *p)
{
    int listenfd;
    struct sockaddr_in saddr;
    fd_set readset;

    listenfd = lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if( listenfd == -1 )
    {
        rt_kprintf("TCP setup can not create socket!\n");
        return;
    }

    memset(&saddr, 0, sizeof(saddr));
    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr = htonl(INADDR_ANY);
    saddr.sin_port = htons(SETUP_TCP_PORT);

    if( lwip_bind(listenfd, (struct sockaddr *)&saddr, sizeof(saddr)) == -1 )
    {
        lwip_close(listenfd);
        rt_kprintf("TCP setup thread socket bind failed!\n");
        return;
    }

    /* Put socket into listening mode */
    if (lwip_listen(listenfd,2) == -1)
    {
        lwip_close(listenfd);
        rt_kprintf("Listen failed.\n");
        return;
    }

    /* Wait for data or a new connection */
    while(1)
    {
        /* Determine what sockets need to be in readset */
        FD_ZERO(&readset);
        FD_SET(listenfd, &readset);
        // wait forever.
        if( lwip_select(listenfd+1, &readset, 0, 0, 0) == 0 )
            continue;

        if (FD_ISSET(listenfd, &readset))
        {
            int ret,optval = 1;
            struct sockaddr_in addrin;
            u32_t sockaddrLen = sizeof(addrin);
            int socket = lwip_accept(listenfd,(struct sockaddr*)&addrin,&sockaddrLen);
            if( socket < 0 ) // accept failed.
            {
                rt_kprintf("TCP setup accept failed.\n");
                continue;
            }
            rt_kprintf("TCP setup accept connection.\n");
            // set socket keep alive.
            lwip_setsockopt(socket,SOL_SOCKET,SO_KEEPALIVE,&optval ,sizeof(optval));

            // begin to recv & send.
            while(1)
            {
                int dataLen,bytesRet;
                ret = blocking_lwip_recv(socket,setup_data_buf,P2X_HEADER_LEN,500);
                if( ret == 0 )
                    continue;
                if( ret != P2X_HEADER_LEN )
                    break;

                dataLen = P2X_GET_LENGTH(setup_data_buf);
                if( dataLen > 0 )
                {
                    int gotDataLen = blocking_lwip_recv(socket,setup_data_buf+P2X_HEADER_LEN,dataLen,500);
                    if( gotDataLen != dataLen )
                        break;
                }
                bytesRet = processCMD(setup_data_buf,P2X_HEADER_LEN+dataLen);
                if( lwip_send(socket,setup_data_buf,bytesRet,0) < 0 )
                    break;
            }
            rt_kprintf("TCP setup disconnected.\n");
            lwip_close(socket);
        }
    }// while(1) listen.
}
/* Codes_SRS_TLSIO_SSL_ESP8266_99_053: [ The tlsio_openssl_send shall send all bytes in a buffer to the ssl connection. ]*/
int tlsio_openssl_send(CONCRETE_IO_HANDLE tls_io, const void* buffer, size_t size, ON_SEND_COMPLETE on_send_complete, void* callback_context)
{
    int result;

    if ((tls_io == NULL) || (buffer == NULL) || (size == 0))
    {
        /* Codes_SRS_TLSIO_SSL_ESP8266_99_060: [ If the tls_io handle is NULL, the tlsio_openssl_send shall not do anything, and return _LINE_. ]*/
        /* Codes_SRS_TLSIO_SSL_ESP8266_99_061: [ If the buffer is NULL, the tlsio_openssl_send shall not do anything, and return _LINE_. ]*/
        /* Codes_SRS_TLSIO_SSL_ESP8266_99_062: [ If the size is 0, the tlsio_openssl_send shall not do anything, and return _LINE_. ]*/
        result = __LINE__;
        LogError("Invalid parameter.");
    }
    else
    {
        TLS_IO_INSTANCE* tls_io_instance = (TLS_IO_INSTANCE*)tls_io;

        if (tls_io_instance->tlsio_state != TLSIO_STATE_OPEN)
        {
            /* Codes_SRS_TLSIO_SSL_ESP8266_99_059: [ If the tlsio state is not TLSIO_STATE_OPEN, the tlsio_openssl_send shall return _LINE_. ]*/
            result = __LINE__;
            LogError("TLS is not ready to send data. Expected state is TLSIO_STATE_OPEN.");
            //LogInfo("TLS is not ready to send data. Expected state is TLSIO_STATE_OPEN.");
        }
        else
        {
            int total_write = 0;
            int ret = 0;
            int need_sent_bytes = (int)size;

            fd_set writeset;
            fd_set errset;
            /* Codes_SRS_TLSIO_SSL_ESP8266_99_056: [ The ssl will continue to send all data in the buffer until all bytes have been sent. ]*/
            while(need_sent_bytes > 0)
            {
                FD_ZERO(&writeset);
                FD_SET(tls_io_instance->sock, &writeset);
                FD_ZERO(&errset);
                FD_SET(tls_io_instance->sock, &errset);

                ret = lwip_select(tls_io_instance->sock + 1, NULL, &writeset, &errset, &timeout);
                if (ret == 0) {
                    result = __LINE__;
                    LogError("select timeout and no data to be write");
                    break;
                } else if (ret < 0 || FD_ISSET(tls_io_instance->sock, &errset)) {
                    result = __LINE__;
                    LogError("get error %d", lwip_net_errno(tls_io_instance->sock));
                    break;
                }
                ret = SSL_write(tls_io_instance->ssl, ((uint8*)buffer)+total_write, (int)size);
                // LogInfo("SSL_write ret: %d", ret);
                //LogInfo("SSL_write res: %d, size: %d, retry: %d", res, size, retry);
                if(ret > 0){
                    total_write += ret;
                    need_sent_bytes = need_sent_bytes - ret;
                }
                else
                {
                    result = __LINE__;
                    LogError("SSL_write failed.");
                    break;
                }
            }

            if (need_sent_bytes != 0)
            {
                LogInfo("ssl write failed, return [-0x%x]", -ret);

                ret = SSL_shutdown(tls_io_instance->ssl);
                LogInfo("SSL_shutdown ret: %d", ret);

                /* Codes_SRS_TLSIO_SSL_ESP8266_99_054: [ The tlsio_openssl_send shall use the provided on_io_send_complete callback function address. ]*/
                /* Codes_SRS_TLSIO_SSL_ESP8266_99_055: [ The tlsio_openssl_send shall use the provided on_io_send_complete_context handle. ]*/
                /* Codes_SRS_TLSIO_SSL_ESP8266_99_057: [ If the ssl was not able to send all the bytes in the buffer, the tlsio_openssl_send shall call the on_send_complete with IO_SEND_ERROR, and return _LINE_. ]*/
                result = __LINE__;
                if (on_send_complete != NULL)
                {
                    /* Codes_SRS_TLSIO_SSL_ESP8266_99_003: [ The tlsio_ssl_esp8266 shall report the send operation status using the IO_SEND_RESULT enumerator defined in the `xio.h`. ]*/
                    on_send_complete(callback_context, IO_SEND_ERROR);
                }
            }
            else
            {
                result = 0;
                // LogInfo("SSL Write OK");
                /* Codes_SRS_TLSIO_SSL_ESP8266_99_058: [ If the ssl finish to send all bytes in the buffer, then tlsio_openssl_send shall call the on_send_complete with IO_SEND_OK, and return 0 ]*/
                /* Codes_SRS_TLSIO_SSL_ESP8266_99_054: [ The tlsio_openssl_send shall use the provided on_io_send_complete callback function address. ]*/
                /* Codes_SRS_TLSIO_SSL_ESP8266_99_055: [ The tlsio_openssl_send shall use the provided on_io_send_complete_context handle. ]*/
                if (on_send_complete != NULL)
                {
                    /* Codes_SRS_TLSIO_SSL_ESP8266_99_003: [ The tlsio_ssl_esp8266 shall report the send operation status using the IO_SEND_RESULT enumerator defined in the `xio.h`. ]*/
                    on_send_complete(callback_context, IO_SEND_OK);
                }
            }

            // LogInfo("total write: %d", total_write);
        }
    }
    return result;
}
Beispiel #29
0
/**************************************************************
 * void chargen_thread(void *arg)
 *
 * chargen task. This server will wait for connections on well
 * known TCP port number: 19. For every connection, the server will
 * write as much data as possible to the tcp port.
 **************************************************************/
static void chargen_thread(void *arg)
{
    int listenfd;
    struct sockaddr_in chargen_saddr;
    fd_set readset;
    fd_set writeset;
    int i, maxfdp1;
    struct charcb *p_charcb;

    /* First acquire our socket for listening for connections */
    listenfd = lwip_socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    LWIP_ASSERT("chargen_thread(): Socket create failed.", listenfd >= 0);
    memset(&chargen_saddr, 0, sizeof(chargen_saddr));
    chargen_saddr.sin_family = AF_INET;
    chargen_saddr.sin_addr.s_addr = htonl(INADDR_ANY);
    chargen_saddr.sin_port = htons(19);     // Chargen server port

    if (lwip_bind(listenfd, (struct sockaddr *) &chargen_saddr, sizeof(chargen_saddr)) == -1)
        LWIP_ASSERT("chargen_thread(): Socket bind failed.", 0);

    /* Put socket into listening mode */
    if (lwip_listen(listenfd, MAX_SERV) == -1)
        LWIP_ASSERT("chargen_thread(): Listen failed.", 0);

    /* Wait forever for network input: This could be connections or data */
    for (;;) {
        maxfdp1 = listenfd+1;

        /* Determine what sockets need to be in readset */
        FD_ZERO(&readset);
        FD_ZERO(&writeset);
        FD_SET(listenfd, &readset);
        for (p_charcb = charcb_list; p_charcb; p_charcb = p_charcb->next) {
            if (maxfdp1 < p_charcb->socket + 1)
                maxfdp1 = p_charcb->socket + 1;
            FD_SET(p_charcb->socket, &readset);
            FD_SET(p_charcb->socket, &writeset);
        }

        /* Wait for data or a new connection */
        i = lwip_select(maxfdp1, &readset, &writeset, 0, 0);

        if (i == 0) continue;

        /* At least one descriptor is ready */
        if (FD_ISSET(listenfd, &readset)) {
            /* We have a new connection request!!! */
            /* Lets create a new control block */
            p_charcb = (struct charcb *)rt_calloc(1, sizeof(struct charcb));
            if (p_charcb) {
                p_charcb->socket = lwip_accept(listenfd,
                                               (struct sockaddr *) &p_charcb->cliaddr,
                                               &p_charcb->clilen);
                if (p_charcb->socket < 0)
                    rt_free(p_charcb);
                else {
                    /* Keep this tecb in our list */
                    p_charcb->next = charcb_list;
                    charcb_list = p_charcb;
                    p_charcb->nextchar = 0x21;
                }
            } else {
                /* No memory to accept connection. Just accept and then close */
                int sock;
                struct sockaddr cliaddr;
                socklen_t clilen;

                sock = lwip_accept(listenfd, &cliaddr, &clilen);
                if (sock >= 0)
                    lwip_close(sock);
            }
        }
        /* Go through list of connected clients and process data */
        for (p_charcb = charcb_list; p_charcb; p_charcb = p_charcb->next) {
            if (FD_ISSET(p_charcb->socket, &readset)) {
                /* This socket is ready for reading. This could be because someone typed
                 * some characters or it could be because the socket is now closed. Try reading
                 * some data to see. */
                if (do_read(p_charcb) < 0)
                    break;
            }
            if (FD_ISSET(p_charcb->socket, &writeset)) {
                char line[80];
                char setchar = p_charcb->nextchar;

                for( i = 0; i < 59; i++) {
                    line[i] = setchar;
                    if (++setchar == 0x7f)
                        setchar = 0x21;
                }
                line[i] = 0;
                strcat(line, "\n\r");
                if (lwip_write(p_charcb->socket, line, strlen(line)) < 0) {
                    close_chargen(p_charcb);
                    break;
                }
                if (++p_charcb->nextchar == 0x7f)
                    p_charcb->nextchar = 0x21;
            }
        }
    }
}
Beispiel #30
0
int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout) {
	return lwip_select(maxfdp1, readset, writeset, exceptset, timeout);
}