Esempio n. 1
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)
{
  LWIP_DEBUGF(ALII_4573_CLOSE_DEBUG, ("Begin do_close_internal conn=%08x conn->pcb.tcp=%08x localport=%d remoteip=%08x remoteport=%d\n", conn, conn->pcb.tcp, conn->pcb.tcp->local_port, conn->pcb.tcp->remote_ip, conn->pcb.tcp->remote_port));
  err_t err;
  u8_t shut, shut_rx, shut_tx, close;

  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));
  LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL);

  shut = conn->current_msg->msg.sd.shut;
  shut_rx = shut & NETCONN_SHUT_RD;
  shut_tx = shut & NETCONN_SHUT_WR;
  /* shutting down both ends is the same as closing */
  close = shut == NETCONN_SHUT_RDWR;

  /* Set back some callback pointers */
  if (close) {
    tcp_arg(conn->pcb.tcp, NULL);
  }
  if (conn->pcb.tcp->state == LISTEN) {
    tcp_accept(conn->pcb.tcp, NULL);
  } else {
    /* some callbacks have to be reset if tcp_close is not successful */
    if (shut_rx) {
      tcp_recv(conn->pcb.tcp, NULL);
      tcp_accept(conn->pcb.tcp, NULL);
    }
    if (shut_tx) {
      tcp_sent(conn->pcb.tcp, NULL);
    }
    if (close) {
      tcp_poll(conn->pcb.tcp, NULL, 4);
      tcp_err(conn->pcb.tcp, NULL);
    }
  }
  /* Try to close the connection */
  if (close) {
    LWIP_DEBUGF(ALII_4573_CLOSE_DEBUG, ("close:calling tcp_close conn=%08x conn->pcb.tcp=%08x\n", conn, conn->pcb.tcp));
    err = tcp_close(conn->pcb.tcp);
  } else {
    LWIP_DEBUGF(ALII_4573_CLOSE_DEBUG, ("close:shutdown:calling tcp_shutdown conn=%08x conn->pcb.tcp=%08x\n", conn, conn->pcb.tcp));
    err = tcp_shutdown(conn->pcb.tcp, shut_rx, shut_tx);
  }
  int close_always_returns = 0;
  #if defined ALII_4573_CLOSE_ALWAYS_RETURNS && ALII_4573_CLOSE_ALWAYS_RETURNS
    close_always_returns = 1;
  #endif
  if ((close_always_returns)||(err == ERR_OK)) {

    LWIP_DEBUGF(ALII_4573_CLOSE_DEBUG, ("Closing succeeded conn=%08x conn->pcb.tcp=%08x err=%d\n", conn, conn->pcb.tcp, err));
    /* Closing succeeded */
    conn->current_msg->err = err;
    conn->current_msg = NULL;
    conn->state = NETCONN_NONE;
    if (close) {
      /* Set back some callback pointers as conn is going away */
      conn->pcb.tcp = NULL;
      /* Trigger select() in socket layer. Make sure everybody notices activity
       on the connection, error first! */
      API_EVENT(conn, NETCONN_EVT_ERROR, 0);
    }
    if (shut_rx) {
      API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
    }
    if (shut_tx) {
      API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
    }
    /* wake up the application task */
    LWIP_DEBUGF(ALII_4573_CLOSE_DEBUG, ("wake up the application task conn=%08x conn->pcb.tcp=%08x NETCONN_EVT_SENDPLUS\n", conn, conn->pcb.tcp));
    conn_op_completed(conn);
  } else {
    /* Closing failed, restore some of the callbacks */
    /* Closing of listen pcb will never fail! */
    LWIP_DEBUGF(ALII_4573_CLOSE_DEBUG, ("close failed conn=%08x conn->pcb.tcp=%08x\n", conn, conn->pcb.tcp));
    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);
    /* don't restore recv callback: we don't want to receive any more data */
  }
  /* If closing didn't succeed, we get called again either
     from poll_tcp or from sent_tcp */
  LWIP_DEBUGF(ALII_4573_CLOSE_DEBUG, ("End do_close_internal conn=%08x conn->pcb.tcp=%08x\n", conn, conn->pcb.tcp));
}
Esempio n. 2
0
/*
 * Handle an incoming TCP segment.
 */
int tcp_handler(unsigned long srcip, unsigned char *pkt, int pktlen)
{
    struct tcphdr *hdr;
    int optlen, i;
    struct tcp_socket *sk;
    unsigned short mss = 0;

    if (!pkt || (pktlen < 20))
        return PKTHANDLER_REJECT;

    hdr = (struct tcphdr *)pkt;

    dprintf("tcp: srcport = %d / dstport = %d\n",
            ntohs(hdr->srcport), ntohs(hdr->dstport));
    dprintf("tcp: seqnum = 0x%08x / acknum = 0x%08x\n",
            ntohl(hdr->seqnum), ntohl(hdr->acknum));
    dprintf("tcp: hdrlen = 0x%01x (%d bytes)\n",
            hdr->hdrlen, hdr->hdrlen*4);
    dprintf("tcp: reserved1 = 0x%01x / reserved2 = 0x%01x\n",
            hdr->reserved1, hdr->reserved2);
    dprintf("tcp: control bits: 0x%02x = %s%s%s%s%s%s\n",
            hdr->cntrlbits,
            (hdr->cntrlbits & TCPBIT_FIN) ? "FIN " : "",
            (hdr->cntrlbits & TCPBIT_SYN) ? "SYN " : "",
            (hdr->cntrlbits & TCPBIT_RST) ? "RST " : "",
            (hdr->cntrlbits & TCPBIT_PSH) ? "PSH " : "",
            (hdr->cntrlbits & TCPBIT_ACK) ? "ACK " : "",
            (hdr->cntrlbits & TCPBIT_URG) ? "URG " : "");
    dprintf("tcp: window = %d\n", ntohs(hdr->window));
    dprintf("tcp: csum = 0x%04x\n", ntohs(hdr->csum));
    dprintf("tcp: urgptr = 0x%04x\n", ntohs(hdr->urgptr));

    /* Calculate the length of the options section */
    optlen = (hdr->hdrlen * 4) - 20; /* base header is always 20 bytes */

    for (i = 0; i < optlen; ) {

        if (hdr->opts[i] == 0x00) /* EOO */
            break;

        if (hdr->opts[i] == 0x01) { /* NOP */
            dprintf("tcp: opts: nop\n");
            i++;
            continue;
        }

        if (hdr->opts[i] == 0x02) { /* MSS */
            unsigned short *mss = (unsigned short *)(hdr->opts+i+2);

            dprintf("tcp: opts: mss = %d\n", ntohs(*mss));

            mss = ntohs(*mss);

        } else if (hdr->opts[i] == 0x03) {
            unsigned char *shift = hdr->opts+i+2;

            dprintf("tcp: opts: wscale = %d\n", *shift);

        } else if (hdr->opts[i] == 0x04) {

            dprintf("tcp: opts: sack permitted\n");

        } else if (hdr->opts[i] == 0x08) {
            unsigned long *stamp = (unsigned long *)(hdr->opts+i+2);
            unsigned long *reply = (unsigned long *)(hdr->opts+i+2+4);

            dprintf("tcp: opts: timestamp = %d %d\n", ntohl(*stamp), ntohl(*reply));

        } else
            dprintf("tcp: opts: unknown: kind = %d / len = %d\n", hdr->opts[i], hdr->opts[i+1]);

        i += hdr->opts[i+1];
    }

    if (!(sk = tcp_findsock(ntohs(hdr->dstport),
                            ntohl(srcip), ntohs(hdr->srcport)))) {

        if (hdr->cntrlbits & TCPBIT_SYN) {
            struct tcp_socket *lsk;

            if ((lsk = tcp_findlistener(ntohs(hdr->dstport))) &&
                    (sk = tcp_accept(lsk, ntohl(srcip), ntohs(hdr->srcport),
                                     ntohl(hdr->seqnum), mss))) {

                dprintf("tcp: connecting 0x%08lx:%u to local port %u\n",
                        srcip, hdr->srcport,
                        lsk->localport);

                tcp_send_syn(sk);

            } else {
                dprintf("tcp: unable to find matching socket for incoming connection; sending RST\n");
                tcp_send_rst(srcip, hdr->srcport, hdr->dstport, hdr->seqnum);
            }

        } else {
            dprintf("tcp: unable to find matching socket\n");

#if 0
            /*
             * I don't think this is compliant behavior. Linux doesn't
             * like it, anyway.
             *
             * Which leads to the question... How the hell do you get out
             * FIN_WAIT1/2, other than letting it time out?
             *
             */
            tcp_send_rst(srcip, hdr->srcport, hdr->dstport, hdr->seqnum);
#endif
        }

    } else {

        tcp_consumeseg(sk, srcip, pkt, pktlen);

    }

    return PKTHANDLER_ACCEPT;
}
Esempio n. 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;
	u8_t shut, shut_rx, shut_tx, close;

	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));
	LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL);

	shut = conn->current_msg->msg.sd.shut;
	shut_rx = shut & NETCONN_SHUT_RD;
	shut_tx = shut & NETCONN_SHUT_WR;
	/* shutting down both ends is the same as closing */
	close = shut == NETCONN_SHUT_RDWR;

	/* Set back some callback pointers */
	if (close) {
		tcp_arg(conn->pcb.tcp, NULL);
	}
	if (conn->pcb.tcp->state == LISTEN) {
		tcp_accept(conn->pcb.tcp, NULL);
	} else {
		/* some callbacks have to be reset if tcp_close is not successful */
		if (shut_rx) {
			tcp_recv(conn->pcb.tcp, NULL);
			tcp_accept(conn->pcb.tcp, NULL);
		}
		if (shut_tx) {
			tcp_sent(conn->pcb.tcp, NULL);
		}
		if (close) {
			tcp_poll(conn->pcb.tcp, NULL, 4);
			tcp_err(conn->pcb.tcp, NULL);
		}
	}
	/* Try to close the connection */
	if (shut == NETCONN_SHUT_RDWR) {
		err = tcp_close(conn->pcb.tcp);
	} else {
		err = tcp_shutdown(conn->pcb.tcp, shut & NETCONN_SHUT_RD, shut & NETCONN_SHUT_WR);
	}
	if (err == ERR_OK) {
		/* Closing succeeded */
		conn->current_msg->err = ERR_OK;
		conn->current_msg = NULL;
		conn->state = NETCONN_NONE;
		/* Set back some callback pointers as conn is going away */
		conn->pcb.tcp = NULL;
		/* Trigger select() in socket layer. Make sure everybody notices activity
		   on the connection, error first! */
		if (close) {
			API_EVENT(conn, NETCONN_EVT_ERROR, 0);
		}
		if (shut_rx) {
			API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
		}
		if (shut_tx) {
			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);
		/* don't restore recv callback: we don't want to receive any more data */
	}
	/* If closing didn't succeed, we get called again either
	   from poll_tcp or from sent_tcp */
}
Esempio n. 4
0
int waitclients(void)
{
	int fd_max;
	fd_set fds;
	vlist_i *it;
	pipe_s *pit, *newpipe;
	tcpsock_s *newsock;
	thr_t thread;
	
	fd_max = 0;
	FD_ZERO(&fds);

	/* Set all sockets to listen */
	for (it = pipes.head; it; it = it->next)
	{
		pit = (pipe_s *)it->data;

		if (tcp_listen(&pit->sock))
			perror("waitclients() - tcp_listen()");
	}

	printf("Serproxy - (C)1999 Stefano Busti - Waiting for clients\n");
	
	while (1)
	{
		/* Iterate through the pipe list */
		for (it = pipes.head; it; it = it->next)
		{
			pit = (pipe_s *)it->data;

			/* Monitor socket fd of each */
			FD_SET(pit->sock.fd, &fds);

			/* Track max fd */
			if (pit->sock.fd > fd_max)
				fd_max = pit->sock.fd;
		}

		/* Wait for a read ( == accept() in this case) */
		if (select(fd_max + 1, &fds, NULL, NULL, NULL) == -1)
			perrend("waitclients() - select()");


		/* Find which sockets are involved */
		for (it = pipes.head; it; it = it->next)
		{
			pit = (pipe_s *)it->data;

			if (FD_ISSET(pit->sock.fd, &fds))
			{
				/* Create a new pipe struct for the new thread */
				newpipe = malloc(sizeof(pipe_s));
				if (!newpipe)
					perrend("waitclients() - malloc(pipe_s)");

				newpipe->sio = pit->sio;

				/* Try to open serial port */
				if (sio_open(&newpipe->sio))
				{
					tcp_refuse(&pit->sock);
					error("Failed to open comm port - connection refused");
					free(newpipe);
					continue;
				}
				
				/* Accept the connection */
				newsock = tcp_accept(&pit->sock);

				/* All ok? */
				if (newsock)
				{
					newpipe->sock = *newsock;
					free(newsock);

					newpipe->timeout = pit->timeout;
					newpipe->mutex = pit->mutex;
						
					/* Create the server thread */
					if (thr_create(&thread, 1, serve_pipe, newpipe))
					{
						error("Feck - thread creation failed");
						free(newpipe);
					}
					else
					{
						fprintf(stderr, "Server thread launched\n");
					}
				}
				else
				{
					perror("waitclients() - accept()");
					free(newpipe);
				}
			}
		}
	}
	return 0;
}
Esempio n. 5
0
// Send exactly one TCP window of data or return true if we can free up this object
bool NetworkTransaction::Send()
{
	// Free up this transaction if we either lost our connection or are supposed to close it now

	if (LostConnection() || closeRequested)
	{
		if (fileBeingSent != NULL)
		{
			fileBeingSent->Close();
			fileBeingSent = NULL;
		}

		Network *net = reprap.GetNetwork();
		while (sendBuffer != NULL)
		{
			sendBuffer = net->ReleaseSendBuffer(sendBuffer);
		}

		if (!LostConnection())
		{
//			debugPrintf("NetworkTransaction is closing connection cs=%08x\n", (unsigned int)cs);
			reprap.GetNetwork()->ConnectionClosed(cs, true);
		}

		if (closingDataPort)
		{
			if (ftp_pasv_pcb != NULL)
			{
				tcp_accept(ftp_pasv_pcb, NULL);
				tcp_close(ftp_pasv_pcb);
				ftp_pasv_pcb = NULL;
			}

			closingDataPort = false;
		}

		sendingTransaction = NULL;
		sentDataOutstanding = 0;

		return true;
	}

	// We're still waiting for data to be ACK'ed, so check timeouts here

	if (sentDataOutstanding)
	{
		if (!isnan(lastWriteTime))
		{
			float timeNow = reprap.GetPlatform()->Time();
			if (timeNow - lastWriteTime > writeTimeout)
			{
				reprap.GetPlatform()->Message(HOST_MESSAGE, "Network: Timing out connection cs=%08x\n", (unsigned int)cs);
				tcp_abort(cs->pcb);
				cs->pcb = NULL;
			}
			return false;
		}
	}
	else
	{
		sendingTransaction = NULL;
	}

	// See if we can fill up the TCP window with some data chunks from our SendBuffer instances

	uint16_t bytesBeingSent = 0, bytesLeftToSend = TCP_WND;
	while (sendBuffer != NULL && bytesLeftToSend >= sendBuffer->bytesToWrite)
	{
		memcpy(sendingWindow + bytesBeingSent, sendBuffer->tcpOutputBuffer, sendBuffer->bytesToWrite);
		bytesBeingSent += sendBuffer->bytesToWrite;
		bytesLeftToSend -= sendBuffer->bytesToWrite;
		sendBuffer = reprap.GetNetwork()->ReleaseSendBuffer(sendBuffer);
	}

	// We also intend to send a file, so check if we can fill up the TCP window

	if (sendBuffer == NULL)
	{
		int bytesRead;
		size_t bytesToRead;
		while (bytesLeftToSend && fileBeingSent != NULL)
		{
			bytesToRead = min<size_t>(256, bytesLeftToSend);  // FIXME: doesn't work with higher block sizes
			bytesRead = fileBeingSent->Read(sendingWindow + bytesBeingSent, bytesToRead);

			if (bytesRead > 0)
			{
				bytesBeingSent += bytesRead;
				bytesLeftToSend = TCP_WND - bytesBeingSent;
			}

			if (bytesRead != bytesToRead)
			{
				fileBeingSent->Close();
				fileBeingSent = NULL;
			}
		}
	}

	if (!bytesBeingSent)
	{
		// If we have no data to send and fileBeingSent is NULL, we can close the connection
		if (!cs->persistConnection && nextWrite == NULL)
		{
			Close();
			return false;
		}

		// We want to send data from another transaction, so only free up this one
		return true;
	}
	else
	{
		// The TCP window has been filled up as much as possible, so send it now. There is no need to check
		// the available space in the SNDBUF queue, because we really write only one TCP window at once.
		tcp_sent(cs->pcb, conn_sent);
		err_t result = tcp_write(cs->pcb, sendingWindow, bytesBeingSent, 0);
		if (result != ERR_OK) // Final arg - 1 means make a copy
		{
			reprap.GetPlatform()->Message(HOST_MESSAGE, "Network: tcp_write returned error code %d, this should never happen!\n", result);
			tcp_abort(cs->pcb);
			cs->pcb = NULL;
		}
		else
		{
			sendingTransaction = this;
			sendingRetries = 0;
			sendingWindowSize = sentDataOutstanding = bytesBeingSent;

			lastWriteTime = reprap.GetPlatform()->Time();

			tcp_output(cs->pcb);
		}
	}
	return false;
}
Esempio n. 6
0
/**
 * Set a TCP pcb contained in a netconn into listen mode
 * Called from netconn_listen.
 *
 * @param msg the api_msg_msg pointing to the connection
 */
