}
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*/
}
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);
{
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;
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*/
}
/*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;
end:
if (err)
- (*io_new_cc)->sock = 0;
+ (io_cc)->sock = 0;
return err;
}
#ifndef _CANL_H
#define _CANL_H
#include <sys/time.h>
+#include "sys/socket.h"
typedef void *canl_io_handler;
typedef void *canl_ctx;
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);
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);
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
+#include <netdb.h>
+#include <errno.h>
#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[])
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);
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);
}
}
}
}
+ /* 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));
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));
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);
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);
#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();
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;
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;
}