#include <stdio.h>
#include <stdlib.h>
+#include <sys/types.h>
+#include <arpa/inet.h>
#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()
{
*/
/*initial values ...*/
- ctx->io_ctx = NULL;
ctx->err_msg = NULL;
ctx->err_code = no_error;
+ ctx->opened_ios = 0;
end:
if (err)
/*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);
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;
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) {
}
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)
//else
/*cc or io set succes*/
end:
+ if (err) {
+ io_clean(cc, io);
+ }
return err;
}
return err;
}
+//TODO improve
/* close connection, preserve some info for the future reuse */
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;
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:
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;
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;
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;
#ifndef CANL_LOCL_H
#define CANL_LOCL_H
#include "canl_err.h"
+#include <ares.h>
+#include <ares_version.h>
+#include <netdb.h>
typedef struct _glb_ctx
{
int opened_ios;
- struct io_handler * io_ctx;
char * err_msg;
CANL_ERROR err_code;
} 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);
#include <stdio.h>
#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){
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;
}
//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);
if (err){
//set_error ("cannot destroy io");
}
+ my_io_h = NULL;
end:
canl_get_error(my_ctx, &err_msg);