summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton <anton@picapica>2016-12-04 22:46:43 +0400
committerAnton <anton@picapica>2016-12-04 22:46:43 +0400
commit158d5b71b968d17c7b50d77302ee73466cb099fe (patch)
treef555c9396f755b329b7d7745796cb7cb8745bfb0
parent29474a9aa7375cef44788b4a2dad8ab137d75748 (diff)
downloadpica-pica-158d5b71b968d17c7b50d77302ee73466cb099fe.tar.gz
pica-pica-158d5b71b968d17c7b50d77302ee73466cb099fe.zip
implementing outgoing direct c2c connections and direct c2c-related packets exchange, work in progress
-rw-r--r--PICA_client.c153
-rw-r--r--PICA_client.h11
-rw-r--r--PICA_proto.h4
3 files changed, 123 insertions, 45 deletions
diff --git a/PICA_client.c b/PICA_client.c
index 57f9877..a54e31f 100644
--- a/PICA_client.c
+++ b/PICA_client.c
@@ -56,6 +56,9 @@ static unsigned int procmsg_PICA_PROTO_C2CDIRECT_FAILED(unsigned char*, unsigned
static struct PICA_proto_msg* c2n_writebuf_push(struct PICA_c2n *ci, unsigned int msgid, unsigned int size);
static struct PICA_proto_msg* c2c_writebuf_push(struct PICA_c2c *chn, unsigned int msgid, unsigned int size);
+static int process_first_async_connect_result(int connect_ret);
+static int check_async_connect_result(int sock, struct sockaddr* a, int addrlen);
+
static int PICA_write_c2n(struct PICA_c2n *ci);
static int PICA_write_c2c(struct PICA_c2c *chn);
static int PICA_write_ssl(SSL *ssl, unsigned char *buf, unsigned int *ppos, unsigned int *btw);
@@ -424,19 +427,8 @@ static int c2c_start(struct PICA_c2c *chnl)
return PICA_OK;
}
- if (ret == SOCKET_ERROR)
- {
-#ifndef WIN32
- if (errno == EINPROGRESS || errno == EINTR)
- return PICA_OK;
-#else
- if (WSAGetLastError() == WSAEWOULDBLOCK)
- return PICA_OK;
-#endif
-
- err_ret = PICA_ERRSOCK;
+ if ((err_ret = process_first_async_connect_result(ret)) != PICA_OK)
goto error_ret;
- }
}
return PICA_OK;
@@ -523,9 +515,74 @@ static unsigned int procmsg_INITRESP_c2c(unsigned char* buf, unsigned int nb, vo
return 1;
}
+static int c2c_direct_connect_next(struct PICA_c2c_direct *dc2c, struct PICA_c2c *c2c)
+{
+ int ret;
+
+ if (dc2c->addrpos == 0)
+ dc2c->addrpos += 2;
+
+ if (dc2c->addrpos >= *(uint16_t*)dc2c->addrlist)
+ return PICA_OK;
+
+ switch(*dc2c->addrpos)
+ {
+ case PICA_PROTO_C2CDIRECT_IPV4:
+ dc2c->sck = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+ memset(&dc2c->addr, 0, sizeof(dc2c->addr));
+ dc2c->addr.sin_family = AF_INET;
+ dc2c->addr.sin_addr.s_addr = *((in_addr_t*)(dc2c->addrpos + 1));
+ dc2c->addr.sin_port = *((uint16_t*)(dc2c->addrpos + 5));
+
+ ret = connect(dc2c->sck, (struct sockaddr*)&dc2c->addr, sizeof(dc2c->addr));
+
+ if (ret)
+ ...
+
+ dc2c->addrpos += PICA_PROTO_C2CDIRECT_ADDRLIST_ITEM_IPV4_SIZE;
+ break;
+
+ case PICA_PROTO_C2CDIRECT_IPV6:
+ break;
+
+ }
+
+
+}
+
static unsigned int procmsg_PICA_PROTO_C2CDIRECT_ADDRLIST(unsigned char* buf, unsigned int nb, void* p)
{
- --
+ struct PICA_c2c *cc = (struct PICA_c2c *)p;
+
+ if (cc->conn->directc2c_config != PICA_DIRECTC2C_CFG_DISABLED)
+ {
+ if (cc->directc2c_state != PICA_DIRECTC2C_STATE_INACTIVE)
+ return 1;
+
+ cc->directc2c_state = PICA_DIRECTC2C_STATE_CONNECTING;
+ cc->direct = calloc(1, sizeof(struct PICA_c2c_direct));
+
+ if (!cc->direct)
+ return 1;
+
+ cc->direct->is_outgoing = PICA_DIRECTC2C_OUTGOING;
+ cc->direct->sck = -1;
+ cc->direct->addrlist = malloc(nb - 2 + 1);
+
+ if (!cc->direct->addrlist)
+ return 1;
+
+ memcpy(cc->direct->addrlist, buf + 2, nb - 2);// copy size and address list
+ cc->direct->addrlist[nb - 2] = 0;
+ cc->direct->addrpos = 0;
+
+
+ ret = c2c_direct_connect_next(cc->direct, cc);
+ ...
+ }
+
+ return 1;
}
static unsigned int procmsg_PICA_PROTO_C2CDIRECT_FAILED(unsigned char* buf, unsigned int nb, void* p)
@@ -1526,20 +1583,8 @@ int PICA_new_c2n(const struct PICA_acc *acc, const char *nodeaddr, unsigned int
if (ret == 0)
return c2n_stage2_sendreq(cid);
- if (ret == SOCKET_ERROR)
- {
-#ifndef WIN32
- if (errno == EINPROGRESS || errno == EINTR)
- return PICA_OK;
-#else
- if (WSAGetLastError() == WSAEWOULDBLOCK)
- return PICA_OK;
-#endif
-
- ret_err = PICA_ERRSOCK;
+ if ((ret_err = process_first_async_connect_result(ret)) != PICA_OK)
goto error_ret_4;
- }
-
/*
@@ -1657,6 +1702,24 @@ int PICA_new_c2c(struct PICA_c2n *ci, const unsigned char *peer_id, struct PICA_
return PICA_OK;
}
+static int process_first_async_connect_result(int connect_ret)
+{
+ if (connect_ret == SOCKET_ERROR)
+ {
+#ifndef WIN32
+ if (errno == EINPROGRESS || errno == EINTR)
+ return PICA_OK;
+#else
+ if (WSAGetLastError() == WSAEWOULDBLOCK)
+ return PICA_OK;
+#endif
+
+ return PICA_ERRSOCK;
+ }
+
+ return PICA_OK;
+}
+
static int check_async_connect_result(int sock, struct sockaddr* a, int addrlen)
{
int ret = PICA_ERRSOCK;
@@ -1895,6 +1958,7 @@ static void listener_add_connection(struct PICA_listener *lst, SOCKET *s)
nc = calloc(1, sizeof(struct PICA_c2c_direct));
+ nc->is_outgoing = PICA_DIRECTC2C_INCOMING;
nc->sck = s;
nc->ssl = SSL_new(lst->acc->ctx);
@@ -1990,7 +2054,7 @@ static int process_listener(struct PICA_listener *lst, fd_set *rfds, fd_set *wfd
if (kill_ptr)
{
- listener_close_conn(kill_ptr);
+ PICA_close_directc2c(kill_ptr);
}
}
@@ -2456,15 +2520,14 @@ int PICA_send_directc2caddrlist(struct PICA_c2c *chn)
{
struct PICA_proto_msg *mp;
//TODO send all possible interface addresses, not one
- unsigned int len = PICA_PROTO_C2CDIRECT_IPV4_SIZE;
+ unsigned int len = PICA_PROTO_C2CDIRECT_ADDRLIST_ITEM_IPV4_SIZE;
if ((mp = c2c_writebuf_push(chn, PICA_PROTO_C2CDIRECT_ADDRLIST, len + 4)))
{
*((uint16_t*)mp->tail) = len;
*((uint8_t*)mp->tail + 2) = PICA_PROTO_C2CDIRECT_IPV4;
- *((uint8_t*)mp->tail + 3) = PICA_PROTO_C2CDIRECT_IPV4;
- *((uint32_t*)mp->tail + 4) = chn->conn->directc2c_listener->public_addr_ipv4;
- *((uint16_t*)mp->tail + 8) = htons(chn->conn->directc2c_listener->public_port);
+ *((uint32_t*)mp->tail + 3) = chn->conn->directc2c_listener->public_addr_ipv4;
+ *((uint16_t*)mp->tail + 7) = htons(chn->conn->directc2c_listener->public_port);
}
}
@@ -2697,6 +2760,20 @@ int PICA_send_file_fragment(struct PICA_c2c *chn)
return PICA_OK;
}
+void PICA_close_directc2c(struct PICA_c2c_direct *d)
+{
+ if (d->peer_cert)
+ X509_free(d->peer_cert);
+
+ if (d->addrlist)
+ free(d->addrlist);
+
+ SSL_free(c->ssl);
+ SHUTDOWN(c->sck);
+ CLOSE(c->sck);
+
+ free(d);
+}
void PICA_close_c2c(struct PICA_c2c *chn)
{
@@ -2759,6 +2836,9 @@ void PICA_close_c2c(struct PICA_c2c *chn)
//puts("PICA_close_c2c_chkp5");//debug
CLOSE(chn->sck_data);
//puts("PICA_close_c2c_chkp6");//debug
+ if (chn->direct)
+ PICA_close_directc2c(chn->direct);
+
free(chn);
//puts("PICA_close_c2c_chkp7");//debug
}
@@ -2790,15 +2870,6 @@ void PICA_close_acc(struct PICA_acc *a)
free(a);
}
-void listener_close_conn(struct PICA_c2c_direct *c)
-{
- SSL_free(c->ssl);
- SHUTDOWN(c->sck);
- CLOSE(c->sck);
-
- X509_free(c->peer_cert);
- free(c);
-}
void PICA_close_listener(struct PICA_listener *l)
{
@@ -2809,7 +2880,7 @@ void PICA_close_listener(struct PICA_listener *l)
{
struct PICA_c2c_direct *c = l->accepted_connections;
l->accepted_connections = c->next;
- listener_close_conn(c);
+ PICA_close_directc2c(c);
}
free(l);
diff --git a/PICA_client.h b/PICA_client.h
index 2dbd1bf..afe51de 100644
--- a/PICA_client.h
+++ b/PICA_client.h
@@ -114,6 +114,8 @@ typedef unsigned __int64 uint64_t;
#define PICA_C2C_INCOMING 0
#define PICA_C2C_OUTGOING 1
+#define PICA_DIRECTC2C_INCOMING 0
+#define PICA_DIRECTC2C_OUTGOING 1
struct PICA_c2n;
struct PICA_c2c;
@@ -191,9 +193,16 @@ enum PICA_directc2c_state
struct PICA_c2c_direct
{
+ int is_outgoing;
SOCKET sck;
SSL *ssl;
X509 *peer_cert;
+
+ uint8_t *addrlist;
+ uint8_t *addrpos;
+
+ struct sockaddr_in addr;
+
struct PICA_c2c_direct *next;
};
@@ -206,8 +215,6 @@ struct PICA_c2c
SSL *ssl;
struct PICA_c2c_direct *direct;
- uint8_t *directc2c_addrlist;
- uint8_t *directc2c_addrpos;
int outgoing;//1 если создание канала инициировано локальным клиентом, 0 - если собеседником
X509 *peer_cert;
diff --git a/PICA_proto.h b/PICA_proto.h
index c6d53db..4d8b506 100644
--- a/PICA_proto.h
+++ b/PICA_proto.h
@@ -88,8 +88,8 @@
#define PICA_PROTO_CONNID_SIZE 58
#define PICA_PROTO_C2CCONNREQ_SIZE 4
-#define PICA_PROTO_C2CDIRECT_IPV4_SIZE 8
-#define PICA_PROTO_C2CDIRECT_IPV6_SIZE 20
+#define PICA_PROTO_C2CDIRECT_ADDRLIST_ITEM_IPV4_SIZE 7
+#define PICA_PROTO_C2CDIRECT_ADDRLIST_ITEM_IPV6_SIZE 19
#define PICA_PROTO_C2CDIRECT_FAILED_SIZE 4
#define PICA_PROTO_MSGOK_SIZE 4