|
|
|
@ -14,12 +14,19 @@
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#include <sys/time.h>
|
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
#include <sys/select.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <netdb.h>
|
|
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
#include <Winsock2.h>
|
|
|
|
|
#define EBADE 1
|
|
|
|
|
#define NETDB_SUCCESS 0
|
|
|
|
|
#else
|
|
|
|
|
#include <sys/select.h>
|
|
|
|
|
#include <netdb.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <uuid/uuid.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include <openssl/ssl.h>
|
|
|
|
|
#include <openssl/err.h>
|
|
|
|
|
|
|
|
|
@ -475,8 +482,10 @@ static int __default_ch_set_types(void *cctx, sexp_t *sx)
|
|
|
|
|
r = ESXRCBADPROT;
|
|
|
|
|
goto __send_reply;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* take length of the list */
|
|
|
|
|
llen = sexp_list_length(lsx);
|
|
|
|
|
|
|
|
|
|
if(!llen) return 0; /* other side will not set any security attributes */
|
|
|
|
|
SEXP_ITERATE_LIST(lsx, sx_iter, idx) {
|
|
|
|
|
if(SEXP_IS_LIST(sx_iter)) {
|
|
|
|
@ -514,12 +523,12 @@ static int __default_ch_set_types(void *cctx, sexp_t *sx)
|
|
|
|
|
|
|
|
|
|
__send_reply:
|
|
|
|
|
snprintf(buf, 1024, "(ch-gl-error (%d))", r);
|
|
|
|
|
|
|
|
|
|
if(__conn_write(co, buf, strlen(buf)) < 0) {
|
|
|
|
|
co->flags &= ~CXCONN_ESTABL;
|
|
|
|
|
co->flags |= CXCONN_BROKEN;
|
|
|
|
|
__wake_up_waiters(co, ESXNOCONNECT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
destroy_sexp(sx);
|
|
|
|
|
|
|
|
|
|
return r;
|
|
|
|
@ -1390,14 +1399,17 @@ static int __eval_cstr(char *cstr, cx_rpc_list_t *rpc_list, void *ctx)
|
|
|
|
|
char *rpcf;
|
|
|
|
|
|
|
|
|
|
if(!(sx = parse_sexp(cstr, strlen(cstr)))) return EBADE;
|
|
|
|
|
|
|
|
|
|
if(sx->ty == SEXP_LIST)
|
|
|
|
|
rpcf = sx->list->val;
|
|
|
|
|
else rpcf = sx->val;
|
|
|
|
|
|
|
|
|
|
/* find an appropriate function */
|
|
|
|
|
node = usrtc_lookup(rpc_list->rpc_tree, rpcf);
|
|
|
|
|
|
|
|
|
|
if(!node) return ENOENT;
|
|
|
|
|
else rentry = (cx_rpc_t *)usrtc_node_getdata(node);
|
|
|
|
|
|
|
|
|
|
/* call it */
|
|
|
|
|
r = rentry->rpcf(ctx, sx);
|
|
|
|
|
|
|
|
|
@ -1895,6 +1907,10 @@ int connection_initiate(conn_t *co, const char *host, int port,
|
|
|
|
|
char *buf = NULL;
|
|
|
|
|
struct hostent *host_;
|
|
|
|
|
struct sockaddr_in addr;
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
WSADATA wsaData;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
usrtc_t *ch_tree, *rpc_tree;
|
|
|
|
|
pth_queue_t *mqueue = malloc(sizeof(pth_queue_t));
|
|
|
|
|
pth_queue_t *rqueue = malloc(sizeof(pth_queue_t));
|
|
|
|
@ -1911,6 +1927,11 @@ int connection_initiate(conn_t *co, const char *host, int port,
|
|
|
|
|
if(idx_ch) free(idx_ch);
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
WSAStartup(MAKEWORD(2, 2), &wsaData);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if(!tpoll) goto __fallenomem;
|
|
|
|
|
if(!idx_ch) goto __fallenomem;
|
|
|
|
|
|
|
|
|
@ -1931,15 +1952,20 @@ int connection_initiate(conn_t *co, const char *host, int port,
|
|
|
|
|
else r = idx_allocator_init(idx_ch, MAX_CHANNELS*MAX_MULTI, 0);
|
|
|
|
|
if(r) return r;
|
|
|
|
|
|
|
|
|
|
if(!(uuid = __generate_uuid())) return ENOMEM;
|
|
|
|
|
if(!(uuid = __generate_uuid())) {
|
|
|
|
|
return ENOMEM;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!(ch_tree = malloc(sizeof(usrtc_t)))) {
|
|
|
|
|
r = ENOMEM;
|
|
|
|
|
goto __fail;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!(rpc_tree = malloc(sizeof(usrtc_t)))) {
|
|
|
|
|
r = ENOMEM;
|
|
|
|
|
goto __fail_1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if((r = pthread_mutex_init(&co->oplock, NULL))) goto __fail_2;
|
|
|
|
|
if((r = pthread_rwlock_init(&co->chnl_lock, NULL))) goto __fail_3;
|
|
|
|
|
|
|
|
|
@ -1974,11 +2000,13 @@ int connection_initiate(conn_t *co, const char *host, int port,
|
|
|
|
|
goto __fail_3;
|
|
|
|
|
}
|
|
|
|
|
/* set the private key from KeyFile (may be the same as CertFile) */
|
|
|
|
|
|
|
|
|
|
if(SSL_CTX_use_PrivateKey_file(co->ctx, SSL_cert,
|
|
|
|
|
SSL_FILETYPE_PEM)<=0) {
|
|
|
|
|
r = EINVAL;
|
|
|
|
|
goto __fail_3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* verify private key */
|
|
|
|
|
if (!SSL_CTX_check_private_key(co->ctx)) {
|
|
|
|
|
r = EINVAL;
|
|
|
|
@ -1996,20 +2024,28 @@ int connection_initiate(conn_t *co, const char *host, int port,
|
|
|
|
|
r = ENOMEM;
|
|
|
|
|
goto __fail_3;
|
|
|
|
|
}
|
|
|
|
|
if(__resolvehost(host, buf, __TMPBUFLEN, &host_) != NETDB_SUCCESS) {
|
|
|
|
|
|
|
|
|
|
//r=__resolvehost(host, buf, __TMPBUFLEN, &host_);
|
|
|
|
|
host_=gethostbyname(host);
|
|
|
|
|
|
|
|
|
|
if(errno) {
|
|
|
|
|
r = ENOENT;
|
|
|
|
|
free(buf);
|
|
|
|
|
goto __fail_3;
|
|
|
|
|
}
|
|
|
|
|
/* create a socket */
|
|
|
|
|
|
|
|
|
|
// /* create a socket */
|
|
|
|
|
sd = socket(PF_INET, SOCK_STREAM, 0);
|
|
|
|
|
bzero(&addr, sizeof(addr));
|
|
|
|
|
|
|
|
|
|
/* try to connect it */
|
|
|
|
|
addr.sin_family = AF_INET;
|
|
|
|
|
addr.sin_port = htons(port);
|
|
|
|
|
addr.sin_addr.s_addr = *(uint32_t*)(host_->h_addr);
|
|
|
|
|
free(host_);
|
|
|
|
|
if (connect(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0) {
|
|
|
|
|
r=connect(sd, (struct sockaddr*)&addr, sizeof(addr));
|
|
|
|
|
|
|
|
|
|
if ( r!= 0) {
|
|
|
|
|
printf("connect error %d %s \n",r, strerror(errno));
|
|
|
|
|
close(sd);
|
|
|
|
|
free(buf);
|
|
|
|
|
r = ENOENT; /* couldn't connect to the desired host */
|
|
|
|
@ -2032,20 +2068,23 @@ int connection_initiate(conn_t *co, const char *host, int port,
|
|
|
|
|
/* send an auth request */
|
|
|
|
|
SSL_write(co->ssl, buf, strlen(buf) + sizeof(char));
|
|
|
|
|
/* read the message reply */
|
|
|
|
|
|
|
|
|
|
bytes = __conn_read(co, buf, __TMPBUFLEN);
|
|
|
|
|
if(bytes == -1) {
|
|
|
|
|
// we've lost the connection
|
|
|
|
|
co->flags &= ~CXCONN_ESTABL;
|
|
|
|
|
r = ESXNOCONNECT;
|
|
|
|
|
co->flags |= CXCONN_BROKEN;
|
|
|
|
|
|
|
|
|
|
free(buf);
|
|
|
|
|
/* shutdown connection */
|
|
|
|
|
goto __fail_3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buf[bytes] = 0;
|
|
|
|
|
|
|
|
|
|
/* perform an rpc call */
|
|
|
|
|
r = __eval_cstr(buf, conn_sys->system_rpc, (void *)co);
|
|
|
|
|
|
|
|
|
|
if(!r) { /* all is fine security context is good */
|
|
|
|
|
snprintf(buf, __TMPBUFLEN, "(ch-get-types)"); /* now we should receive possible channel types */
|
|
|
|
|
SSL_write(co->ssl, buf, strlen(buf) + sizeof(char));
|
|
|
|
@ -2056,11 +2095,11 @@ int connection_initiate(conn_t *co, const char *host, int port,
|
|
|
|
|
co->flags &= ~CXCONN_ESTABL;
|
|
|
|
|
co->flags |= CXCONN_BROKEN;
|
|
|
|
|
r = ESXNOCONNECT;
|
|
|
|
|
|
|
|
|
|
free(buf);
|
|
|
|
|
/* shutdown connection */
|
|
|
|
|
goto __fail_3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buf[bytes] = 0;
|
|
|
|
|
/* perform an rpc call */
|
|
|
|
|
r = __eval_cstr(buf, conn_sys->system_rpc, (void *)co);
|
|
|
|
|