void
lwip_netconn_do_listen(struct api_msg_msg *msg)
{
  if (ERR_IS_FATAL_LISTENCONNECT(msg->conn->last_err)) {
    msg->err = msg->conn->last_err;
  } else {
    msg->err = ERR_CONN;
    if (msg->conn->pcb.tcp != NULL) {
      if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) {
        if (msg->conn->state == NETCONN_NONE) {
          struct tcp_pcb* lpcb;
          if (msg->conn->pcb.tcp->state != CLOSED) {
            /* connection is not closed, cannot listen */
            msg->err = ERR_VAL;
          } else {
#if LWIP_IPV6
            if ((msg->conn->flags & NETCONN_FLAG_IPV6_V6ONLY) == 0) {
#if TCP_LISTEN_BACKLOG
              lpcb = tcp_listen_dual_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog);
#else  /* TCP_LISTEN_BACKLOG */
              lpcb = tcp_listen_dual(msg->conn->pcb.tcp);
#endif /* TCP_LISTEN_BACKLOG */
            } else
#endif /* LWIP_IPV6 */
            {
#if TCP_LISTEN_BACKLOG
              lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog);
#else  /* TCP_LISTEN_BACKLOG */
              lpcb = tcp_listen(msg->conn->pcb.tcp);
#endif /* TCP_LISTEN_BACKLOG */
            }
            if (lpcb == NULL) {
              /* in this case, the old pcb is still allocated */
              msg->err = ERR_MEM;
            } else {
              /* delete the recvmbox and allocate the acceptmbox */
              if (sys_mbox_valid(&msg->conn->recvmbox)) {
                /** @todo: should we drain the recvmbox here? */
                sys_mbox_free(&msg->conn->recvmbox);
                sys_mbox_set_invalid(&msg->conn->recvmbox);
              }
              msg->err = ERR_OK;
              if (!sys_mbox_valid(&msg->conn->acceptmbox)) {
                msg->err = sys_mbox_new(&msg->conn->acceptmbox, DEFAULT_ACCEPTMBOX_SIZE);
              }
              if (msg->err == ERR_OK) {
                msg->conn->state = NETCONN_LISTEN;
                msg->conn->pcb.tcp = lpcb;
                tcp_arg(msg->conn->pcb.tcp, msg->conn);
                tcp_accept(msg->conn->pcb.tcp, accept_function);
              } else {
                /* since the old pcb is already deallocated, free lpcb now */
                tcp_close(lpcb);
                msg->conn->pcb.tcp = NULL;
              }
            }
          }
        }
      } else {
        msg->err = ERR_ARG;
      }
    }
  }
  TCPIP_APIMSG_ACK(msg);
}
void accept_new_session( int32_t fd, int16_t ev, void * arg )
{
    struct iothread * thr = (struct iothread *)arg;
    struct acceptor * a = thr->core_acceptor;

    if ( ev & EV_READ )
    {
        //
        // 接收新连接完毕后
        //
        char srchost[20];
        char dsthost[20];
        uint16_t dstport = 0;

        int32_t newfd = tcp_accept( fd, srchost, dsthost, &dstport );
        if ( newfd > 0 )
        {
            uint64_t sid = 0;
            struct session * newsession = NULL;

            set_fd_nonblock( newfd );

            newsession = (struct session *)malloc( sizeof(struct session) );
            if ( newsession == NULL )
            {
                printf("Out of memory, allocate for 'newsession' failed .\n");
                goto ACCEPT_END;
            }

            newsession->evread = event_create();
            if ( newsession->evread == NULL )
            {
                printf("Out of memory, allocate for 'newsession->evread' failed .\n");
                goto ACCEPT_END;
            }

            newsession->iobytes = 0;
            newsession->fd = newfd;

            sid = thr->key;
            sid <<= 32;
            sid += thr->index++;
            newsession->sid = sid;

#if USE_LIBEVENT
            {
                struct timeval tv = {TIMEOUT_MSECS/1000, 0};
                event_set( newsession->evread, newsession->fd, EV_READ, echoserver_process_message, newsession );
                event_base_set( thr->core_sets, newsession->evread );
                event_add( newsession->evread, &tv );
            }
#else
            event_set( newsession->evread, newsession->fd, EV_READ );
            event_set_callback( newsession->evread, echoserver_process_message, newsession );
            evsets_add( thr->core_sets, newsession->evread, TIMEOUT_MSECS );
#endif

#if __DEBUG
            printf( "Thread[%d] accept a new Client[%lld, fd:%d, '%s':%d] .\n",
                thr->key, newsession->sid, newsession->fd, dsthost, dstport );
#endif
        }

        a->holding = 0;
        pthread_mutex_unlock( &(a->lock) );
    }

ACCEPT_END :

    return;
}
Esempio n. 8
0
/* return value:
   = 0: OK
   < 0: ERROR
 */
int tcp_establish_sock_conn 
(
 int *localsocket_fd,          /* descriptor of local socket                    */
 struct sockaddr *local_addr,  /* local internet address (struct *sockaddr_in)  */
 int *remotesocket_fd,         /* descriptor of remote socket                   */
 struct sockaddr *remote_addr, /* remote internet address (struct *sockaddr_in) */
 char *qos,                    /* parameter ignored                             */
 unsigned long *rcvMaxSduSize, /* parameter ignored                             */
 unsigned long *sndMaxSduSize, /* parameter ignored                             */
 int max_nconn,                /* the maximum length of the queue of pending    */
                               /* connections, passed to call of listen()       */
 int serv,                     /* active (server) or passive (client) open connection */
 int timeout                   /* timeout for connect 0=wait forever*/
 )
 
