#include #define __USE_GNU #include #include #include #include #include #include #include #include #include #ifdef WIN32 #include #include #else #include #include #include #include #include #include #include #include #include #endif #include #include #include #include /* define a little bit */ #define DEFAULT_PORT 13133 #define CHANNEL_COUNT 200 #define CLIENT_COUNT 256 #define MESSAGES_PER_SESSION 10000 #define ITERATION_COUNT 1000 #define FAILS_ONLY struct testdata { int uc; pthread_mutex_t ulock; conn_t *co; }; static int __init_testdata(struct testdata *t, conn_t *co) { t->uc = 0; pthread_mutex_init(&t->ulock, NULL); t->co = co; return 0; } static void __wait_completion(struct testdata *t) { pthread_mutex_lock(&t->ulock); if(t->uc) { pthread_mutex_lock(&t->ulock); } return; } static int __set_typed_list_callback(conn_t *co, int ch, char *desc) { printf("allowed channel %d (%s)\n", ch, desc); return SNE_SUCCESS; } static void *__addsthrd(void *a) { struct testdata *t = a; conn_t *co = t->co; chnl_t *mch; sxmsg_t *msg; char mmbuf[1024]; size_t ln; int mr, i; pthread_mutex_lock(&t->ulock); t->uc++; pthread_mutex_unlock(&t->ulock); /* here we go */ mch = sxchannel_open(co, 12); if(!mch) { fprintf(stderr, "Failed to openchannel with %d\n", errno); goto __fini; } for(i = 0; i < MESSAGES_PER_SESSION; i++) { ln = snprintf(mmbuf, 1024, "(ar-add (10 10))"); mr = sxmsg_send(mch, mmbuf, ln, &msg); switch(mr) { case SNE_RAPIDMSG: //fprintf(stdout, "Rapidly replied: %s\n", (char *)sxmsg_payload(msg)); sxmsg_clean(msg); break; case SNE_REPLYREQ: if(sxmsg_datalen(msg)) fprintf(stdout, "Replied (confirmation required): %s\n", sxmsg_payload(msg)); mr = sxmsg_return(msg, SNE_SUCCESS); fprintf(stderr, "mr = %d\n", mr); break; case SNE_SUCCESS: fprintf(stdout, "Success.\n"); break; default: fprintf(stderr, "ERROR: %d\n", mr); break; } } sxchannel_close(mch); __fini: t->uc--; if(t->uc <= 1) pthread_mutex_unlock(&t->ulock); return NULL; } int main(int argc, char **argv) { char *rootca = NULL, *cert = NULL; int port = DEFAULT_PORT; char *addr = NULL, *login = NULL, *password = NULL; int opt; conn_sys_t *ssys; conn_t *co; 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; } sntl_init(); /* all is fine let's init connection subsystem */ ssys = connections_create(); if(!ssys) { fprintf(stderr, "Subsystem init failed: %d\n", errno); return errno; } /* set working certificates */ opt = connections_setsslserts(ssys, rootca, cert, cert); if(opt) { fprintf(stderr, "Subsystem init failed (set SSL x.509 pems): %d\n", opt); return opt; } /* Tests */ struct timeval beg, end; /* try to open connection */ connections_set_channelcall(ssys, __set_typed_list_callback); gettimeofday(&beg, NULL); co = connection_link(ssys, addr, port, cert, login, password); if(!co) { fprintf(stderr, "Failed to connection with %d\n", errno); return errno; } gettimeofday(&end, NULL); if((end.tv_sec - beg.tv_sec) > 0) { printf("Seconds: %ld ", end.tv_sec - beg.tv_sec); printf("µS: %ld\n", end.tv_usec + (1000000 - beg.tv_usec)); } else printf("µS: %ld\n", end.tv_usec - beg.tv_usec); /* ok now we should open a channel */ chnl_t *testchannel = sxchannel_open(co, 12); if(!testchannel) { fprintf(stderr, "Failed to openchannel with %d\n", errno); return errno; } gettimeofday(&end, NULL); if((end.tv_sec - beg.tv_sec) > 0) { printf("Seconds: %ld ", end.tv_sec - beg.tv_sec); printf("µS: %ld\n", end.tv_usec + (1000000 - beg.tv_usec)); } else printf("µS: %ld\n", end.tv_usec - beg.tv_usec); /* ok, send a message */ char mmbuf[1024]; sxmsg_t *msg; size_t ln; ln = snprintf(mmbuf, 1024, "(ar-add (10 10))"); int mr = sxmsg_send(testchannel, mmbuf, ln, &msg); switch(mr) { case SNE_RAPIDMSG: fprintf(stdout, "Rapidly replied: %s\n", (char *)sxmsg_payload(msg)); sxmsg_clean(msg); break; case SNE_REPLYREQ: if(sxmsg_datalen(msg)) fprintf(stdout, "Replied (confirmation required): %s\n", sxmsg_payload(msg)); mr = sxmsg_return(msg, SNE_SUCCESS); fprintf(stderr, "mr = %d\n", mr); break; case SNE_SUCCESS: fprintf(stdout, "Success.\n"); break; default: fprintf(stderr, "ERROR: %d\n", mr); break; } int ee = sxchannel_close(testchannel); printf("ee = %d\n", ee); gettimeofday(&end, NULL); if((end.tv_sec - beg.tv_sec) > 0) { printf("Seconds: %ld ", end.tv_sec - beg.tv_sec); printf("µS: %ld\n", end.tv_usec + (1000000 - beg.tv_usec)); } else printf("µS: %ld\n", end.tv_usec - beg.tv_usec); sleep(10); /* ok, now we need to create many threads */ struct testdata trd; pthread_t thrd; int i; __init_testdata(&trd, co); for(i = 0; i < 256; i++) pthread_create(&thrd, NULL, __addsthrd, &trd); __wait_completion(&trd); return 0; }