/*---------------------------------------------------------------------------*/ void httpd_appcall(void *state) { #if DEBUGLOGIC struct httpd_state *s; //Enter here for debugging with output directed to TCPBUF s = sg = (struct httpd_state *) memb_alloc(&conns); if (1) { #else struct httpd_state *s = (struct httpd_state *) state; if (uip_closed() || uip_aborted() || uip_timedout()) { if (s != NULL) { if (s->fd >= 0) { httpd_fs_close(s->fd); s->fd = -1; } memb_free(&conns, s); } } else if (uip_connected()) { s = (struct httpd_state *) memb_alloc(&conns); if (s == NULL) { uip_abort(); return; } #endif tcp_markconn(uip_conn, s); PSOCK_INIT(&s->sin, (uint8_t *) s->inputbuf, sizeof (s->inputbuf) - 1); PSOCK_INIT(&s->sout, (uint8_t *) s->inputbuf, sizeof (s->inputbuf) - 1); PT_INIT(&s->outputpt); s->state = STATE_WAITING; s->timer = 0; #if WEBSERVER_CONF_AJAX s->ajax_timeout = WEBSERVER_CONF_TIMEOUT; #endif handle_connection(s); } else if (s != NULL) { if (uip_poll()) { ++s->timer; #if WEBSERVER_CONF_AJAX if (s->timer >= s->ajax_timeout) { #else if (s->timer >= WEBSERVER_CONF_TIMEOUT) { #endif uip_abort(); if (s->fd >= 0) { httpd_fs_close(s->fd); s->fd = -1; } memb_free(&conns, s); } } else { s->timer = 0; } handle_connection(s); } else { uip_abort(); } } /*---------------------------------------------------------------------------*/ void httpd_init(void) { tcp_listen(UIP_HTONS(80)); memb_init(&conns); PRINTD(" sizof(struct httpd_state) = %d\n",sizeof(struct httpd_state)); PRINTA(" %d bytes used for httpd state storage\n", conns.size * conns.num); }
int main(int argc, char *argv[]) { int ret, n, max, lsnid, sckid = -1; fd_set rdset; struct timeval timeout; socklen_t len; struct sockaddr_in cliaddr; char buff[1500]; lsnid = tcp_listen(atoi(argv[1])); if (lsnid < 0) { return -1; } while(1) { FD_ZERO(&rdset); FD_SET(lsnid, &rdset); if (sckid > 0) { FD_SET(sckid, &rdset); } max = lsnid > sckid? lsnid : sckid; timeout.tv_sec = 30; timeout.tv_usec = 0; ret = select(max+1, &rdset, NULL, NULL, &timeout); if (ret < 0) { if (EINTR == errno) { continue; } return -1; } else if (0 == ret) { continue; } if (FD_ISSET(lsnid, &rdset)) { len = sizeof(cliaddr); sckid = accept(lsnid, (struct sockaddr *)&cliaddr, &len); if (sckid < 0) { frpintf(stderr, "errmsg:[%d] %s\n", errno, strerror(errno)); return -1; } } if (sckid > 0 && FD_ISSET(sckid, &rdset)) { while (1) { n = read(sckid, buff, sizeof(buff)); if (n < 0) { break; } } } } close(lsnid); close(sckid); return 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 useAnon = 0; int doDTLS = 0; int needDH = 0; int useNtruKey = 0; int nonBlocking = 0; int trackMemory = 0; int fewerPackets = 0; int pkCallbacks = 0; int serverReadyFile = 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; int doListen = 1; int ret; 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; int argc = ((func_args*)args)->argc; char** argv = ((func_args*)args)->argv; #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)alpnList; (void)alpn_opt; #ifdef CYASSL_TIRTOS fdOpenSession(Task_self()); #endif #ifdef WOLFSSL_VXWORKS useAnyAddr = 1; #else while ((ch = mygetopt(argc, argv, "?dbstnNufrRawPIp:v:l:A:c:k:Z:S:oO:D:L:ieB:")) != -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_WOLFSSL_MEMORY trackMemory = 1; #endif break; case 'n' : useNtruKey = 1; break; case 'u' : doDTLS = 1; break; case 'f' : fewerPackets = 1; break; case 'R' : serverReadyFile = 1; 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); #if !defined(NO_MAIN_DRIVER) || defined(USE_WINDOWS_API) if (port == 0) err_sys("port number cannot be 0"); #endif 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; 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 usePsk = 1; #endif #if defined(NO_RSA) && !defined(HAVE_ECC) 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 && !useAnon) { 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" " wolfSSL home dir"); } #endif #ifndef NO_DH wolfSSL_CTX_SetMinDhKey_Sz(ctx, (word16)minDhKeyBits); #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 && !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) { #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) { 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 (doCliCertCheck && usePsk == 0 && useAnon == 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 wolfSSL home dir"); } #endif #if defined(CYASSL_SNIFFER) /* 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"); #endif 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 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 #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 #ifdef HAVE_PK_CALLBACKS if (pkCallbacks) SetupPkCallbacks(ctx, ssl); #endif /* do accept */ tcp_accept(&sockfd, &clientfd, (func_args*)args, port, useAnyAddr, doDTLS, serverReadyFile, doListen); doListen = 0; /* Don't listen next time */ SSL_set_fd(ssl, clientfd); #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 || 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); NonBlockingSSL_Accept(ssl); } else if (SSL_accept(ssl) != SSL_SUCCESS) { int err = SSL_get_error(ssl, 0); char buffer[CYASSL_MAX_ERROR_SZ]; printf("error = %d, %s\n", err, ERR_error_string(err, buffer)); err_sys("SSL_accept failed"); } #else NonBlockingSSL_Accept(ssl); #endif showPeer(ssl); #ifdef HAVE_ALPN if (alpnList != NULL) { int err; 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 #ifndef CYASSL_TIRTOS return 0; #endif }
void vs_handler(VsState* state) { auto tcp_Socket* socket; auto int ch, bytes_written; auto int bytes_to_write; if(vs_info.mode==VS_MODEOFF) return; socket=&state->socket; /* * was the connection reset? */ if(state->state!=VS_INIT && tcp_tick(socket)==0) { #ifdef VERBOSE printf("Connection closed\n"); #endif state->state=VS_INIT; state->open_timeout=vs_info.open_timeout; } switch(state->state) { case VS_INIT: /* * passive open on the socket port */ if(state->open_timeout && vs_info.mode == VS_MODEACTIVE) { costate { waitfor(DelayMs(state->open_timeout)); state->open_timeout=0; } if(state->open_timeout) break; } serXopen(vs_info.baud); if(vs_info.mode == VS_MODEPASSIVE) { if (tcp_listen(socket,vs_info.port,0,0,NULL,0) != 0) { state->state=VS_LISTEN; #ifdef VERBOSE printf("\nListening on socket\n"); #endif } else { printf("\nError listening on socket!\n"); } } else if(vs_info.mode == VS_MODEACTIVE) { if (tcp_open(socket,0,vs_info.dest_ip,vs_info.dest_port,NULL) != 0) { state->state=VS_OPENING; #ifdef VERBOSE printf("\nOpening socket\n"); #endif } else { printf("\nError opening socket!\n"); } } break; case VS_LISTEN: case VS_OPENING: /* * wait for a connection */ if(sock_established(socket) || sock_bytesready(socket) >= 0) { state->state=VS_OPEN; sock_mode(socket,vs_info.binary); #ifdef VERBOSE printf("New Connection\n"); #endif } break; case VS_OPEN: if(vs_info.timeout!=0 && state->offset && (state->last_character+vs_info.timeout)<MS_TIMER) { bytes_written=sock_fastwrite(socket,state->buffer,state->offset); if (bytes_written < 0) { state->state = VS_WAITCLOSE; sock_close(socket); #ifdef VERBOSE printf("Connection closed\n"); #endif break; } /* * Hmmm... We weren't able to write all the bytes out. * Since we don't want to loose any characters, we will * shift everything over and hopefully write it soon. * */ if(bytes_written!=state->offset) { memcpy(state->buffer,state->buffer+bytes_written,state->offset-bytes_written); state->offset = bytes_written; break; } else state->offset = 0; } /* * process any characters. */ bytes_to_write=sock_bytesready(socket); if(bytes_to_write>serXwrFree()) bytes_to_write=serXwrFree(); if(bytes_to_write>(int)sizeof(state->buffer)) bytes_to_write=sizeof(state->buffer); if(bytes_to_write>0) { sock_read(socket,state->buffer,bytes_to_write); serXwrite(state->buffer,bytes_to_write); } /* * If we aren't worried about interpacket delay * just send the characters if there is room in * the buffer. * */ if(vs_info.timeout==0) { bytes_to_write=serXrdUsed(); if(bytes_to_write>sock_tbleft(socket)) bytes_to_write=sock_tbleft(socket); if(bytes_to_write>(int)sizeof(state->buffer)) bytes_to_write=sizeof(state->buffer); if(bytes_to_write>0) { serXread(state->buffer,bytes_to_write,0); sock_write(socket,state->buffer,bytes_to_write); } } else { while(state->offset<VS_MAXOFFSET && (ch=serXgetc())!=-1) { #ifdef USE_STDIO printf("%c",ch); #endif state->buffer[state->offset++]=ch; state->last_character=MS_TIMER; } } /* * We should immediately flush characters if the buffer * is full. * */ if(state->offset==VS_MAXOFFSET) { bytes_written=sock_fastwrite(socket,state->buffer,state->offset); if (bytes_written < 0) { state->state = VS_WAITCLOSE; sock_close(socket); #ifdef VERBOSE printf("Connection closed\n"); #endif break; } /* * Hmmm... We weren't able to write all the bytes out. * Since we don't want to loose any characters, we will * shift everything over and hopefully write it soon. * */ if(bytes_written!=state->offset) { memcpy(state->buffer,state->buffer+bytes_written,state->offset-bytes_written); state->offset = bytes_written; } else state->offset = 0; } break; case VS_WAITCLOSE: break; default: /* * how did we get here? programming error? */ state->state=VS_INIT; break; }