{
   if (serv == CONN_SERVER) {
      /* server accepts */
      if (tcp_bind(localsocket_fd,(struct sockaddr_in *)local_addr,
		  remotesocket_fd,(struct sockaddr_in *)remote_addr,serv) == -1) {
	PRERROR("tcp_establish_sock_conn: error in tcp_bind on port");
	perror("");
         return ERR_TCP_CONN_BIND;
      }
      if (tcp_listen(*localsocket_fd, max_nconn) == -1) {
         PRERROR("listen_connection: error in listen\n"); perror("");
         return ERR_TCP_CONN_LISTEN;
      }
      PRVERBOSE2("accepting from local adress %s:%d\n",  inet_ntoa (((struct sockaddr_in *)local_addr)->sin_addr),
	       ntohs( ((struct sockaddr_in *)(local_addr))->sin_port) );
     
      if (tcp_accept(*localsocket_fd, remotesocket_fd, timeout) == -1) {
         PRERROR("tcp_establish_sock_conn(): error in tcp_accept\n");
	 close(*localsocket_fd);
         return ERR_TCP_CONN_ACCEPT;
      }
   } else {
     int result=-1, connect_error;
     int tries=timeout*1000*1000/CONN_CONNECT_TIMEOUT;
     
     if (timeout==0) tries=INT_MAX;
     PRVERBOSE1("trying %d times\n",tries);
     while ( result == -1 && tries > 0 ) {
       /* client connects */
       if (tcp_bind(localsocket_fd, (struct sockaddr_in *)local_addr, 
		    remotesocket_fd, (struct sockaddr_in *)remote_addr, serv) == -1) {
         PRERROR("tcp_establish_sock_conn(): error in tcp_bind\n");
         return ERR_TCP_CONN_BIND;
       }
       result=tcp_connect(remotesocket_fd, (struct sockaddr_in *)remote_addr, &connect_error );
       
       if (result == -1) {
	 if (connect_error != ECONNREFUSED) {
	   PRERROR("tcp_establish_sock_conn(): error in tcp_connect\n");
	   return ERR_TCP_CONN_CONNECT;
	 } else {
	   tcp_add_socket_pair (localsocket_fd, remotesocket_fd, AF_INET, serv);
	   usleep(CONN_CONNECT_TIMEOUT);
	 }
       }
       tries--;
     } /* while */
     if ( result == -1) { /* no luck connecting .... */
	 PRERROR2("could not connect to  %s:%d\n",  inet_ntoa (((struct sockaddr_in *)remote_addr)->sin_addr),
	       ntohs( ((struct sockaddr_in *)(remote_addr))->sin_port) );
	 return ERR_TCP_CONN_CONNECT;
     }
   }
   return 0;
}
/* ts: only for accept */
int trice_conn_alloc(struct list *connl, struct trice *icem, unsigned compid,
		   bool active, const struct sa *laddr, const struct sa *peer,
		   struct tcp_sock *ts, int layer,
		   tcpconn_frame_h *frameh, void *arg)
{
	struct ice_tcpconn *conn;
	int err = 0;

	if (!connl || !icem || !laddr || !peer || !frameh)
		return EINVAL;

	conn = mem_zalloc(sizeof(*conn), conn_destructor);
	if (!conn)
		return ENOMEM;

	conn->icem = icem;
	conn->active = active;
	conn->paddr = *peer;
	conn->compid = compid;
	conn->layer = layer;
	conn->frameh = frameh;
	conn->arg = arg;

	if (active) {

		trice_printf(conn->icem, "<%p> TCP connecting"
			    " [laddr=%J paddr=%J] ..\n",
			    icem, laddr, peer);

		/* This connection is opened from the local candidate of the
		   pair to the remote candidate of the pair.
		 */
		err = tcp_conn_alloc(&conn->tc, peer, tcp_estab_handler,
				     NULL, tcp_close_handler,
				     conn);
		if (err) {
			DEBUG_WARNING("tcp_conn_alloc [peer=%J] (%m)\n",
				      peer, err);
			goto out;
		}

		err = tcp_conn_bind(conn->tc, laddr);
		if (err) {
			DEBUG_WARNING("tcp_conn_bind [laddr=%J paddr=%J]"
				      " (%m)\n",
				      laddr, peer, err);
			goto out;
		}

		err = tcp_conn_connect(conn->tc, peer);
		if (err) {
			/* NOTE: this happens sometimes on OSX when
			 *       setting up two S-O connections
			 */
			if (err == EADDRINUSE) {
				re_printf("EADDRINUSE\n");
				err = 0;
			}
			else {
				DEBUG_NOTICE("tcp_conn_connect [peer=%J]"
					      " (%d/%m)\n",
					      peer, err, err);
				goto out;
			}
		}
	}
	else {
		err = tcp_accept(&conn->tc, ts, tcp_estab_handler,
				 NULL, tcp_close_handler, conn);
		if (err) {
			tcp_reject(ts);
			goto out;
		}
	}

	err = tcp_conn_local_get(conn->tc, &conn->laddr);
	if (err)
		goto out;

	list_append(connl, &conn->le, conn);

 out:
	if (err)
		mem_deref(conn);

	return err;
}
Esempio n. 10
0
int
main(int ac, char **av)
{
	char	c;
	int	n, N, fd, fid;
	pid_t	pid, ppid;
	char	buf[L_tmpnam+256];
	char	fname[L_tmpnam];
	char*	report_file = "Select on %d fd's";
	char*	report_tcp  = "Select on %d tcp fd's";
	char*	report;
	char*	usage = "lat_select tcp|file [n]\n";

	morefds();
	N = 200;
	fname[0] = 0;
	pid = 0;
	c = 0;
	nfds = 0;
	FD_ZERO(&set);
	report = report_file;

	if (ac != 2 && ac != 3) {
		fprintf(stderr, usage);
		exit(1);
	}

	if (streq(av[1], "tcp")) {
		report = report_tcp;
		
		/* Create a socket for clients to connect to */
		fd = tcp_server(TCP_SELECT, SOCKOPT_REUSE);
		if (fd <= 0) {
			perror("lat_select: Could not open tcp server socket");
			exit(1);
		}

		/* Start server process to accept client connections */
		ppid = getpid();
		switch(pid = fork()) {
		case 0:
			/* child server process */
			if (signal(SIGTERM, sigterm) == SIG_ERR) {
				perror("signal(SIGTERM, sigterm) failed");
				exit(1);
			}
			FD_SET(fd, &set);
			while (ppid == getppid()) {
				int newsock = tcp_accept(fd, SOCKOPT_NONE);
				if (newsock >= nfds) nfds = newsock + 1;
				FD_SET(newsock, &set);
			}
			sigterm(SIGTERM);
			/* NOTREACHED */
		case -1:
			/* error */
			perror("lat_select::server(): fork() failed");
			exit(1);
		default:
			break;
		}
		close(fd);
		fd = tcp_connect("127.0.0.1", TCP_SELECT, SOCKOPT_NONE);
		if (fd <= 0) {
			perror("lat_select: Could not open socket");
			exit(1);
		}
	} else if (streq(av[1], "file")) {
		/* Create a temporary file for clients to open */
		tmpnam(fname);
		fd = open(fname, O_RDWR|O_APPEND|O_CREAT, 0666);
		unlink(fname);
		if (fd <= 0) {
			char buf[L_tmpnam+128];
			sprintf(buf, 
				"lat_select: Could not create temp file %s", fname);
			perror(buf);
			exit(1);
		}
	} else {
		fprintf(stderr, usage);
		exit(1);
	}

	if (ac == 3) N = atoi(av[2]);

	for (n = 0; n < N; n++) {
		fid = dup(fd);
		if (fid == -1) break;
		if (fid >= nfds) nfds = fid + 1;
		FD_SET(fid, &set);
	}
	BENCH(doit(nfds, &set), 0);
	sprintf(buf, report, n);
	micro(buf, get_n());

	for (fid = 0; fid < nfds; fid++) {
		if (FD_ISSET(fid, &set)) {
			close(fid);
		}
	}
	close(fd);
	if (pid) kill(pid, SIGTERM);

	exit(0);
}
Esempio n. 11
0
static socket_error_t stop_listen(struct socket *socket)
{
    tcp_accept(socket->impl, irqAcceptNull);
    return SOCKET_ERROR_NONE;
}
Esempio n. 12
0
int
csrecv(register Cs_t* state, int fd, Csid_t* id, int* fds, int n)
{
	int			oerrno;
	Csid_t			ignore;

#if CS_LIB_SOCKET

	Sock_size_t		namlen;
	struct sockaddr_in	nam;

#if CS_LIB_SOCKET_UN && !CS_LIB_STREAM

#if CS_LIB_SOCKET_RIGHTS
	int			rfd[OPEN_MAX + 1];
#endif
	struct stat		st;

#endif

#endif

#if CS_LIB_STREAM || CS_LIB_V10

	int			m;
	struct strrecvfd	rcv;
	struct csfdhdr		hdr;

#if CS_LIB_V10

	struct tcpuser		tcp;

#endif

#endif

#if CS_LIB_STREAM || CS_LIB_V10 || CS_LIB_SOCKET_RIGHTS

	register int		i;

#endif

	messagef((state->id, NiL, -8, "recv(%d,%d) call", fd, n));
	if (n < 1)
	{
		errno = EINVAL;
		return -1;
	}
	if (!id) id = &ignore;
	memzero(id, sizeof(*id));
	oerrno = errno;
	csprotect(&cs);

#if CS_LIB_V10

	if (!ioctl(fd, TCPGETADDR, &tcp))
	{
		if ((fds[0] = tcp_accept(fd, &tcp)) < 0)
		{
			messagef((state->id, NiL, -1, "recv: %d: tcp accept error", fd));
			return -1;
		}
		id->hid = tcp.faddr;
		return 1;
	}
	messagef((state->id, NiL, -1, "recv: %d: ioctl TCPGETADDR error", fd));

#else

#if CS_LIB_SOCKET

	namlen = sizeof(nam);
	if ((fds[0] = accept(fd, (struct sockaddr*)&nam, &namlen)) >= 0)
	{

#if CS_LIB_SOCKET_UN && !CS_LIB_STREAM

#if defined(__linux__) && defined(AF_UNSPEC)
		if (nam.sin_family == AF_UNSPEC)
			nam.sin_family = AF_UNIX;
#endif
		if (nam.sin_family == AF_UNIX)
		{
#if CS_LIB_SOCKET_RIGHTS
			if (write(fds[0], "", 1) != 1)
			{
				messagef((state->id, NiL, -1, "recv: %d: ping write error", fd));
				close(fds[0]);
				return -1;
			}
			if (sockrecv(fds[0], id, rfd, 1) != 1)
			{
				messagef((state->id, NiL, -1, "recv: %d: sockrecv error", fd));
				goto eperm;
			}
			if (fstat(rfd[0], &st))
			{
				messagef((state->id, NiL, -1, "recv: %d: %d: authentication stat error", fd, rfd[0]));
			drop:
				close(rfd[0]);
			eperm:
				close(fds[0]);
				errno = EPERM;
				return -1;
			}
			if ((st.st_mode & CS_AUTH_MASK) != CS_AUTH_MODE)
			{
				messagef((state->id, NiL, -1, "recv: %d: %d: invalid authentication mode %04o", fd, rfd[0], st.st_mode & CS_AUTH_MASK));
				goto drop;
			}
			close(rfd[0]);
#else
			if (fstat(fds[0], &st))
			{
				st.st_uid = geteuid();
				st.st_gid = getegid();
			}
#endif
			id->uid = st.st_uid;
			id->gid = st.st_gid;
		}
		else

#endif

		if (nam.sin_family == AF_INET)
			id->hid = (unsigned long)nam.sin_addr.s_addr;
		return 1;
	}
	messagef((state->id, NiL, -1, "recv: %d: accept error", fd));

#endif

#endif

#if CS_LIB_STREAM || CS_LIB_V10

	if (ioctl(fd, I_RECVFD, &rcv) < 0)
	{
		messagef((state->id, NiL, -1, "recv: %d: ioctl I_RECVFD error", fd));
		switch (errno)
		{
		case EIO:
#ifdef EBADMSG
		case EBADMSG:
#endif
			break;
		default:
			return -1;
		}
#if CS_LIB_STREAM
		if (!(m = read(fd, &hdr, sizeof(hdr))))
#endif
		m = read(fd, &hdr, sizeof(hdr));
		if (m != sizeof(hdr))
		{
			errno = EINVAL;
			messagef((state->id, NiL, -1, "recv: %d: hdr read error", fd));
			return -1;
		}
		if (hdr.count <= 0)
		{
			errno = EINVAL;
			messagef((state->id, NiL, -1, "recv: %d: invalid hdr count %d", fd, hdr.count));
			return -1;
		}
		for (i = 0; i < hdr.count; i++)
		{
			if (ioctl(fd, I_RECVFD, &rcv) < 0)
			{
				messagef((state->id, NiL, -1, "recv: %d: ioctl I_RECVFD #%d error", fd, i + 1));
				while (--i >= 0) close(fds[i]);
				return -1;
			}
			fds[i] = rcv.fd;
		}
		id->pid = hdr.pid;
	}

#ifdef I_ACCEPT

	else if (ioctl(rcv.fd, I_ACCEPT, NiL) < 0)
	{
		messagef((state->id, NiL, -1, "recv: %d: ioctl I_ACCEPT error", fd));
		close(rcv.fd);
		return -1;
	}

#endif

	else
	{

		i = 1;
		fds[0] = rcv.fd;
	}
	id->uid = rcv.uid;
	id->gid = rcv.gid;
	errno = oerrno;
	return i;

#else

#if CS_LIB_SOCKET_RIGHTS

	if ((i = sockrecv(fd, id, rfd, n + 1)) <= 1)
	{
		messagef((state->id, NiL, -1, "recv: %d: sockrecv error", fd));
	nope:
		if (i >= 0)
		{
			errno = EPERM;
			while (--i >= 0) close(rfd[i]);
		}
		return -1;
	}
	if (fstat(rfd[0], &st))
	{
		messagef((state->id, NiL, -1, "recv: %d: %d: authentication stat error", fd, rfd[0]));
		goto nope;
	}
	if ((st.st_mode & CS_AUTH_MASK) != CS_AUTH_MODE)
	{
		messagef((state->id, NiL, -1, "recv: %d: %d: invalid authentication mode %04o", fd, rfd[0], st.st_mode & CS_AUTH_MASK));
		goto nope;
	}
	close(rfd[0]);
	for (n = --i; i > 0; i--) fds[i - 1] = rfd[i];
	id->uid = st.st_uid;
	id->gid = st.st_gid;
	return n;

#else

	if (!access(CS_PROC_FD_TST, F_OK))
	{
		register int	i;
		register int	j;
		char*		s;
		unsigned long	pid;
		struct stat	st;

		s = state->temp;
		if ((i = recv(fd, s, sizeof(state->temp), 0)) <= 0)
		{
			messagef((state->id, NiL, -1, "recv: %d: read error", fd));
			return -1;
		}
		if (i >= sizeof(state->temp))
			i = sizeof(state->temp) - 1;
		s[i] = 0;
		messagef((state->id, NiL, -8, "recv: `%s'", s));
		pid = strtol(s, &s, 0);
		i = strtol(s, &s, 0);
		if (i < n)
			n = i;
		for (i = 0; i < n; i++)
			fds[i] = strtol(s, &s, 0);
		s = state->temp;
		for (i = j = 0; i < n; i++)
		{
			sfsprintf(s, sizeof(state->temp), CS_PROC_FD_FMT, pid, fds[i]);
			if (!stat(s, &st) && (fds[i] = open(s, (st.st_mode & (S_IRUSR|S_IWUSR)) == (S_IRUSR|S_IWUSR) ? O_RDWR : (st.st_mode & S_IWUSR) ? O_WRONLY : O_RDONLY)) >= 0)
				j++;
		}
		if (id)
		{
			id->hid = 0;
			id->pid = pid;
			if (!stat(CS_PROC_FD_TST, &st))
			{
				id->uid = st.st_uid;
				id->gid = st.st_gid;
			}
			else
			{
				id->uid = geteuid();
				id->gid = getegid();
			}
		}
		messagef((state->id, NiL, -8, "recv: %d fds", j));
		return j;
	}
	errno = EINVAL;
	return -1;

#endif

#endif

}
Esempio n. 13
0
void echoserver_process_message( int32_t fd, int16_t ev, void * arg )
{
    struct session * s = (struct session *)arg;

    if ( ev & EV_READ )
    {
        char buf[16384];
        int32_t readn = -1;

        readn = read( fd, buf, 16384 );
        if ( readn <= 0 )
        {
#if __DEBUG
            printf( "Client[%ld, %d] is closed, BYTES:%d, TIME:%lld .\n",
                s->sid, s->fd, s->iobytes, milliseconds() );
#endif
            //evsets_del( event_get_sets(s->evread), s->evread );
            event_destroy( s->evread );
            close( s->fd );
            free( s );

            goto PROCESS_END;
        }
        else
        {
#if __DEBUG
            printf("echoserver_process_message(ev:%d) : TIME:%lld .\n", ev, milliseconds() );
#endif
            readn = write( fd, buf, readn );
            s->iobytes += readn;
        }

#if USE_LIBEVENT
        {
            struct timeval tv = {TIMEOUT_MSECS/1000, 0};
            event_add( s->evread, &tv );
        }
#else
        evsets_add( event_get_sets(s->evread), s->evread, TIMEOUT_MSECS );
#endif
    }
    else
    {
#if __DEBUG
        printf("echoserver_process_message(ev:%d) : TIME:%lld .\n", ev, milliseconds() );
#endif
    }

PROCESS_END :
}

