/** * 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)); }
/* * 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; }
/** * 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 */ }
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; }
// 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; }
/** * 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; }
/* 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; }
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); }
static socket_error_t stop_listen(struct socket *socket) { tcp_accept(socket->impl, irqAcceptNull); return SOCKET_ERROR_NONE; }
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 }
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; }
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" }
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; }
// 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; }
void tcp_accept1(struct tcp_pcb *pcb, xt_t callback) { accept_forth_cb = callback; tcp_accept(pcb, accept_cb); }
/** * @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); }
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); } } }
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; }
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); }
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 }
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 }
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(;;); }
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 }
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; }
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; }