#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; } 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]; 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); connections_destroy(ssys); sntl_finalize(); return 0; }