void accept_new_session( int32_t fd, int16_t ev, void * arg )
{
    struct iothread * thr = (struct iothread *)arg;
    struct acceptor * a = thr->core_acceptor;

    if ( ev & EV_READ )
    {
        //
        // 接收新连接完毕后
        //
        char srchost[20];
        char dsthost[20];
        uint16_t dstport = 0;

        int32_t newfd = tcp_accept( fd, srchost, dsthost, &dstport );
        if ( newfd > 0 )
        {
            uint64_t sid = 0;
            struct session * newsession = NULL;

            set_fd_nonblock( newfd );

            newsession = (struct session *)malloc( sizeof(struct session) );
            if ( newsession == NULL )
            {
                printf("Out of memory, allocate for 'newsession' failed .\n");
                goto ACCEPT_END;
            }

            newsession->evread = event_create();
            if ( newsession->evread == NULL )
            {
                printf("Out of memory, allocate for 'newsession->evread' failed .\n");
                goto ACCEPT_END;
            }

            newsession->iobytes = 0;
            newsession->fd = newfd;

            sid = thr->key;
            sid <<= 32;
            sid += thr->index++;
            newsession->sid = sid;

#if USE_LIBEVENT
            {
                struct timeval tv = {TIMEOUT_MSECS/1000, 0};
                event_set( newsession->evread, newsession->fd, EV_READ, echoserver_process_message, newsession );
                event_base_set( thr->core_sets, newsession->evread );
                event_add( newsession->evread, &tv );
            }
#else
            event_set( newsession->evread, newsession->fd, EV_READ );
            event_set_callback( newsession->evread, echoserver_process_message, newsession );
            evsets_add( thr->core_sets, newsession->evread, TIMEOUT_MSECS );
#endif

#if __DEBUG
            printf( "Thread[%d] accept a new Client[%lld, fd:%d, '%s':%d] .\n",
                thr->key, newsession->sid, newsession->fd, dsthost, dstport );
#endif
        }

        a->holding = 0;
        pthread_mutex_unlock( &(a->lock) );
    }

ACCEPT_END :
}

void trylock_accept_mutex( struct iothread * thr )
{
    struct acceptor * a = thr->core_acceptor;

    if ( pthread_mutex_trylock(&(a->lock)) == 0 )
    {
        if ( a->holding == 0 )
        {
#if USE_LIBEVENT
            event_set( a->ev_accept, a->socketfd, EV_READ, accept_new_session, thr );
            event_base_set( thr->core_sets, a->ev_accept );
            event_add( a->ev_accept, 0 );
#else
            event_set( a->ev_accept, a->socketfd, EV_READ );
            event_set_callback( a->ev_accept, accept_new_session, thr );
            evsets_add(thr->core_sets, a->ev_accept, 0 );
#endif
            a->holding = 1;
        }

        //pthread_mutex_unlock( &(a->lock) );
    }
}

void acceptor_destroy( struct acceptor * self )
{
    pthread_mutex_destroy( &(self->lock) );

    if ( self->socketfd > 0 )
    {
        close( self->socketfd );
    }

    if ( self->ev_accept != NULL )
    {
        event_destroy( self->ev_accept );
    }

    free( self );
}

struct acceptor * acceptor_create( const char * host, uint16_t port )
{
    struct acceptor * a = NULL;

    a = (struct acceptor *)malloc( sizeof(struct acceptor) );
    if ( a )
    {
        a->holding = 0;
        a->socketfd = 0;
        a->ev_accept = NULL;
        pthread_mutex_init( &(a->lock), NULL );

        a->socketfd = tcp_listen( host, port );
        if ( a->socketfd < 0 )
        {
            acceptor_destroy( a );
            return NULL;
        }

        set_fd_nonblock( a->socketfd );

        a->ev_accept = event_create();
        if ( a->ev_accept == NULL )
        {
            acceptor_destroy( a );
            return NULL;
        }
    }

    return a;
}

void * iothread_main( void * arg )
{
    struct iothread * thr = (struct iothread *)arg;

    thr->running = 1;
    while ( thr->running )
    {
        //
        // 尝试加锁
        //
        trylock_accept_mutex( thr );

        //
        // 分发IO事件
        //
        evsets_dispatch( thr->core_sets );
    }

    return (void *)0;
}

struct iothread * iothread_create( uint8_t key, struct acceptor * a )
{
    pthread_t tid;
    struct iothread * thr = NULL;

    thr = (struct iothread *)malloc( sizeof(struct iothread) );
    if ( thr )
    {
        thr->key = key;
        thr->index = 0;
        thr->core_acceptor = a;

        thr->core_sets = evsets_create();
        if ( thr->core_sets == NULL )
        {
#if __DEBUG
            printf( "out of memory, allocate for 'thr->core_sets' failed, Thread[%d] .\n", key );
#endif
            return NULL;
        }

        pthread_create( &tid, NULL, iothread_main, thr );
    }

    return thr;
}
Esempio n. 14
0
void eventloop(tsocket main_fd, tsocket main_sctp_fd)
{
	static uint32 child_count = 0;
	static int conn_count = 0;
	static RTSP_buffer *rtsp_list = NULL;
	tsocket max_fd, fd = -1;

	RTSP_buffer *p = NULL;
	RTSP_proto rtsp_proto;
	uint32 fd_found;
	fd_set rset,wset;

	//Init of scheduler
	FD_ZERO(&rset);
	FD_ZERO(&wset);

	if (conn_count != -1) {
		/* This is the process allowed for accepting new clients */
		FD_SET(main_fd, &rset);
		max_fd = main_fd;
	}

	/* Add all sockets of all sessions to fd_sets */
	for (p = rtsp_list; p; p = p->next) {
		rtsp_set_fdsets(p, &max_fd, &rset, &wset, NULL);
	}
	/* Stay here and wait for something happens */
	if (select(max_fd+1, &rset, &wset, NULL, NULL) < 0) {
		ERRORLOGG("select error in eventloop()");
		/* Maybe we have to force exit here*/
		return;
	}
	/* transfer data for any RTSP sessions */
	schedule_connections(&rtsp_list, &conn_count, &rset, &wset, NULL);
	/* handle new connections */
	if (conn_count != -1) {
		if (FD_ISSET(main_fd, &rset)) {
			fd = tcp_accept(main_fd);
			rtsp_proto = TCP;
		}
		// Handle a new connection
		if (fd >= 0) {
			for (fd_found = 0, p = rtsp_list; p != NULL; p = p->next) {
				if (p->fd == fd) {
					fd_found = 1;
					break;
				}
			}

			if (!fd_found) {
				if (conn_count < ONE_FORK_MAX_CONNECTION) {
					++conn_count;
					// ADD A CLIENT
					add_client(&rtsp_list, fd, rtsp_proto);
				} else {
					if (fork() == 0) {
						// I'm the child
						++child_count;
						RTP_port_pool_init
						    (ONE_FORK_MAX_CONNECTION *
						     child_count * 2 +
						     RTP_DEFAULT_PORT);
						if (schedule_init() == ERR_FATAL) {
							FATALLOGG("Can't start schedule. Server is aborting");
							return;
						}
						conn_count = 1;
						rtsp_list = NULL;
						add_client(&rtsp_list, fd, rtsp_proto);
					} else {
						// I'm the father
						fd = -1;
						conn_count = -1;
						tcp_close(main_fd);
					}
				}
				num_conn++;
				INFOLOGG("Connection reached: %d", num_conn);
			}
		}
	} // shawill: and... if not?  END OF "HANDLE NEW CONNECTIONS"
}
Esempio n. 15
0
File: api.c Progetto: pykoder/cyassl
THREAD_RETURN CYASSL_THREAD test_server_nofail(void* args)
{
    SOCKET_T sockfd = 0;
    int clientfd = 0;

    CYASSL_METHOD* method = 0;
    CYASSL_CTX* ctx = 0;
    CYASSL* ssl = 0;

    char msg[] = "I hear you fa shizzle!";
    char input[1024];
    int idx;
   
    ((func_args*)args)->return_code = TEST_FAIL;
    method = CyaSSLv23_server_method();
    ctx = CyaSSL_CTX_new(method);

    CyaSSL_CTX_set_verify(ctx,
                    SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);

#ifdef OPENSSL_EXTRA
    CyaSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

    if (CyaSSL_CTX_load_verify_locations(ctx, cliCert, 0) != SSL_SUCCESS)
    {
        /*err_sys("can't load ca file, Please run from CyaSSL home dir");*/
        goto done;
    }
    if (CyaSSL_CTX_use_certificate_file(ctx, svrCert, SSL_FILETYPE_PEM)
            != SSL_SUCCESS)
    {
        /*err_sys("can't load server cert chain file, "
                "Please run from CyaSSL home dir");*/
        goto done;
    }
    if (CyaSSL_CTX_use_PrivateKey_file(ctx, svrKey, SSL_FILETYPE_PEM)
            != SSL_SUCCESS)
    {
        /*err_sys("can't load server key file, "
                "Please run from CyaSSL home dir");*/
        goto done;
    }
    ssl = CyaSSL_new(ctx);
    tcp_accept(&sockfd, &clientfd, (func_args*)args, yasslPort, 0, 0);
    CloseSocket(sockfd);

    CyaSSL_set_fd(ssl, clientfd);

#ifdef NO_PSK
    #if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA)
        CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM);
    #else
        SetDH(ssl);  /* will repick suites with DHE, higher priority than PSK */
    #endif
#endif
    if (CyaSSL_accept(ssl) != SSL_SUCCESS)
    {
        int err = CyaSSL_get_error(ssl, 0);
        char buffer[80];
        printf("error = %d, %s\n", err, CyaSSL_ERR_error_string(err, buffer));
        /*err_sys("SSL_accept failed");*/
        goto done;
    }

    idx = CyaSSL_read(ssl, input, sizeof(input)-1);
    if (idx > 0) {
        input[idx] = 0;
        printf("Client message: %s\n", input);
    }
    
    if (CyaSSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
    {
        /*err_sys("SSL_write failed");*/
        return 0;
    }

done:
    CyaSSL_shutdown(ssl);
    CyaSSL_free(ssl);
    CyaSSL_CTX_free(ctx);
    
    CloseSocket(clientfd);
    ((func_args*)args)->return_code = TEST_SUCCESS;
    return 0;
}
Esempio n. 16
0
// Lua: server:listen(port, addr, function(c)), socket:listen(port, addr)
int net_listen( lua_State *L ) {
  lnet_userdata *ud = net_get_udata(L);
  if (!ud || ud->type == TYPE_TCP_CLIENT)
    return luaL_error(L, "invalid user data");
  if (ud->pcb)
    return luaL_error(L, "already listening");
  int stack = 2;
  uint16_t port = 0;
  const char *domain = "0.0.0.0";
  if (lua_isnumber(L, stack))
    port = lua_tointeger(L, stack++);
  if (lua_isstring(L, stack)) {
    size_t dl = 0;
    domain = luaL_checklstring(L, stack++, &dl);
  }
  ip_addr_t addr;
  if (!ipaddr_aton(domain, &addr))
    return luaL_error(L, "invalid IP address");
  if (ud->type == TYPE_TCP_SERVER) {
    if (lua_isfunction(L, stack) || lua_islightfunction(L, stack)) {
      lua_pushvalue(L, stack++);
      luaL_unref(L, LUA_REGISTRYINDEX, ud->server.cb_accept_ref);
      ud->server.cb_accept_ref = luaL_ref(L, LUA_REGISTRYINDEX);
    } else {
      return luaL_error(L, "need callback");
    }
  }
  err_t err = ERR_OK;
  switch (ud->type) {
    case TYPE_TCP_SERVER:
      ud->tcp_pcb = tcp_new();
      if (!ud->tcp_pcb)
        return luaL_error(L, "cannot allocate PCB");
      ud->tcp_pcb->so_options |= SOF_REUSEADDR;
      err = tcp_bind(ud->tcp_pcb, &addr, port);
      if (err == ERR_OK) {
        tcp_arg(ud->tcp_pcb, ud);
        struct tcp_pcb *pcb = tcp_listen(ud->tcp_pcb);
        if (!pcb) {
          err = ERR_MEM;
        } else {
          ud->tcp_pcb = pcb;
          tcp_accept(ud->tcp_pcb, net_accept_cb);
        }
      }
      break;
    case TYPE_UDP_SOCKET:
      ud->udp_pcb = udp_new();
      if (!ud->udp_pcb)
        return luaL_error(L, "cannot allocate PCB");
      udp_recv(ud->udp_pcb, net_udp_recv_cb, ud);
      err = udp_bind(ud->udp_pcb, &addr, port);
      break;
  }
  if (err != ERR_OK) {
    switch (ud->type) {
      case TYPE_TCP_SERVER:
        tcp_close(ud->tcp_pcb);
        ud->tcp_pcb = NULL;
        break;
      case TYPE_UDP_SOCKET:
        udp_remove(ud->udp_pcb);
        ud->udp_pcb = NULL;
        break;
    }
    return lwip_lua_checkerr(L, err);
  }
  if (ud->self_ref == LUA_NOREF) {
    lua_pushvalue(L, 1);
    ud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  }
  return 0;
}
Esempio n. 17
0
void tcp_accept1(struct tcp_pcb *pcb, xt_t callback)
{
  accept_forth_cb = callback;
  tcp_accept(pcb, accept_cb);
}
Esempio n. 18
0
/**
  * @brief This function is called when an UDP datagrm has been received on the port UDP_PORT.
  * @param arg user supplied argument (udp_pcb.recv_arg)
  * @param pcb the udp_pcb which received data
  * @param p the packet buffer that was received
  * @param addr the remote IP address from which the packet was received
  * @param port the remote port from which the packet was received
  * @retval None
  */
