|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
#include <pthread.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <getopt.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
#include <tdata/usrtc.h>
|
|
|
|
#include <sexpr/sexp.h>
|
|
|
|
#include <sntl/connection.h>
|
|
|
|
|
|
|
|
/* define a little bit */
|
|
|
|
#define DEFAULT_PORT 13133
|
|
|
|
#define CHANNEL_COUNT 1
|
|
|
|
#define CLIENT_COUNT 2
|
|
|
|
|
|
|
|
/*static*/ sexp_t *make_request(const char *req)
|
|
|
|
{
|
|
|
|
char *request = strdup(req);
|
|
|
|
sexp_t *sx = parse_sexp(request, strlen(request));
|
|
|
|
free(request);
|
|
|
|
return sx;
|
|
|
|
}
|
|
|
|
|
|
|
|
void *test_send_message(void *ch)
|
|
|
|
{
|
|
|
|
__DBGLINE;
|
|
|
|
chnl_t *chnl = (chnl_t *)ch;
|
|
|
|
char buf[1024];
|
|
|
|
int a = rand() % 100;
|
|
|
|
int b = rand() % 100;
|
|
|
|
sprintf(buf, "(ar-add (%d %d))", a, b);
|
|
|
|
sexp_t *add_request = make_request(buf);
|
|
|
|
sxmsg_t *msg = NULL;
|
|
|
|
int rc = 0;
|
|
|
|
clock_t start = clock();
|
|
|
|
rc = msg_send(chnl, add_request, &msg);
|
|
|
|
clock_t end = clock();
|
|
|
|
double time = (double)(end - start) / CLOCKS_PER_SEC;
|
|
|
|
printf("msg_send execution time: %lf. rc = %d\n", time, rc);
|
|
|
|
assert(rc == a + b);
|
|
|
|
destroy_sexp(add_request);
|
|
|
|
return 0x00;
|
|
|
|
}
|
|
|
|
|
|
|
|
void *test_channel(void *ctx)
|
|
|
|
{
|
|
|
|
conn_t *co = (conn_t *)ctx;
|
|
|
|
printf("Testing channel (%ld)\n", pthread_self());
|
|
|
|
chnl_t *channel = NULL;
|
|
|
|
int rc = 0;
|
|
|
|
rc = channel_open(co, &channel, 12);
|
|
|
|
if(rc) {
|
|
|
|
printf("Failed to open channel. rc=%d\n", rc);
|
|
|
|
}
|
|
|
|
assert(rc == 0);
|
|
|
|
|
|
|
|
// test message sending
|
|
|
|
int i;
|
|
|
|
pthread_t threads[CLIENT_COUNT];
|
|
|
|
for(i = 0; i < CLIENT_COUNT; ++i) {
|
|
|
|
if(pthread_create(&(threads[i]), NULL, test_send_message, channel)) {
|
|
|
|
fprintf(stderr, "Error creating thread\n");
|
|
|
|
return 0x00;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for(i = 0; i < CLIENT_COUNT; ++i) {
|
|
|
|
pthread_join(threads[i], NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
rc = channel_close(channel);
|
|
|
|
if(rc) {
|
|
|
|
printf("Failed to close channel. rc=%d\n", rc);
|
|
|
|
}
|
|
|
|
assert(rc == 0);
|
|
|
|
|
|
|
|
return 0x00;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*static*/ int start_testing(conn_t *co)
|
|
|
|
{
|
|
|
|
printf("---------------=========== Testing... ===========------------------\n");
|
|
|
|
int i;
|
|
|
|
pthread_t threads[CHANNEL_COUNT];
|
|
|
|
for(i = 0; i < CHANNEL_COUNT; ++i) {
|
|
|
|
if(pthread_create(&(threads[i]), NULL, test_channel, co)) {
|
|
|
|
fprintf(stderr, "Error creating thread\n");
|
|
|
|
return EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for(i = 0; i < CHANNEL_COUNT; ++i) {
|
|
|
|
pthread_join(threads[i], NULL);
|
|
|
|
}
|
|
|
|
printf("---------------=========== Testing end ===========------------------\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*static*/ int test_error_codes(conn_t *co)
|
|
|
|
{
|
|
|
|
printf("---------------=========== Error codes ===========------------------\n");
|
|
|
|
chnl_t *channel = NULL;
|
|
|
|
// there is no such channel on the server
|
|
|
|
assert(channel_open(co, &channel, 777) == EINVAL);
|
|
|
|
|
|
|
|
printf("---------------=========== Error codes end ===========------------------\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
|
|
|
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 <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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
|
|
|
assert(connection_initiate(co, addr, port, cert, ctx) == 0);
|
|
|
|
assert(start_testing(co) == 0);
|
|
|
|
assert(test_error_codes(co) == 0);
|
|
|
|
assert(connection_close(co) == 0);
|
|
|
|
|
|
|
|
free(rootca);
|
|
|
|
free(cert);
|
|
|
|
free(co);
|
|
|
|
free(ctx);
|
|
|
|
free(password);
|
|
|
|
free(login);
|
|
|
|
free(addr);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|