From 8f9aeafbbbf3176004d1a4a18b4da369cffce518 Mon Sep 17 00:00:00 2001 From: Marcel Poul Date: Wed, 7 Dec 2011 14:28:34 +0000 Subject: [PATCH] canl_io_accept do only ssl_accept; server serves accept() on his own; typo --- emi.canl.canl-c/src/canl.c | 116 ++++++------------------------- emi.canl.canl-c/src/canl.h | 6 +- emi.canl.canl-c/src/canl_locl.h | 4 +- emi.canl.canl-c/src/canl_sample_server.c | 98 ++++++++++++++++++++------ emi.canl.canl-c/src/canl_ssl.c | 27 +++---- 5 files changed, 114 insertions(+), 137 deletions(-) diff --git a/emi.canl.canl-c/src/canl.c b/emi.canl.canl-c/src/canl.c index 6a5ec74..2d77013 100644 --- a/emi.canl.canl-c/src/canl.c +++ b/emi.canl.canl-c/src/canl.c @@ -141,7 +141,7 @@ int canl_io_connect(canl_ctx cc, canl_io_handler io, char * host, int port, } if (!io_cc || !io_cc->ar || !io_cc->ar->ent || !io_cc->s_addr) - return set_error(cc, EINVAL, posix_error, "IO handler not initialized"); + return set_error(cc, EINVAL, posix_error, "IO handler not initialized"); /*dns TODO - wrap it for using ipv6 and ipv4 at the same time*/ @@ -161,16 +161,16 @@ int canl_io_connect(canl_ctx cc, canl_io_handler io, char * host, int port, } if (err) - /* XXX add error msg from ares */ - return set_error(cc, err, posix_error, - "Cannot resolve the server hostname (%s)", host); + /* XXX add error msg from ares */ + return set_error(cc, err, posix_error, + "Cannot resolve the server hostname (%s)", host); sa_in = (struct sockaddr_in *) io_cc->s_addr; io_cc->sock = socket(AF_INET, SOCK_STREAM, 0); if (io_cc->sock == -1) - return set_error(cc, err, posix_error, "Failed to create socket: %s", - strerror(err)); + return set_error(cc, err, posix_error, "Failed to create socket: %s", + strerror(err)); sa_in->sin_family = AF_INET; sa_in->sin_port = htons(port); @@ -181,7 +181,7 @@ int canl_io_connect(canl_ctx cc, canl_io_handler io, char * host, int port, { memcpy(&sa_in->sin_addr.s_addr, io_cc->ar->ent->h_addr_list[i], sizeof(struct in_addr)); - /* XXX timeouts missing */ + /* XXX timeouts missing */ err = connect(io_cc->sock, (struct sockaddr*) sa_in, sizeof(*sa_in)); if (err) err = errno; @@ -189,19 +189,19 @@ int canl_io_connect(canl_ctx cc, canl_io_handler io, char * host, int port, break; //success i++; } - + if (err) - return set_error(cc, ECONNREFUSED, posix_error, - "Failed to make network connection to server %s", host); + return set_error(cc, ECONNREFUSED, posix_error, + "Failed to make network connection to server %s", host); err = ssl_client_init(glb_cc, io_cc); if (err) - goto end; + goto end; err = ssl_connect(glb_cc, io_cc, timeout); //TODO timeout if (err) - goto end; - + goto end; + /*write succes or failure to cc, io*/ //if (err) /*cc or io set error*/ @@ -214,99 +214,27 @@ end: } /*TODO select + timeout, EINTR!!! */ -int canl_io_accept(canl_ctx cc, canl_io_handler io, int port, - int flags, cred_handler ch, struct timeval *timeout, - canl_io_handler *new_io) +int canl_io_accept(canl_ctx cc, canl_io_handler io, int new_fd, + struct sockaddr s_addr, int flags, cred_handler ch, + struct timeval *timeout) { - int err = 0, sockfd = 0, new_fd = 0; + int err = 0; io_handler *io_cc = (io_handler*) io; glb_ctx *glb_cc = (glb_ctx*) cc; - io_handler **io_new_cc = (io_handler**) new_io; - char str_port[8]; - struct addrinfo hints, *servinfo, *p; - socklen_t sin_size; - int yes=1; if (!glb_cc) return EINVAL; /* XXX Should rather be a CANL error */ if (!io_cc || !io_cc->ar || !io_cc->ar->ent || !io_cc->s_addr) - return set_error(cc, EINVAL, posix_error, "IO handler not initialized"); - - /* XXX perhaps remove entirely from the API ? */ - if (!*io_new_cc || !(*io_new_cc)->ar || !(*io_new_cc)->ar->ent - || !(*io_new_cc)->s_addr) { - err = EINVAL; - goto end; - } - - memset(&hints, 0, sizeof hints); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_PASSIVE; // use my IP - - if (snprintf(str_port, 8, "%d", port) < 0) - return set_error(cc, EINVAL, posix_error, "Wrong port requested (%d)", port); - - /* XXX timeouts - use c-ares, too */ - if ((err = getaddrinfo(NULL, str_port, &hints, &servinfo)) != 0) { - update_error(glb_cc, "getaddrinfo: %s\n", gai_strerror(err)); - /*TODO what kind of error return?, getaddrinfo returns its own - error codes*/ - goto end; - } - - for(p = servinfo; p != NULL; p = p->ai_next) { - if ((sockfd = socket(p->ai_family, p->ai_socktype, - p->ai_protocol)) == -1) { - // set err? no - err = errno; - continue; - } - if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, - sizeof(int)) == -1) { - err = errno; - freeaddrinfo(servinfo); // all done with this structure - return -1; - } - if ((err = bind(sockfd, p->ai_addr, p->ai_addrlen))) { - close(sockfd); - err = errno; - continue; - } - if ((err = listen(sockfd, BACKLOG))) { - close(sockfd); - err = errno; - continue; - } - - - break; - } - - freeaddrinfo(servinfo); // all done with this structure - if (p == NULL) { - return set_error(glb_cc, -1, unknown_error, - "Failed to acquire a server socket"); - } + return set_error(cc, EINVAL, posix_error, "IO handler not initialized"); -#ifdef DEBUG - printf("server: waiting for connections...\n"); -#endif - sin_size = sizeof((*io_new_cc)->s_addr); - new_fd = accept(sockfd, (*io_new_cc)->s_addr, &sin_size); - if (new_fd == -1){ - return set_error(glb_cc, errno, posix_error, - "Failed to accept network connection: %s", - strerror(errno)); - } - (*io_new_cc)->sock = new_fd; + io_cc->sock = new_fd; - err = ssl_server_init(glb_cc, *io_new_cc); + err = ssl_server_init(glb_cc); if (err) goto end; - err = ssl_accept(glb_cc, io_cc, (*io_new_cc), timeout); + err = ssl_accept(glb_cc, io_cc, timeout); if (err) goto end; @@ -314,7 +242,7 @@ int canl_io_accept(canl_ctx cc, canl_io_handler io, int port, end: if (err) - (*io_new_cc)->sock = 0; + (io_cc)->sock = 0; return err; } diff --git a/emi.canl.canl-c/src/canl.h b/emi.canl.canl-c/src/canl.h index a0a97f6..1e9ca21 100644 --- a/emi.canl.canl-c/src/canl.h +++ b/emi.canl.canl-c/src/canl.h @@ -1,6 +1,7 @@ #ifndef _CANL_H #define _CANL_H #include +#include "sys/socket.h" typedef void *canl_io_handler; typedef void *canl_ctx; @@ -18,8 +19,9 @@ canl_io_handler canl_create_io_handler(canl_ctx cc); int canl_io_connect(canl_ctx cc, canl_io_handler io, char * host, int port, int flags, cred_handler ch, struct timeval *timeout); -int canl_io_accept(canl_ctx cc, canl_io_handler io, int port, int flags, cred_handler ch, - struct timeval *timeout, canl_io_handler * new_io); +int canl_io_accept(canl_ctx cc, canl_io_handler io, int fd, + struct sockaddr s_addr, int flags, cred_handler ch, + struct timeval *timeout); size_t canl_io_read(canl_ctx cc, canl_io_handler io, void *buffer, size_t size, struct timeval *timeout); size_t canl_io_write(canl_ctx cc, canl_io_handler io, void *buffer, size_t size, struct timeval *timeout); diff --git a/emi.canl.canl-c/src/canl_locl.h b/emi.canl.canl-c/src/canl_locl.h index 7bb5042..e9b9ec9 100644 --- a/emi.canl.canl-c/src/canl_locl.h +++ b/emi.canl.canl-c/src/canl_locl.h @@ -58,9 +58,9 @@ void free_hostent(struct hostent *h); //TODO is there some standard funcion to f int asyn_getservbyname(int a_family, asyn_result *ares_result,char const *name, struct timeval *timeout); int ssl_client_init(glb_ctx *cc, io_handler *io); -int ssl_server_init(glb_ctx *cc, io_handler *io); +int ssl_server_init(glb_ctx *cc); int ssl_connect(glb_ctx *cc, io_handler *io, struct timeval *timeout); -int ssl_accept(glb_ctx *cc, io_handler *io, io_handler *new_io, +int ssl_accept(glb_ctx *cc, io_handler *io, struct timeval *timeout); int ssl_read(glb_ctx *cc, io_handler *io, void *buffer, size_t size, struct timeval *tout); diff --git a/emi.canl.canl-c/src/canl_sample_server.c b/emi.canl.canl-c/src/canl_sample_server.c index 18b2c23..5ca61fa 100644 --- a/emi.canl.canl-c/src/canl_sample_server.c +++ b/emi.canl.canl-c/src/canl_sample_server.c @@ -2,9 +2,12 @@ #include #include #include +#include +#include #include "canl.h" #define BUF_LEN 1000 +#define BACKLOG 10 static void print_error_from_canl(canl_ctx cc); int main(int argc, char *argv[]) @@ -24,7 +27,7 @@ int main(int argc, char *argv[]) switch (opt) { case 'h': fprintf(stderr, "Usage: %s [-p port] [-c certificate]" - " [-k private key] [-h] \n", argv[0]); + " [-k private key] [-h] \n", argv[0]); break; case 'p': port = atoi(optarg); @@ -37,7 +40,7 @@ int main(int argc, char *argv[]) break; default: /* '?' */ fprintf(stderr, "Usage: %s [-p port] [-c certificate]" - " [-k private key] [-h] \n", argv[0]); + " [-k private key] [-h] \n", argv[0]); exit(-1); } } @@ -72,12 +75,76 @@ int main(int argc, char *argv[]) } } + /* ACCEPT from canl_io_accept*/ + int sockfd = 0, new_fd = 0; + char str_port[8]; + struct addrinfo hints, *servinfo, *p; + struct sockaddr s_addr; + socklen_t sin_size; + int yes=1; + + memset(&hints, 0, sizeof hints); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; // use my IP + + if (snprintf(str_port, 8, "%d", port) < 0) { + printf ("[SERVER] Wrong port request"); + return 1; + } + + /* XXX timeouts - use c-ares, too */ + if ((err = getaddrinfo(NULL, str_port, &hints, &servinfo)) != 0) { + printf("[SERVER] getaddrinfo: %s\n", gai_strerror(err)); + return 1; + } + + for (p = servinfo; p != NULL; p = p->ai_next) { + if ((sockfd = socket(p->ai_family, p->ai_socktype, + p->ai_protocol)) == -1) { + err = errno; + continue; + } + if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, + sizeof(int)) == -1) { + err = errno; + freeaddrinfo(servinfo); // all done with this structure + return -1; + } + if ((err = bind(sockfd, p->ai_addr, p->ai_addrlen))) { + close(sockfd); + err = errno; + continue; + } + if ((err = listen(sockfd, BACKLOG))) { + close(sockfd); + err = errno; + continue; + } + + + break; + } + + freeaddrinfo(servinfo); // all done with this structure + if (p == NULL) { + printf("Failed to acquire a server socket"); + return 1; + } + + printf("server: waiting for connections...\n"); + sin_size = sizeof(s_addr); + new_fd = accept(sockfd, &s_addr, &sin_size); + if (new_fd == -1){ + printf("Failed to accept network connection: %s", strerror(errno)); + } + timeout.tv_sec = 150; timeout.tv_usec = 0; - /* canl_create_io_handler has to be called for my_new_io_h and my_io_h*/ - /* TODO timeout in this function?*/ - err = canl_io_accept(my_ctx, my_io_h, port, 0, NULL, &timeout, &my_new_io_h); + /* canl_create_io_handler has to be called for my_io_h*/ + /* TODO timeout in this function? and select around it*/ + err = canl_io_accept(my_ctx, my_io_h, new_fd, s_addr, 0, NULL, &timeout); if (err) { printf("[SERVER] connection cannot be established: %s\n", canl_get_error_message(my_ctx)); @@ -89,7 +156,7 @@ int main(int argc, char *argv[]) buf_len = strlen(buf) + 1; printf("[SERVER] Trying to send sth to the client\n"); - err = canl_io_write (my_ctx, my_new_io_h, buf, buf_len, &timeout); + err = canl_io_write (my_ctx, my_io_h, buf, buf_len, &timeout); if (err <= 0) { printf("[SERVER] cannot send message to the client: %s\n", canl_get_error_message(my_ctx)); @@ -100,7 +167,7 @@ int main(int argc, char *argv[]) printf("[SERVER] message \"%s\" sent successfully\n", buf); } - err = canl_io_read (my_ctx, my_new_io_h, buf, sizeof(buf)-1, NULL); + err = canl_io_read (my_ctx, my_io_h, buf, sizeof(buf)-1, NULL); if (err > 0) { buf[err] = '\0'; printf ("[SERVER] received: %s\n", buf); @@ -110,22 +177,7 @@ int main(int argc, char *argv[]) canl_get_error_message(my_ctx)); end: - if (my_new_io_h) { - err = canl_io_close(my_ctx, my_new_io_h); - if (err){ - printf("[SERVER] Cannot close connection\n"); - print_error_from_canl(my_ctx); - } - } - - if (my_new_io_h) { - err = canl_io_destroy(my_ctx, my_new_io_h); - if (err){ - printf("[SERVER] Cannot destroy connection\n"); - print_error_from_canl(my_ctx); - } - my_new_io_h = NULL; - } + print_error_from_canl(my_ctx); if (my_io_h) { err = canl_io_close(my_ctx, my_io_h); diff --git a/emi.canl.canl-c/src/canl_ssl.c b/emi.canl.canl-c/src/canl_ssl.c index bd8e6ca..0ae8d3a 100644 --- a/emi.canl.canl-c/src/canl_ssl.c +++ b/emi.canl.canl-c/src/canl_ssl.c @@ -9,19 +9,14 @@ static int do_ssl_accept( glb_ctx *cc, io_handler *io, struct timeval *timeout); #ifdef DEBUG static void dbg_print_ssl_error(int errorcode); #endif -int ssl_server_init(glb_ctx *cc, io_handler *io) +int ssl_server_init(glb_ctx *cc) { int err = 0; unsigned long ssl_err = 0; CANL_ERROR_ORIGIN e_orig = unknown_error; if (!cc) { - return EINVAL; - } - if (!io) { - err = EINVAL; - e_orig = posix_error; - goto end; + return EINVAL; } SSL_library_init(); @@ -224,7 +219,7 @@ end: return err; } -int ssl_accept(glb_ctx *cc, io_handler *io, io_handler *new_io, +int ssl_accept(glb_ctx *cc, io_handler *io, struct timeval *timeout) { int err = 0, flags; @@ -237,18 +232,18 @@ int ssl_accept(glb_ctx *cc, io_handler *io, io_handler *new_io, goto end; } - flags = fcntl(new_io->sock, F_GETFL, 0); - (void)fcntl(new_io->sock, F_SETFL, flags | O_NONBLOCK); + flags = fcntl(io->sock, F_GETFL, 0); + (void)fcntl(io->sock, F_SETFL, flags | O_NONBLOCK); - new_io->s_ctx->bio_conn = BIO_new_socket(new_io->sock, BIO_NOCLOSE); - (void)BIO_set_nbio(new_io->s_ctx->bio_conn,1); + io->s_ctx->bio_conn = BIO_new_socket(io->sock, BIO_NOCLOSE); + (void)BIO_set_nbio(io->s_ctx->bio_conn,1); - new_io->s_ctx->ssl_io = SSL_new(cc->ssl_ctx); + io->s_ctx->ssl_io = SSL_new(cc->ssl_ctx); //setup_SSL_proxy_handler(cc->ssl_ctx, cacertdir); - SSL_set_bio(new_io->s_ctx->ssl_io, new_io->s_ctx->bio_conn, - new_io->s_ctx->bio_conn); + SSL_set_bio(io->s_ctx->ssl_io, io->s_ctx->bio_conn, + io->s_ctx->bio_conn); - err = do_ssl_accept(cc, new_io, timeout); + err = do_ssl_accept(cc, io, timeout); if (err) { goto end; } -- 1.8.2.3