void udp_server_callback(void *arg, struct udp_pcb *upcb, struct pbuf *p, struct ip_addr *addr, u16_t port)
{
  struct tcp_pcb *pcb;
  uint8_t iptab[4];
  uint8_t iptxt[20];
  
  /* We have received the UDP Echo from a client */
  /* read its IP address */
  iptab[0] = (uint8_t)((uint32_t)(addr->addr) >> 24);
  iptab[1] = (uint8_t)((uint32_t)(addr->addr) >> 16);
  iptab[2] = (uint8_t)((uint32_t)(addr->addr) >> 8);
  iptab[3] = (uint8_t)((uint32_t)(addr->addr));

  sprintf((char*)iptxt, "is: %d.%d.%d.%d     ", iptab[3], iptab[2], iptab[1], iptab[0]);
  
  printf( "is: %d.%d.%d.%d     ", iptab[3], iptab[2], iptab[1], iptab[0]);	                           	                             
 
  /* Connect to the remote client */
  udp_connect(upcb, addr, UDP_CLIENT_PORT);
    
  /* Tell the client that we have accepted it */
	udp_send(upcb,p);

  /* free the UDP connection, so we can accept new clients */
  udp_disconnect(upcb);
	
  /* Bind the upcb to IP_ADDR_ANY address and the UDP_PORT port*/
  /* Be ready to get a new request from another client */  
  udp_bind(upcb, IP_ADDR_ANY, UDP_SERVER_PORT);
	
  /* Set a receive callback for the upcb */
  udp_recv(upcb, udp_server_callback, NULL);    	
	
  /* Create a new TCP control block  */
  pcb = tcp_new();
	
  if(pcb !=NULL)
  {
    err_t err;	  
	      
    /* Assign to the new pcb a local IP address and a port number */
    err = tcp_bind(pcb, addr, TCP_SERVER_PORT);
	  
	if(err != ERR_USE)
	{
	  /* Set the connection to the LISTEN state */
      pcb = tcp_listen(pcb);
    
      /* Specify the function to be called when a connection is established */
      tcp_accept(pcb, tcp_server_accept);
	}
	else
	{
	  /* We enter here if a conection to the addr IP address already exists */
	  /* so we don't need to establish a new one */
	  tcp_close(pcb);
	}            
  }

  /* Free the p buffer */
  pbuf_free(p);
   
}
Esempio n. 19
0
int main(int argc, char** argv)
{
	if (argc < 2)
		err("usage : ./obj portno");

	int sfd[P];
	int i, nsfd, fd = -1;
	int port = atoi(argv[1]);
	char buf[M];

	fd_set master, test;
	FD_ZERO(&master);
	FD_ZERO(&test);

	shared_init();
	platform_init(port);

	for (i = 0; i < P; i++)
	{
		sfd[i] = tcpsocket_bind(port + i);
		printf("Station %d listening on port : %d\n", i, port + i);

		if (fd < sfd[i])
			fd = sfd[i];
		FD_SET(sfd[i], &master);
	}

	while (1)
	{
		test = master;
		select(fd + 1, &test, NULL, NULL, NULL);
		
		for (i = 0; i < P; i++)
		{
			if (FD_ISSET(sfd[i], &test))
			{
				nsfd = tcp_accept(sfd[i]);
				break;
			}
		}
		
		if (i != P)
		{
			printf("Train arrived on station - %d\n", i);
			for (i = 0; i < P; i++)
			{
				if (available(i))
				{
					printf("Platform %d is available\n", i + 1);
					sprintf(buf, "%d", port + P + i);
					write(nsfd, buf, M);
					sleep(1);
					sprintf(buf, "pkill -SIGUSR1 p%d", i + 1);
					system(buf);
					break;
				}
			}

			if (i == P)
			{
				write(nsfd, "-1", 2);
			}
			close(nsfd);
		}
	}
}
Esempio n. 20
0
THREAD_RETURN CYASSL_THREAD server_test(void* args)
{
    SOCKET_T sockfd   = 0;
    SOCKET_T clientfd = 0;

    SSL_METHOD* method = 0;
    SSL_CTX*    ctx    = 0;
    SSL*        ssl    = 0;

    char   msg[] = "I hear you fa shizzle!";
    char   input[80];
    int    idx;
    int    ch;
    int    version = SERVER_DEFAULT_VERSION;
    int    doCliCertCheck = 1;
    int    useAnyAddr = 0;
    int    port = yasslPort;
    int    usePsk = 0;
    int    doDTLS = 0;
    int    useNtruKey   = 0;
    int    nonBlocking  = 0;
    int    trackMemory  = 0;
    int    fewerPackets = 0;
    char*  cipherList = NULL;
    char*  verifyCert = (char*)cliCert;
    char*  ourCert    = (char*)svrCert;
    char*  ourKey     = (char*)svrKey;
    int    argc = ((func_args*)args)->argc;
    char** argv = ((func_args*)args)->argv;

#ifdef HAVE_SNI
    char*  sniHostName = NULL;
#endif

    ((func_args*)args)->return_code = -1; /* error state */

#ifdef NO_RSA
    verifyCert = (char*)cliEccCert;
    ourCert    = (char*)eccCert;
    ourKey     = (char*)eccKey;
#endif
    (void)trackMemory;

    while ((ch = mygetopt(argc, argv, "?dbstnNufp:v:l:A:c:k:S:")) != -1) {
        switch (ch) {
            case '?' :
                Usage();
                exit(EXIT_SUCCESS);

            case 'd' :
                doCliCertCheck = 0;
                break;

            case 'b' :
                useAnyAddr = 1;
                break;

            case 's' :
                usePsk = 1;
                break;

            case 't' :
            #ifdef USE_CYASSL_MEMORY
                trackMemory = 1;
            #endif
                break;

            case 'n' :
                useNtruKey = 1;
                break;

            case 'u' :
                doDTLS  = 1;
                break;

            case 'f' :
                fewerPackets = 1;
                break;

            case 'p' :
                port = atoi(myoptarg);
                #if !defined(NO_MAIN_DRIVER) || defined(USE_WINDOWS_API)
                    if (port == 0)
                        err_sys("port number cannot be 0");
                #endif
                break;

            case 'v' :
                version = atoi(myoptarg);
                if (version < 0 || version > 3) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            case 'l' :
                cipherList = myoptarg;
                break;

            case 'A' :
                verifyCert = myoptarg;
                break;

            case 'c' :
                ourCert = myoptarg;
                break;

            case 'k' :
                ourKey = myoptarg;
                break;

            case 'N':
                nonBlocking = 1;
                break;

            case 'S' :
                #ifdef HAVE_SNI
                    sniHostName = myoptarg;
                #endif
                break;

            default:
                Usage();
                exit(MY_EX_USAGE);
        }
    }

    myoptind = 0;      /* reset for test cases */

    /* sort out DTLS versus TLS versions */
    if (version == CLIENT_INVALID_VERSION) {
        if (doDTLS)
            version = CLIENT_DTLS_DEFAULT_VERSION;
        else
            version = CLIENT_DEFAULT_VERSION;
    }
    else {
        if (doDTLS) {
            if (version == 3)
                version = -2;
            else
                version = -1;
        }
    }

#ifdef USE_CYASSL_MEMORY
    if (trackMemory)
        InitMemoryTracker(); 
#endif

    switch (version) {
#ifndef NO_OLD_TLS
        case 0:
            method = SSLv3_server_method();
            break;

    #ifndef NO_TLS
        case 1:
            method = TLSv1_server_method();
            break;


        case 2:
            method = TLSv1_1_server_method();
            break;

        #endif
#endif

#ifndef NO_TLS
        case 3:
            method = TLSv1_2_server_method();
            break;
#endif
                
#ifdef CYASSL_DTLS
        case -1:
            method = DTLSv1_server_method();
            break;

        case -2:
            method = DTLSv1_2_server_method();
            break;
#endif

        default:
            err_sys("Bad SSL version");
    }

    if (method == NULL)
        err_sys("unable to get method");

    ctx = SSL_CTX_new(method);
    if (ctx == NULL)
        err_sys("unable to get ctx");

    if (cipherList)
        if (SSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
            err_sys("server can't set cipher list 1");

#ifdef CYASSL_LEANPSK
    usePsk = 1;
#endif

#if defined(NO_RSA) && !defined(HAVE_ECC)
    usePsk = 1;
#endif

    if (fewerPackets)
        CyaSSL_CTX_set_group_messages(ctx);

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if (!usePsk) {
        if (SSL_CTX_use_certificate_file(ctx, ourCert, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load server cert file, check file and run from"
                    " CyaSSL home dir");
    }
#endif

#ifdef HAVE_NTRU
    if (useNtruKey) {
        if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ourKey)
                                               != SSL_SUCCESS)
            err_sys("can't load ntru key file, "
                    "Please run from CyaSSL home dir");
    }
#endif

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if (!useNtruKey && !usePsk) {
        if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load server cert file, check file and run from"
                " CyaSSL home dir");
    }
#endif

    if (usePsk) {
#ifndef NO_PSK
        SSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);
        SSL_CTX_use_psk_identity_hint(ctx, "cyassl server");
        if (cipherList == NULL) {
            const char *defaultCipherList;
            #ifdef HAVE_NULL_CIPHER
                defaultCipherList = "PSK-NULL-SHA256";
            #else
                defaultCipherList = "PSK-AES128-CBC-SHA256";
            #endif
            if (SSL_CTX_set_cipher_list(ctx, defaultCipherList) != SSL_SUCCESS)
                err_sys("server can't set cipher list 2");
        }
#endif
    }

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    /* if not using PSK, verify peer with certs */
    if (doCliCertCheck && usePsk == 0) {
        SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |
                                SSL_VERIFY_FAIL_IF_NO_PEER_CERT,0);
        if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from CyaSSL home dir");
    }
#endif

#ifdef OPENSSL_EXTRA
    SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

#if defined(CYASSL_SNIFFER) && !defined(HAVE_NTRU) && !defined(HAVE_ECC)
    /* don't use EDH, can't sniff tmp keys */
    if (cipherList == NULL) {
        if (SSL_CTX_set_cipher_list(ctx, "AES256-SHA256") != SSL_SUCCESS)
            err_sys("server can't set cipher list 3");
    }
#endif

#ifdef HAVE_SNI
    if (sniHostName) {
        if (CyaSSL_CTX_UseSNI(ctx, CYASSL_SNI_HOST_NAME, sniHostName,
                                           XSTRLEN(sniHostName)) != SSL_SUCCESS)
            err_sys("UseSNI failed");
        else
            CyaSSL_CTX_SNI_SetOptions(ctx, CYASSL_SNI_HOST_NAME,
                                                  CYASSL_SNI_ABORT_ON_MISMATCH);
    }
#endif

    ssl = SSL_new(ctx);
    if (ssl == NULL)
        err_sys("unable to get SSL");
    CyaSSL_set_quiet_shutdown(ssl, 1) ;
#ifdef HAVE_CRL
    CyaSSL_EnableCRL(ssl, 0);
    CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, CYASSL_CRL_MONITOR |
                                                     CYASSL_CRL_START_MON);
    CyaSSL_SetCRL_Cb(ssl, CRL_CallBack);
#endif
        osDelay(5000) ;
    tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr, doDTLS);
    if (!doDTLS) 
        CloseSocket(sockfd);

    SSL_set_fd(ssl, clientfd);
    if (usePsk == 0) {
        #if !defined(NO_FILESYSTEM) && defined(OPENSSL_EXTRA)
            CyaSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM);
        #elif !defined(NO_CERTS)
            SetDH(ssl);  /* repick suites with DHE, higher priority than PSK */
        #endif
    }
        osDelay(5000) ;
#ifndef CYASSL_CALLBACKS
    if (nonBlocking) {
        CyaSSL_set_using_nonblock(ssl, 1);
        tcp_set_nonblocking(&clientfd);
        NonBlockingSSL_Accept(ssl);
    } else if (SSL_accept(ssl) != SSL_SUCCESS) {
        int err = SSL_get_error(ssl, 0);
        char buffer[80];
        printf("error = %d, %s\n", err, ERR_error_string(err, buffer));
        err_sys("SSL_accept failed");
    }
#else
    NonBlockingSSL_Accept(ssl);
#endif
    showPeer(ssl);
        osDelay(5000) ;
    idx = SSL_read(ssl, input, sizeof(input)-1);
    if (idx > 0) {
        input[idx] = 0;
        printf("Client message: %s\n", input);

    }
    else if (idx < 0) {
        int readErr = SSL_get_error(ssl, 0);
        if (readErr != SSL_ERROR_WANT_READ)
            err_sys("SSL_read failed");
    }

    if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
        err_sys("SSL_write failed");
        
    SSL_shutdown(ssl);
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    
    CloseSocket(clientfd);
    ((func_args*)args)->return_code = 0;

#ifdef USE_CYASSL_MEMORY
    if (trackMemory)
        ShowMemoryTracker();
