From df2f80a3c37e1a13d0187fc31f794ef9504b3d99 Mon Sep 17 00:00:00 2001 From: Marcel Poul Date: Thu, 10 Nov 2011 12:32:12 +0000 Subject: [PATCH] simple tcp connection(wo ssl); client side at the moment --- emi.canl.canl-c/src/canl.c | 113 +++++++++++++++++++++++++------ emi.canl.canl-c/src/canl_dns.c | 5 +- emi.canl.canl-c/src/canl_err.c | 1 + emi.canl.canl-c/src/canl_locl.h | 20 ++++-- emi.canl.canl-c/src/canl_sample_client.c | 15 ++-- emi.canl.canl-c/src/canl_sample_server.c | 2 +- 6 files changed, 119 insertions(+), 37 deletions(-) diff --git a/emi.canl.canl-c/src/canl.c b/emi.canl.canl-c/src/canl.c index 02db50c..009db72 100644 --- a/emi.canl.canl-c/src/canl.c +++ b/emi.canl.canl-c/src/canl.c @@ -1,7 +1,13 @@ #include #include +#include +#include #include "canl.h" #include "canl_locl.h" +#include "sys/socket.h" +#include "string.h" + +static void io_clean(canl_ctx cc, canl_io_handler io); canl_ctx canl_create_ctx() { @@ -24,9 +30,9 @@ canl_ctx canl_create_ctx() */ /*initial values ...*/ - ctx->io_ctx = NULL; ctx->err_msg = NULL; ctx->err_code = no_error; + ctx->opened_ios = 0; end: if (err) @@ -45,10 +51,6 @@ void canl_free_ctx(canl_ctx cc) /*delete content*/ - if (ctx->io_ctx) { - canl_io_destroy(ctx, ctx->io_ctx); - ctx->io_ctx = NULL; - } if (ctx->err_msg) { free(ctx->err_msg); @@ -78,6 +80,9 @@ canl_io_handler canl_create_io_handler(canl_ctx cc) goto end; /*read cc and set io_handler accordingly ...*/ + new_io_h->ar = NULL; + new_io_h->s_addr = NULL; + new_io_h->sock = -1; end: return new_io_h; @@ -86,9 +91,11 @@ end: int canl_io_connect(canl_ctx cc, canl_io_handler io, char * host, int port, int flags, cred_handler ch, struct timeval *timeout) { - int err; + int err = 0; io_handler *io_cc = (io_handler*) io; glb_ctx *glb_cc = (glb_ctx*) cc; + int sock; + struct sockaddr_in *sa_in = NULL; /*check cc and io*/ if (!cc) { @@ -97,17 +104,49 @@ int canl_io_connect(canl_ctx cc, canl_io_handler io, char * host, int port, } if (!io) { - //set_error(ctx->err_msg); err = 1; goto end; } + if (io_cc->ar) { + free (io_cc->ar); + io_cc->ar = NULL; + } + io_cc->ar = (asyn_result *) malloc(sizeof(*(io_cc->ar))); + if (!io_cc->ar) { + err = 1; + goto end; + } + io_cc->ar->ent = (struct hostent *) calloc (1, sizeof(struct hostent)); + if (!io_cc->ar->ent) { + err=1; + goto end; + } - /*dns*/ - //err = dns_resolve(&ret_addr, ipver, host, port, timeout); - - /*open socket*/ - - /*call openssl to make a secured connection, optional?*/ + /*dns TODO - wrap it for using ipv6 and ipv4 at the same time*/ + err = asyn_getservbyname(AF_INET, io_cc->ar, host, NULL); + if (err) + goto end; + + io_cc->s_addr = (struct sockaddr *) malloc(sizeof(struct sockaddr)); + if (!io_cc->s_addr) { + err = 1; + goto end; + } + sa_in = (struct sockaddr_in *) io_cc->s_addr; + + + /*open socket TODO just for testing purpose*/ + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock != -1) + io_cc->sock = sock; + + sa_in->sin_family = AF_INET; + sa_in->sin_port = htons(port); + //TODO loop through h_addr_list + memcpy(&sa_in->sin_addr.s_addr, io_cc->ar->ent->h_addr, sizeof(struct in_addr)); + err = connect(io_cc->sock, (struct sockaddr*) sa_in, sizeof(*sa_in)); + + /*call openssl */ /*write succes or failure to cc, io*/ //if (err) @@ -115,6 +154,9 @@ int canl_io_connect(canl_ctx cc, canl_io_handler io, char * host, int port, //else /*cc or io set succes*/ end: + if (err) { + io_clean(cc, io); + } return err; } @@ -153,6 +195,7 @@ end: return err; } +//TODO improve /* close connection, preserve some info for the future reuse */ int canl_io_close(canl_ctx cc, canl_io_handler io) { @@ -176,10 +219,35 @@ int canl_io_close(canl_ctx cc, canl_io_handler io) end: return err; } +static void io_clean(canl_ctx cc, canl_io_handler io) +{ + io_handler *io_cc = (io_handler*) io; + /*check cc and io*/ + if (!cc) { + return; + } + + if (!io) { + //set_error(ctx->err_msg); + return; + } + + // delete io_handle content + if (io_cc->ar) { + free_hostent(io_cc->ar->ent); + io_cc->ar->ent = NULL; + io_cc->ar = NULL; + } + if (io_cc->s_addr) { + free (io_cc->s_addr); + io_cc->s_addr = NULL; + } +} int canl_io_destroy(canl_ctx cc, canl_io_handler io) { int err = 0; + io_handler *io_cc = (io_handler*) io; /*check cc and io*/ if (!cc) { err = 1; @@ -189,13 +257,13 @@ int canl_io_destroy(canl_ctx cc, canl_io_handler io) if (!io) { //set_error(ctx->err_msg); err = 1; + goto end; } - // delete io_handle content - + io_clean(cc, io); // delete io itself - if (io) { - free (io); + if (io_cc) { + free (io_cc); io = NULL; } end: @@ -204,6 +272,7 @@ end: size_t canl_io_read(canl_ctx cc, canl_io_handler io, void *buffer, size_t size, struct timeval *timeout) { + io_handler *io_cc = (io_handler*) io; int err = 0; if (!cc) { err = 1; @@ -216,15 +285,16 @@ size_t canl_io_read(canl_ctx cc, canl_io_handler io, void *buffer, size_t size, goto end; } - //read something using openssl - + //TODO testing: read something without using openssl + err = recv(io_cc->sock, buffer, size, 0); end: return err; } size_t canl_io_write(canl_ctx cc, canl_io_handler io, void *buffer, size_t size, struct timeval *timeout) { - int err; + io_handler *io_cc = (io_handler*) io; + int err = 0; if (!cc) { err = 1; goto end; @@ -236,7 +306,8 @@ size_t canl_io_write(canl_ctx cc, canl_io_handler io, void *buffer, size_t size, goto end; } - //write sometring using openssl + //TODO testing: read something without using openssl + err = send(io_cc->sock, "Hello, world!", 13, 0); end: return err; diff --git a/emi.canl.canl-c/src/canl_dns.c b/emi.canl.canl-c/src/canl_dns.c index 84a47d0..28c683d 100644 --- a/emi.canl.canl-c/src/canl_dns.c +++ b/emi.canl.canl-c/src/canl_dns.c @@ -1,13 +1,10 @@ -#include #include -#include #include #include #include #include #include "canl_locl.h" -static void free_hostent(struct hostent *h); static int decrement_timeout(struct timeval *timeout, struct timeval before, struct timeval after); //#if ARES_VERSION >= 0x010500 @@ -80,7 +77,7 @@ static int decrement_timeout(struct timeval *timeout, struct timeval before, str } -static void free_hostent(struct hostent *h) +void free_hostent(struct hostent *h) { int i; diff --git a/emi.canl.canl-c/src/canl_err.c b/emi.canl.canl-c/src/canl_err.c index 157c2ca..29cd7fd 100644 --- a/emi.canl.canl-c/src/canl_err.c +++ b/emi.canl.canl-c/src/canl_err.c @@ -1,3 +1,4 @@ +#define _GNU_SOURCE //vasprintf #include #include #include diff --git a/emi.canl.canl-c/src/canl_locl.h b/emi.canl.canl-c/src/canl_locl.h index 53ec1be..4d5e9a4 100644 --- a/emi.canl.canl-c/src/canl_locl.h +++ b/emi.canl.canl-c/src/canl_locl.h @@ -1,11 +1,13 @@ #ifndef CANL_LOCL_H #define CANL_LOCL_H #include "canl_err.h" +#include +#include +#include typedef struct _glb_ctx { int opened_ios; - struct io_handler * io_ctx; char * err_msg; CANL_ERROR err_code; } glb_ctx; @@ -17,17 +19,23 @@ typedef struct _glb_ctx SSL ssl_conn_ctx; } */ -typedef struct _io_handler -{ - int something; -} io_handler; - typedef struct _asyn_result { struct hostent *ent; int err; } asyn_result; + +typedef struct _io_handler +{ + asyn_result *ar; + struct sockaddr *s_addr; + int sock; +} io_handler; + #endif void reset_error (glb_ctx *cc, CANL_ERROR err_code); void set_error (glb_ctx *cc, CANL_ERROR err_code, const char *err_format, ...); void update_error (glb_ctx *cc, CANL_ERROR err_code, const char *err_format, ...); +void free_hostent(struct hostent *h); //TODO is there some standard funcion to free hostent? +int asyn_getservbyname(int a_family, asyn_result *ares_result,char const *name, + struct timeval *timeout); diff --git a/emi.canl.canl-c/src/canl_sample_client.c b/emi.canl.canl-c/src/canl_sample_client.c index 081a663..349569e 100644 --- a/emi.canl.canl-c/src/canl_sample_client.c +++ b/emi.canl.canl-c/src/canl_sample_client.c @@ -1,12 +1,15 @@ #include #include "canl.h" +#define BUF_LEN 1000 + int main() { canl_ctx my_ctx; canl_io_handler my_io_h; int err = 0; char *err_msg = NULL; + char buf[BUF_LEN]; my_ctx = canl_create_ctx(); if (!my_ctx){ @@ -20,9 +23,9 @@ int main() goto end; } - err = canl_io_connect(my_ctx, my_io_h, NULL, 1234, 0, NULL, NULL); + err = canl_io_connect(my_ctx, my_io_h, "www.seznam.cz", 80, 0, NULL, NULL); if (err) { - //set_error("cannot make a connection"); + printf("connection cannot be established\n"); goto end; } @@ -31,9 +34,10 @@ int main() //set_error ("cannot write"); } - err = canl_io_read (my_ctx, my_io_h, NULL, 0, NULL); - if (err) { - //set_error ("cannot read"); + err = canl_io_read (my_ctx, my_io_h, buf, sizeof(buf)-1, NULL); + if (err > 0) { + buf[err] = '\0'; + printf ("received: %s\n", buf); } err = canl_io_close(my_ctx, my_io_h); @@ -45,6 +49,7 @@ int main() if (err){ //set_error ("cannot destroy io"); } + my_io_h = NULL; end: canl_get_error(my_ctx, &err_msg); diff --git a/emi.canl.canl-c/src/canl_sample_server.c b/emi.canl.canl-c/src/canl_sample_server.c index 3a4aec6..6f1f88d 100644 --- a/emi.canl.canl-c/src/canl_sample_server.c +++ b/emi.canl.canl-c/src/canl_sample_server.c @@ -26,7 +26,7 @@ int main() goto end; } - err = canl_io_connect(my_ctx, my_io_h, NULL, 1234, 0, NULL, NULL); + err = canl_io_connect(my_ctx, my_io_h, "", 1234, 0, NULL, NULL); if (err) { //set_error("cannot make a connection"); canl_io_destroy(my_ctx, my_io_h); -- 1.8.2.3