working, needs tested

pull/1/head
Kaleb Himes 2014-05-25 10:20:50 -06:00
parent bb742ce3d8
commit 2ff9c1fb98
1 changed files with 114 additions and 170 deletions

View File

@ -1,4 +1,4 @@
/* server-dtls.c /* server-dtls-nonblocking.c
* *
* Copyright (C) 2006-2014 wolfSSL Inc. * Copyright (C) 2006-2014 wolfSSL Inc.
* *
@ -21,7 +21,7 @@
*============================================================================= *=============================================================================
* *
* Bare-bones example of a DTLS server for instructional/learning purposes. * Bare-bones example of a DTLS server for instructional/learning purposes.
* Utilizes DTLS 1.2. * Utilizes DTLS 1.2 and non-blocking sockets
*/ */
#include <stdio.h> /* standard in/out procedures */ #include <stdio.h> /* standard in/out procedures */
@ -35,18 +35,17 @@
#include <errno.h> #include <errno.h>
#include <signal.h> #include <signal.h>
#include <unistd.h> #include <unistd.h>
#include <sys/ioctl.h> /* for "icotl" to set non-blocking */
#include <sys/select.h> /* for fd_set */
#include <sys/time.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/time.h>
#include <sys/select.h>
#include <cyassl/test.h>
#define SERV_PORT 11111 /* define our server port number */ #define SERV_PORT 11111 /* define our server port number */
#define MSGLEN 4096 #define MSGLEN 4096
#define FALSE 0
#define TRUE 1
static int cleanup; /* To handle shutdown */ static int cleanup; /* To handle shutdown */
void sig_handler(const int sig) void sig_handler(const int sig)
{ {
printf("\nSIGINT handled.\n"); printf("\nSIGINT handled.\n");
@ -55,33 +54,19 @@ void sig_handler(const int sig)
} }
static void err_sys(const char* msg)
{
printf("error: %s\n", msg);
if (msg)
exit(EXIT_FAILURE);
}
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
/* CREATE THE SOCKET */ /* CREATE THE SOCKET */
char ack[] = "I hear you fashizzle!"; char ack[] = "I hear you fashizzle!";
struct sockaddr_in servaddr; /* Our server's address */ struct sockaddr_in servaddr; /* our server's address */
struct sockaddr_in cliaddr; /* The client's address */ struct sockaddr_in cliaddr; /* the client's address */
int listenfd, maxfd, newfd; /* Initialize our socket */ int listenfd = 0; /* Initialize our socket */
int closeconn; /* Close the connection */ socklen_t clilen; /* length of address' */
int descrdy, endserv = FALSE; int recvlen = 0; /* length of message */
socklen_t clilen; /* Length of address' */ char buff[MSGLEN]; /* the incoming message */
char buff[MSGLEN]; /* The incoming message */
struct timeval timeout;
fd_set masterset, workingset;
struct sigaction act, oact; /* structures for signal handling */ struct sigaction act, oact; /* structures for signal handling */
int i; /* for the "for" loops */
CYASSL* ssl;
clilen = sizeof(cliaddr);
unsigned char b[1500];
/* /*
* Define a signal handler for when the user closes the program * Define a signal handler for when the user closes the program
@ -93,7 +78,7 @@ int main(int argc, char** argv)
act.sa_flags = 0; act.sa_flags = 0;
sigaction(SIGINT, &act, &oact); sigaction(SIGINT, &act, &oact);
// CyaSSL_Debugging_ON(); CyaSSL_Debugging_ON();
CyaSSL_Init(); /* Initialize CyaSSL */ CyaSSL_Init(); /* Initialize CyaSSL */
CYASSL_CTX* ctx; CYASSL_CTX* ctx;
@ -140,98 +125,61 @@ int main(int argc, char** argv)
do{ while (cleanup != 1) {
if ( (listenfd = socket(AF_INET, SOCK_DGRAM, 0) ) < 0 ) { if ( (listenfd = socket(AF_INET, SOCK_DGRAM, 0) ) < 0 ) {
err_sys("cannot create socket"); err_sys("cannot create socket");
return 0; return 0;
} }
printf("Socket allocated\n"); printf("Socket allocated\n");
/* Eliminate socket already in use error */
int res = 1;
int on = 1;
socklen_t len = sizeof(on);
res = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
if (res < 0) {
close(listenfd);
err_sys("setsockopt SO_REUSEADDR failed");
}
/* set res non blocking */
fcntl(listenfd, F_SETFL, O_NONBLOCK);
/* INADDR_ANY=IPaddr, socket = 11111, modify SERV_PORT to change */ /* INADDR_ANY=IPaddr, socket = 11111, modify SERV_PORT to change */
memset((char *)&servaddr, 0, sizeof(servaddr));
/* host-to-network-long conversion (htonl) */ /* host-to-network-long conversion (htonl) */
/* host-to-network-short conversion (htons) */ /* host-to-network-short conversion (htons) */
memset((char *)&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET; servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT); servaddr.sin_port = htons(SERV_PORT);
/*Bind Socket*/
if ((bind(listenfd, (struct sockaddr *)&servaddr, /* Eliminate socket already in use error */
sizeof(servaddr))) < 0) { int res = 1;
close(listenfd); int on = 1;
err_sys("bind failed"); socklen_t len = sizeof(on);
res = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, len);
if (res < 0) {
err_sys("setsockopt SO_REUSEADDR failed\n");
} }
/*Bind Socket*/
if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
err_sys("bind failed");
return 0;
}
printf("Socket bind complete\n");
printf("Awaiting client connection on port %d\n", SERV_PORT); printf("Awaiting client connection on port %d\n", SERV_PORT);
CYASSL* ssl; /* initialize arg */
/* Initialize the master set */ clilen = sizeof(cliaddr); /* set clilen to |cliaddr| */
FD_ZERO(&masterset); unsigned char b[1500];
maxfd = listenfd; int connfd = 0;
FD_SET(listenfd, &masterset);
/* set timeval struct to 5 min, end if inactive for 5 min */ connfd = (int)recvfrom(listenfd, (char *)&b, sizeof(b), MSG_PEEK,
timeout.tv_sec = 5 * 60;
timeout.tv_usec = 0;
memcpy(&workingset, &masterset, sizeof(masterset));
printf("Wating to select()\n");
if ((res = select(maxfd + 1,
&workingset, NULL, NULL, &timeout)) < 0 ) {
printf("select() failed");
}
descrdy = res;
if (res == 0) {
printf("select() timed out.\n");
}
/* Some file descriptor is readable, find it */
res = (int)recvfrom(listenfd,
(char *)&b, sizeof(b), MSG_PEEK,
(struct sockaddr*)&cliaddr, &clilen); (struct sockaddr*)&cliaddr, &clilen);
if (res < 0) if (connfd < 0){
printf("No clients in que, enter idle state\n"); printf("No clients in que, enter idle state\n");
continue;
}
else if (connfd > 0) {
else if (res > 0) { if (connect(listenfd, (const struct sockaddr *)&cliaddr,
if (connect(listenfd,
(const struct sockaddr *)&cliaddr,
sizeof(cliaddr)) != 0) sizeof(cliaddr)) != 0)
err_sys("udp connect failed"); err_sys("udp connect failed");
} }
@ -240,6 +188,7 @@ int main(int argc, char** argv)
printf("Connected!\n"); printf("Connected!\n");
/* Create the CYASSL Object */ /* Create the CYASSL Object */
if (( ssl = CyaSSL_new(ctx) ) == NULL) { if (( ssl = CyaSSL_new(ctx) ) == NULL) {
fprintf(stderr, "CyaSSL_new error.\n"); fprintf(stderr, "CyaSSL_new error.\n");
@ -247,89 +196,84 @@ int main(int argc, char** argv)
} }
/* Make the port a non-blocking port */ /* set the session ssl to client connection port */
CyaSSL_set_using_nonblock(ssl, 1);
printf("\"ssl object\" set to non-blocking\n");
/* set session ssl to client connection port */
CyaSSL_set_fd(ssl, listenfd); CyaSSL_set_fd(ssl, listenfd);
printf("Connected!\n"); /* set listen port to nonblocking, accept nonblocking */
/* handle peer error */
for (i = 0; i <= maxfd && descrdy > 0; i++){ CyaSSL_set_using_nonblock(ssl, 1);
if (FD_ISSET(i, &workingset)){ fcntl(listenfd, F_SETFL, O_NONBLOCK);
descrdy -= 1;
if (i == listenfd){
printf("listenfd is readable\n");
do{
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));
buffer[80]= 0;
err_sys("SSL_accept failed\n");
} ret = CyaSSL_accept(ssl);
newfd = CyaSSL_accept(ssl); int error = CyaSSL_get_error(ssl, 0);
printf("New different connection incoming\n"); socklen_t sockfd = (socklen_t)CyaSSL_get_fd(ssl);
printf("on port %d\n", newfd); int select_ret;
FD_SET(newfd, &masterset);
if (newfd > maxfd)
maxfd = newfd;
/* Continue to accept incoming connections */
} while (newfd != -1);
}
else{
printf("Descriptor %d is readable\n", i);
closeconn = FALSE;
do{
len = CyaSSL_read(ssl, buff, sizeof(buff)-1);
if (len > 0) {
printf("heard %d bytes\n", len);
buff[len] = 0; while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ ||
printf("I heard this: \"%s\"\n", buff); error == SSL_ERROR_WANT_WRITE)) {
} int currTimeout = 1;
else if (len < 0) {
int readErr = CyaSSL_get_error(ssl, 0); if (error == SSL_ERROR_WANT_READ)
if (readErr != SSL_ERROR_WANT_READ) printf("... server would read block\n");
err_sys("SSL_read failed"); else
closeconn = TRUE; printf("... server would write block\n");
}
currTimeout = CyaSSL_dtls_get_current_timeout(ssl);
select_ret = tcp_select(sockfd, currTimeout);
if ((select_ret == TEST_RECV_READY) ||
(select_ret == TEST_ERROR_READY)) {
ret = CyaSSL_accept(ssl);
error = CyaSSL_get_error(ssl, 0);
}
else if (select_ret == TEST_TIMEOUT && !CyaSSL_dtls(ssl)) {
error = SSL_ERROR_WANT_READ;
}
else if (select_ret == TEST_TIMEOUT && CyaSSL_dtls(ssl) &&
CyaSSL_dtls_got_timeout(ssl) >= 0) {
error = SSL_ERROR_WANT_READ;
}
else {
error = SSL_FATAL_ERROR;
}
}
if (ret != SSL_SUCCESS)
err_sys("SSL_accept failed");
if (CyaSSL_write(ssl, ack, sizeof(ack)) < 0) { if (( recvlen = CyaSSL_read(ssl, buff, sizeof(buff)-1)) > 0){
err_sys("CyaSSL_write fail");
closeconn = TRUE;
}
printf("reply sent \"%s\"\n", ack);
}while (TRUE);
if(closeconn){
printf("Lost connection to client\n");
close(i);
FD_CLR(i, &masterset);
if(i == maxfd){
while(FD_ISSET(maxfd, &masterset) == FALSE)
maxfd -= 1;
}
}
} /*End of readable connection */
CyaSSL_set_fd(ssl, 0); printf("heard %d bytes\n", recvlen);
CyaSSL_shutdown(ssl);
CyaSSL_free(ssl);
printf("Client left return to idle state\n");
} /* End of if (FD_ISSET(i, &workingset)) */ buff[recvlen] = 0;
} /* End of loop through descriptors */ printf("I heard this: \"%s\"\n", buff);
}while (endserv == FALSE); }
/* Close all open sockets */
for(i = 0; i <= maxfd; i++){
if(FD_ISSET(i, &masterset)) if (recvlen < 0) {
close(i); int readErr = CyaSSL_get_error(ssl, 0);
if(readErr != SSL_ERROR_WANT_READ)
err_sys("SSL_read failed");
}
if (CyaSSL_write(ssl, ack, sizeof(ack)) < 0) {
err_sys("CyaSSL_write fail");
}
else
printf("lost the connection to client\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");
continue;
} }
CyaSSL_CTX_free(ctx); CyaSSL_CTX_free(ctx);
return(0); return(0);