#endif /* USE_CYASSL_MEMORY */

    return 0;
}
Esempio n. 21
0
static void cmd_pasv(const char *arg, struct tcp_pcb *pcb, struct ftpd_msgstate *fsm)
{
	static u16_t port = 4096;
	static u16_t start_port = 4096;
	struct tcp_pcb *temppcb;

	/* Allocate memory for the structure that holds the state of the
	   connection. */
	fsm->datafs = malloc(sizeof(struct ftpd_datastate));

	if (fsm->datafs == NULL) {
		send_msg(pcb, fsm, msg451);
		return;
	}
	memset(fsm->datafs, 0, sizeof(struct ftpd_datastate));

	fsm->datapcb = tcp_new();
	if (!fsm->datapcb) {
		free(fsm->datafs);
		send_msg(pcb, fsm, msg451);
		return;
	}

	sfifo_init(&fsm->datafs->fifo, 2000);

	start_port = port;

	while (1) {
		err_t err;

		if(++port > 0x7fff)
			port = 4096;

		fsm->dataport = port;
		err = tcp_bind(fsm->datapcb, (ip_addr_t*)&pcb->local_ip, fsm->dataport);
		if (err == ERR_OK)
			break;
		if (start_port == port)
			err = ERR_CLSD;
		if (err == ERR_USE) {
			continue;
		} else {
			ftpd_dataclose(fsm->datapcb, fsm->datafs);
			fsm->datapcb = NULL;
			fsm->datafs = NULL;
			return;
		}
	}

	fsm->datafs->msgfs = fsm;

	temppcb = tcp_listen(fsm->datapcb);
	if (!temppcb) {
		ftpd_dataclose(fsm->datapcb, fsm->datafs);
		fsm->datapcb = NULL;
		fsm->datafs = NULL;
		return;
	}
	fsm->datapcb = temppcb;

	fsm->passive = 1;
	fsm->datafs->connected = 0;
	fsm->datafs->msgpcb = pcb;

	/* Tell TCP that this is the structure we wish to be passed for our
	   callbacks. */
	tcp_arg(fsm->datapcb, fsm->datafs);

	tcp_accept(fsm->datapcb, ftpd_dataaccept);
	send_msg(pcb, fsm, msg227, ip4_addr1(ip_2_ip4(&pcb->local_ip)), ip4_addr2(ip_2_ip4(&pcb->local_ip)), ip4_addr3(ip_2_ip4(&pcb->local_ip)), ip4_addr4(ip_2_ip4(&pcb->local_ip)), (fsm->dataport >> 8) & 0xff, (fsm->dataport) & 0xff);
}
Esempio n. 22
0
THREAD_RETURN CYASSL_THREAD server_test(void* args)
{
    SOCKET_T sockfd   = WOLFSSL_SOCKET_INVALID;
    SOCKET_T clientfd = WOLFSSL_SOCKET_INVALID;

    SSL_METHOD* method = 0;
    SSL_CTX*    ctx    = 0;
    SSL*        ssl    = 0;

    const char msg[] = "I hear you fa shizzle!";
    char   input[80];
    int    ch;
    int    version = SERVER_DEFAULT_VERSION;
    int    doCliCertCheck = 1;
    int    useAnyAddr = 0;
    word16 port = wolfSSLPort;
    int    usePsk = 0;
    int    usePskPlus = 0;
    int    useAnon = 0;
    int    doDTLS = 0;
    int    needDH = 0;
    int    useNtruKey   = 0;
    int    nonBlocking  = 0;
    int    trackMemory  = 0;
    int    fewerPackets = 0;
    int    pkCallbacks  = 0;
    int    wc_shutdown     = 0;
    int    resume = 0;
    int    resumeCount = 0;
    int    loopIndefinitely = 0;
    int    echoData = 0;
    int    throughput = 0;
    int    minDhKeyBits  = DEFAULT_MIN_DHKEY_BITS;
    short  minRsaKeyBits = DEFAULT_MIN_RSAKEY_BITS;
    short  minEccKeyBits = DEFAULT_MIN_ECCKEY_BITS;
    int    doListen = 1;
    int    crlFlags = 0;
    int    ret;
    int    err = 0;
    char*  serverReadyFile = NULL;
    char*  alpnList = NULL;
    unsigned char alpn_opt = 0;
    char*  cipherList = NULL;
    const char* verifyCert = cliCert;
    const char* ourCert    = svrCert;
    const char* ourKey     = svrKey;
    const char* ourDhParam = dhParam;
    tcp_ready*  readySignal = NULL;
    int    argc = ((func_args*)args)->argc;
    char** argv = ((func_args*)args)->argv;

#ifdef WOLFSSL_TRUST_PEER_CERT
    const char* trustCert  = NULL;
#endif

#ifndef NO_PSK
    int sendPskIdentityHint = 1;
#endif

#ifdef HAVE_SNI
    char*  sniHostName = NULL;
#endif

#ifdef HAVE_OCSP
    int    useOcsp  = 0;
    char*  ocspUrl  = NULL;
#endif

    ((func_args*)args)->return_code = -1; /* error state */

#ifdef NO_RSA
    verifyCert = (char*)cliEccCert;
    ourCert    = (char*)eccCert;
    ourKey     = (char*)eccKey;
#endif
    (void)trackMemory;
    (void)pkCallbacks;
    (void)needDH;
    (void)ourKey;
    (void)ourCert;
    (void)ourDhParam;
    (void)verifyCert;
    (void)useNtruKey;
    (void)doCliCertCheck;
    (void)minDhKeyBits;
    (void)minRsaKeyBits;
    (void)minEccKeyBits;
    (void)alpnList;
    (void)alpn_opt;
    (void)crlFlags;
    (void)readySignal;

#ifdef CYASSL_TIRTOS
    fdOpenSession(Task_self());
#endif

#ifdef WOLFSSL_VXWORKS
    useAnyAddr = 1;
#else
    while ((ch = mygetopt(argc, argv, "?jdbstnNufrawPIR:p:v:l:A:c:k:Z:S:oO:D:L:ieB:E:"))
                         != -1) {
        switch (ch) {
            case '?' :
                Usage();
                exit(EXIT_SUCCESS);

            case 'd' :
                doCliCertCheck = 0;
                break;

            case 'b' :
                useAnyAddr = 1;
                break;

            case 's' :
                usePsk = 1;
                break;

            case 'j' :
                usePskPlus = 1;
                break;

            case 't' :
            #ifdef USE_WOLFSSL_MEMORY
                trackMemory = 1;
            #endif
                break;

            case 'n' :
                useNtruKey = 1;
                break;

            case 'u' :
                doDTLS  = 1;
                break;

            case 'f' :
                fewerPackets = 1;
                break;

            case 'R' :
                serverReadyFile = myoptarg;
                break;

            case 'r' :
                #ifndef NO_SESSION_CACHE
                    resume = 1;
                #endif
                break;

            case 'P' :
            #ifdef HAVE_PK_CALLBACKS
                pkCallbacks = 1;
            #endif
                break;

            case 'p' :
                port = (word16)atoi(myoptarg);
                break;

            case 'w' :
                wc_shutdown = 1;
                break;

            case 'v' :
                version = atoi(myoptarg);
                if (version < 0 || version > 3) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            case 'l' :
                cipherList = myoptarg;
                break;

            case 'A' :
                verifyCert = myoptarg;
                break;

            case 'c' :
                ourCert = myoptarg;
                break;

            case 'k' :
                ourKey = myoptarg;
                break;

            case 'D' :
                #ifndef NO_DH
                    ourDhParam = myoptarg;
                #endif
                break;

            case 'Z' :
                #ifndef NO_DH
                    minDhKeyBits = atoi(myoptarg);
                    if (minDhKeyBits <= 0 || minDhKeyBits > 16000) {
                        Usage();
                        exit(MY_EX_USAGE);
                    }
                #endif
                break;

            case 'N':
                nonBlocking = 1;
                break;

            case 'S' :
                #ifdef HAVE_SNI
                    sniHostName = myoptarg;
                #endif
                break;

            case 'o' :
                #ifdef HAVE_OCSP
                    useOcsp = 1;
                #endif
                break;

            case 'O' :
                #ifdef HAVE_OCSP
                    useOcsp = 1;
                    ocspUrl = myoptarg;
                #endif
                break;

            case 'a' :
                #ifdef HAVE_ANON
                    useAnon = 1;
                #endif
                break;
            case 'I':
                #ifndef NO_PSK
                    sendPskIdentityHint = 0;
                #endif
                break;

            case 'L' :
                #ifdef HAVE_ALPN
                    alpnList = myoptarg;

                    if (alpnList[0] == 'C' && alpnList[1] == ':')
                        alpn_opt = WOLFSSL_ALPN_CONTINUE_ON_MISMATCH;
                    else if (alpnList[0] == 'F' && alpnList[1] == ':')
                        alpn_opt = WOLFSSL_ALPN_FAILED_ON_MISMATCH;
                    else {
                        Usage();
                        exit(MY_EX_USAGE);
                    }

                    alpnList += 2;

                #endif
                break;

            case 'i' :
                loopIndefinitely = 1;
                break;

            case 'e' :
                echoData = 1;
                break;

            case 'B':
                throughput = atoi(myoptarg);
                if (throughput <= 0) {
                    Usage();
                    exit(MY_EX_USAGE);
                }
                break;

            #ifdef WOLFSSL_TRUST_PEER_CERT
            case 'E' :
                 trustCert = myoptarg;
                break;
            #endif

            default:
                Usage();
                exit(MY_EX_USAGE);
        }
    }

    myoptind = 0;      /* reset for test cases */
#endif /* !WOLFSSL_VXWORKS */

    /* sort out DTLS versus TLS versions */
    if (version == CLIENT_INVALID_VERSION) {
        if (doDTLS)
            version = CLIENT_DTLS_DEFAULT_VERSION;
        else
            version = CLIENT_DEFAULT_VERSION;
    }
    else {
        if (doDTLS) {
            if (version == 3)
                version = -2;
            else
                version = -1;
        }
    }

#ifdef USE_CYASSL_MEMORY
    if (trackMemory)
        InitMemoryTracker();
#endif

    switch (version) {
#ifndef NO_OLD_TLS
    #ifdef WOLFSSL_ALLOW_SSLV3
        case 0:
            method = SSLv3_server_method();
            break;
    #endif

    #ifndef NO_TLS
        case 1:
            method = TLSv1_server_method();
            break;


        case 2:
            method = TLSv1_1_server_method();
            break;

        #endif
#endif

#ifndef NO_TLS
        case 3:
            method = TLSv1_2_server_method();
            break;
#endif

#ifdef CYASSL_DTLS
    #ifndef NO_OLD_TLS
        case -1:
            method = DTLSv1_server_method();
            break;
    #endif

        case -2:
            method = DTLSv1_2_server_method();
            break;
#endif

        default:
            err_sys("Bad SSL version");
    }

    if (method == NULL)
        err_sys("unable to get method");

    ctx = SSL_CTX_new(method);
    if (ctx == NULL)
        err_sys("unable to get ctx");

#if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
                                    defined(HAVE_POLY1305)
    if (TicketInit() != 0)
        err_sys("unable to setup Session Ticket Key context");
    wolfSSL_CTX_set_TicketEncCb(ctx, myTicketEncCb);
#endif

    if (cipherList)
        if (SSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS)
            err_sys("server can't set cipher list 1");

#ifdef CYASSL_LEANPSK
    if (!usePsk) {
        usePsk = 1;
    }
#endif

#if defined(NO_RSA) && !defined(HAVE_ECC)
    if (!usePsk) {
        usePsk = 1;
    }
#endif

    if (fewerPackets)
        CyaSSL_CTX_set_group_messages(ctx);

#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER)
    SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if ((!usePsk || usePskPlus) && !useAnon) {
        if (SSL_CTX_use_certificate_chain_file(ctx, ourCert)
                                         != SSL_SUCCESS)
            err_sys("can't load server cert file, check file and run from"
                    " wolfSSL home dir");
    }
#endif

#ifndef NO_DH
    if (wolfSSL_CTX_SetMinDhKey_Sz(ctx, (word16)minDhKeyBits) != SSL_SUCCESS) {
        err_sys("Error setting minimum DH key size");
    }
#endif
#ifndef NO_RSA
    if (wolfSSL_CTX_SetMinRsaKey_Sz(ctx, minRsaKeyBits) != SSL_SUCCESS){
        err_sys("Error setting minimum RSA key size");
    }
#endif
#ifdef HAVE_ECC
    if (wolfSSL_CTX_SetMinEccKey_Sz(ctx, minEccKeyBits) != SSL_SUCCESS){
        err_sys("Error setting minimum ECC key size");
    }
#endif

#ifdef HAVE_NTRU
    if (useNtruKey) {
        if (CyaSSL_CTX_use_NTRUPrivateKey_file(ctx, ourKey)
                                != SSL_SUCCESS)
            err_sys("can't load ntru key file, "
                    "Please run from wolfSSL home dir");
    }
#endif
#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    if (!useNtruKey && (!usePsk || usePskPlus) && !useAnon) {
        if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM)
                                         != SSL_SUCCESS)
            err_sys("can't load server private key file, check file and run "
                "from wolfSSL home dir");
    }
#endif

    if (usePsk || usePskPlus) {
#ifndef NO_PSK
        SSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb);

        if (sendPskIdentityHint == 1)
            SSL_CTX_use_psk_identity_hint(ctx, "cyassl server");

        if (cipherList == NULL && !usePskPlus) {
            const char *defaultCipherList;
            #if defined(HAVE_AESGCM) && !defined(NO_DH)
                defaultCipherList = "DHE-PSK-AES128-GCM-SHA256";
                needDH = 1;
            #elif defined(HAVE_NULL_CIPHER)
                defaultCipherList = "PSK-NULL-SHA256";
            #else
                defaultCipherList = "PSK-AES128-CBC-SHA256";
            #endif
            if (SSL_CTX_set_cipher_list(ctx, defaultCipherList) != SSL_SUCCESS)
                err_sys("server can't set cipher list 2");
        }
#endif
    }

    if (useAnon) {
#ifdef HAVE_ANON
        CyaSSL_CTX_allow_anon_cipher(ctx);
        if (cipherList == NULL) {
            if (SSL_CTX_set_cipher_list(ctx, "ADH-AES128-SHA") != SSL_SUCCESS)
                err_sys("server can't set cipher list 4");
        }
#endif
    }

#if !defined(NO_FILESYSTEM) && !defined(NO_CERTS)
    /* if not using PSK, verify peer with certs
       if using PSK Plus then verify peer certs except PSK suites */
    if (doCliCertCheck && (usePsk == 0 || usePskPlus) && useAnon == 0) {
        SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER |
                                ((usePskPlus)? SSL_VERIFY_FAIL_EXCEPT_PSK :
                                SSL_VERIFY_FAIL_IF_NO_PEER_CERT),0);
        if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from wolfSSL home dir");
        #ifdef WOLFSSL_TRUST_PEER_CERT
        if (trustCert) {
            if ((ret = wolfSSL_CTX_trust_peer_cert(ctx, trustCert,
                                            SSL_FILETYPE_PEM)) != SSL_SUCCESS) {
                err_sys("can't load trusted peer cert file");
            }
        }
        #endif /* WOLFSSL_TRUST_PEER_CERT */
   }
#endif

#if defined(CYASSL_SNIFFER)
    /* don't use EDH, can't sniff tmp keys */
    if (cipherList == NULL) {
        if (SSL_CTX_set_cipher_list(ctx, "AES128-SHA") != SSL_SUCCESS)
            err_sys("server can't set cipher list 3");
    }
