From b75a5d4e7cf33baee2004736c9f096b023bfbd45 Mon Sep 17 00:00:00 2001 From: Kaleb Himes Date: Mon, 30 Jun 2014 10:06:07 -0600 Subject: [PATCH] threaded updates, not yet complete --- .../server-dtls-threaded.c | 242 +++++++++++------- 1 file changed, 148 insertions(+), 94 deletions(-) diff --git a/project1/dtls_secured_multithreaded/server-dtls-threaded.c b/project1/dtls_secured_multithreaded/server-dtls-threaded.c index d2282a7e..9800a475 100644 --- a/project1/dtls_secured_multithreaded/server-dtls-threaded.c +++ b/project1/dtls_secured_multithreaded/server-dtls-threaded.c @@ -49,66 +49,104 @@ struct sockaddr_in servAddr; /* our server's address */ int AwaitDGram(CYASSL_CTX* ctx); void* ThreadControl(void*); +typedef struct { + int activefd; + int size; + unsigned char b[MSGLEN]; +}threadArgs; + int AwaitDGram(CYASSL_CTX* ctx) { int on = 1; int res = 1; int bytesRcvd = 0; - int recvLen = 0; /* length of message */ int listenfd = 0; /* Initialize our socket */ - CYASSL* ssl = NULL; socklen_t cliLen; socklen_t len = sizeof(on); - unsigned char b[MSGLEN]; /* watch for incoming messages */ - char buff[MSGLEN]; /* the incoming message */ - char ack[] = "I hear you fashizzle!\n"; + unsigned char buf[MSGLEN]; /* watch for incoming messages */ + + /* Create a UDP/IP socket */ + if ((listenfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) { + printf("Cannot create socket.\n"); + cleanup = 1; + } + printf("Socket allocated\n"); + + /* clear servAddr each loop */ + memset((char *)&servAddr, 0, sizeof(servAddr)); + + /* host-to-network-long conversion (htonl) */ + /* host-to-network-short conversion (htons) */ + servAddr.sin_family = AF_INET; + servAddr.sin_addr.s_addr = htonl(INADDR_ANY); + servAddr.sin_port = htons(SERV_PORT); + + /* Eliminate socket already in use error */ + res = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, len); + if (res < 0) { + printf("Setsockopt SO_REUSEADDR failed.\n"); + cleanup = 1; + return 1; + } + + /*Bind Socket*/ + if (bind(listenfd, + (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0) { + printf("Bind failed.\n"); + cleanup = 1; + return 1; + } + + printf("Awaiting client connection on port %d\n", SERV_PORT); while (cleanup != 1) { - /* Create a UDP/IP socket */ - if ((listenfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) { - printf("Cannot create socket.\n"); - cleanup = 1; - } - printf("Socket all/ocated\n"); + + threadArgs* args; + args = (threadArgs *) malloc(sizeof(threadArgs)); - /* clear servAddr each loop */ - memset((char *)&servAddr, 0, sizeof(servAddr)); - - /* host-to-network-long conversion (htonl) */ - /* host-to-network-short conversion (htons) */ - servAddr.sin_family = AF_INET; - servAddr.sin_addr.s_addr = htonl(INADDR_ANY); - servAddr.sin_port = htons(SERV_PORT); - - /* Eliminate socket already in use error */ - res = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, len); - if (res < 0) { - printf("Setsockopt SO_REUSEADDR failed.\n"); - cleanup = 1; - return 1; - } - - /*Bind Socket*/ - if (bind(listenfd, - (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0) { - printf("Bind failed.\n"); - cleanup = 1; - return 1; - } - - printf("Awaiting client connection on port %d\n", SERV_PORT); - - cliLen = sizeof(cliaddr); - bytesRcvd = (int)recvfrom(listenfd, (char *)&b, sizeof(b), MSG_PEEK, - (struct sockaddr*)&cliaddr, &cliLen); + cliLen = sizeof(cliAddr); + /* note argument 4 of recvfrom not MSG_PEEK as dtls will see + * handshake packets and think a message is arriving. Instead + * read any real message to struct and pass struct into thread + * for processing. + */ + bytesRcvd = (int)recvfrom(listenfd, (char *)buf, sizeof(buf), 0, + (struct sockaddr*)&cliAddr, &cliLen); if (bytesRcvd < 0) { printf("No clients in que, enter idle state\n"); continue; } + else if (bytesRcvd > 0) { - if (connect(listenfd, (const struct sockaddr *)&cliaddr, - sizeof(cliaddr)) != 0) { + + memcpy(args->b, buf, sizeof(buf)); + + args->size = bytesRcvd; + + if ((args->activefd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) { + printf("Cannot create socket.\n"); + cleanup = 1; + } + + res = setsockopt(args->activefd, SOL_SOCKET, SO_REUSEADDR, &on, + len); + if (res < 0) { + printf("Setsockopt SO_REUSEADDR failed.\n"); + cleanup = 1; + return 1; + } + #ifdef SO_REUSEPORT + res = setsockopt(args->activefd, SOL_SOCKET, SO_REUSEPORT, &on, len); + if (res < 0) { + printf("Setsockopt SO_REUSEPORT failed.\n"); + cleanup = 1; + return 1; + } + #endif + + if (connect(args->activefd, (const struct sockaddr *)&cliAddr, + sizeof(cliAddr)) != 0) { printf("Udp connect failed.\n"); cleanup = 1; return 1; @@ -121,57 +159,13 @@ int AwaitDGram(CYASSL_CTX* ctx) } printf("Connected!\n"); - /* Create the CYASSL Object */ - if ((ssl = CyaSSL_new(ctx)) == NULL) { - printf("CyaSSL_new error.\n"); - cleanup = 1; - return 1; - } - - /* set the session ssl to client connection port */ - CyaSSL_set_fd(ssl, listenfd); - - if (CyaSSL_accept(ssl) != SSL_SUCCESS) { + pthread_t threadid; + printf("new id %d created.\n",(int) threadid); + /* SPIN A THREAD HERE TO HANDLE "buff" and "reply/ack" */ + pthread_create(&threadid, NULL, ThreadControl, args); + printf("control passed to thread control.\n"); + } - int e = CyaSSL_get_error(ssl, 0); - - printf("error = %d, %s\n", e, CyaSSL_ERR_reason_error_string(e)); - printf("SSL_accept failed.\n"); - continue; - } - if ((recvLen = CyaSSL_read(ssl, buff, sizeof(buff)-1)) > 0) { - printf("heard %d bytes\n", recvLen); - - /* SPIN A THREAD HERE TO HANDLE "buff" and "reply/ack" */ - - /* buff[recvLen] = 0; - printf("I heard this: \"%s\"\n", buff); - } - else if (recvLen < 0) { - int readErr = CyaSSL_get_error(ssl, 0); - if(readErr != SSL_ERROR_WANT_READ) { - printf("SSL_read failed.\n"); - cleanup = 1; - return 1; - } - } - if (CyaSSL_write(ssl, ack, sizeof(ack)) < 0) { - printf("CyaSSL_write fail.\n"); - cleanup = 1; - return 1; - } - else { - printf("Sending reply.\n"); - } - - printf("reply sent \"%s\"\n", ack); - - CyaSSL_set_fd(ssl, 0); - CyaSSL_shutdown(ssl); - CyaSSL_free(ssl); - - printf("Client left return to idle state\n"); - }*/ return 0; } @@ -179,8 +173,68 @@ void* ThreadControl(void* openSock) { pthread_detach(pthread_self()); + threadArgs* args = (threadArgs*)openSock; + int recvLen = 0; /* length of message */ + int activefd = args->activefd; /* the active descriptor */ + int msgLen = args->size; /* the size of message */ + unsigned char buff[msgLen]; /* the incoming message */ + char ack[] = "I hear you fashizzle!\n"; + CYASSL* ssl; + + memcpy(buff, args->b, msgLen); + + /* Create the CYASSL Object */ + if ((ssl = CyaSSL_new(ctx)) == NULL) { + printf("CyaSSL_new error.\n"); + cleanup = 1; + return NULL; + } + + /* set the session ssl to client connection port */ + CyaSSL_set_fd(ssl, activefd); + + if (CyaSSL_accept(ssl) != SSL_SUCCESS) { + + int e = CyaSSL_get_error(ssl, 0); + + printf("error = %d, %s\n", e, CyaSSL_ERR_reason_error_string(e)); + printf("SSL_accept failed.\n"); + return NULL; + } + if ((recvLen = CyaSSL_read(ssl, buff, msgLen-1)) > 0) { + printf("heard %d bytes\n", recvLen); + + buff[recvLen] = 0; + printf("I heard this: \"%s\"\n", buff); + } + else if (recvLen < 0) { + int readErr = CyaSSL_get_error(ssl, 0); + if(readErr != SSL_ERROR_WANT_READ) { + printf("SSL_read failed.\n"); + cleanup = 1; + return NULL; + } + } + if (CyaSSL_write(ssl, ack, sizeof(ack)) < 0) { + printf("CyaSSL_write fail.\n"); + cleanup = 1; + return NULL; + } + else { + printf("Sending reply.\n"); + } + + printf("reply sent \"%s\"\n", ack); + + + CyaSSL_shutdown(ssl); + CyaSSL_free(ssl); + close(activefd); + free(openSock); /* valgrind friendly free */ + + printf("Client left return to idle state\n"); printf("Exiting thread.\n\n"); - pthread_exit(&exitRet); + pthread_exit(openSock); } int main(int argc, char** argv)