diff --git a/examples/sntlc.c b/examples/sntlc.c index ddf5a3a..fee1b35 100644 --- a/examples/sntlc.c +++ b/examples/sntlc.c @@ -1,6 +1,220 @@ #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* define a little bit */ +#define DEFAULT_PORT 13133 +#define INVALID_PORT 11111 +#define INVALID_ADDRESS "192.168.0.0" +#define ITERATION_COUNT 10 +#define THREADS_PER_MESSAGE_TYPE 10 + +typedef struct +{ + int type; + chnl_t *channel; + struct timespec *timeout; + sexp_t *sx; +} msg_data_t; + +/*static*/ sexp_t *make_request(const char *req) +{ + char *request = strdup(req); + sexp_t *sx = parse_sexp(request, strlen(request)); + free(request); + return sx; +} + +/*static*/ void *test_send_message(void *d) +{ + msg_data_t *data = (msg_data_t *)d; + int i = 0; + for(i = 0; i < ITERATION_COUNT; ++i) { + sxmsg_t *reply = NULL; + clock_t begin = clock(); + assert(msg_send(data->channel, data->sx, &reply) == 0); + clock_t end = clock(); + double time_spent = (double)(end - begin) / CLOCKS_PER_SEC; + printf("msg_send execution time: %f seconds.\n", time_spent); + } + return NULL; +} + +/*static*/ int test_messages(chnl_t *ch) +{ + int i = 0; + msg_data_t msg_data; + msg_data.channel = ch; + msg_data.sx = make_request("(ar_add (1 2 3 4 5))"); + pthread_t threads[THREADS_PER_MESSAGE_TYPE]; + for(i = 0; i < THREADS_PER_MESSAGE_TYPE; ++i) { + if(pthread_create(&(threads[i]), NULL, test_send_message, &msg_data)) { + fprintf(stderr, "Error creating thread\n"); + return EINVAL; + } + printf("created a new thread\n"); + } + for(i = 0; i < THREADS_PER_MESSAGE_TYPE; ++i) { + pthread_join(threads[i], NULL); + } + destroy_sexp(msg_data.sx); + return 0; +} int main(int argc, char **argv) { -return 0; + char *rootca = NULL, *cert = NULL; + int port = DEFAULT_PORT; + char *addr = NULL, *login = NULL, *password = NULL; + int opt; + while((opt = getopt(argc, argv, "p:r:a:u:l:w:")) != -1) { + switch(opt) { + case 'p': + port = atoi(optarg); + break; + case 'r': + rootca = strdup(optarg); + break; + case 'a': + addr = strdup(optarg); + break; + case 'u': + cert = strdup(optarg); + break; + case 'l': + login = strdup(optarg); + break; + case 'w': + password = strdup(optarg); + break; + default: + fprintf(stderr, "usage: %s [-p ] -r -a -u -l -w \n", argv[0]); + return EINVAL; + } + } + + if(!rootca) { + fprintf(stderr, "Root CA not pointed.\n Failure.\n"); + return EINVAL; + } + + if(!addr) { + fprintf(stderr, "Server address not pointed.\n Failure.\n"); + return EINVAL; + } + + if(!cert) { + fprintf(stderr, "User certificate not pointed.\n Failure.\n"); + return EINVAL; + } + + if(!login) { + fprintf(stderr, "User login not pointed.\n Failure.\n"); + return EINVAL; + } + + if(!password) { + fprintf(stderr, "User password not pointed.\n Failure.\n"); + return EINVAL; + } + + /* all is fine let's init connection subsystem */ + opt = connections_subsystem_init(); + if(opt) { + fprintf(stderr, "Subsystem init failed: %d\n", opt); + return opt; + } + /* set working certificates */ + opt = connections_subsystem_setsslserts(rootca, cert, cert); + if(opt) { + fprintf(stderr, "Subsystem init failed (set SSL x.509 pems): %d\n", opt); + return opt; + } + + /* Tests */ + /* try to open connection */ + conn_t *co = malloc(sizeof(conn_t)); + perm_ctx_t *ctx = (perm_ctx_t *)malloc(sizeof(perm_ctx_t)); + ctx->login = login; + ctx->passwd = password; + + int rc = 0; + assert((rc = connection_initiate(co, addr, port, cert, ctx)) == 0); + if(rc) { + fprintf(stderr, "Failed to initiate connection\n"); + goto __failed; + } + + chnl_t *channel = NULL; + //assert(channel_open(co, &channel, 13) == EINVAL); + assert((rc = channel_open(co, &channel, 12)) == 0); + if(rc) { + fprintf(stderr, "Failed to open channel\n"); + goto __failed; + } + sexp_t *sx = make_request("(ar_add (1 2 3 4 5))"); + sxmsg_t *msg = NULL; + + printf("------======== DEBUG ========------\n"); + printf("channel pointer: %p\n", channel); + printf("sx pointer: %p\n", sx); + char b[1024]; + print_sexp(b, 1024, sx); + printf("sx: %s\n", b); + printf("channel->connection pointer: %p\n", channel->connection); + printf("channel id: %ld - %s\n", channel->cid, channel->uuid); + printf("------======== DEBUG END ========------\n"); + rc = msg_send(channel, sx, &msg); + destroy_sexp(sx); + //assert(test_messages(channel) == 0); + + assert((rc = channel_close(co)) == 0); + if(rc) { + fprintf(stderr, "Failed to close channel\n"); + goto __failed; + } + + assert((rc = connection_close(co)) == 0); + if(rc) { + fprintf(stderr, "Failed to close connection\n"); + goto __failed; + } + + free(rootca); + free(cert); + free(co); + free(ctx); + free(password); + free(login); + free(addr); + + return 0; + +__failed: + fprintf(stderr, "Failed with rc=%d", rc); + if(rootca) free(rootca); + if(cert) free(cert); + if(co) free(co); + if(ctx) free(ctx); + if(password) free(password); + if(login) free(login); + if(addr) free(addr); + + return -1; } diff --git a/examples/sntld.c b/examples/sntld.c index 998981e..40ab1c2 100644 --- a/examples/sntld.c +++ b/examples/sntld.c @@ -75,11 +75,46 @@ usrtc_t *__rettlist(conn_t *c) /* RPC functions implementation */ static int __ar_add(void *data, sexp_t *sx) { + sexp_t *lsx = NULL; + int idx; + sexp_t *sx_iter; + if(sexp_list_cdr(sx, &lsx)) { + printf("Invalid protocol\n"); + return EINVAL; + } + + long int sum = 0; + SEXP_ITERATE_LIST(lsx, sx_iter, idx) { + if(!SEXP_IS_TYPE(sx_iter, SEXP_BASIC)) { + printf("Invalid value type\n"); + return EINVAL; + } + sum += atoi(sx->val); + } + printf("Result = %ld\n", sum); + return 0; } static int __ar_multiply(void *data, sexp_t *sx) { + sexp_t *lsx = NULL; + int idx; + sexp_t *sx_iter; + if(sexp_list_cdr(sx, &lsx)) { + printf("Invalid protocol\n"); + return EINVAL; + } + + long int mult = 0; + SEXP_ITERATE_LIST(lsx, sx_iter, idx) { + if(!SEXP_IS_TYPE(sx_iter, SEXP_BASIC)) { + printf("Invalid value type\n"); + return EINVAL; + } + mult *= atoi(sx->val); + } + printf("Result = %ld\n", mult); return 0; }