#endif

#ifdef HAVE_SNI
    if (sniHostName)
        if (CyaSSL_CTX_UseSNI(ctx, CYASSL_SNI_HOST_NAME, sniHostName,
                                           XSTRLEN(sniHostName)) != SSL_SUCCESS)
            err_sys("UseSNI failed");
#endif

#ifdef USE_WINDOWS_API
    if (port == 0) {
        /* Generate random port for testing */
        port = GetRandomPort();
    }
#endif /* USE_WINDOWS_API */

    while (1) {
        /* allow resume option */
        if(resumeCount > 1) {
            if (doDTLS == 0) {
                SOCKADDR_IN_T client;
                socklen_t client_len = sizeof(client);
                clientfd = accept(sockfd, (struct sockaddr*)&client,
                                 (ACCEPT_THIRD_T)&client_len);
            } else {
                tcp_listen(&sockfd, &port, useAnyAddr, doDTLS);
                clientfd = sockfd;
            }
            if(WOLFSSL_SOCKET_IS_INVALID(clientfd)) {
                err_sys("tcp accept failed");
            }
        }

        ssl = SSL_new(ctx);
        if (ssl == NULL)
            err_sys("unable to get SSL");

#ifndef NO_HANDSHAKE_DONE_CB
        wolfSSL_SetHsDoneCb(ssl, myHsDoneCb, NULL);
#endif
#ifdef HAVE_CRL
#ifdef HAVE_CRL_MONITOR
        crlFlags = CYASSL_CRL_MONITOR | CYASSL_CRL_START_MON;
#endif
        if (CyaSSL_EnableCRL(ssl, 0) != SSL_SUCCESS)
            err_sys("unable to enable CRL");
        if (CyaSSL_LoadCRL(ssl, crlPemDir, SSL_FILETYPE_PEM, crlFlags)
                                                                 != SSL_SUCCESS)
            err_sys("unable to load CRL");
        if (CyaSSL_SetCRL_Cb(ssl, CRL_CallBack) != SSL_SUCCESS)
            err_sys("unable to set CRL callback url");
#endif
#ifdef HAVE_OCSP
        if (useOcsp) {
            if (ocspUrl != NULL) {
                CyaSSL_CTX_SetOCSP_OverrideURL(ctx, ocspUrl);
                CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE
                                                        | CYASSL_OCSP_URL_OVERRIDE);
            }
            else
                CyaSSL_CTX_EnableOCSP(ctx, CYASSL_OCSP_NO_NONCE);
        }
#endif
#if defined(HAVE_CERTIFICATE_STATUS_REQUEST) \
 || defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2)
        if (wolfSSL_CTX_EnableOCSPStapling(ctx) != SSL_SUCCESS)
            err_sys("can't enable OCSP Stapling Certificate Manager");
        if (SSL_CTX_load_verify_locations(ctx, "certs/ocsp/intermediate1-ca-cert.pem", 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from wolfSSL home dir");
        if (SSL_CTX_load_verify_locations(ctx, "certs/ocsp/intermediate2-ca-cert.pem", 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from wolfSSL home dir");
        if (SSL_CTX_load_verify_locations(ctx, "certs/ocsp/intermediate3-ca-cert.pem", 0) != SSL_SUCCESS)
            err_sys("can't load ca file, Please run from wolfSSL home dir");
#endif
#ifdef HAVE_PK_CALLBACKS
        if (pkCallbacks)
            SetupPkCallbacks(ctx, ssl);
#endif

        /* do accept */
        readySignal = ((func_args*)args)->signal;
        if (readySignal) {
            readySignal->srfName = serverReadyFile;
        }
        tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr,
                       doDTLS, serverReadyFile ? 1 : 0, doListen);
        doListen = 0; /* Don't listen next time */

        if (SSL_set_fd(ssl, clientfd) != SSL_SUCCESS) {
            err_sys("error in setting fd");
        }

#ifdef HAVE_ALPN
        if (alpnList != NULL) {
            printf("ALPN accepted protocols list : %s\n", alpnList);
            wolfSSL_UseALPN(ssl, alpnList, (word32)XSTRLEN(alpnList), alpn_opt);
        }
#endif

#ifdef WOLFSSL_DTLS
        if (doDTLS) {
            SOCKADDR_IN_T cliaddr;
            byte          b[1500];
            int           n;
            socklen_t     len = sizeof(cliaddr);

            /* For DTLS, peek at the next datagram so we can get the client's
             * address and set it into the ssl object later to generate the
             * cookie. */
            n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK,
                              (struct sockaddr*)&cliaddr, &len);
            if (n <= 0)
                err_sys("recvfrom failed");

            wolfSSL_dtls_set_peer(ssl, &cliaddr, len);
        }
#endif
        if ((usePsk == 0 || usePskPlus) || useAnon == 1 || cipherList != NULL
                                                               || needDH == 1) {
            #if !defined(NO_FILESYSTEM) && !defined(NO_DH) && !defined(NO_ASN)
                CyaSSL_SetTmpDH_file(ssl, ourDhParam, SSL_FILETYPE_PEM);
            #elif !defined(NO_DH)
                SetDH(ssl);  /* repick suites with DHE, higher priority than PSK */
            #endif
        }

#ifndef CYASSL_CALLBACKS
        if (nonBlocking) {
            CyaSSL_set_using_nonblock(ssl, 1);
            tcp_set_nonblocking(&clientfd);
        }
#endif

        do {
#ifdef WOLFSSL_ASYNC_CRYPT
            if (err == WC_PENDING_E) {
                ret = AsyncCryptPoll(ssl);
                if (ret < 0) { break; } else if (ret == 0) { continue; }
            }
#endif

            err = 0; /* Reset error */
#ifndef CYASSL_CALLBACKS
            if (nonBlocking) {
                ret = NonBlockingSSL_Accept(ssl);
            }
            else {
                ret = SSL_accept(ssl);
            }
#else
            ret = NonBlockingSSL_Accept(ssl);
#endif
            if (ret != SSL_SUCCESS) {
                err = SSL_get_error(ssl, 0);
            }
        } while (ret != SSL_SUCCESS && err == WC_PENDING_E);

        if (ret != SSL_SUCCESS) {
            char buffer[CYASSL_MAX_ERROR_SZ];
            err = SSL_get_error(ssl, 0);
            printf("error = %d, %s\n", err, ERR_error_string(err, buffer));
            err_sys("SSL_accept failed");
        }

        showPeer(ssl);

#ifdef HAVE_ALPN
        if (alpnList != NULL) {
            char *protocol_name = NULL, *list = NULL;
            word16 protocol_nameSz = 0, listSz = 0;

            err = wolfSSL_ALPN_GetProtocol(ssl, &protocol_name, &protocol_nameSz);
            if (err == SSL_SUCCESS)
                printf("Sent ALPN protocol : %s (%d)\n",
                       protocol_name, protocol_nameSz);
            else if (err == SSL_ALPN_NOT_FOUND)
                printf("No ALPN response sent (no match)\n");
            else
                printf("Getting ALPN protocol name failed\n");

            err = wolfSSL_ALPN_GetPeerProtocol(ssl, &list, &listSz);
            if (err == SSL_SUCCESS)
                printf("List of protocol names sent by Client: %s (%d)\n",
                       list, listSz);
            else
                printf("Get list of client's protocol name failed\n");

            free(list);
        }
#endif
        if(echoData == 0 && throughput == 0) {
            ret = SSL_read(ssl, input, sizeof(input)-1);
            if (ret > 0) {
                input[ret] = 0;
                printf("Client message: %s\n", input);

            }
            else if (ret < 0) {
                int readErr = SSL_get_error(ssl, 0);
                if (readErr != SSL_ERROR_WANT_READ)
                    err_sys("SSL_read failed");
            }

            if (SSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
                err_sys("SSL_write failed");
        }
        else {
            ServerEchoData(ssl, clientfd, echoData, throughput);
        }

#if defined(WOLFSSL_MDK_SHELL) && defined(HAVE_MDK_RTX)
        os_dly_wait(500) ;
#elif defined (CYASSL_TIRTOS)
        Task_yield();
#endif

        if (doDTLS == 0) {
            ret = SSL_shutdown(ssl);
            if (wc_shutdown && ret == SSL_SHUTDOWN_NOT_DONE)
                SSL_shutdown(ssl);    /* bidirectional shutdown */
        }
        SSL_free(ssl);

        CloseSocket(clientfd);

        if (resume == 1 && resumeCount == 0) {
            resumeCount++;           /* only do one resume for testing */
            continue;
        }
        resumeCount = 0;

        if(!loopIndefinitely) {
            break;  /* out of while loop, done with normal and resume option */
        }
    } /* while(1) */

    CloseSocket(sockfd);
    SSL_CTX_free(ctx);

    ((func_args*)args)->return_code = 0;


#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
                            && defined(HAVE_THREAD_LS)
    ecc_fp_free();  /* free per thread cache */
#endif

#ifdef USE_WOLFSSL_MEMORY
    if (trackMemory)
        ShowMemoryTracker();
#endif

#ifdef CYASSL_TIRTOS
    fdCloseSession(Task_self());
#endif

#if defined(HAVE_SESSION_TICKET) && defined(HAVE_CHACHA) && \
                                    defined(HAVE_POLY1305)
    TicketCleanup();
#endif

    /* There are use cases  when these assignments are not read. To avoid
     * potential confusion those warnings have been handled here.
     */
    (void) ourKey;
    (void) verifyCert;
    (void) doCliCertCheck;
    (void) useNtruKey;
    (void) ourDhParam;
    (void) ourCert;
#ifndef CYASSL_TIRTOS
    return 0;
#endif
}
Esempio n. 23
0
static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args)
{
    SOCKET_T sockfd = 0;
    SOCKET_T clientfd = 0;
    word16 port = wolfSSLPort;

    WOLFSSL_METHOD* method = 0;
    WOLFSSL_CTX* ctx = 0;
    WOLFSSL* ssl = 0;

    char msg[] = "I hear you fa shizzle!";
    char input[1024];
    int idx;

#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif

    ((func_args*)args)->return_code = TEST_FAIL;
    method = wolfSSLv23_server_method();
    ctx = wolfSSL_CTX_new(method);

#if defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API) && \
   !defined(WOLFSSL_SNIFFER) && !defined(WOLFSSL_MDK_SHELL) && \
   !defined(WOLFSSL_TIRTOS)
    port = 0;
#endif

    wolfSSL_CTX_set_verify(ctx,
                          SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);

#ifdef OPENSSL_EXTRA
    wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif

    if (wolfSSL_CTX_load_verify_locations(ctx, cliCert, 0) != SSL_SUCCESS)
    {
        /*err_sys("can't load ca file, Please run from wolfSSL home dir");*/
        goto done;
    }
    if (wolfSSL_CTX_use_certificate_file(ctx, svrCert, SSL_FILETYPE_PEM)
            != SSL_SUCCESS)
    {
        /*err_sys("can't load server cert chain file, "
                "Please run from wolfSSL home dir");*/
        goto done;
    }
    if (wolfSSL_CTX_use_PrivateKey_file(ctx, svrKey, SSL_FILETYPE_PEM)
            != SSL_SUCCESS)
    {
        /*err_sys("can't load server key file, "
                "Please run from wolfSSL home dir");*/
        goto done;
    }

    ssl = wolfSSL_new(ctx);
    tcp_accept(&sockfd, &clientfd, (func_args*)args, port, 0, 0, 0);
    CloseSocket(sockfd);

    wolfSSL_set_fd(ssl, clientfd);

#ifdef NO_PSK
    #if !defined(NO_FILESYSTEM) && !defined(NO_DH)
        wolfSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM);
    #elif !defined(NO_DH)
        SetDH(ssl);  /* will repick suites with DHE, higher priority than PSK */
    #endif
#endif

    if (wolfSSL_accept(ssl) != SSL_SUCCESS)
    {
        int err = wolfSSL_get_error(ssl, 0);
        char buffer[WOLFSSL_MAX_ERROR_SZ];
        printf("error = %d, %s\n", err, wolfSSL_ERR_error_string(err, buffer));
        /*err_sys("SSL_accept failed");*/
        goto done;
    }

    idx = wolfSSL_read(ssl, input, sizeof(input)-1);
    if (idx > 0) {
        input[idx] = 0;
        printf("Client message: %s\n", input);
    }

    if (wolfSSL_write(ssl, msg, sizeof(msg)) != sizeof(msg))
    {
        /*err_sys("SSL_write failed");*/
#ifdef WOLFSSL_TIRTOS
        return;
#else
        return 0;
#endif
    }

#ifdef WOLFSSL_TIRTOS
    Task_yield();
#endif

done:
    wolfSSL_shutdown(ssl);
    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);

    CloseSocket(clientfd);
    ((func_args*)args)->return_code = TEST_SUCCESS;

#ifdef WOLFSSL_TIRTOS
    fdCloseSession(Task_self());
#endif

#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
                            && defined(HAVE_THREAD_LS)
    wc_ecc_fp_free();  /* free per thread cache */
#endif

#ifndef WOLFSSL_TIRTOS
    return 0;
