diff options
| author | Anton <anton@picapica> | 2018-12-14 22:41:27 +0400 |
|---|---|---|
| committer | Anton <anton@picapica> | 2018-12-14 22:41:27 +0400 |
| commit | 0b6656e30c83a328e2b70c0802584e98b1da0a40 (patch) | |
| tree | 44000a140f54a26310eb95b3ee24741f40df9955 | |
| parent | 240d089596ff9727ba257e539b88584d6fa6a9f9 (diff) | |
| download | pica-pica-0b6656e30c83a328e2b70c0802584e98b1da0a40.tar.gz pica-pica-0b6656e30c83a328e2b70c0802584e98b1da0a40.zip | |
pica-node: implemented anon DH TLS connection stage, reworked newconns
| -rw-r--r-- | PICA_node.c | 523 | ||||
| -rw-r--r-- | PICA_node.h | 58 | ||||
| -rw-r--r-- | PICA_nodewait.c | 20 | ||||
| -rw-r--r-- | PICA_security.h | 1 |
4 files changed, 481 insertions, 121 deletions
diff --git a/PICA_node.c b/PICA_node.c index 04a5c9c..0113bab 100644 --- a/PICA_node.c +++ b/PICA_node.c @@ -61,7 +61,8 @@ char *my_addr;//TEMP CONF FIXME SOCKET listen_comm_sck;//* -SSL_CTX* ctx; +SSL_CTX *ctx; +SSL_CTX *anon_ctx; struct newconn newconns[MAX_NEWCONNS]; unsigned int newconns_pos = 0; @@ -80,9 +81,8 @@ struct nodelink *nodelink_list_end; unsigned int nodelink_list_count; - -char msg_VERDIFFER[4] = {PICA_PROTO_VERDIFFER, PICA_PROTO_VERDIFFER, PICA_PROTO_VER_HIGH, PICA_PROTO_VER_LOW}; -const unsigned int msg_VERDIFFER_len = 4; +const char msg_INITRESPOK[] = {PICA_PROTO_INITRESPOK, PICA_PROTO_INITRESPOK, 'O', 'K'}; +const char msg_VERDIFFER[] = {PICA_PROTO_VERDIFFER, PICA_PROTO_VERDIFFER, PICA_PROTO_VER_HIGH, PICA_PROTO_VER_LOW}; unsigned int procmsg_INITREQ(unsigned char* buf, unsigned int size, void* ptr); unsigned int procmsg_CONNID(unsigned char* buf, unsigned int size, void* ptr); @@ -116,7 +116,8 @@ void cclink_list_delete(struct cclink *l); void cclink_list_addn2nclr(struct client *clr, const unsigned char *callee_id); void cclink_setwaitconn(struct cclink *ccl); void cclink_list_addn2ncle(const unsigned char *caller_id, struct nodelink *caller_node, struct client *cle); -void cclink_activate(struct cclink *ccl, SOCKET s); +void cclink_activate(struct cclink *ccl); +void cclink_setwaitanontlsshutdown(struct cclink *link, struct newconn *nc); void cclink_attach_remotecle_node(struct cclink *ccl, struct nodelink *callee_node); void cclink_list_delete_by_client(struct client *cl); @@ -179,6 +180,26 @@ struct PICA_msginfo _msginfo_newconn[] = {PICA_PROTO_NODECONNREQ, PICA_MSG_FIXED_SIZE, PICA_PROTO_NODECONNREQ_SIZE, procmsg_NODECONNREQ} }; +static int process_async_ssl_readwrite(SSL *ssl, int ret) +{ + if (ret == 0) + return 0; + + if (ret < 0) + { + switch(SSL_get_error(ssl, ret)) + { + case SSL_ERROR_WANT_WRITE: + case SSL_ERROR_WANT_READ: + break; + default: + return 0; + } + } + + return 1; +} + static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) { //return 1 for self-signed certificates @@ -210,6 +231,8 @@ unsigned int procmsg_INITREQ(unsigned char* buf, unsigned int size, void* ptr) PICA_debug1("received INITREQ"); + nc->type = NEWCONN_C2N; + if (buf[2] == PICA_PROTO_VER_HIGH && buf[3] == PICA_PROTO_VER_LOW) { struct client *c; @@ -217,6 +240,10 @@ unsigned int procmsg_INITREQ(unsigned char* buf, unsigned int size, void* ptr) if (!c) return 0; + c->state = PICA_CLSTATE_WAITANONTLSSHUTDOWN; + nc->iconn.cl = c; + nc->state = PICA_NEWCONN_SENDINGOK; + /* newconn_free(nc); if ((mp = client_wbuf_push(c, PICA_PROTO_INITRESPOK, PICA_PROTO_INITRESPOK_SIZE))) @@ -225,12 +252,11 @@ unsigned int procmsg_INITREQ(unsigned char* buf, unsigned int size, void* ptr) mp->tail[1] = 'K'; } - c->state = PICA_CLSTATE_SENDINGRESP; + c->state = PICA_CLSTATE_SENDINGRESP;*/ }///////---------<<<<<<<<<<< new client else { - //// PICA_PROTO_VERDIFFER - send(nc->sck, msg_VERDIFFER, msg_VERDIFFER_len, 0); + nc->state = PICA_NEWCONN_SENDINGREJECT; if (buf[2] > PICA_PROTO_VER_HIGH || (buf[2] == PICA_PROTO_VER_HIGH && buf[3] > PICA_PROTO_VER_LOW)) { @@ -240,13 +266,44 @@ unsigned int procmsg_INITREQ(unsigned char* buf, unsigned int size, void* ptr) { PICA_info("Client has older protocol version. Disconnecting ..."); } - - return 0; } return 1; } +void cclink_sendcleconnected(struct cclink *link) +{ + struct PICA_proto_msg *mp; + + if (link->state == PICA_CCLINK_LOCAL_WAITCONNCLEANONTLSSHUTDOWN) + { + if((mp = client_wbuf_push(link->p1, PICA_PROTO_FOUND, PICA_PROTO_FOUND_SIZE))) + { + memcpy(mp->tail, link->callee_id, PICA_ID_SIZE); + } + else + { + cclink_list_delete(link); + return 0; + } + } + + if (link->state == PICA_CCLINK_N2NCLE_WAITCONNCLEANONTLSSHUTDOWN) + { + if((mp = nodelink_wbuf_push(link->caller_node, PICA_PROTO_N2NALLOW, PICA_PROTO_N2NALLOW_SIZE))) + { + memcpy(mp->tail, link->caller_id, PICA_ID_SIZE); + memcpy(mp->tail + PICA_ID_SIZE, link->callee_id, PICA_ID_SIZE); + } + else + { + cclink_list_delete(link); + return 0; + } + } + +} + unsigned int procmsg_CONNID(unsigned char* buf, unsigned int size, void* ptr) { struct PICA_proto_msg *mp; @@ -256,6 +313,8 @@ unsigned int procmsg_CONNID(unsigned char* buf, unsigned int size, void* ptr) PICA_debug1("received CONNID"); + nc->type = NEWCONN_C2C; + caller_id = buf + 2; callee_id = buf + 2 + PICA_ID_SIZE; @@ -296,35 +355,9 @@ unsigned int procmsg_CONNID(unsigned char* buf, unsigned int size, void* ptr) } } - if (link->state == PICA_CCLINK_LOCAL_WAITCONNCLE) - { - if((mp = client_wbuf_push(link->p1, PICA_PROTO_FOUND, PICA_PROTO_FOUND_SIZE))) - { - memcpy(mp->tail, callee_id, PICA_ID_SIZE); - } - else - { - cclink_list_delete(link); - return 0; - } - } - - if (link->state == PICA_CCLINK_N2NCLE_WAITCONNCLE) - { - if((mp = nodelink_wbuf_push(link->caller_node, PICA_PROTO_N2NALLOW, PICA_PROTO_N2NALLOW_SIZE))) - { - memcpy(mp->tail, caller_id, PICA_ID_SIZE); - memcpy(mp->tail + PICA_ID_SIZE, callee_id, PICA_ID_SIZE); - } - else - { - cclink_list_delete(link); - return 0; - } - } PICA_debug3("CONNID processed successfully"); - cclink_activate(link, nc->sck); - newconn_free(nc); + cclink_setwaitanontlsshutdown(link, nc); + return 1; } @@ -335,12 +368,15 @@ unsigned int procmsg_NODECONNREQ(unsigned char* buf, unsigned int size, void* pt PICA_debug1("received NODECONNREQ"); + nc->type = NEWCONN_N2N; + if (buf[2] == PICA_PROTO_VER_HIGH && buf[3] == PICA_PROTO_VER_LOW) { ////-прием входящего подключения //-------------------------- - struct nodelink *nl; + nc->state = PICA_NEWCONN_SENDINGOK; + /*struct nodelink *nl; nl = nodelink_list_addnew(nc); newconn_free(nc); if (!nl) @@ -350,10 +386,12 @@ unsigned int procmsg_NODECONNREQ(unsigned char* buf, unsigned int size, void* pt { mp->tail[0] = 'O'; mp->tail[1] = 'K'; - } + }*/ } else { + nc->state = PICA_NEWCONN_SENDINGREJECT; + /* //// PICA_PROTO_VERDIFFER send(nc->sck, msg_VERDIFFER, msg_VERDIFFER_len, 0); @@ -367,7 +405,7 @@ unsigned int procmsg_NODECONNREQ(unsigned char* buf, unsigned int size, void* pt PICA_info("Node %s has older protocol version. Disconnecting ...", inet_ntoa(nc->addr.sin_addr)); } - return 0; + return 0;*/ } return 1; @@ -1286,39 +1324,68 @@ int cclink_allocbufs(struct cclink *ccl) return 1; } -void cclink_activate(struct cclink *ccl, SOCKET s) +void cclink_setwaitanontlsshutdown(struct cclink *link, struct newconn *nc) { - switch(ccl->state) + nc->iconn.cc = link; + nc->state = PICA_NEWCONN_WAITANONTLSSHUTDOWN; + + switch(link->state) { case PICA_CCLINK_LOCAL_WAITCONNCLE: - ccl->sck_p2 = s; - ccl->state = PICA_CCLINK_LOCAL_WAITCONNCLR; + link->sck_p2 = nc->sck; + link->state = PICA_CCLINK_LOCAL_WAITCONNCLEANONTLSSHUTDOWN; break; + case PICA_CCLINK_LOCAL_WAITCONNCLR: - ccl->sck_p1 = s; - if (!cclink_allocbufs(ccl)) + link->sck_p1 = nc->sck; + + if (!cclink_allocbufs(link)) { - cclink_list_delete(ccl); + cclink_list_delete(link); return; } - ccl->state = PICA_CCLINK_LOCAL_ACTIVE; + link->state = PICA_CCLINK_LOCAL_WAITCONNCLRANONTLSSHUTDOWN; break; + case PICA_CCLINK_N2NCLR_WAITCONNCLR: - ccl->sck_p1 = s; - if (!cclink_allocbufs(ccl)) + link->sck_p1 = nc->sck; + + if (!cclink_allocbufs(link)) { - cclink_list_delete(ccl); + cclink_list_delete(link); return; } - ccl->state = PICA_CCLINK_N2NCLR_ACTIVE; + link->state = PICA_CCLINK_N2NCLR_WAITCONNCLRANONTLSSHUTDOWN; break; + case PICA_CCLINK_N2NCLE_WAITCONNCLE: - ccl->sck_p2 = s; - if (!cclink_allocbufs(ccl)) + link->sck_p2 = nc->sck; + + if (!cclink_allocbufs(link)) { - cclink_list_delete(ccl); + cclink_list_delete(link); return; } + + link->state = PICA_CCLINK_N2NCLE_WAITCONNCLEANONTLSSHUTDOWN; + break; + } +} + +void cclink_activate(struct cclink *ccl) +{ + switch(ccl->state) + { + case PICA_CCLINK_LOCAL_WAITCONNCLEANONTLSSHUTDOWN: + ccl->state = PICA_CCLINK_LOCAL_WAITCONNCLR; + break; + case PICA_CCLINK_LOCAL_WAITCONNCLRANONTLSSHUTDOWN: + ccl->state = PICA_CCLINK_LOCAL_ACTIVE; + break; + case PICA_CCLINK_N2NCLR_WAITCONNCLRANONTLSSHUTDOWN: + ccl->state = PICA_CCLINK_N2NCLR_ACTIVE; + break; + case PICA_CCLINK_N2NCLE_WAITCONNCLEANONTLSSHUTDOWN: ccl->state = PICA_CCLINK_N2NCLE_ACTIVE; break; } @@ -1330,6 +1397,8 @@ int PICA_node_init() struct sockaddr_in sd; int ret; int flag; + FILE *dh_file; + DH *dh = NULL; SSL_load_error_strings(); SSL_library_init(); @@ -1389,22 +1458,39 @@ int PICA_node_init() //#endif ctx = SSL_CTX_new(TLSv1_2_method()); + anon_ctx = SSL_CTX_new(TLSv1_2_method()); - if (!ctx) + if (!ctx || !anon_ctx) PICA_fatal("unable to create SSL_CTX object"); - ret = SSL_CTX_set_cipher_list(ctx, PICA_TLS_CIPHERLIST); if (!ret) PICA_fatal("failed to set cipher list " PICA_TLS_CIPHERLIST); - ret = SSL_CTX_load_verify_locations(ctx, nodecfg.CA_cert_file, 0); + SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback); + + dh_file = fopen(nodecfg.dh_param_file, "r"); + + if (dh_file) + { + dh = PEM_read_DHparams(dh_file, NULL, NULL, NULL); + fclose(dh_file); + } + else + PICA_fatal("Unable to open DH parameters file %", nodecfg.dh_param_file); + + ret = SSL_CTX_set_tmp_dh(anon_ctx, dh); + + if (ret != 1) + PICA_fatal("Failed to set DH parameters"); + + ret = SSL_CTX_set_cipher_list(anon_ctx, PICA_TLS_ANONDHCIPHERLIST); if (!ret) - PICA_fatal("call to SSL_CTX_load_verify_locations failed(). Check if %s exists and is accesible", nodecfg.CA_cert_file); + PICA_fatal("failed to set cipher list " PICA_TLS_ANONDHCIPHERLIST); - SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback); + newconns_init(); return 1; } @@ -1415,8 +1501,31 @@ void newconn_close(struct newconn* nc) CLOSE(nc->sck); PICA_debug3("newconn_close(): nc = %p closed socket %i", nc, nc->sck); - nc->sck = 0; + nc->sck = -1; nc->pos = 0; + + if (nc->iconn.cl && nc->type == NEWCONN_C2N) + client_list_delete(nc->iconn.cl); + + if (nc->iconn.cc && nc->type == NEWCONN_C2C) + cclink_list_delete(nc->iconn.cc); + + nc->iconn.cl = NULL; + + nc->type = NEWCONN_UNKNOWN; +} + +void newconns_init() +{ + int i; + + memset(newconns, 0, sizeof(struct newconn) * MAX_NEWCONNS); + + for (i = 0; i < MAX_NEWCONNS; i++) + { + newconns[i].sck = -1; + newconns[i].type = NEWCONN_UNKNOWN; + } } //функция ищет свободный элемент в массиве структур newconn и возвращает на него указатель @@ -1426,7 +1535,7 @@ struct newconn* newconn_add(struct newconn *ncs, int *pos) { time_t min; int min_pos = 0; - if (*pos < MAX_NEWCONNS && !ncs[*pos].sck) + if (*pos < MAX_NEWCONNS && ncs[*pos].sck == -1) { goto ret; } @@ -1434,7 +1543,7 @@ struct newconn* newconn_add(struct newconn *ncs, int *pos) { *pos = 0; min = ncs->tmst; - while(ncs[*pos].sck && *pos < MAX_NEWCONNS) + while(*pos < MAX_NEWCONNS && ncs[*pos].sck >= 0) { if (ncs[*pos].tmst < min) { @@ -1449,11 +1558,12 @@ struct newconn* newconn_add(struct newconn *ncs, int *pos) *pos = min_pos; SHUTDOWN(ncs[min_pos].sck); CLOSE(ncs[min_pos].sck); - PICA_debug2("closed socket %i", ncs[min_pos].sck); + PICA_debug2("closed newconn socket %i", ncs[min_pos].sck); } } ret: + ncs[*pos].sck = -1; ncs[*pos].pos = 0; ncs[*pos].tmst = time(0); return &ncs[(*pos)++]; @@ -1461,7 +1571,7 @@ ret: void newconn_free(struct newconn* nc) { - nc->sck = 0; + nc->sck = -1; //nc->pos=0; - pos value is being used in processmsgdatastream } @@ -1765,6 +1875,7 @@ struct nodelink *nodelink_list_addnew(struct newconn *nc) nl->sck = nc->sck; nl->addr = nc->addr; + nl->anonssl = nc->anonssl; nl->r_buf = calloc(1, DEFAULT_BUF_SIZE); if (!nl->r_buf) @@ -1914,7 +2025,7 @@ void process_timeouts_newconn() for (i = 0; i < MAX_NEWCONNS; i++) { - if (newconns[i].sck) + if (newconns[i].sck >= 0) { if (newconns[i].tmst < t) { @@ -2113,7 +2224,7 @@ void newconn_set_fds(fd_set *readfds, int *nfds) int i; for (i = 0; i < MAX_NEWCONNS; i++) - if (newconns[i].sck) + if (newconns[i].sck >= 0) set_select_fd(newconns[i].sck, readfds, nfds); } @@ -2173,8 +2284,27 @@ void process_listen_read(fd_set *readfds) { nc = newconn_add(newconns, &newconns_pos); + nc->anonssl = SSL_new(anon_ctx); + + if (!nc->anonssl) + { + PICA_error("failed to allocate SSL struct"); + return; + } + + if (!SSL_set_fd(nc->anonssl, s)) + { + SSL_free(nc->anonssl); + return; + } + + nc->sck = s; nc->addr = addr; + nc->state = PICA_NEWCONN_WAITANONTLSACCEPT; + + IOCTLSETNONBLOCKINGSOCKET(s, 1); + PICA_debug1("accepted connection from %.16s, new socket %i", inet_ntoa(addr.sin_addr), s);//IPv6 } else @@ -2186,28 +2316,208 @@ void process_listen_read(fd_set *readfds) //IPv6 } -void process_newconn_read(fd_set *readfds) +void process_newconn_write() { int i, ret; for (i = 0; i < MAX_NEWCONNS; i++) - if (newconns[i].sck && FD_ISSET(newconns[i].sck, readfds)) + if (newconns[i].sck >= 0) { - ret = recv(newconns[i].sck, newconns[i].buf + newconns[i].pos, NEWCONN_BUFSIZE - newconns[i].pos, 0); - if (ret <= 0) + switch(newconns[i].state) { - //perror("process_newconn_read - recv:");//debug - newconn_close(newconns + i); - continue; + case PICA_NEWCONN_SENDINGOK: + PICA_debug3("sending OK response to newconn on socket %i...\n", newconns[i].sck); + ret = SSL_write(newconns[i].anonssl, msg_INITRESPOK, sizeof msg_INITRESPOK); + + if (ret < 0 && process_async_ssl_readwrite(newconns[i].anonssl, ret)) + break; + + if (ret <= 0) + { + SSL_free(newconns[i].anonssl); + newconn_close(&newconns[i]); + break; + } + + if (ret == sizeof msg_INITRESPOK) + { + if (newconns[i].type == NEWCONN_N2N) + { + if (!nodelink_list_addnew(&newconns[i])) + { + SSL_free(newconns[i].anonssl); + newconn_close(&newconns[i]); + } + + newconn_free(&newconns[i]); + } + else + newconns[i].state = PICA_NEWCONN_WAITANONTLSSHUTDOWN; + } + break; + + case PICA_NEWCONN_SENDINGREJECT: + PICA_debug3("sending reject response to newconn on socket %i...\n", newconns[i].sck); + ret = SSL_write(newconns[i].anonssl, msg_VERDIFFER, sizeof msg_VERDIFFER); + + if (ret < 0 && process_async_ssl_readwrite(newconns[i].anonssl, ret)) + break; + + if (ret <= 0) + { + SSL_free(newconns[i].anonssl); + newconn_close(&newconns[i]); + break; + } + + SSL_shutdown(newconns[i].anonssl); + SHUTDOWN(newconns[i].sck); + SSL_free(newconns[i].anonssl); + newconn_close(&newconns[i]); } - newconns[i].pos += ret; - if(!PICA_processdatastream(newconns[i].buf, &(newconns[i].pos), newconns + i /*arg*/, _msginfo_newconn, MSGINFO_MSGSNUM(_msginfo_newconn) )) + } + +} + +void process_newconn_read(fd_set *readfds) +{ + int i, ret; + + for (i = 0; i < MAX_NEWCONNS; i++) + if (newconns[i].sck >= 0 && FD_ISSET(newconns[i].sck, readfds)) + { + + switch(newconns[i].state) { - newconn_close(newconns + i); + case PICA_NEWCONN_WAITANONTLSACCEPT: + ret = SSL_accept(newconns[i].anonssl); + + if (ret < 0 && process_async_ssl_readwrite(newconns[i].anonssl, ret)) + break; + + if (ret <= 0) + { + SSL_free(newconns[i].anonssl); + newconn_close(&newconns[i]); + break; + } + else if (ret == 1) + { + newconns[i].state = PICA_NEWCONN_WAITREQUEST; + } + + case PICA_NEWCONN_WAITREQUEST: + ret = SSL_read(newconns[i].anonssl, newconns[i].buf + newconns[i].pos, NEWCONN_BUFSIZE - newconns[i].pos); + + if (ret < 0 && process_async_ssl_readwrite(newconns[i].anonssl, ret)) + break; + + if (ret <= 0) + { + SSL_free(newconns[i].anonssl); + newconn_close(&newconns[i]); + break; + } + + newconns[i].pos += ret; + + if(!PICA_processdatastream(newconns[i].buf, &(newconns[i].pos), newconns + i, _msginfo_newconn, MSGINFO_MSGSNUM(_msginfo_newconn) )) + { + SSL_free(newconns[i].anonssl); + newconn_close(&newconns[i]); + } + + break; + + /*case PICA_NEWCONN_SENDINGOK: + PICA_debug3("sending OK response to newconn on socket %i...\n", newconns[i].sck); + ret = SSL_write(newconns[i].anonssl, msg_INITRESPOK, sizeof msg_INITRESPOK); + + if (ret < 0 && process_async_ssl_readwrite(newconns[i].anonssl, ret)) + break; + + if (ret <= 0) + { + SSL_free(newconns[i].anonssl); + newconn_close(&newconns[i]); + break; + } + + if (ret == sizeof msg_INITRESPOK) + { + if (newconns[i].type == NEWCONN_N2N) + { + if (!nodelink_list_addnew(&newconns[i])) + { + SSL_free(newconns[i].anonssl); + newconn_close(&newconns[i]); + } + + newconn_free(&newconns[i]); + } + else + newconns[i].state = PICA_NEWCONN_WAITANONTLSSHUTDOWN; + }*/ + + case PICA_NEWCONN_WAITANONTLSSHUTDOWN: + PICA_debug3("waiting for anon TLS shutdown on socket %i...\n", newconns[i].sck); + ret = SSL_shutdown(newconns[i].anonssl); + + if (ret == 0) + break; + + if (ret < 0 && process_async_ssl_readwrite(newconns[i].anonssl, ret)) + break; + + if (ret < 0) + { + SSL_free(newconns[i].anonssl); + newconn_close(&newconns[i]); + break; + } + + //switch state of client or cclink on successful shutdown + if (ret == 1) + { + if (newconns[i].iconn.cl && newconns[i].type == NEWCONN_C2N) + { + newconns[i].iconn.cl->state = PICA_CLSTATE_TLSNEGOTIATION; + newconn_free(&newconns[i]); + break; + } + + if (newconns[i].iconn.cc && newconns[i].type == NEWCONN_C2C) + { + cclink_sendcleconnected(newconns[i].iconn.cc); + cclink_activate(newconns[i].iconn.cc); + + newconn_free(&newconns[i]); + break; + } + } + break; + + /*case PICA_NEWCONN_SENDINGREJECT: + ret = SSL_write(newconns[i].anonssl, msg_VERDIFFER, sizeof msg_VERDIFFER); + + if (ret < 0 && process_async_ssl_readwrite(newconns[i].anonssl, ret)) + break; + + if (ret <= 0) + { + SSL_free(newconns[i].anonssl); + newconn_close(&newconns[i]); + break; + } + + SSL_shutdown(newconns[i].anonssl); + SHUTDOWN(newconns[i].sck); + SSL_free(newconns[i].anonssl); + newconn_close(&newconns[i]);*/ } - //FD_CLR(newconns[i].sck,readfds); + } } @@ -2330,15 +2640,9 @@ void process_n2n_read(fd_set *readfds) { if (FD_ISSET(nl->sck, readfds)) { - ret = recv(nl->sck, nl->r_buf + nl->r_pos, nl->buflen_r - nl->r_pos, 0); + ret = SSL_read(nl->anonssl, nl->r_buf + nl->r_pos, nl->buflen_r - nl->r_pos); - if (ret <= 0) - { - if (ret < 0) - PICA_debug3("recv() failed in process_n2n_read(): %s", strerror(errno)); - kill_ptr = nl; - } - else + if (ret > 0) { nl->r_pos += ret; @@ -2349,6 +2653,14 @@ void process_n2n_read(fd_set *readfds) if (!nodelink_rbuf_grow(nl)) kill_ptr = nl; } + else + { + if (ret == 0 || process_async_ssl_readwrite(nl->anonssl, ret) == 0) + { + PICA_debug3("SSL_read() failed in process_n2n_read()"); + kill_ptr = nl; + } + } } nl = nl->next; @@ -2387,6 +2699,9 @@ void process_c2n_write() if (ret == i_ptr->btw_ssl) { + if (ret < i_ptr->w_pos) + memmove(i_ptr->w_buf, i_ptr->w_buf + ret, i_ptr->w_pos - ret); //may be it's better to implement ring buffer here + i_ptr->w_pos -= i_ptr->btw_ssl; i_ptr->btw_ssl = 0; } @@ -2401,7 +2716,10 @@ void process_c2n_write() kill_ptr = i_ptr; } break; - case PICA_CLSTATE_SENDINGRESP: + case PICA_CLSTATE_WAITANONTLSSHUTDOWN: + // do nothing here, state will be switched by newconn + break; +/* case PICA_CLSTATE_SENDINGRESP: ret = send(i_ptr->sck_comm, i_ptr->w_buf, i_ptr->w_pos, 0); if (!ret) kill_ptr = i_ptr; @@ -2418,7 +2736,7 @@ void process_c2n_write() if (!i_ptr->w_pos) i_ptr->state = PICA_CLSTATE_TLSNEGOTIATION; - break; + break;*/ case PICA_CLSTATE_TLSNEGOTIATION: i_ptr->w_pos = 0; ret = SSL_connect(i_ptr->ssl_comm); @@ -2662,28 +2980,24 @@ void process_n2n_write() { if (nl->w_pos > 0) { - ret = send(nl->sck, nl->w_buf, nl->w_pos, MSG_NOSIGNAL); + if (!nl->btw_ssl) + nl->btw_ssl = nl->w_pos; - if (ret > 0) + ret = SSL_write(nl->anonssl, nl->w_buf, nl->btw_ssl); + + if (ret == nl->btw_ssl) { if (ret < nl->w_pos) memmove(nl->w_buf, nl->w_buf + ret, nl->w_pos - ret); //may be it's better to implement ring buffer here - nl->w_pos -= ret; + nl->w_pos -= nl->btw_ssl; + nl->btw_ssl = 0; } - if (ret < 0) + + if (ret == 0 || ret < 0 && process_async_ssl_readwrite(nl->anonssl, ret) == 0) { -#ifdef WIN32 - ret = WSAGetLastError(); - if (!(ret == WSAEWOULDBLOCK || ret == WSAENOBUFS)) - kill_ptr = nl; -#else - ret = errno; - if (!(ret == EAGAIN || ret == ENOBUFS || ret == EINTR)) - kill_ptr = nl; -#endif - } - if (ret == 0) kill_ptr = nl; + } + } nl = nl->next; @@ -2834,6 +3148,7 @@ int node_loop() process_c2n_write(); process_c2c_write(); process_n2n_write(); + process_newconn_write(); process_timeouts(); process_nodewait(); diff --git a/PICA_node.h b/PICA_node.h index c5fd45e..7d8d19e 100644 --- a/PICA_node.h +++ b/PICA_node.h @@ -58,27 +58,38 @@ //#define PICA_DATA_PORT 51915 //#define PICA_NODE_PORT 51916 -#define PICA_CLSTATE_SENDINGRESP 1 +#define PICA_NEWCONN_WAITANONTLSACCEPT 1 +#define PICA_NEWCONN_WAITREQUEST 2 +#define PICA_NEWCONN_SENDINGOK 3 +#define PICA_NEWCONN_SENDINGREJECT 4 +#define PICA_NEWCONN_WAITANONTLSSHUTDOWN 5 + +#define PICA_CLSTATE_WAITANONTLSSHUTDOWN 1 +//#define PICA_CLSTATE_SENDINGRESP 1 #define PICA_CLSTATE_TLSNEGOTIATION 2 #define PICA_CLSTATE_CONNECTED 3 -//LOCAL - оба клиента подсоединены к одному узлу -//N2NCLR - к узлу подключен вызывающий клиент -//N2NCLE - к узлу подключен вызываемый клиент +//LOCAL - both clients are connected to the same node +//N2NCLR - caller client is connected to this node +//N2NCLE - callee client is connected to this node #define PICA_CCLINK_LOCAL_WAITREP 1 #define PICA_CCLINK_LOCAL_WAITCONNCLE 2 -#define PICA_CCLINK_LOCAL_WAITCONNCLR 3 -#define PICA_CCLINK_LOCAL_ACTIVE 4 +#define PICA_CCLINK_LOCAL_WAITCONNCLEANONTLSSHUTDOWN 3 +#define PICA_CCLINK_LOCAL_WAITCONNCLR 4 +#define PICA_CCLINK_LOCAL_WAITCONNCLRANONTLSSHUTDOWN 5 +#define PICA_CCLINK_LOCAL_ACTIVE 6 -#define PICA_CCLINK_N2NCLR_WAITSEARCH 5 -#define PICA_CCLINK_N2NCLR_WAITREP 6 -#define PICA_CCLINK_N2NCLR_WAITCONNCLR 7 -#define PICA_CCLINK_N2NCLR_ACTIVE 8 +#define PICA_CCLINK_N2NCLR_WAITSEARCH 7 +#define PICA_CCLINK_N2NCLR_WAITREP 8 +#define PICA_CCLINK_N2NCLR_WAITCONNCLR 9 +#define PICA_CCLINK_N2NCLR_WAITCONNCLRANONTLSSHUTDOWN 10 +#define PICA_CCLINK_N2NCLR_ACTIVE 11 -#define PICA_CCLINK_N2NCLE_WAITREP 9 -#define PICA_CCLINK_N2NCLE_WAITCONNCLE 10 -#define PICA_CCLINK_N2NCLE_ACTIVE 11 +#define PICA_CCLINK_N2NCLE_WAITREP 12 +#define PICA_CCLINK_N2NCLE_WAITCONNCLE 13 +#define PICA_CCLINK_N2NCLE_WAITCONNCLEANONTLSSHUTDOWN 14 +#define PICA_CCLINK_N2NCLE_ACTIVE 15 @@ -90,7 +101,6 @@ #define DEFAULT_BUF_SIZE 4096 - struct nodelink; struct client @@ -151,20 +161,36 @@ struct cclink //структура, описывающая соединение int disconnect_ticking; }; +enum newconn_type +{ + NEWCONN_UNKNOWN, + NEWCONN_C2N, + NEWCONN_C2C, + NEWCONN_N2N +}; + struct newconn //структура, описывающая новое подключение (клиента) { SOCKET sck; + SSL *anonssl; struct sockaddr_in addr; time_t tmst; int pos; + int state; + enum newconn_type type; unsigned char buf[NEWCONN_BUFSIZE]; + union + { + struct client *cl; + struct cclink *cc; + } iconn; }; struct nodelink { struct sockaddr_in addr; SOCKET sck; - SSL *ssl; + SSL *anonssl; unsigned int addr_type;//тип адреса узла - PICA_PROTO_NEWNODE_IPV4,PICA_PROTE_NEWNODE_IPV6,... void *node_addr;//указатель на структуру адреса {PICA_nodeaddr_ipv4, PICA_nodeaddr_ipv6,PICA_nodeaddr_dns,..} @@ -175,6 +201,7 @@ struct nodelink unsigned int buflen_w; unsigned int r_pos; unsigned int w_pos; + unsigned int btw_ssl; struct nodelink *next; struct nodelink *prev; @@ -183,5 +210,6 @@ struct nodelink int disconnect_ticking; }; +extern SSL_CTX *anon_ctx; #endif diff --git a/PICA_nodewait.c b/PICA_nodewait.c index 6bae525..c2467e1 100644 --- a/PICA_nodewait.c +++ b/PICA_nodewait.c @@ -162,6 +162,22 @@ static void *nodewait_connect_thread (void *arg) } else { + nw->nc.anonssl = SSL_new(anon_ctx); + + if (!nw->nc.anonssl) + { + CLOSE(nw->nc.sck); + return (void *)0; + } + + if (!SSL_set_fd(nw->nc.anonssl, nw->nc.sck) || 1 != SSL_connect(nw->nc.anonssl)) + { + SSL_free(nw->nc.anonssl); + CLOSE(nw->nc.sck); + ap = ap->ai_next; + continue; + } + break; } } @@ -171,11 +187,11 @@ static void *nodewait_connect_thread (void *arg) nw->nc.addr = *((struct sockaddr_in*)(ap->ai_addr)); nw->state = PICA_NODEWAIT_CONNECTED; - return 1; + return (void *)1; } nw->state = PICA_NODEWAIT_CONNECT_FAILED; - return 0; + return (void *)0; } void nodewait_start_resolve(struct PICA_nodeaddr *a) diff --git a/PICA_security.h b/PICA_security.h index c928adb..6697e7a 100644 --- a/PICA_security.h +++ b/PICA_security.h @@ -23,6 +23,7 @@ #define PICA_RSA_MINKEYSIZE 4096 #define PICA_TLS_CIPHERLIST "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CAMELLIA256-SHA" +#define PICA_TLS_ANONDHCIPHERLIST "ADH-AES256-GCM-SHA384:ADH-CAMELLIA256-SHA" #define PICA_OPENSSL_SECURUTY_LEVEL 3 #define PICA_CERTDIGESTALGO "-sha256" #define PICA_PRIVKEYENCALGO "-aes256" |
