#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 DEBUG #define FREE(x) { if (x) { free(x); x = NULL; } } /* 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", (char *)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 msg_send(chnl_t *ch, const char *mmbuf, size_t buflen, sxmsg_t *msg, char **rs) { #ifdef DEBUG printf("%s: got sx '%s'\n", __FUNCTION__, mmbuf); #endif /* DEBUG */ int mr = sxmsg_send(ch, mmbuf, buflen, &msg); switch(mr) { case SNE_RAPIDMSG: if (rs) *rs = strdup((char *)sxmsg_payload(msg)); 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", (char *)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; } #ifdef DEBUG // printf("%s: got rs %d\n", __FUNCTION__, mr); #endif /* DEBUG */ return mr; } static pthread_mutex_t *lockarray; static void lock_callback(int mode, int type, char *file, int line) { (void)file; (void)line; if (mode & CRYPTO_LOCK) { pthread_mutex_lock(&(lockarray[type])); } else { pthread_mutex_unlock(&(lockarray[type])); } } static unsigned long thread_id(void) { unsigned long ret; ret=(unsigned long)pthread_self(); return(ret); } static void init_locks(void) { int i; lockarray=(pthread_mutex_t *)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); for (i=0; i] -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(); init_locks(); /* 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]; char *s_ret = NULL; sxmsg_t *msg = NULL; size_t ln; int mr, ee, stid; sexp_t *sx_ret = NULL; ln = snprintf(mmbuf, 1024, "(dir-open \".\")"); mr = msg_send(testchannel, mmbuf, ln, msg, &s_ret); if (mr != SNE_RAPIDMSG) goto __finish; sx_ret = parse_sexp(s_ret, strlen(s_ret)); FREE(s_ret); if (!sx_ret || !sx_ret->list || strcmp(sx_ret->list->val, "dir-stream") || !sx_ret->list->next || !sx_ret->list->next->val) goto __finish; stid = atoi(sx_ret->list->next->val); ln = snprintf(mmbuf, 1024, "(dir-read %d)", stid); while (1) { mr = msg_send(testchannel, mmbuf, ln, msg, &s_ret); if (mr != SNE_RAPIDMSG) goto __finish; sx_ret = parse_sexp(s_ret, strlen(s_ret)); if (!sx_ret || !sx_ret->list || !sx_ret->list->val) goto __finish; if (!strcmp(sx_ret->list->val, "dir-end")) { ln = snprintf(mmbuf, 1024, "(dir-close %d)", stid); mr = msg_send(testchannel, mmbuf, ln, msg, &s_ret); break; } #ifdef DEBUG printf("%s: '%s'\n", __FUNCTION__, s_ret); #endif /* DEBUG */ FREE(s_ret); } // 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", // (char *)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; // } __finish: 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); connection_close(co); return 0; }