You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
353 lines
8.4 KiB
C
353 lines
8.4 KiB
C
#include <stdio.h>
|
|
#define __USE_GNU
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
#include <sys/types.h>
|
|
|
|
#include <pthread.h>
|
|
#include <stdint.h>
|
|
#include <getopt.h>
|
|
#include <errno.h>
|
|
#include <assert.h>
|
|
#include <time.h>
|
|
|
|
#ifdef WIN32
|
|
#include <Winsock2.h>
|
|
#include <signal.h>
|
|
#else
|
|
#include <sys/select.h>
|
|
#include <sys/wait.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/resource.h>
|
|
#include <netdb.h>
|
|
#include <unistd.h>
|
|
#include <uuid/uuid.h>
|
|
#include <execinfo.h>
|
|
#include <netinet/in.h>
|
|
#endif
|
|
|
|
#include <tdata/usrtc.h>
|
|
#include <sexpr/sexp.h>
|
|
#include <sntl/sntllv2.h>
|
|
#include <sntl/limits.h>
|
|
|
|
#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 <PORTNUM>] -r <PATH to Root CA> -a <Server ip address> -u <PATH"
|
|
" to SSL certificate> -l <User login> -w <User password>\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;
|
|
}
|