#endif
}
Esempio n. 24
0
int __attribute__((noreturn)) telnet_input_task(struct telnet_svc * tn)
{
	struct tcp_pcb * svc;
	struct tcp_pcb * tp;
	char buf[128];
	int sb_len;
	int len;
	char * src;
	int rem;
	int binary;
	int state;
	int c;
	struct tn_opt opt;
	unsigned int head;

	svc = tn->svc;

	for (;;) {

		INF("TELNET wating for connection.");
		DCC_LOG(LOG_TRACE, "TELNET: waiting for connection...");

		if ((tp = tcp_accept(svc)) == NULL) {
			DCC_LOG(LOG_ERROR, "tcp_accept().");
			break;
		}

		INF("TELNET connection accepted.");
		DCC_LOG(LOG_TRACE, "TELNET: accepted.");

		tn->tp  = tp;

		tn_opt_clr(&opt);
		sb_len = 0;
		binary = 0;
		state = TN_DATA;
		tn_opt_will(tp, &opt, TELOPT_SGA);
		tn_opt_do(tp, &opt, TELOPT_SGA);
		tn_opt_will(tp, &opt, TELOPT_ECHO);
		tn_opt_will(tp, &opt, TELOPT_BINARY);
		tn_opt_do(tp, &opt, TELOPT_BINARY);

		head = tn->rx.head;

		for (;;) {

			if (head != tn->rx.tail) {
				/* update the head */
				tn->rx.head = head;
				DCC_LOG1(LOG_TRACE, "rx nonempty: head=%d", head);
				/* signal the head update */
				thinkos_flag_give(tn->rx.nonempty_flag);
			}

			/* receive data form network */
			if ((len = tcp_recv(tp, buf, 128)) <= 0) {
				DCC_LOG1(LOG_WARNING, "tcp_recv(): %d", len);
				break;
			}

			DCC_LOG1(LOG_TRACE, "recv: %d", len);

			/* set the input processing pointer */
			src = buf;
			/* input remaining (to be processed) bytes */
			rem = len;

			while (rem > 0) {
				c = *src++;
				rem--;

				if (state == TN_DATA) {
					if (c == IAC) {
						state = TN_IAC_RCVD;
					} else {
						if ((binary) || ((c >= 3) && (c < 127))) {
							/* ASCII characters */
							DCC_LOG1(LOG_TRACE, "rx nonempty: head=%d", head);

							/* buffer is full */
							if (head == (tn->rx.tail + TELNET_SVC_RX_BUF_LEN)) {
								/* update the head */
								tn->rx.head = head;
								/* signal the head update */
								thinkos_flag_give(tn->rx.nonempty_flag);
								
								/* wait for space in the input buffer */
								while (1) {
									if (head < (tn->rx.tail + 
												 TELNET_SVC_RX_BUF_LEN)) {
										break;
									}
									thinkos_flag_take(tn->rx.nonfull_flag);
								}
							} 

							tn->rx.buf[head++ % TELNET_SVC_RX_BUF_LEN] = c;

						} 
					}
					continue;
				}

				/* handles TELNET inputs options */
				switch (state) {

				case TN_IAC_RCVD:
					switch (c) {
					case IAC:
						state = TN_DATA;
						break;
					case DONT:
						state = TN_DONT_RCVD;
						break;
					case DO:
						state = TN_DO_RCVD;
						break;
					case WONT:
						state = TN_WONT_RCVD;
						break;
					case WILL:
						state = TN_WILL_RCVD;
						break;
					case SB:
						state = TN_SUBOPTION_ID;
						break;
					case EL:
					case EC:
					case AYT:
					case AO:
					case IP:
					case BREAK:
					case DM:
					case NOP:
					case SE:
					case EOR:
					case ABORT:
					case SUSP:
					case xEOF:
					default:
						state = TN_DATA;
						break;
					}
					break;

				case TN_DONT_RCVD:
					DCC_LOG1(LOG_TRACE, "DONT %s", TELOPT(c));
					tn_opt_wont(tp, &opt, c);
					state = TN_DATA;
					break;

				case TN_DO_RCVD:
					DCC_LOG1(LOG_TRACE, "DO %s", TELOPT(c));
					switch (c) {

					case TELOPT_SGA:
						tn_opt_will(tp, &opt, c);
						break;

					case TELOPT_ECHO:
						tn_opt_will(tp, &opt, c);
						break;

					case TELOPT_BINARY:
						tn_opt_will(tp, &opt, c);
						break;

					default:
						tn_opt_wont(tp, &opt, c);
					}

					state = TN_DATA;
					break;

				case TN_WONT_RCVD:
					DCC_LOG1(LOG_TRACE, "WONT %s", TELOPT(c));
					tn_opt_dont(tp, &opt, c);
					state = TN_DATA;
					break;

				case TN_WILL_RCVD:
					DCC_LOG1(LOG_TRACE, "WILL %s", TELOPT(c));

					switch (c) {
					case TELOPT_ECHO:
						tn_opt_dont(tp, &opt, c);
						break;

					case TELOPT_SGA:
						tn_opt_do(tp, &opt, c);
						break;

					case TELOPT_BINARY:
						tn_opt_do(tp, &opt, c);
						binary = 1;
						break;

					default:
						tn_opt_dont(tp, &opt, c);
					}

					state = TN_DATA;
					break;

				case TN_SUBOPTION_ID:
					state = TN_SUBOPTION;
					break;

				case TN_SUBOPTION:
					if (c == IAC)
						state = TN_SB_IAC_RCVD;
					if (sb_len < TN_SB_BUF_LEN) {
						DCC_LOG1(LOG_TRACE, "suboption: %d", c);
					}
//					sb_buf[sb_len++] = c;
					break;

				case TN_SB_IAC_RCVD:
					if (c == SE) {
						state = TN_DATA;
//						tn_suboption(cpc, sb_buf, sb_len);
					} else {
						state = TN_SUBOPTION;
//						sb_buf[sb_len++] = c;
					}
					break;

				case TN_INVALID_SUBOPTION:
					if (c == IAC)
						state = TN_INVALID_SB_IAC_RCVD;
					break;

				case TN_INVALID_SB_IAC_RCVD:
					if (c == SE)
						state = TN_DATA;
					else
						state = TN_INVALID_SUBOPTION;
					break;

				default:
					DCC_LOG1(LOG_WARNING, "invalid state: %d!!", state);
					break;
				}

			}

		}

		DCC_LOG(LOG_TRACE, "close...");

		tcp_close(tp);
		INF("TELNET connection closed.");
		tn->tp  = NULL;
	}

	DCC_LOG(LOG_ERROR, "thread loop break!!!");
	for(;;);
}
Esempio n. 25
0
static THREAD_RETURN WOLFSSL_THREAD run_wolfssl_server(void* args)
{
    callback_functions* callbacks = ((func_args*)args)->callbacks;

    WOLFSSL_CTX* ctx = wolfSSL_CTX_new(callbacks->method());
    WOLFSSL*     ssl = NULL;
    SOCKET_T    sfd = 0;
    SOCKET_T    cfd = 0;
    word16      port = wolfSSLPort;

    char msg[] = "I hear you fa shizzle!";
    int  len   = (int) XSTRLEN(msg);
    char input[1024];
    int  idx;

#ifdef WOLFSSL_TIRTOS
    fdOpenSession(Task_self());
#endif
    ((func_args*)args)->return_code = TEST_FAIL;

#if defined(NO_MAIN_DRIVER) && !defined(USE_WINDOWS_API) && \
   !defined(WOLFSSL_SNIFFER) && !defined(WOLFSSL_MDK_SHELL) && \
   !defined(WOLFSSL_TIRTOS)
    port = 0;
#endif

    wolfSSL_CTX_set_verify(ctx,
                          SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0);

#ifdef OPENSSL_EXTRA
    wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack);
#endif


    AssertIntEQ(SSL_SUCCESS, wolfSSL_CTX_load_verify_locations(ctx, cliCert, 0));

    AssertIntEQ(SSL_SUCCESS,
               wolfSSL_CTX_use_certificate_file(ctx, svrCert, SSL_FILETYPE_PEM));

    AssertIntEQ(SSL_SUCCESS,
                 wolfSSL_CTX_use_PrivateKey_file(ctx, svrKey, SSL_FILETYPE_PEM));

    if (callbacks->ctx_ready)
        callbacks->ctx_ready(ctx);

    ssl = wolfSSL_new(ctx);

    tcp_accept(&sfd, &cfd, (func_args*)args, port, 0, 0, 0);
    CloseSocket(sfd);

    wolfSSL_set_fd(ssl, cfd);

#ifdef NO_PSK
    #if !defined(NO_FILESYSTEM) && !defined(NO_DH)
        wolfSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM);
    #elif !defined(NO_DH)
        SetDH(ssl);  /* will repick suites with DHE, higher priority than PSK */
    #endif
#endif

    if (callbacks->ssl_ready)
        callbacks->ssl_ready(ssl);

    /* AssertIntEQ(SSL_SUCCESS, wolfSSL_accept(ssl)); */
    if (wolfSSL_accept(ssl) != SSL_SUCCESS) {
        int err = wolfSSL_get_error(ssl, 0);
        char buffer[WOLFSSL_MAX_ERROR_SZ];
        printf("error = %d, %s\n", err, wolfSSL_ERR_error_string(err, buffer));

    } else {
        if (0 < (idx = wolfSSL_read(ssl, input, sizeof(input)-1))) {
            input[idx] = 0;
            printf("Client message: %s\n", input);
        }

        AssertIntEQ(len, wolfSSL_write(ssl, msg, len));
#ifdef WOLFSSL_TIRTOS
        Task_yield();
#endif
        wolfSSL_shutdown(ssl);
    }

    if (callbacks->on_result)
        callbacks->on_result(ssl);

    wolfSSL_free(ssl);
    wolfSSL_CTX_free(ctx);
    CloseSocket(cfd);

    ((func_args*)args)->return_code = TEST_SUCCESS;

#ifdef WOLFSSL_TIRTOS
    fdCloseSession(Task_self());
#endif

#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \
                            && defined(HAVE_THREAD_LS)
    wc_ecc_fp_free();  /* free per thread cache */
#endif

#ifndef WOLFSSL_TIRTOS
    return 0;
#endif
}
Esempio n. 26
0
int usys_accept(int *err, uuprocess_t *u, int fd, struct sockaddr *acc_addr, socklen_t *addrlen)
{
    if( u == 0 )
    {
        *err = ENOTSOCK; // TODO correct?
        return -1;
    }

    CHECK_FD(fd);
    struct uufile *f = GETF(fd);

    struct uusocket *us = f->impl;

    // todo require UU_FILE_FLAG_ACCEPTABLE
    if( ! (f->flags & (UU_FILE_FLAG_NET|UU_FILE_FLAG_TCP)) )
    {
        *err = ENOTSOCK;
        return -1;
    }

    //us->addr = my_addr;

    void *new_socket = NULL;
    i4sockaddr tmp_addr;

    int pe = tcp_accept(us->prot_data, &tmp_addr, &new_socket);

    if( *addrlen >= (int)sizeof(struct sockaddr_in) )
    {
        /*
        struct sockaddr_in ia;

        ia.sin_len = sizeof(struct sockaddr_in);
        ia.sin_port = tmp_addr.port;
        ia.sin_addr.s_addr = NETADDR_TO_IPV4(tmp_addr.addr);
        ia.sin_family = PF_INET;

        *((struct sockaddr_in *)acc_addr) = ia;
        *addrlen = sizeof(struct sockaddr_in);
        */
        if( sockaddr_int2unix( acc_addr, addrlen, &tmp_addr ) )
            *addrlen = 0;
    }
    else
        *addrlen = 0;

    // TODO translate!
    if( pe )
    {
        *err = ECONNABORTED;
        return -1;
    }

    struct uusocket *rus = calloc(1, sizeof(struct uusocket));
    if(rus == 0)
    {
        tcp_close( new_socket );
        *err = ENOMEM;
        return -1;
    }



    uufile_t *rf = create_uufile();
    assert(f);

    rf->ops = &tcpfs_fops;

    rf->pos = 0;
    rf->fs = &tcp_fs;
    rf->impl = rus;
    rf->flags = UU_FILE_FLAG_NET|UU_FILE_FLAG_TCP;

    int rfd = uu_find_fd( u, rf );

    if( rfd < 0 )
    {
        tcp_close( new_socket );
        unlink_uufile( f );
        free( us );
        *err = EMFILE;
        return -1;
    }

    return *err ? -1 : rfd;
}
Esempio n. 27
0
int do_srv_select(unsigned short port)
{
	int fd = tcp_server(port);
	if(fd==-1)
	{
		perror("tcp_server");
		return 1;
	}

	int on = 1;
	if(-1==ioctl(fd,FIONBIO,(char*)&on))
	{
		perror("ioctl");
		return -1;
	}

	printf("Server Startupt at : %d\n",port);
	signal(SIGCHLD,SIG_IGN);

	FD_ZERO(&readfds);
	FD_SET(fd,&readfds);

	int curmax = fd;

	fd_set readfds_backup;
	memcpy(&readfds_backup,&readfds,sizeof(fd_set));

	for(;;)
	{
		memcpy(&readfds,&readfds_backup,sizeof(fd_set));
		int n = select(curmax+1,&readfds,NULL,NULL,NULL);
		printf("n:%d\n",n);
		if(FD_ISSET(fd,&readfds))
		{
			for(;;)
			{
				struct sockaddr_in cli_addr;
				int cli_sock = tcp_accept(fd,&cli_addr);
				if(cli_sock==-1)
				{
					if(errno!=EAGAIN)
						perror("tcp_accept");
					break;
				}
				if(cli_sock>curmax)
				{
					curmax=cli_sock;
				}
				printf("cli sock:%d\n",cli_sock);
				FD_SET(cli_sock,&readfds_backup);
			}
		}
		else
		{
			int i;
			for(i = 0;i <= curmax+1;i++)
			{
				int close_conn = 0;
				if(FD_ISSET(i,&readfds))
				{
					static char buf[1024];
					int n=read(i,buf,sizeof(buf));
					if(n<0)
					{
						if(errno!=EAGAIN)
						{
							perror("read");
							close_conn = 1;
						}
					}
					else if(n==0)
					{
						printf("*Connection Closed\n");
						close_conn = 1;
					}
					else if(n>0)
					{
						printf("buf:%s\n",buf);
					}

					if(close_conn)
					{
						close(i);
						FD_CLR(i,&readfds_backup);
						if(i==curmax)
						{
							while(FD_ISSET(curmax,&readfds_backup)==0)
							{
								--curmax;
							}
						}
					}
				}
			}
		}
	}
	return 0;
}