From 04e991d8146aeff27b2d793b3f6a3c7c1f20913e Mon Sep 17 00:00:00 2001 From: me_desk Date: Fri, 23 Jan 2015 10:23:27 +0000 Subject: updated files in doc/ git-svn-id: svn://localhost/project_picapica/trunk@338 fb96df88-216d-11de-830c-f3023f12d8ac --- doc/TASKS.txt | 16 ++++++++-------- doc/proto.txt | 9 +++++++++ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/doc/TASKS.txt b/doc/TASKS.txt index 89908c9..f92ca7e 100755 --- a/doc/TASKS.txt +++ b/doc/TASKS.txt @@ -37,9 +37,9 @@ - Балансировка нагрузки между узлами (Узлы обмениваются количеством подключенных юзеров, потом самые нагруженные узлы посылают клиентам команду "сменить узел" с отсортированным списком N наименее нагруженных узлов) -- автоматическая регистрация аккаунтов ++ автоматическая регистрация аккаунтов -- сайт, багтрекер, VCS, форум, почтовая рассылка ++ сайт, багтрекер, VCS, форум, почтовая рассылка + сохранение открытых ключей контактов и их сопоставление при каждом сеансе @@ -49,9 +49,9 @@ + autotools -- хранение недоставленных сообщений на стороне клиента, в базе sqlite, пока абонент не появится в сети ++ хранение недоставленных сообщений на стороне клиента, в базе sqlite, пока абонент не появится в сети -- история сообщений, с опциональным шифрованием ++ история сообщений, с опциональным шифрованием + проверка сертификата клиента узлом (узел должен иметь копию корневого сертификата) @@ -61,18 +61,18 @@ - текст лицензий (OpenSSL, iniparser, pica pica, Qt) в окошке about и файлах LICENSE -- собрать и протестировать под Windows (32 и 64 бита) ++ собрать и протестировать под Windows (32 и 64 бита) - аудио-видео звонки (ffmpeg) -- передача файлов ++ передача файлов - возможность прямого P2P соединения между клиентами, клиент может выбирать предпочитаемый вариант (запретить P2P / использовать по возможности) -- периодическая смена CA ключей и уничтожение старого приватного ключа, публикация списков выданных сертификатов для каждого ключа (???) +(уже не нужно) периодическая смена CA ключей и уничтожение старого приватного ключа, публикация списков выданных сертификатов для каждого ключа (???) + конфигурация узла (конфиг файл, опции командной строки, дефолтные значения) -- пакеты для разных дистрибутивов (ebuild, deb, rpm) ++- пакеты для разных дистрибутивов (ebuild +, deb +, mac os x dmg -, windows +, freebsd -) diff --git a/doc/proto.txt b/doc/proto.txt index 0f05d6a..e8a99ad 100755 --- a/doc/proto.txt +++ b/doc/proto.txt @@ -63,6 +63,15 @@ UH - user hash - SHA224 хэш от сертификата пользовате Протокол обмена сообщениями (между клиентами через сервер(ы) ) |КЛИЕНТ-КЛИЕНТ| ++++[начало c2c соединения] - клиент клиенту +0xCC 0xCC Ver_major Ver_minor - версия протокола клиента +варианты ответа - 0x01,0x02 + ++++[анонс адреса клиента] +0xA0, 0xA1, 0xA1 - аналогично сообщениям n2n +Если клиент настроен для приёма входящих прямых соединений между клиентами (минуя ноду), он может послать анонс своего +адреса. Получив анонс, другой клиент может создать соединение с этим адресом и закрыть соединение через ноду + +++[сообщение - текст в кодировке UTF8] 0x30 0x30 (длина сообщения в байтах- 2 байта в формате little-endian) сообщение в кодировке UTF8 -- cgit v1.2.1 From 74419352eeeb2e7b8717978f782d20ff788c0e56 Mon Sep 17 00:00:00 2001 From: me_desk Date: Fri, 30 Jan 2015 19:53:56 +0000 Subject: added new protocol messages definitions, updated protocol version git-svn-id: svn://localhost/project_picapica/trunk@339 fb96df88-216d-11de-830c-f3023f12d8ac --- PICA_client.c | 4 ++-- PICA_proto.h | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 50751d4..da192ee 100755 --- a/PICA_client.c +++ b/PICA_client.c @@ -65,8 +65,8 @@ const struct PICA_msginfo c2c_messages[] = { {PICA_PROTO_SENDFILEREQUEST, PICA_MSG_VAR_SIZE, PICA_MSG_VARSIZE_INT16, procmsg_SENDFILEREQUEST}, {PICA_PROTO_ACCEPTEDFILE, PICA_MSG_FIXED_SIZE, PICA_PROTO_ACCEPTEDFILE_SIZE, procmsg_ACCEPTEDFILE}, {PICA_PROTO_DENIEDFILE, PICA_MSG_FIXED_SIZE, PICA_PROTO_DENIEDFILE_SIZE, procmsg_DENIEDFILE}, - {PICA_PROTO_FILEFRAGMENT, PICA_MSG_VAR_SIZE, PICA_MSG_VARSIZE_INT16, procmsg_FILEFRAGMENT}, - {PICA_PROTO_FILECONTROL, PICA_MSG_FIXED_SIZE, PICA_PROTO_FILECONTROL_SIZE, procmsg_FILECONTROL} + {PICA_PROTO_FILEFRAGMENT, PICA_MSG_VAR_SIZE, PICA_MSG_VARSIZE_INT16, procmsg_FILEFRAGMENT}, + {PICA_PROTO_FILECONTROL, PICA_MSG_FIXED_SIZE, PICA_PROTO_FILECONTROL_SIZE, procmsg_FILECONTROL} }; struct PICA_msginfo c2n_init_messages[] = { diff --git a/PICA_proto.h b/PICA_proto.h index cb20db5..71450e8 100755 --- a/PICA_proto.h +++ b/PICA_proto.h @@ -5,7 +5,10 @@ #define PICA_PROTO_VER_HIGH 0 -#define PICA_PROTO_VER_LOW 4 +#define PICA_PROTO_VER_LOW 5 + +#define PICA_C2CPROTO_VER_HIGH 0 +#define PICA_C2CPROTO_VER_LOW 1 #define PICA_PROTO_VER_STRING PICA_STRINGIFY2(PICA_PROTO_VER_HIGH, PICA_PROTO_VER_LOW) #define PICA_STRINGIFY2(H, L) PICA_STRINGIFY(H, L) @@ -26,6 +29,12 @@ #define PICA_PROTO_CONNID 0x20 +#define PICA_PROTO_C2CCONNREQ 0xCC + +#define PICA_PROTO_C2CDIRECT_IPV4 0xA0 +#define PICA_PROTO_C2CDIRECT_IPV6 0xA1 +#define PICA_PROTO_C2CDIRECT_DNS 0xA2 + #define PICA_PROTO_MSGUTF8 0x30 #define PICA_PROTO_MSGOK 0x40 #define PICA_PROTO_SENDFILEREQUEST 0x50 @@ -76,6 +85,10 @@ #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_MSGOK_SIZE 4 #define PICA_PROTO_ACCEPTEDFILE_SIZE 4 -- cgit v1.2.1 From c6f557b7259ee8c8b5d71706abd3ac9b6db0bff8 Mon Sep 17 00:00:00 2001 From: me_desk Date: Fri, 30 Jan 2015 20:10:57 +0000 Subject: renamed structs PICA_conninfo to PICA_c2n (client-to-node) and PICA_chaninfo to PICA_c2c (client-to-client) git-svn-id: svn://localhost/project_picapica/trunk@340 fb96df88-216d-11de-830c-f3023f12d8ac --- PICA_client.c | 112 ++++++++++++++++++++++----------------------- PICA_client.h | 48 +++++++++---------- pica-client/nodethread.cpp | 2 +- pica-client/nodethread.h | 6 +-- pica-client/skynet.cpp | 30 ++++++------ pica-client/skynet.h | 4 +- tests/test_client.c | 6 +-- 7 files changed, 104 insertions(+), 104 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index da192ee..c30f283 100755 --- a/PICA_client.c +++ b/PICA_client.c @@ -28,10 +28,10 @@ static pthread_mutex_t *mt_locks; #endif -static int PICA_send_file_fragment(struct PICA_chaninfo *chn); -static int PICA_sendfile_open_read(struct PICA_chaninfo *chn, const char *filename_utf8, uint64_t *file_size); -static int PICA_recvfile_open_write(struct PICA_chaninfo *chn, const char *filename_utf8, unsigned int filenamesize); -static int PICA_send_filecontrol(struct PICA_chaninfo *chan, int senderctl, int receiverctl); +static int PICA_send_file_fragment(struct PICA_c2c *chn); +static int PICA_sendfile_open_read(struct PICA_c2c *chn, const char *filename_utf8, uint64_t *file_size); +static int PICA_recvfile_open_write(struct PICA_c2c *chn, const char *filename_utf8, unsigned int filenamesize); +static int PICA_send_filecontrol(struct PICA_c2c *chan, int senderctl, int receiverctl); static unsigned int procmsg_INITRESP(unsigned char*,unsigned int,void*); static unsigned int procmsg_CONNREQINC(unsigned char*,unsigned int,void*); @@ -47,8 +47,8 @@ static unsigned int procmsg_DENIEDFILE(unsigned char*,unsigned int,void*); static unsigned int procmsg_FILEFRAGMENT(unsigned char*,unsigned int,void*); static unsigned int procmsg_FILECONTROL(unsigned char*,unsigned int,void*); -static struct PICA_proto_msg* c2n_writebuf_push(struct PICA_conninfo *ci, unsigned int msgid, unsigned int size); -static struct PICA_proto_msg* c2c_writebuf_push(struct PICA_chaninfo *chn, unsigned int msgid, unsigned int size); +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); #define MSGINFO_MSGSNUM(arr) (sizeof(arr)/sizeof(struct PICA_msginfo)) const struct PICA_msginfo c2n_messages[] = { @@ -193,11 +193,11 @@ if (!preverify_ok) { return preverify_ok; } -static int add_chaninfo(struct PICA_conninfo *ci, struct PICA_chaninfo **chn, const unsigned char *peer_id, int is_outgoing) +static int add_chaninfo(struct PICA_c2n *ci, struct PICA_c2c **chn, const unsigned char *peer_id, int is_outgoing) { -struct PICA_chaninfo *chnl,*ipt; +struct PICA_c2c *chnl,*ipt; -chnl=*chn=(struct PICA_chaninfo*)calloc(sizeof(struct PICA_chaninfo),1); +chnl=*chn=(struct PICA_c2c*)calloc(sizeof(struct PICA_c2c),1); if (!chnl) return 0;//ERR_CHECK @@ -227,7 +227,7 @@ else return 1; } -static int establish_data_connection(struct PICA_chaninfo *chnl) +static int establish_data_connection(struct PICA_c2c *chnl) { char* DN_str; //unsigned char buf[12]; @@ -400,7 +400,7 @@ return err_ret; static unsigned int procmsg_INITRESP(unsigned char* buf, unsigned int nb,void* p) { -struct PICA_conninfo *ci=(struct PICA_conninfo *)p; +struct PICA_c2n *ci=(struct PICA_c2n *)p; switch(buf[0]) { @@ -424,14 +424,14 @@ return 1; static unsigned int procmsg_CONNREQINC(unsigned char* buf,unsigned int nb,void* p) { int ret; -struct PICA_conninfo *ci=(struct PICA_conninfo *)p; +struct PICA_c2n *ci=(struct PICA_c2n *)p; struct PICA_proto_msg *mp; unsigned char *peer_id = buf + 2; if (callbacks.accept_cb(peer_id)) { - struct PICA_chaninfo *_chnl; + struct PICA_c2c *_chnl; mp = c2n_writebuf_push( ci, PICA_PROTO_CONNALLOW, PICA_PROTO_CONNALLOW_SIZE); @@ -480,8 +480,8 @@ return 1; static unsigned int procmsg_NOTFOUND(unsigned char* buf,unsigned int nb,void* p) { -struct PICA_conninfo *ci=(struct PICA_conninfo *)p; -struct PICA_chaninfo *ipt,*rq=0; +struct PICA_c2n *ci=(struct PICA_c2n *)p; +struct PICA_c2c *ipt,*rq=0; unsigned char *peer_id = buf + 2; //puts("procmsg_NOTFOUND");//debug @@ -511,8 +511,8 @@ return 1; static unsigned int procmsg_FOUND(unsigned char* buf,unsigned int nb,void* p) { -struct PICA_conninfo *ci=(struct PICA_conninfo *)p; -struct PICA_chaninfo *ipt,*rq=0; +struct PICA_c2n *ci=(struct PICA_c2n *)p; +struct PICA_c2c *ipt,*rq=0; unsigned char *peer_id = buf + 2; int ret; @@ -609,7 +609,7 @@ return 1; static unsigned int procmsg_MSGUTF8(unsigned char* buf, unsigned int nb, void* p) { -struct PICA_chaninfo *chan = (struct PICA_chaninfo *)p; +struct PICA_c2c *chan = (struct PICA_c2c *)p; struct PICA_proto_msg *mp; callbacks.newmsg_cb(chan->peer_id, buf + 4, nb - 4, buf[0]); @@ -629,7 +629,7 @@ return 1; static unsigned int procmsg_MSGOK(unsigned char* buf, unsigned int nb, void* p) { -struct PICA_chaninfo *chan = (struct PICA_chaninfo *)p; +struct PICA_c2c *chan = (struct PICA_c2c *)p; callbacks.msgok_cb(chan -> peer_id); return 1; @@ -637,7 +637,7 @@ return 1; unsigned int procmsg_PINGREQ(unsigned char* buf,unsigned int nb,void* p) { -struct PICA_conninfo *ci=(struct PICA_conninfo *)p; +struct PICA_c2n *ci=(struct PICA_c2n *)p; struct PICA_proto_msg *mp; mp = c2n_writebuf_push(ci, PICA_PROTO_PINGREP, PICA_PROTO_PINGREP_SIZE); @@ -652,7 +652,7 @@ else return 1; } -int PICA_deny_file(struct PICA_chaninfo *chan) +int PICA_deny_file(struct PICA_c2c *chan) { struct PICA_proto_msg *mp; @@ -673,7 +673,7 @@ else return PICA_OK; } -int PICA_accept_file(struct PICA_chaninfo *chan, char *filename, unsigned int filenamesize) +int PICA_accept_file(struct PICA_c2c *chan, char *filename, unsigned int filenamesize) { struct PICA_proto_msg *mp; int ret; @@ -703,7 +703,7 @@ return PICA_OK; static unsigned int procmsg_SENDFILEREQUEST(unsigned char* buf, unsigned int nb, void* p) { -struct PICA_chaninfo *chan = (struct PICA_chaninfo *)p; +struct PICA_c2c *chan = (struct PICA_c2c *)p; struct PICA_proto_msg *mp; int ret; @@ -740,7 +740,7 @@ return 1; static unsigned int procmsg_ACCEPTEDFILE(unsigned char* buf, unsigned int nb, void* p) { -struct PICA_chaninfo *chan = (struct PICA_chaninfo *)p; +struct PICA_c2c *chan = (struct PICA_c2c *)p; if (chan->sendfilestate != PICA_CHANSENDFILESTATE_SENTREQ) return 0; @@ -754,7 +754,7 @@ return 1; static unsigned int procmsg_DENIEDFILE(unsigned char* buf, unsigned int nb, void* p) { -struct PICA_chaninfo *chan = (struct PICA_chaninfo *)p; +struct PICA_c2c *chan = (struct PICA_c2c *)p; if (chan->sendfilestate != PICA_CHANSENDFILESTATE_SENTREQ) return 0; @@ -771,7 +771,7 @@ return 1; static unsigned int procmsg_FILEFRAGMENT(unsigned char* buf, unsigned int nb, void* p) { -struct PICA_chaninfo *chan = (struct PICA_chaninfo *)p; +struct PICA_c2c *chan = (struct PICA_c2c *)p; /* *Allow incoming FILEFRAGMENTs while paused @@ -818,7 +818,7 @@ return 1; static unsigned int procmsg_FILECONTROL(unsigned char* buf, unsigned int nb, void* p) { -struct PICA_chaninfo *chan = (struct PICA_chaninfo *)p; +struct PICA_c2c *chan = (struct PICA_c2c *)p; unsigned int sender_cmd, receiver_cmd; sender_cmd = buf[2]; @@ -997,7 +997,7 @@ return 1; //cert_file - имя файла, содержащего сертфикат клиента в формате PEM //pkey_file - имя файла, содержащего приватный ключ в формате PEM //password_cb - callback-функция, запрашивающая пароль к приватному ключу, см. man 3 SSL_CTX_set_default_passwd_cb;в userdata передается указатель на id -//ci -указатель на указатель на структуру PICA_conninfo, который будет проинициализирован при успешном выполнении функции +//ci -указатель на указатель на структуру PICA_c2n, который будет проинициализирован при успешном выполнении функции //Память, выделенная под структуру, освобождается при вызове PICA_close_connection //Возвращаемое значение - код завершения //PICA_OK - успешное завершение функции @@ -1010,10 +1010,10 @@ int PICA_new_connection(const char *nodeaddr, const char *pkey_file, const char *dh_param_file, int (*password_cb)(char *buf, int size, int rwflag, void *userdata), - struct PICA_conninfo **ci) + struct PICA_c2n **ci) { int ret,ret_err; -struct PICA_conninfo *cid; +struct PICA_c2n *cid; struct sockaddr_in a; DH *dh = NULL; FILE *dh_file = NULL; @@ -1023,7 +1023,7 @@ if (!(nodeaddr && CA_file && cert_file && pkey_file && ci)) return PICA_ERRINVARG; -cid=*ci=(struct PICA_conninfo*)calloc(sizeof(struct PICA_conninfo),1);//(1) +cid=*ci=(struct PICA_c2n*)calloc(sizeof(struct PICA_c2n),1);//(1) if (!cid) return PICA_ERRNOMEM; @@ -1268,10 +1268,10 @@ return ret_err; //создает ИСХОДЯЩИЙ логический зашифрованный канал связи с указанным собеседником, если тот доступен // в данный момент. -int PICA_create_channel(struct PICA_conninfo *ci,const unsigned char *peer_id,struct PICA_chaninfo **chn) +int PICA_create_channel(struct PICA_c2n *ci,const unsigned char *peer_id,struct PICA_c2c **chn) { struct PICA_proto_msg *mp; -struct PICA_chaninfo *chnl; +struct PICA_c2c *chnl; if (!(ci && chn)) return PICA_ERRINVARG; @@ -1294,11 +1294,11 @@ mp = c2n_writebuf_push( ci, PICA_PROTO_CONNREQOUTG, PICA_PROTO_CONNREQOUTG_SIZE) return PICA_OK; } -int PICA_read(struct PICA_conninfo *ci,int timeout) +int PICA_read(struct PICA_c2n *ci,int timeout) { fd_set fds; struct timeval tv={0,1000}; -struct PICA_chaninfo *ipt, *kill_ptr = 0; +struct PICA_c2c *ipt, *kill_ptr = 0; int ret,nfds; //puts("PICA_read<<");//debug @@ -1379,9 +1379,9 @@ if (ret>0) return PICA_OK; } -int PICA_write(struct PICA_conninfo *ci) +int PICA_write(struct PICA_c2n *ci) { -struct PICA_chaninfo *ipt, *kill_ptr = 0; +struct PICA_c2c *ipt, *kill_ptr = 0; int ret = PICA_OK; //puts("PICA_write>>");//debug @@ -1494,7 +1494,7 @@ return PICA_OK; //int PICA_read_socket() //int PICA_read_ssl() -int PICA_write_c2n(struct PICA_conninfo *ci) +int PICA_write_c2n(struct PICA_c2n *ci) { int ret = PICA_ERRINVARG; @@ -1506,7 +1506,7 @@ else if (PICA_CONNSTATE_CONNECTED == ci->state) return ret; } -int PICA_write_c2c(struct PICA_chaninfo *chn) +int PICA_write_c2c(struct PICA_c2c *chn) { int ret = PICA_ERRINVARG; @@ -1590,7 +1590,7 @@ if (ret > 0) return PICA_OK; } -int PICA_read_c2c(struct PICA_chaninfo *chn) +int PICA_read_c2c(struct PICA_c2c *chn) { int ret; @@ -1610,7 +1610,7 @@ return ret; } //функция читает и обрабатывает данные, приходящие от сервера по управляющему соединению. -int PICA_read_c2n(struct PICA_conninfo *ci) +int PICA_read_c2n(struct PICA_c2n *ci) { int ret; @@ -1636,7 +1636,7 @@ if (ret == PICA_OK) return ret; } -struct PICA_proto_msg* c2n_writebuf_push(struct PICA_conninfo *ci, unsigned int msgid, unsigned int size) +struct PICA_proto_msg* c2n_writebuf_push(struct PICA_c2n *ci, unsigned int msgid, unsigned int size) { struct PICA_proto_msg *mp; @@ -1669,7 +1669,7 @@ ci->write_pos += size; return mp; } -struct PICA_proto_msg* c2c_writebuf_push(struct PICA_chaninfo *chn, unsigned int msgid, unsigned int size) +struct PICA_proto_msg* c2c_writebuf_push(struct PICA_c2c *chn, unsigned int msgid, unsigned int size) { struct PICA_proto_msg *mp; @@ -1702,7 +1702,7 @@ chn->write_pos += size; return mp; } -int PICA_send_msg(struct PICA_chaninfo *chn, char *buf,unsigned int len) +int PICA_send_msg(struct PICA_c2c *chn, char *buf,unsigned int len) { struct PICA_proto_msg *mp; @@ -1720,7 +1720,7 @@ else return PICA_OK; } -int PICA_send_file(struct PICA_chaninfo *chn, const char *filepath) +int PICA_send_file(struct PICA_c2c *chn, const char *filepath) { struct PICA_proto_msg *mp; size_t namelen; @@ -1771,7 +1771,7 @@ chn->sendfile_pos = 0; return PICA_OK; } -int PICA_pause_file(struct PICA_chaninfo *chan, int sending) +int PICA_pause_file(struct PICA_c2c *chan, int sending) { int senderctl = PICA_PROTO_FILECONTROL_VOID; int receiverctl = PICA_PROTO_FILECONTROL_VOID; @@ -1800,7 +1800,7 @@ if (sending) return PICA_send_filecontrol(chan, senderctl, receiverctl); } -int PICA_resume_file(struct PICA_chaninfo *chan, int sending) +int PICA_resume_file(struct PICA_c2c *chan, int sending) { int senderctl = PICA_PROTO_FILECONTROL_VOID; int receiverctl = PICA_PROTO_FILECONTROL_VOID; @@ -1827,7 +1827,7 @@ if (sending) return PICA_send_filecontrol(chan, senderctl, receiverctl); } -int PICA_cancel_file(struct PICA_chaninfo *chan, int sending) +int PICA_cancel_file(struct PICA_c2c *chan, int sending) { int senderctl = PICA_PROTO_FILECONTROL_VOID; int receiverctl = PICA_PROTO_FILECONTROL_VOID; @@ -1860,7 +1860,7 @@ if (sending) return PICA_send_filecontrol(chan, senderctl, receiverctl); } -int PICA_send_filecontrol(struct PICA_chaninfo *chan, int senderctl, int receiverctl) +int PICA_send_filecontrol(struct PICA_c2c *chan, int senderctl, int receiverctl) { struct PICA_proto_msg *mp; @@ -1877,7 +1877,7 @@ else return PICA_OK; } -int PICA_send_file_fragment(struct PICA_chaninfo *chn) +int PICA_send_file_fragment(struct PICA_c2c *chn) { struct PICA_proto_msg *mp; char buf[PICA_FILEFRAGMENTSIZE]; @@ -1929,9 +1929,9 @@ if (chn->sendfile_pos > chn->sendfile_size) return PICA_OK; } -void PICA_close_channel(struct PICA_chaninfo *chn) +void PICA_close_channel(struct PICA_c2c *chn) { -struct PICA_chaninfo *ipt; +struct PICA_c2c *ipt; fprintf(stderr, "PICA_close_channel(%p)\n", chn);//debug @@ -1994,9 +1994,9 @@ free(chn); //puts("PICA_close_channel_chkp7");//debug } -void PICA_close_connection(struct PICA_conninfo *cid) +void PICA_close_connection(struct PICA_c2n *cid) { -struct PICA_chaninfo *ipt; +struct PICA_c2c *ipt; while((ipt = cid->chan_list_head)) PICA_close_channel(ipt); @@ -2041,7 +2041,7 @@ free(cid); #endif -int PICA_sendfile_open_read(struct PICA_chaninfo *chn, const char *filename_utf8, uint64_t *file_size) +int PICA_sendfile_open_read(struct PICA_c2c *chn, const char *filename_utf8, uint64_t *file_size) { #ifdef WIN32 { @@ -2093,7 +2093,7 @@ if (fseeko(chn->sendfile_stream, 0, SEEK_SET) != 0) return PICA_OK; } -int PICA_recvfile_open_write(struct PICA_chaninfo *chn, const char *filename_utf8, unsigned int filenamesize) +int PICA_recvfile_open_write(struct PICA_c2c *chn, const char *filename_utf8, unsigned int filenamesize) { ///////////// #ifdef WIN32 diff --git a/PICA_client.h b/PICA_client.h index db1a52d..cbd3ed8 100755 --- a/PICA_client.h +++ b/PICA_client.h @@ -115,10 +115,10 @@ typedef unsigned __int64 uint64_t; #define PICA_CHANNEL_INCOMING 0 #define PICA_CHANNEL_OUTGOING 1 -struct PICA_conninfo; -struct PICA_chaninfo; +struct PICA_c2n; +struct PICA_c2c; -struct PICA_conninfo +struct PICA_c2n { //#warning "sockaddr!" struct sockaddr_in srv_addr; // sockaddr !! @@ -137,16 +137,16 @@ unsigned int write_pos; unsigned int write_buflen; unsigned int write_sslbytestowrite; -struct PICA_chaninfo *chan_list_head; -struct PICA_chaninfo *chan_list_end; +struct PICA_c2c *chan_list_head; +struct PICA_c2c *chan_list_end; int init_resp_ok; unsigned char node_ver_major, node_ver_minor; }; -struct PICA_chaninfo +struct PICA_c2c { -struct PICA_conninfo *conn;//соединение с сервером, через которое установлен данный логический канал связи +struct PICA_c2n *conn;//соединение с сервером, через которое установлен данный логический канал связи unsigned char peer_id[PICA_ID_SIZE]; SOCKET sck_data; SSL *ssl; @@ -161,8 +161,8 @@ unsigned int write_pos; unsigned int write_buflen; unsigned int write_sslbytestowrite; -struct PICA_chaninfo *next; -struct PICA_chaninfo *prev; +struct PICA_c2c *next; +struct PICA_c2c *prev; int state; time_t timestamp; int sendfilestate; @@ -231,28 +231,28 @@ int PICA_new_connection const char *pkey_file, const char *dh_param_file, int (*password_cb)(char *buf, int size, int rwflag, void *userdata), - struct PICA_conninfo **ci); + struct PICA_c2n **ci); -int PICA_create_channel(struct PICA_conninfo *ci,const unsigned char *peer_id,struct PICA_chaninfo **chn); -int PICA_read_c2n(struct PICA_conninfo *ci); +int PICA_create_channel(struct PICA_c2n *ci,const unsigned char *peer_id,struct PICA_c2c **chn); +int PICA_read_c2n(struct PICA_c2n *ci); -int PICA_read(struct PICA_conninfo *ci,int timeout); -int PICA_write(struct PICA_conninfo *ci); +int PICA_read(struct PICA_c2n *ci,int timeout); +int PICA_write(struct PICA_c2n *ci); -int PICA_send_msg(struct PICA_chaninfo *chn, char *buf,unsigned int len); -int PICA_read_msg(struct PICA_chaninfo *chn,char *buf,unsigned int *n); +int PICA_send_msg(struct PICA_c2c *chn, char *buf,unsigned int len); +int PICA_read_msg(struct PICA_c2c *chn,char *buf,unsigned int *n); //filename - ASCII or UTF-8 encoded string -int PICA_send_file(struct PICA_chaninfo *chn, const char *filepath); -int PICA_accept_file(struct PICA_chaninfo *chan, char *filename, unsigned int filenamesize); -int PICA_deny_file(struct PICA_chaninfo *chan); +int PICA_send_file(struct PICA_c2c *chn, const char *filepath); +int PICA_accept_file(struct PICA_c2c *chan, char *filename, unsigned int filenamesize); +int PICA_deny_file(struct PICA_c2c *chan); // if sending != 0 then pause sending file, else pause receiving of file -int PICA_pause_file(struct PICA_chaninfo *chan, int sending); -int PICA_resume_file(struct PICA_chaninfo *chan, int sending); -int PICA_cancel_file(struct PICA_chaninfo *chan, int sending); +int PICA_pause_file(struct PICA_c2c *chan, int sending); +int PICA_resume_file(struct PICA_c2c *chan, int sending); +int PICA_cancel_file(struct PICA_c2c *chan, int sending); -void PICA_close_channel(struct PICA_chaninfo *chn); -void PICA_close_connection(struct PICA_conninfo *cid); +void PICA_close_channel(struct PICA_c2c *chn); +void PICA_close_connection(struct PICA_c2n *cid); #ifdef __cplusplus } diff --git a/pica-client/nodethread.cpp b/pica-client/nodethread.cpp index 393c156..3850397 100644 --- a/pica-client/nodethread.cpp +++ b/pica-client/nodethread.cpp @@ -6,7 +6,7 @@ QMutex NodeThread::finished_mutex; -NodeThread::NodeThread(Nodes::NodeRecord &addr, bool *completed, Accounts::AccountRecord &acc, PICA_conninfo **pica_conn, QMutex *wm) : +NodeThread::NodeThread(Nodes::NodeRecord &addr, bool *completed, Accounts::AccountRecord &acc, PICA_c2n **pica_conn, QMutex *wm) : QThread(0) { node_addr = addr; diff --git a/pica-client/nodethread.h b/pica-client/nodethread.h index 79de4d0..524688e 100644 --- a/pica-client/nodethread.h +++ b/pica-client/nodethread.h @@ -12,7 +12,7 @@ class NodeThread : public QThread { Q_OBJECT public: - explicit NodeThread( Nodes::NodeRecord &addr, bool *completed,Accounts::AccountRecord &acc,struct PICA_conninfo **pica_conn, QMutex *wm); + explicit NodeThread( Nodes::NodeRecord &addr, bool *completed,Accounts::AccountRecord &acc,struct PICA_c2n **pica_conn, QMutex *wm); void CloseThread(); private: void run(); @@ -22,9 +22,9 @@ private: bool *finished_flag; Nodes::NodeRecord node_addr; - struct PICA_conninfo *ci; + struct PICA_c2n *ci; Accounts::AccountRecord user_account; - struct PICA_conninfo **connection; + struct PICA_c2n **connection; int exit; diff --git a/pica-client/skynet.cpp b/pica-client/skynet.cpp index 54b1a85..fda9a31 100644 --- a/pica-client/skynet.cpp +++ b/pica-client/skynet.cpp @@ -89,7 +89,7 @@ void SkyNet::nodethread_connected(QString addr, quint16 port, NodeThread *thread { int ret; write_mutex.lock(); - struct PICA_chaninfo *chan = NULL; + struct PICA_c2c *chan = NULL; ret = PICA_create_channel(nodelink, (const unsigned char*)c2c_peer_ids[i].constData(), &chan); @@ -181,7 +181,7 @@ void SkyNet::timerEvent(QTimerEvent *e) { int ret; - struct PICA_chaninfo *chan = NULL; + struct PICA_c2c *chan = NULL; ret = PICA_create_channel(nodelink, (const unsigned char*)c2c_peer_ids[i].constData(), &chan); @@ -240,7 +240,7 @@ bool SkyNet::isSelfAware() void SkyNet::SendFile(QByteArray to, QString filepath) { int ret = PICA_OK; -struct PICA_chaninfo *iptr; +struct PICA_c2c *iptr; write_mutex.lock();//<< @@ -263,7 +263,7 @@ if ( (iptr = find_active_chan(to)) ) } else { - struct PICA_chaninfo *chan = NULL; + struct PICA_c2c *chan = NULL; ret = PICA_create_channel(nodelink, (const unsigned char*)to.constData(), &chan); @@ -283,7 +283,7 @@ write_mutex.unlock();//>> void SkyNet::AcceptFile(QByteArray from, QString filepath) { int ret = PICA_OK; -struct PICA_chaninfo *iptr; +struct PICA_c2c *iptr; write_mutex.lock();//<< if ( (iptr = find_active_chan(from)) ) @@ -302,7 +302,7 @@ write_mutex.unlock();//>> void SkyNet::DenyFile(QByteArray from) { int ret = PICA_OK; -struct PICA_chaninfo *iptr; +struct PICA_c2c *iptr; write_mutex.lock();//<< if ( (iptr = find_active_chan(from)) ) @@ -321,7 +321,7 @@ write_mutex.unlock();//>> void SkyNet::PauseFile(QByteArray peer_id, bool pause_sending) { int ret = PICA_OK; -struct PICA_chaninfo *iptr; +struct PICA_c2c *iptr; write_mutex.lock();//<< if ( (iptr = find_active_chan(peer_id)) ) @@ -340,7 +340,7 @@ write_mutex.unlock();//>> void SkyNet::ResumeFile(QByteArray peer_id, bool resume_sending) { int ret = PICA_OK; -struct PICA_chaninfo *iptr; +struct PICA_c2c *iptr; write_mutex.lock();//<< if ( (iptr = find_active_chan(peer_id)) ) @@ -358,7 +358,7 @@ write_mutex.unlock();//>> void SkyNet::CancelFile(QByteArray peer_id, bool cancel_sending) { int ret = PICA_OK; -struct PICA_chaninfo *iptr; +struct PICA_c2c *iptr; write_mutex.lock();//<< if ( (iptr = find_active_chan(peer_id)) ) @@ -376,7 +376,7 @@ write_mutex.unlock();//>> void SkyNet::SendMessage(QByteArray to, QString msg) { int ret = PICA_OK; -struct PICA_chaninfo *iptr; +struct PICA_c2c *iptr; write_mutex.lock();//<< @@ -399,7 +399,7 @@ if ( (iptr = find_active_chan(to)) ) } else { - struct PICA_chaninfo *chan = NULL; + struct PICA_c2c *chan = NULL; ret = PICA_create_channel(nodelink, (const unsigned char*)to.constData(), &chan); @@ -418,7 +418,7 @@ write_mutex.unlock();//>> void SkyNet::flush_queues(QByteArray to) { - struct PICA_chaninfo *chan; + struct PICA_c2c *chan; int ret; if (self_aware && (msgqueues.contains(to) || sndfilequeues.contains(to))) @@ -466,12 +466,12 @@ void SkyNet::flush_queues(QByteArray to) } } -struct PICA_chaninfo * SkyNet::find_active_chan(QByteArray peer_id) +struct PICA_c2c * SkyNet::find_active_chan(QByteArray peer_id) { if (!nodelink) return NULL; -struct PICA_chaninfo *iptr = nodelink->chan_list_head; +struct PICA_c2c *iptr = nodelink->chan_list_head; while(iptr) { @@ -491,7 +491,7 @@ QList SkyNet::filter_existing_chans(QList peer_ids) if (!nodelink) return ret; - struct PICA_chaninfo *iptr = nodelink->chan_list_head; + struct PICA_c2c *iptr = nodelink->chan_list_head; while(iptr) { diff --git a/pica-client/skynet.h b/pica-client/skynet.h index 5aeb332..a0f974b 100644 --- a/pica-client/skynet.h +++ b/pica-client/skynet.h @@ -62,7 +62,7 @@ private: QList threads; bool self_aware; QString status; - struct PICA_conninfo *nodelink; + struct PICA_c2n *nodelink; Accounts::AccountRecord skynet_account; QMutex write_mutex; QMap > msgqueues; @@ -72,7 +72,7 @@ private: void timerEvent(QTimerEvent * e); void flush_queues(QByteArray to); - struct PICA_chaninfo *find_active_chan(QByteArray peer_id); + struct PICA_c2c *find_active_chan(QByteArray peer_id); QList filter_existing_chans(QList peer_ids); void emit_MessageReceived(QByteArray from, QString msg); diff --git a/tests/test_client.c b/tests/test_client.c index f8ef157..9ea2de2 100755 --- a/tests/test_client.c +++ b/tests/test_client.c @@ -6,8 +6,8 @@ struct sockaddr_in a; -struct PICA_conninfo *c; -struct PICA_chaninfo *chn; +struct PICA_c2n *c; +struct PICA_c2c *chn; int _outgoing_chnl=0; @@ -124,7 +124,7 @@ PICA_client_init(&cbs); printf("making connection...\n"); -//PICA_new_connection(const char *nodeaddr, unsigned int port, const char *CA_file, const char *cert_file, const char *pkey_file, const char* password, struct PICA_conninfo **ci) +//PICA_new_connection(const char *nodeaddr, unsigned int port, const char *CA_file, const char *cert_file, const char *pkey_file, const char* password, struct PICA_c2n **ci) ret=PICA_new_connection(argv[1], atoi(argv[2]), /*"trusted_CA.pem"*/ argv[3], argv[3],argv[3],NULL,&c); ERR_print_errors_fp(stdout); -- cgit v1.2.1 From 94587f893a83cf505d655169b6b45b24345a8aa9 Mon Sep 17 00:00:00 2001 From: me_desk Date: Mon, 9 Mar 2015 23:41:26 +0000 Subject: new structs PICA_acc - represents account credentials, certificate file and private key and PICA_listener - represents port opened on client for accepting incoming direct p2p (client-to-client, bypassing node) connections; new functions for handling PICA_acc and PICA_listener, moved part of code from PICA_new_connection() to PICA_open_acc() git-svn-id: svn://localhost/project_picapica/trunk@341 fb96df88-216d-11de-830c-f3023f12d8ac --- PICA_client.c | 264 +++++++++++++++++++++++++++++++++++++++------------------- PICA_client.h | 60 +++++++++++-- 2 files changed, 232 insertions(+), 92 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index c30f283..4b6f3a9 100755 --- a/PICA_client.c +++ b/PICA_client.c @@ -46,6 +46,7 @@ static unsigned int procmsg_ACCEPTEDFILE(unsigned char*,unsigned int,void*); static unsigned int procmsg_DENIEDFILE(unsigned char*,unsigned int,void*); static unsigned int procmsg_FILEFRAGMENT(unsigned char*,unsigned int,void*); static unsigned int procmsg_FILECONTROL(unsigned char*,unsigned int,void*); +static unsigned int procmsg_INITRESP_c2c(unsigned char*,unsigned int,void*); 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); @@ -70,10 +71,14 @@ const struct PICA_msginfo c2c_messages[] = { }; struct PICA_msginfo c2n_init_messages[] = { - {PICA_PROTO_INITRESPOK, PICA_MSG_FIXED_SIZE, PICA_PROTO_INITRESPOK_SIZE, procmsg_INITRESP}, - {PICA_PROTO_VERDIFFER, PICA_MSG_FIXED_SIZE, PICA_PROTO_VERDIFFER_SIZE, procmsg_INITRESP} + {PICA_PROTO_INITRESPOK, PICA_MSG_FIXED_SIZE, PICA_PROTO_INITRESPOK_SIZE, procmsg_INITRESP}, + {PICA_PROTO_VERDIFFER, PICA_MSG_FIXED_SIZE, PICA_PROTO_VERDIFFER_SIZE, procmsg_INITRESP} }; +struct PICA_msginfo c2c_init_messages[] = { + {PICA_PROTO_INITRESPOK, PICA_MSG_FIXED_SIZE, PICA_PROTO_INITRESPOK_SIZE, procmsg_INITRESP_c2c}, + {PICA_PROTO_VERDIFFER, PICA_MSG_FIXED_SIZE, PICA_PROTO_VERDIFFER_SIZE, procmsg_INITRESP_c2c} +}; // static int pem_passwd_cb(char *buf, int size, int rwflag, void *userdata) //{ @@ -206,6 +211,8 @@ chnl->conn = ci; chnl->outgoing = is_outgoing; memcpy(chnl->peer_id, peer_id, PICA_ID_SIZE); +chnl->acc = ci->acc; + chnl->timestamp = time(0); chnl->sck_data = -1;//prevent closing stdin when closing non-active connection @@ -243,7 +250,7 @@ struct sockaddr_in addr=chnl->conn->srv_addr; addr.sin_port = htons(ntohs(addr.sin_port)); ret=connect( chnl->sck_data, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)); - +/////////////////state_ if (ret==SOCKET_ERROR) { err_ret=PICA_ERRSOCK; @@ -256,13 +263,13 @@ if (mp) { if (chnl->outgoing) { - memcpy(mp->tail, chnl->conn->id, PICA_ID_SIZE);//вызвывающий + memcpy(mp->tail, chnl->acc->id, PICA_ID_SIZE);//вызвывающий memcpy(mp->tail + PICA_ID_SIZE, chnl->peer_id, PICA_ID_SIZE);//вызываемый } else { memcpy(mp->tail, chnl->peer_id, PICA_ID_SIZE);//вызвывающий - memcpy(mp->tail + PICA_ID_SIZE, chnl->conn->id, PICA_ID_SIZE);//вызываемый + memcpy(mp->tail + PICA_ID_SIZE, chnl->acc->id, PICA_ID_SIZE);//вызываемый } } else @@ -279,7 +286,7 @@ do } while( chnl->write_pos > 0); -chnl->ssl=SSL_new(chnl->conn->ctx); +chnl->ssl=SSL_new(chnl->acc->ctx); if (!chnl->ssl) { @@ -305,7 +312,7 @@ if (chnl->outgoing) ret=SSL_connect(chnl->ssl); else ret=SSL_accept(chnl->ssl); - +/////////////////state_ //printf("verify result:%i\n",(int)SSL_get_verify_result(chnl->ssl));//debug if (ret!=1) @@ -398,6 +405,10 @@ PICA_close_channel(chnl); return err_ret; } +static unsigned int procmsg_INITRESP_c2c(unsigned char* buf, unsigned int nb,void* p) +{ +} + static unsigned int procmsg_INITRESP(unsigned char* buf, unsigned int nb,void* p) { struct PICA_c2n *ci=(struct PICA_c2n *)p; @@ -987,61 +998,67 @@ signal(SIGPIPE, SIG_IGN); return 1; } -/*адрес сервера, сертификат клиента и закрытый ключ*/ +static int check_pkey_passphrase(const char *pkey_file, + int (*password_cb)(char *buf, int size, int rwflag, void *userdata), + void *userdata) +{ +RSA *rsa; +FILE *f; -//Осуществляет подключение к серверу по указанному адресу. -//Аргументы: -//nodeaddr - адрес узла -//port - номер порта, в нативном для хост-машины порядке байт -//CA_file - имя файла, содержащего корневой сертификат в формате PEM -//cert_file - имя файла, содержащего сертфикат клиента в формате PEM -//pkey_file - имя файла, содержащего приватный ключ в формате PEM -//password_cb - callback-функция, запрашивающая пароль к приватному ключу, см. man 3 SSL_CTX_set_default_passwd_cb;в userdata передается указатель на id -//ci -указатель на указатель на структуру PICA_c2n, который будет проинициализирован при успешном выполнении функции -//Память, выделенная под структуру, освобождается при вызове PICA_close_connection -//Возвращаемое значение - код завершения -//PICA_OK - успешное завершение функции -//.... -int PICA_new_connection(const char *nodeaddr, - unsigned int port, - const char *CA_file, - const char *cert_file, - const char *pkey_file, - const char *dh_param_file, - int (*password_cb)(char *buf, int size, int rwflag, void *userdata), - struct PICA_c2n **ci) +f = fopen(pkey_file, "r"); + +if (!f) + return PICA_ERRINVPKEYFILE; + +rsa = PEM_read_RSAPrivateKey(f, NULL, password_cb, userdata); + +fclose(f); + +if (!rsa) + { + unsigned long int e = ERR_get_error(); + + // 0x6065064 is an OpenSSL error code corresponding to decryption failure + if (e == 0x6065064 || strcmp("bad decrypt", ERR_reason_error_string(e)) == 0) + return PICA_ERRINVPKEYPASSPHRASE; + + return PICA_ERRINVPKEYFILE; + } + +RSA_free(rsa); + +return PICA_OK; +} + +int PICA_open_acc(const char *cert_file, + const char *pkey_file, + const char *dh_param_file, + int (*password_cb)(char *buf, int size, int rwflag, void *userdata), + struct PICA_acc **acc) { int ret,ret_err; -struct PICA_c2n *cid; -struct sockaddr_in a; DH *dh = NULL; FILE *dh_file = NULL; +struct PICA_acc *a = NULL; -if (!(nodeaddr && CA_file && cert_file && pkey_file && ci)) - return PICA_ERRINVARG; +if (!(cert_file && pkey_file && dh_param_file && acc)) + return PICA_ERRINVARG; +a = *acc = (struct PICA_acc*)calloc(sizeof(struct PICA_acc), 1);//(1) -cid=*ci=(struct PICA_c2n*)calloc(sizeof(struct PICA_c2n),1);//(1) -if (!cid) - return PICA_ERRNOMEM; +if (!a) + return PICA_ERRNOMEM; -cid->read_buf = calloc(PICA_CONNREADBUFSIZE, 1);//(2) -if (!cid->read_buf) +a->ctx = SSL_CTX_new(TLSv1_2_method());//(2) + +if (!a->ctx) { - ret_err = PICA_ERRNOMEM; + ret_err=PICA_ERRSSL; goto error_ret_1; } -cid->ctx=SSL_CTX_new(TLSv1_2_method());//(3) - -if (!cid->ctx) - { - ret_err=PICA_ERRSSL; - goto error_ret_2; - } - dh_file = fopen(dh_param_file, "r"); if (dh_file) @@ -1050,45 +1067,56 @@ if (dh_file) fclose(dh_file); } -if (1 != SSL_CTX_set_tmp_dh(cid->ctx, dh)) +if (1 != SSL_CTX_set_tmp_dh(a->ctx, dh)) { ret_err = PICA_ERRSSL; goto error_ret_2; } -DH_free (dh); +DH_free(dh); -if (!PICA_get_id_from_cert_file(cert_file, cid->id)) +if (!PICA_get_id_from_cert_file(cert_file, a->id)) { - ret_err=PICA_ERRINVCERT; - goto error_ret_3; + ret_err = PICA_ERRINVCERT; + goto error_ret_2; + } + +ret = check_pkey_passphrase(pkey_file, password_cb, a->id); + +if (ret != PICA_OK) + { + ret_err = ret; + goto error_ret_2; } + ////<< if (password_cb) { - SSL_CTX_set_default_passwd_cb(cid->ctx, password_cb); - SSL_CTX_set_default_passwd_cb_userdata(cid->ctx,cid->id); + SSL_CTX_set_default_passwd_cb(a->ctx, password_cb); + SSL_CTX_set_default_passwd_cb_userdata(a->ctx, a->id); } -ret=SSL_CTX_use_certificate_file(cid->ctx,cert_file,SSL_FILETYPE_PEM); -if (ret!=1) - {//ERR_CHECK - ret_err=PICA_ERRSSL; - goto error_ret_3; - } -ret=SSL_CTX_use_PrivateKey_file(cid->ctx,pkey_file,SSL_FILETYPE_PEM); -if (ret!=1) - {//ERR_CHECK - ret_err=PICA_ERRSSL; - goto error_ret_3; +ret = SSL_CTX_use_certificate_file(a->ctx, cert_file, SSL_FILETYPE_PEM); + +if (ret != 1) + { + ret_err=PICA_ERRSSL; + goto error_ret_2; + } + +ret = SSL_CTX_use_PrivateKey_file(a->ctx, pkey_file, SSL_FILETYPE_PEM); +if (ret != 1) + { + ret_err = PICA_ERRSSL; + goto error_ret_2; } ////<< -ret=SSL_CTX_load_verify_locations(cid->ctx,CA_file,0/*"trustedCA/"*/); +//ret=SSL_CTX_load_verify_locations(cid->ctx,CA_file,0/*"trustedCA/"*/); //printf("loadverifylocations ret=%i\n",ret);//debug -SSL_CTX_set_client_CA_list(cid->ctx,SSL_load_client_CA_file(CA_file)); +//SSL_CTX_set_client_CA_list(cid->ctx,SSL_load_client_CA_file(CA_file)); -ret = SSL_CTX_set_cipher_list(cid->ctx,"DHE-RSA-CAMELLIA256-SHA"/*:DHE-RSA-AES256-SHA256"*/); +ret = SSL_CTX_set_cipher_list(a->ctx,"DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CAMELLIA256-SHA"); if (ret != 1) { @@ -1096,13 +1124,66 @@ if (ret != 1) goto error_ret_2; } +return PICA_OK; + +error_ret_2: //(2) +SSL_CTX_free(a->ctx); + +error_ret_1: //(1) +free(a); +*acc = 0; + +return ret_err; +} + +/*адрес сервера, сертификат клиента и закрытый ключ*/ + +//Осуществляет подключение к серверу по указанному адресу. +//Аргументы: +//nodeaddr - адрес узла +//port - номер порта, в нативном для хост-машины порядке байт +//CA_file - имя файла, содержащего корневой сертификат в формате PEM +//cert_file - имя файла, содержащего сертфикат клиента в формате PEM +//pkey_file - имя файла, содержащего приватный ключ в формате PEM +//password_cb - callback-функция, запрашивающая пароль к приватному ключу, см. man 3 SSL_CTX_set_default_passwd_cb;в userdata передается указатель на id +//ci -указатель на указатель на структуру PICA_c2n, который будет проинициализирован при успешном выполнении функции +//Память, выделенная под структуру, освобождается при вызове PICA_close_connection +//Возвращаемое значение - код завершения +//PICA_OK - успешное завершение функции +//.... + +int PICA_new_connection(const struct PICA_acc *acc, const char *nodeaddr, + unsigned int port, + struct PICA_c2n **ci) +{ +int ret,ret_err; +struct PICA_c2n *cid; +struct sockaddr_in a; + + +if (!(nodeaddr && acc && port && ci)) + return PICA_ERRINVARG; + + +cid=*ci=(struct PICA_c2n*)calloc(sizeof(struct PICA_c2n),1);//(1) +if (!cid) + return PICA_ERRNOMEM; -cid->ssl_comm=SSL_new(cid->ctx);//(4) +cid->acc = acc; + +cid->read_buf = calloc(PICA_CONNREADBUFSIZE, 1);//(2) +if (!cid->read_buf) + { + ret_err = PICA_ERRNOMEM; + goto error_ret_1; + } + +cid->ssl_comm=SSL_new(acc->ctx);//(3) if (!cid->ssl_comm) { ret_err=PICA_ERRSSL; - goto error_ret_3; + goto error_ret_2; } @@ -1144,18 +1225,18 @@ cid->sck_comm=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//(5) if (cid->sck_comm==SOCKET_ERROR) { ret_err=PICA_ERRSOCK; - goto error_ret_4; + goto error_ret_3; } cid->state = PICA_CONNSTATE_CONNECTING; ret=connect(cid->sck_comm,(struct sockaddr*)&a,sizeof(struct sockaddr_in)); - +/////////////////state_ if (ret==SOCKET_ERROR) { ret_err=PICA_ERRSOCK; - goto error_ret_5; + goto error_ret_4; } @@ -1172,10 +1253,12 @@ if (mp) else { ret_err = PICA_ERRNOMEM; - goto error_ret_5; + goto error_ret_4; } } +cid->state = PICA_CONNSTATE_WAITINGREP; + do { ret = PICA_write_c2n(cid); @@ -1204,7 +1287,7 @@ if (cid->init_resp_ok != 1) else ret_err = PICA_ERRPROTOOLD; } - goto error_ret_5; + goto error_ret_4; } //printf("6\n");//debug @@ -1214,13 +1297,14 @@ ret=SSL_set_fd(cid->ssl_comm,cid->sck_comm); //printf("SSL_set_fd=%i\n",ret); ret=SSL_accept(cid->ssl_comm); - +/////////////////state_ +cid->state = PICA_CONNSTATE_WAITINGTLS; if (ret!=1) { //printf("SSL_accept ret=%i\n SSL_get_error=%i\n",ret,SSL_get_error(cid->ssl_comm,ret));//debug //ERR_CHECK ret_err=PICA_ERRSSL; - goto error_ret_5; + goto error_ret_4; } cid->state = PICA_CONNSTATE_CONNECTED;//<<sck_comm, &arg); return PICA_OK; -error_ret_5: //(5) +error_ret_4: //(4) SHUTDOWN(cid->sck_comm); CLOSE(cid->sck_comm); -error_ret_4: //(4) - SSL_free(cid->ssl_comm); - error_ret_3: //(3) - SSL_CTX_free(cid->ctx); + SSL_free(cid->ssl_comm); error_ret_2: //(2) free(cid->read_buf); @@ -1268,7 +1349,7 @@ return ret_err; //создает ИСХОДЯЩИЙ логический зашифрованный канал связи с указанным собеседником, если тот доступен // в данный момент. -int PICA_create_channel(struct PICA_c2n *ci,const unsigned char *peer_id,struct PICA_c2c **chn) +int PICA_create_channel(struct PICA_c2n *ci,const unsigned char *peer_id, struct PICA_listener *l,struct PICA_c2c **chn) { struct PICA_proto_msg *mp; struct PICA_c2c *chnl; @@ -1294,6 +1375,11 @@ mp = c2n_writebuf_push( ci, PICA_PROTO_CONNREQOUTG, PICA_PROTO_CONNREQOUTG_SIZE) return PICA_OK; } +int PICA_event_loop(struct PICA_c2n **connections, struct PICA_listener **listeners) +{ + +} + int PICA_read(struct PICA_c2n *ci,int timeout) { fd_set fds; @@ -1614,6 +1700,11 @@ int PICA_read_c2n(struct PICA_c2n *ci) { int ret; +switch(ci->state) +{ +//<<< +} + //ret=SSL_read(ci->ssl_comm, ci->read_buf + ci->read_pos, PICA_CONNREADBUFSIZE - ci->read_pos); if (PICA_CONNSTATE_CONNECTING == ci->state) ret = PICA_read_socket(ci->sck_comm, ci->read_buf, &ci->read_pos, PICA_CONNREADBUFSIZE); @@ -2006,7 +2097,7 @@ SSL_shutdown(cid->ssl_comm); SSL_free(cid->ssl_comm); SHUTDOWN(cid->sck_comm); CLOSE(cid->sck_comm); -SSL_CTX_free(cid->ctx); + free(cid->read_buf); if (cid->write_buf) @@ -2015,6 +2106,11 @@ if (cid->write_buf) free(cid); } +void PICA_close_acc(struct PICA_acc *a) +{ +SSL_CTX_free(a->ctx); +} + #ifdef WIN32 const char *PICA_inet_ntop(int af, const void *src, char *dst, size_t size) { diff --git a/PICA_client.h b/PICA_client.h index cbd3ed8..bf4a2de 100755 --- a/PICA_client.h +++ b/PICA_client.h @@ -87,6 +87,9 @@ typedef unsigned __int64 uint64_t; #define PICA_ERRFILEOPEN -20 #define PICA_ERRFILEIO -21 +#define PICA_ERRINVPKEYPASSPHRASE -22 +#define PICA_ERRINVPKEYFILE -23 + //#define PICA_CHNMSGBUFLEN 104 #define PICA_CHANREADBUFSIZE 65536 @@ -96,7 +99,10 @@ typedef unsigned __int64 uint64_t; #define PICA_FILEFRAGMENTSIZE 16384 //max size of TLS record #define PICA_CHANSTATE_ACTIVE 13 + #define PICA_CONNSTATE_CONNECTING 17 +#define PICA_CONNSTATE_WAITINGREP 18 +#define PICA_CONNSTATE_WAITINGTLS 21 #define PICA_CONNSTATE_CONNECTED 19 #define PICA_CHANSENDFILESTATE_IDLE 0 @@ -118,12 +124,19 @@ typedef unsigned __int64 uint64_t; struct PICA_c2n; struct PICA_c2c; +struct PICA_acc +{ +unsigned char id[PICA_ID_SIZE]; //SHA224 hash of user's certificate in DER format +SSL_CTX* ctx; +}; + struct PICA_c2n { +struct PICA_acc *acc; //#warning "sockaddr!" struct sockaddr_in srv_addr; // sockaddr !! -unsigned char id[PICA_ID_SIZE]; //SHA224 hash of user's certificate in DER format -SSL_CTX* ctx; +//unsigned char id[PICA_ID_SIZE]; //SHA224 hash of user's certificate in DER format +//SSL_CTX* ctx; SOCKET sck_comm; SSL* ssl_comm; @@ -146,6 +159,7 @@ unsigned char node_ver_major, node_ver_minor; struct PICA_c2c { +struct PICA_acc *acc; struct PICA_c2n *conn;//соединение с сервером, через которое установлен данный логический канал связи unsigned char peer_id[PICA_ID_SIZE]; SOCKET sck_data; @@ -176,6 +190,19 @@ uint64_t recvfile_pos; FILE *recvfile_stream; }; +struct PICA_listener +{ +struct PICA_acc *acc; +SOCKET sck_listener; + +int public_port; +int local_port; + +in_addr_t public_addr_ipv4; +const char *public_addr_dns; + +}; + struct PICA_client_callbacks { //получение сообщения. @@ -224,21 +251,37 @@ int PICA_get_id_from_cert_string(const char *cert_pem, unsigned char *id); int PICA_client_init(struct PICA_client_callbacks *clcbs); int PICA_new_connection - (const char *nodeaddr, - unsigned int port, - const char *CA_file, + (const struct PICA_acc *acc, + const char *nodeaddr, + unsigned int port, +/* const char *CA_file, const char *cert_file, const char *pkey_file, const char *dh_param_file, - int (*password_cb)(char *buf, int size, int rwflag, void *userdata), + int (*password_cb)(char *buf, int size, int rwflag, void *userdata), //move callback to PICA_client_callbacks? */ struct PICA_c2n **ci); -int PICA_create_channel(struct PICA_c2n *ci,const unsigned char *peer_id,struct PICA_c2c **chn); +int PICA_create_channel(struct PICA_c2n *ci,const unsigned char *peer_id, struct PICA_listener *l,struct PICA_c2c **chn); + +int PICA_new_listener(const char *public_addr, int public_port, int local_port, struct PICA_listener **l); + + +// << Date: Fri, 13 Mar 2015 03:45:11 +0400 Subject: updated client library calls in pica-client and fixed password asking dialog behaviour, now invalid password error is detected and asked again, cancel button is handled --- pica-client/askpassword.cpp | 73 +++++++++++++++++++++++++++++++++++---------- pica-client/askpassword.h | 8 ++++- pica-client/nodethread.cpp | 7 +++-- pica-client/nodethread.h | 4 +-- pica-client/skynet.cpp | 31 +++++++++++++++---- pica-client/skynet.h | 1 + 6 files changed, 98 insertions(+), 26 deletions(-) diff --git a/pica-client/askpassword.cpp b/pica-client/askpassword.cpp index a171217..70f8644 100644 --- a/pica-client/askpassword.cpp +++ b/pica-client/askpassword.cpp @@ -2,38 +2,54 @@ #include "globals.h" #include #include +#include #include "accounts.h" QMutex AskPassword::passwd_mutex; -QMap AskPassword::idpasswd; +char AskPassword::current_password[256]; +int AskPassword::is_invalid = 0; +int AskPassword::is_cancelled = 0; +int AskPassword::is_set = 0; AskPassword::AskPassword(QObject *parent) : QObject(parent) { - connect(this,SIGNAL(password_requested()),this,SLOT(password_dialog()),Qt::BlockingQueuedConnection); + connect(this,SIGNAL(password_requested()),this,SLOT(password_dialog()), Qt::BlockingQueuedConnection); +} + +AskPassword::~AskPassword() +{ + memset(current_password, 0, sizeof(current_password)); } int AskPassword::ask_password_cb(char *buf, int size, int rwflag, void *userdata) { - QString pswd; - QByteArray id = QByteArray((const char*) userdata, PICA_ID_SIZE); + //QString pswd; + //QByteArray id = QByteArray((const char*) userdata, PICA_ID_SIZE); + + if (is_cancelled) + return 0; passwd_mutex.lock(); - if (idpasswd.contains(id)) + if (!is_set || is_invalid) { - pswd = idpasswd[id]; + if (askpassword->thread() != QThread::currentThread()) + askpassword->emit_sig(); + else + askpassword->password_dialog(); } - else + + if (is_set) { - askpassword->emit_sig(); - pswd = idpasswd[id]; + strncpy(buf, current_password, size); + buf[size - 1] = 0; } + passwd_mutex.unlock(); - strncpy(buf, pswd.toUtf8().constData(), size); - buf[size - 1] = 0; - return(strlen(buf)); + + return is_set ? (strlen(buf)) : 0; } void AskPassword::emit_sig() @@ -41,15 +57,42 @@ void AskPassword::emit_sig() emit password_requested(); } +void AskPassword::clear() +{ + passwd_mutex.lock(); + is_invalid = 0; + is_set = 0; + is_cancelled = 0; + memset(current_password, 0, sizeof(current_password)); + passwd_mutex.unlock(); + +} + +void AskPassword::setInvalidPassword() +{ + passwd_mutex.lock(); + is_invalid = 1; + memset(current_password, 0, sizeof(current_password)); + passwd_mutex.unlock(); +} + void AskPassword::password_dialog() { - bool ok; - QString title = QObject::tr("Enter private key passphrase"); + bool ok = false; + QString title = is_invalid ? QObject::tr("Invalid passphrase, try again") : QObject::tr("Enter private key passphrase"); QString text = QObject::tr(QString("Passphrase for account %1 \n (%2)") .arg(Accounts::GetCurrentAccount().name) .arg(Accounts::GetCurrentAccount().id.toBase64().constData()).toUtf8().constData()); QString psw = QInputDialog::getText((QWidget*)mainwindow,title,text,QLineEdit::Password,QString(),&ok); + if (ok) - idpasswd[Accounts::GetCurrentAccount().id] = psw; + { + strncpy(current_password, psw.toUtf8().constData(), sizeof(current_password)); + current_password[sizeof(current_password) - 1] = 0; + is_set = 1; + is_invalid = 0; + } + else + is_cancelled = 1; } diff --git a/pica-client/askpassword.h b/pica-client/askpassword.h index 6abc009..9deb691 100644 --- a/pica-client/askpassword.h +++ b/pica-client/askpassword.h @@ -10,12 +10,18 @@ class AskPassword : public QObject Q_OBJECT public: explicit AskPassword(QObject *parent = 0); + ~AskPassword(); static int ask_password_cb(char *buf, int size, int rwflag, void *userdata); + static void setInvalidPassword(); + static void clear(); private: void emit_sig(); - static QMap idpasswd; static QMutex passwd_mutex; + static char current_password[256]; + static int is_cancelled; + static int is_invalid; + static int is_set; signals: void password_requested(); diff --git a/pica-client/nodethread.cpp b/pica-client/nodethread.cpp index 3850397..579b84b 100644 --- a/pica-client/nodethread.cpp +++ b/pica-client/nodethread.cpp @@ -6,7 +6,7 @@ QMutex NodeThread::finished_mutex; -NodeThread::NodeThread(Nodes::NodeRecord &addr, bool *completed, Accounts::AccountRecord &acc, PICA_c2n **pica_conn, QMutex *wm) : +NodeThread::NodeThread(Nodes::NodeRecord &addr, bool *completed, PICA_acc *acc, PICA_c2n **pica_conn, QMutex *wm) : QThread(0) { node_addr = addr; @@ -23,14 +23,15 @@ void NodeThread::run() int ret; exit = 0; - ret = PICA_new_connection(node_addr.address.toUtf8().constData(), + /*ret = PICA_new_connection(node_addr.address.toUtf8().constData(), node_addr.port, user_account.CA_file.toUtf8().constData(), user_account.cert_file.toUtf8().constData(), user_account.pkey_file.toUtf8().constData(), DHParam::GetDHParamFilename().toUtf8().constData(), AskPassword::ask_password_cb, - &ci); + &ci);*/ + ret = PICA_new_connection(user_account, node_addr.address.toUtf8().constData(), node_addr.port, &ci); switch(ret) { diff --git a/pica-client/nodethread.h b/pica-client/nodethread.h index 524688e..8974255 100644 --- a/pica-client/nodethread.h +++ b/pica-client/nodethread.h @@ -12,7 +12,7 @@ class NodeThread : public QThread { Q_OBJECT public: - explicit NodeThread( Nodes::NodeRecord &addr, bool *completed,Accounts::AccountRecord &acc,struct PICA_c2n **pica_conn, QMutex *wm); + explicit NodeThread( Nodes::NodeRecord &addr, bool *completed, PICA_acc *acc,struct PICA_c2n **pica_conn, QMutex *wm); void CloseThread(); private: void run(); @@ -23,7 +23,7 @@ private: bool *finished_flag; Nodes::NodeRecord node_addr; struct PICA_c2n *ci; - Accounts::AccountRecord user_account; + struct PICA_acc *user_account; struct PICA_c2n **connection; int exit; diff --git a/pica-client/skynet.cpp b/pica-client/skynet.cpp index fda9a31..122df47 100644 --- a/pica-client/skynet.cpp +++ b/pica-client/skynet.cpp @@ -8,6 +8,8 @@ //#include "dialogs/forgedcertdialog.h" #include #include "history.h" +#include "dhparam.h" +#include "askpassword.h" SkyNet::SkyNet() : nodes(config_dbname), QObject(0) @@ -91,7 +93,7 @@ void SkyNet::nodethread_connected(QString addr, quint16 port, NodeThread *thread write_mutex.lock(); struct PICA_c2c *chan = NULL; - ret = PICA_create_channel(nodelink, (const unsigned char*)c2c_peer_ids[i].constData(), &chan); + ret = PICA_create_channel(nodelink, (const unsigned char*)c2c_peer_ids[i].constData(), NULL, &chan); qDebug()<<"restoring channel to "< nodelist; skynet_account = accrec; nodelist = nodes.GetNodes(); + int ret; + + AskPassword::clear(); + do + { + ret = PICA_open_acc(skynet_account.cert_file.toUtf8().constData(), + skynet_account.pkey_file.toUtf8().constData(), + DHParam::GetDHParamFilename().toUtf8().constData(), + AskPassword::ask_password_cb, + &acc); + + if (ret == PICA_ERRINVPKEYPASSPHRASE) + AskPassword::setInvalidPassword(); + } while (ret == PICA_ERRINVPKEYPASSPHRASE); + + qDebug() << "PICA_open_acc() returned " << ret; + + if (ret != PICA_OK) + return; if (nodelist.count()==0) { @@ -213,7 +234,7 @@ void SkyNet::Join(Accounts::AccountRecord &accrec) for (int i=0;i l; l.append(filepath); @@ -401,7 +422,7 @@ if ( (iptr = find_active_chan(to)) ) { struct PICA_c2c *chan = NULL; - ret = PICA_create_channel(nodelink, (const unsigned char*)to.constData(), &chan); + ret = PICA_create_channel(nodelink, (const unsigned char*)to.constData(), NULL, &chan); QList l; l.append(msg); diff --git a/pica-client/skynet.h b/pica-client/skynet.h index a0f974b..41aac0d 100644 --- a/pica-client/skynet.h +++ b/pica-client/skynet.h @@ -63,6 +63,7 @@ private: bool self_aware; QString status; struct PICA_c2n *nodelink; + struct PICA_acc *acc; Accounts::AccountRecord skynet_account; QMutex write_mutex; QMap > msgqueues; -- cgit v1.2.1 From a32462dd698ebf58615a5fed3af5b50c28df9fce Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 16 Mar 2015 23:56:02 +0400 Subject: updated test client --- PICA_client.c | 2 +- tests/test_client | Bin 35075 -> 0 bytes tests/test_client.c | 13 +++++++++++-- 3 files changed, 12 insertions(+), 3 deletions(-) delete mode 100755 tests/test_client diff --git a/PICA_client.c b/PICA_client.c index 4b6f3a9..0f6460d 100755 --- a/PICA_client.c +++ b/PICA_client.c @@ -1257,7 +1257,7 @@ else } } -cid->state = PICA_CONNSTATE_WAITINGREP; +//cid->state = PICA_CONNSTATE_WAITINGREP; do { diff --git a/tests/test_client b/tests/test_client deleted file mode 100755 index a384dee..0000000 Binary files a/tests/test_client and /dev/null differ diff --git a/tests/test_client.c b/tests/test_client.c index 9ea2de2..a94951c 100755 --- a/tests/test_client.c +++ b/tests/test_client.c @@ -6,6 +6,7 @@ struct sockaddr_in a; +struct PICA_acc *acc; struct PICA_c2n *c; struct PICA_c2c *chn; @@ -121,11 +122,19 @@ PICA_client_init(&cbs); // a.sin_addr.s_addr = inet_addr (argv[1]);//("127.0.0.1"); // a.sin_port = htons(51914); +printf("opening account..."); +ret = PICA_open_acc(argv[3], argv[3],argv[3], NULL, &acc); + +if (ret != PICA_OK) +{ + printf("failed to open account, ret = %i\n", ret); + return 1; +} printf("making connection...\n"); //PICA_new_connection(const char *nodeaddr, unsigned int port, const char *CA_file, const char *cert_file, const char *pkey_file, const char* password, struct PICA_c2n **ci) -ret=PICA_new_connection(argv[1], atoi(argv[2]), /*"trusted_CA.pem"*/ argv[3], argv[3],argv[3],NULL,&c); +ret=PICA_new_connection(acc, argv[1], atoi(argv[2]), /*"trusted_CA.pem"*/ &c); ERR_print_errors_fp(stdout); @@ -147,7 +156,7 @@ if (argc==5) printf("Creating channel to %s...\n",PICA_id_to_base64(peer_id, NULL)); - ret=PICA_create_channel(c,peer_id,&chn); + ret=PICA_create_channel(c,peer_id,NULL,&chn); //sleep(17);//timeout test if (ret!=PICA_OK) { -- cgit v1.2.1 From 0a71ba2f66ce2a56d4ada62ef28bbb3f2ba7b991 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 30 Mar 2015 00:43:24 +0400 Subject: added missing free() call for PICA_acc struct in PICA_close_acc() --- PICA_client.c | 1 + 1 file changed, 1 insertion(+) diff --git a/PICA_client.c b/PICA_client.c index 0f6460d..286e163 100755 --- a/PICA_client.c +++ b/PICA_client.c @@ -2109,6 +2109,7 @@ free(cid); void PICA_close_acc(struct PICA_acc *a) { SSL_CTX_free(a->ctx); +free(a); } #ifdef WIN32 -- cgit v1.2.1 From e3d99b9dc12974ba13806e0c344a52f6c02d4ba6 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 30 Mar 2015 00:57:46 +0400 Subject: do not open account again if already opened, fixed memory leak, added new method SkyNet::open_account() --- pica-client/skynet.cpp | 25 +++++++++++++++++++------ pica-client/skynet.h | 1 + 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/pica-client/skynet.cpp b/pica-client/skynet.cpp index 122df47..9d66377 100644 --- a/pica-client/skynet.cpp +++ b/pica-client/skynet.cpp @@ -36,7 +36,8 @@ PICA_client_callbacks cbs = { PICA_client_init(&cbs); -nodelink = NULL; +this->nodelink = NULL; +this->acc = NULL; connect(this, SIGNAL(PeerCertificateReceived(QByteArray,QString,bool*)), this, SLOT(verify_peer_cert(QByteArray,QString,bool*)),Qt::DirectConnection); @@ -201,11 +202,8 @@ else } } -void SkyNet::Join(Accounts::AccountRecord &accrec) +bool SkyNet::open_account() { - QList nodelist; - skynet_account = accrec; - nodelist = nodes.GetNodes(); int ret; AskPassword::clear(); @@ -224,7 +222,22 @@ void SkyNet::Join(Accounts::AccountRecord &accrec) qDebug() << "PICA_open_acc() returned " << ret; if (ret != PICA_OK) - return; + return false; + + return true; +} + +void SkyNet::Join(Accounts::AccountRecord &accrec) +{ + QList nodelist; + skynet_account = accrec; + nodelist = nodes.GetNodes(); + + if (!acc) + { + if (!open_account()) + return; + } if (nodelist.count()==0) { diff --git a/pica-client/skynet.h b/pica-client/skynet.h index 41aac0d..4df41db 100644 --- a/pica-client/skynet.h +++ b/pica-client/skynet.h @@ -75,6 +75,7 @@ private: void flush_queues(QByteArray to); struct PICA_c2c *find_active_chan(QByteArray peer_id); QList filter_existing_chans(QList peer_ids); + bool open_account(); void emit_MessageReceived(QByteArray from, QString msg); void emit_UnableToDeliver(QByteArray to, QString msg); -- cgit v1.2.1 From 4c69b79f681490bcd71c86fc30f5e37300eb91f1 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 30 Mar 2015 03:53:09 +0400 Subject: implemented PICA_new_listener() and PICA_close_listener() --- PICA_client.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ PICA_client.h | 2 +- 2 files changed, 95 insertions(+), 1 deletion(-) diff --git a/PICA_client.c b/PICA_client.c index 286e163..12e3f68 100755 --- a/PICA_client.c +++ b/PICA_client.c @@ -1031,6 +1031,93 @@ RSA_free(rsa); return PICA_OK; } +// Opens socket to listen for incoming direct c2c connections bypassing nodes +// +// acc - pointer to opened account +// +// public_addr - DNS name or IP address string, +// it is an address that will be used for connecting from global Internet. +// Should be set to router's external IP if computer running pica-client is located behind the NAT. +// +// public_port - TCP port for incoming connections from global Internet +// +// local_port - TCP port that will be actually opened on computer listening for direct c2c connections +// +// l - address of pointer that will be filled with address of created PICA_listener structure +// +int PICA_new_listener(const struct PICA_acc *acc,const char *public_addr, int public_port, int local_port, struct PICA_listener **l) +{ + int ret, ret_err, flag; + struct PICA_listener *lst = NULL; + struct sockaddr_in s; + + + if (!acc || !public_addr || public_port <= 0 || public_port > 65535 || local_port <= 0 || local_port > 65535 || !l) + return PICA_ERRINVARG; + + lst = *l = (struct PICA_listener*)calloc(sizeof(struct PICA_listener), 1); + + if (!lst) + return PICA_ERRNOMEM; + + lst->public_addr_dns = strdup(public_addr); + + if (!lst->public_addr_dns) + return PICA_ERRNOMEM; + + lst->public_addr_ipv4 = inet_addr(public_addr); + + lst->acc = acc; + lst->public_port = public_port; + lst->local_port = local_port; + + lst->sck_listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //(1) + + if (lst->sck_listener == SOCKET_ERROR) + { + ret_err = PICA_ERRSOCK; + goto error_ret_1; + } + + flag = 1; + setsockopt(lst->sck_listener, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)); + + memset(&s, 0, sizeof(s)); + s.sin_family = AF_INET; + s.sin_addr.s_addr = INADDR_ANY; + s.sin_port = htons(local_port); + + ret = bind(lst->sck_listener, (const struct sockaddr*) &s, sizeof(s));//(2) + + if (ret == SOCKET_ERROR) + { + ret_err = PICA_ERRSOCK; + goto error_ret_2; + } + + ret = listen(lst->sck_listener, 10); + + if (ret == SOCKET_ERROR) + { + ret_err = PICA_ERRSOCK; + goto error_ret_2; + } + + return PICA_OK; + + error_ret_2: //(2) + + CLOSE(lst->sck_listener); + + error_ret_1: //(1) + + free(lst->public_addr_dns); + free(lst); + *l = 0; + + return ret_err; +} + int PICA_open_acc(const char *cert_file, const char *pkey_file, const char *dh_param_file, @@ -2112,6 +2199,13 @@ SSL_CTX_free(a->ctx); free(a); } +void PICA_close_listener(struct PICA_listener *l) +{ +CLOSE(l->sck_listener); +free(l->public_addr_dns); +free(l); +} + #ifdef WIN32 const char *PICA_inet_ntop(int af, const void *src, char *dst, size_t size) { diff --git a/PICA_client.h b/PICA_client.h index bf4a2de..d37e0f0 100755 --- a/PICA_client.h +++ b/PICA_client.h @@ -263,7 +263,7 @@ int PICA_new_connection int PICA_create_channel(struct PICA_c2n *ci,const unsigned char *peer_id, struct PICA_listener *l,struct PICA_c2c **chn); -int PICA_new_listener(const char *public_addr, int public_port, int local_port, struct PICA_listener **l); +int PICA_new_listener(const struct PICA_acc *acc, const char *public_addr, int public_port, int local_port, struct PICA_listener **l); // << Date: Mon, 6 Apr 2015 02:19:07 +0400 Subject: implementing PICA_event_loop(), created enums for c2n and c2c states --- PICA_client.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- PICA_client.h | 29 +++++++++++++++++--------- 2 files changed, 81 insertions(+), 15 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 12e3f68..4e2bcdd 100755 --- a/PICA_client.c +++ b/PICA_client.c @@ -1462,8 +1462,69 @@ mp = c2n_writebuf_push( ci, PICA_PROTO_CONNREQOUTG, PICA_PROTO_CONNREQOUTG_SIZE) return PICA_OK; } -int PICA_event_loop(struct PICA_c2n **connections, struct PICA_listener **listeners) +static void fdset_add(fd_set *fds, int fd, int *max) { +FD_SET(fd, fds); + +if (fd > *max) + *max = fd; +} + +int PICA_event_loop(struct PICA_c2n **connections, struct PICA_listener **listeners, int timeout) +{ +fd_set rfds, wfds; +struct timeval tv; +int ret, nfds = 0; +struct PICA_c2n **ic2n; +struct PICA_listener **ilst; + +tv.tv_sec = timeout / 1000; +tv.tv_usec = (timeout % 1000) * 1000; + +FD_ZERO(&rfds); +FD_ZERO(&wfds); + +ilst = listeners; + +while(ilst && *ilst) + { + fdset_add(&rfds, (*ilst)->sck_listener, &nfds); + ilst++; + } + +ic2n = connections; + +while(ic2n && *ic2n) + { + struct PICA_c2c *ic2c; + + fdset_add(&rfds, (*ic2n)->sck_comm, &nfds); + + if ((*ic2n)->write_pos) + fdset_add(&wfds, (*ic2n)->sck_comm, &nfds); + + ic2c = (*ic2n)->chan_list_head; + + while(ic2c) + { + if (ic2c->state == PICA_CHANSTATE_ACTIVE) + { + fdset_add(&rfds, ic2c->sck_data, &nfds); + + if (ic2c->write_pos) + fdset_add(&wfds, ic2c->sck_data, &nfds); + } + + ic2c = ic2c->next; + } + + ic2n++; + } + + + +ret = select(nfds + 1, &rfds, &wfds, NULL, &tv); + } @@ -1787,10 +1848,6 @@ int PICA_read_c2n(struct PICA_c2n *ci) { int ret; -switch(ci->state) -{ -//<<< -} //ret=SSL_read(ci->ssl_comm, ci->read_buf + ci->read_pos, PICA_CONNREADBUFSIZE - ci->read_pos); if (PICA_CONNSTATE_CONNECTING == ci->state) diff --git a/PICA_client.h b/PICA_client.h index d37e0f0..1d40612 100755 --- a/PICA_client.h +++ b/PICA_client.h @@ -98,13 +98,6 @@ typedef unsigned __int64 uint64_t; #define PICA_CONNWRITEBUFSIZE 4096 #define PICA_FILEFRAGMENTSIZE 16384 //max size of TLS record -#define PICA_CHANSTATE_ACTIVE 13 - -#define PICA_CONNSTATE_CONNECTING 17 -#define PICA_CONNSTATE_WAITINGREP 18 -#define PICA_CONNSTATE_WAITINGTLS 21 -#define PICA_CONNSTATE_CONNECTED 19 - #define PICA_CHANSENDFILESTATE_IDLE 0 #define PICA_CHANSENDFILESTATE_SENTREQ 20 #define PICA_CHANSENDFILESTATE_SENDING 22 @@ -130,6 +123,15 @@ unsigned char id[PICA_ID_SIZE]; //SHA224 hash of user's certificate in DER forma SSL_CTX* ctx; }; +enum PICA_c2n_state +{ +PICA_CONNSTATE_NONE = 0, +PICA_CONNSTATE_CONNECTING, +PICA_CONNSTATE_WAITINGREP, +PICA_CONNSTATE_WAITINGTLS, +PICA_CONNSTATE_CONNECTED +}; + struct PICA_c2n { struct PICA_acc *acc; @@ -141,7 +143,7 @@ SOCKET sck_comm; SSL* ssl_comm; -int state; +enum PICA_c2n_state state; unsigned char *read_buf; unsigned char *write_buf; @@ -157,6 +159,12 @@ int init_resp_ok; unsigned char node_ver_major, node_ver_minor; }; +enum PICA_c2c_state +{ +PICA_CHANSTATE_NONE = 0, +PICA_CHANSTATE_ACTIVE +}; + struct PICA_c2c { struct PICA_acc *acc; @@ -177,7 +185,7 @@ unsigned int write_sslbytestowrite; struct PICA_c2c *next; struct PICA_c2c *prev; -int state; +PICA_c2c_state state; time_t timestamp; int sendfilestate; uint64_t sendfile_size; @@ -280,7 +288,8 @@ int PICA_read(struct PICA_c2n *ci,int timeout); int PICA_write(struct PICA_c2n *ci); //connections, listeners - NULL-terminated arrays of pointers to appropriate structures -int PICA_event_loop(struct PICA_c2n **connections, struct PICA_listener **listeners); +// timeout - timeout in milliseconds +int PICA_event_loop(struct PICA_c2n **connections, struct PICA_listener **listeners, int timeout); int PICA_send_msg(struct PICA_c2c *chn, char *buf,unsigned int len); int PICA_read_msg(struct PICA_c2c *chn,char *buf,unsigned int *n); -- cgit v1.2.1 From 0672d6c3a65dc6246a5e17caa92c1bf2fdf7136b Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 9 Apr 2015 01:29:34 +0400 Subject: implementation of PICA_event_loop(), work in progress --- PICA_client.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- PICA_client.h | 2 +- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 4e2bcdd..c7eeabf 100755 --- a/PICA_client.c +++ b/PICA_client.c @@ -1462,6 +1462,25 @@ mp = c2n_writebuf_push( ci, PICA_PROTO_CONNREQOUTG, PICA_PROTO_CONNREQOUTG_SIZE) return PICA_OK; } +static int process_c2n(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) +{ + +} + +static int process_c2c(struct PICA_c2c *c2c, fd_set *rfds, fd_set *wfds) +{ +//if (ic2c->state == PICA_CHANSTATE_ACTIVE) +// { +// +// } + +} + +static int process_listener(struct PICA_listener *lst, fd_set *rfds) +{ + +} + static void fdset_add(fd_set *fds, int fd, int *max) { FD_SET(fd, fds); @@ -1522,10 +1541,59 @@ while(ic2n && *ic2n) } - ret = select(nfds + 1, &rfds, &wfds, NULL, &tv); +if (ret == 0) + return PICA_OK; + +if (ret == -1) + { +#ifndef WIN32 + if (errno == EINTR) + return PICA_OK; + else + return PICA_ERRSOCK; +#else +#warning "implement handling of select() errors on Windows!" +#endif + } + +//processing listeners, c2n and c2c connections + +ilst = listeners; +while(ilst && *ilst) + { + ret = process_listener(*ilst, &rfds); + + if (ret != PICA_OK) + return ret; + + ilst++; + } + +while(ic2n && *ic2n) + { + struct PICA_c2c *ic2c; + + //processing current c2n + + ret = process_c2n(*ic2n, &rfds, &wfds); + + ic2c = (*ic2n)->chan_list_head; + + //processing c2c connections associated with current c2n + while(ic2c) + { + ret = process_c2c(ic2c, &rfds, &wfds); + + ic2c = ic2c->next; + } + + ic2n++; + } + +return PICA_OK; } int PICA_read(struct PICA_c2n *ci,int timeout) diff --git a/PICA_client.h b/PICA_client.h index 1d40612..8e1778f 100755 --- a/PICA_client.h +++ b/PICA_client.h @@ -185,7 +185,7 @@ unsigned int write_sslbytestowrite; struct PICA_c2c *next; struct PICA_c2c *prev; -PICA_c2c_state state; +enum PICA_c2c_state state; time_t timestamp; int sendfilestate; uint64_t sendfile_size; -- cgit v1.2.1 From ec751f3f1260b72ade3a9fcb2dae5b55a6854fa9 Mon Sep 17 00:00:00 2001 From: Anton Date: Sat, 11 Apr 2015 23:34:46 +0400 Subject: more consistent naming, renamed conn -> c2n, channel -> c2c in function names and enumerations --- PICA_client.c | 95 ++++++++++++++++++++++++---------------------- PICA_client.h | 30 +++++++-------- PICA_node.c | 4 +- doc/bugtraq.txt | 21 ---------- doc/concepts.txt | 1 - doc/glossary.txt | 1 - pica-client/nodethread.cpp | 4 +- pica-client/skynet.cpp | 36 +++++++++--------- pica-client/skynet.h | 10 ++--- tests/test_client.c | 36 +++++++++--------- 10 files changed, 110 insertions(+), 128 deletions(-) delete mode 100755 doc/bugtraq.txt delete mode 100755 doc/concepts.txt delete mode 100755 doc/glossary.txt diff --git a/PICA_client.c b/PICA_client.c index c7eeabf..5433a4e 100755 --- a/PICA_client.c +++ b/PICA_client.c @@ -388,7 +388,7 @@ if (callbacks.peer_cert_verify_cb(chnl->peer_id, (const char*)cert_pem, cert_pem BIO_free(mem); } -chnl->state=PICA_CHANSTATE_ACTIVE; +chnl->state=PICA_C2C_STATE_ACTIVE; { unsigned long arg = 1; @@ -400,8 +400,8 @@ return PICA_OK; error_ret_: error_ret: -callbacks.channel_failed(chnl->peer_id); -PICA_close_channel(chnl); +callbacks.c2c_failed(chnl->peer_id); +PICA_close_c2c(chnl); return err_ret; } @@ -471,7 +471,7 @@ unsigned char *peer_id = buf + 2; if (ret!=PICA_OK) return 1; - callbacks.channel_established_cb(_chnl->peer_id);//*nchn=_chnl; + callbacks.c2c_established_cb(_chnl->peer_id);//*nchn=_chnl; return 1; } @@ -512,7 +512,7 @@ if (!rq) return 0;// ERR_CHECK -левое сообщение, такой запрос не посылался //puts("procmsg_NOTFOUND_chkp0");//debug -PICA_close_channel(rq); +PICA_close_c2c(rq); //puts("procmsg_NOTFOUND_chkp1");//debug @@ -546,7 +546,7 @@ ret=establish_data_connection(rq); if (ret!=PICA_OK) return 0; -callbacks.channel_established_cb(rq->peer_id);//*nchn=_chnl; +callbacks.c2c_established_cb(rq->peer_id);//*nchn=_chnl; return 1; } @@ -1239,7 +1239,7 @@ return ret_err; //PICA_OK - успешное завершение функции //.... -int PICA_new_connection(const struct PICA_acc *acc, const char *nodeaddr, +int PICA_new_c2n(const struct PICA_acc *acc, const char *nodeaddr, unsigned int port, struct PICA_c2n **ci) { @@ -1315,7 +1315,7 @@ if (cid->sck_comm==SOCKET_ERROR) goto error_ret_3; } -cid->state = PICA_CONNSTATE_CONNECTING; +cid->state = PICA_C2N_STATE_CONNECTING; ret=connect(cid->sck_comm,(struct sockaddr*)&a,sizeof(struct sockaddr_in)); /////////////////state_ @@ -1344,7 +1344,7 @@ else } } -//cid->state = PICA_CONNSTATE_WAITINGREP; +//cid->state = PICA_C2N_STATE_WAITINGREP; do { @@ -1385,7 +1385,7 @@ ret=SSL_set_fd(cid->ssl_comm,cid->sck_comm); ret=SSL_accept(cid->ssl_comm); /////////////////state_ -cid->state = PICA_CONNSTATE_WAITINGTLS; +cid->state = PICA_C2N_STATE_WAITINGTLS; if (ret!=1) { //printf("SSL_accept ret=%i\n SSL_get_error=%i\n",ret,SSL_get_error(cid->ssl_comm,ret));//debug @@ -1393,7 +1393,7 @@ if (ret!=1) ret_err=PICA_ERRSSL; goto error_ret_4; } -cid->state = PICA_CONNSTATE_CONNECTED;//<<state = PICA_C2N_STATE_CONNECTED;//<<state) +// { +// case PICA_C2N_STATE_CONNECTED: +// } +return PICA_OK; } static int process_c2c(struct PICA_c2c *c2c, fd_set *rfds, fd_set *wfds) { -//if (ic2c->state == PICA_CHANSTATE_ACTIVE) +//if (ic2c->state == PICA_C2C_STATE_ACTIVE) // { // // } - +return PICA_OK; } static int process_listener(struct PICA_listener *lst, fd_set *rfds) { - +return PICA_OK; } static void fdset_add(fd_set *fds, int fd, int *max) @@ -1526,7 +1531,7 @@ while(ic2n && *ic2n) while(ic2c) { - if (ic2c->state == PICA_CHANSTATE_ACTIVE) + if (ic2c->state == PICA_C2C_STATE_ACTIVE) { fdset_add(&rfds, ic2c->sck_data, &nfds); @@ -1616,7 +1621,7 @@ ipt=ci->chan_list_head; while(ipt) { - if (ipt->state==PICA_CHANSTATE_ACTIVE) + if (ipt->state==PICA_C2C_STATE_ACTIVE) { FD_SET(ipt->sck_data,&fds); @@ -1624,7 +1629,7 @@ while(ipt) nfds=ipt->sck_data; } - if (ipt->state != PICA_CHANSTATE_ACTIVE && (time(0) - ipt->timestamp) > PICA_CHAN_ACTIVATE_TIMEOUT) + if (ipt->state != PICA_C2C_STATE_ACTIVE && (time(0) - ipt->timestamp) > PICA_CHAN_ACTIVATE_TIMEOUT) { kill_ptr = ipt; } @@ -1633,7 +1638,7 @@ while(ipt) if (kill_ptr) { - PICA_close_channel(kill_ptr); + PICA_close_c2c(kill_ptr); kill_ptr = 0; } } @@ -1655,12 +1660,12 @@ if (ret>0) ipt=ci->chan_list_head; while(ipt) { - if (ipt->state==PICA_CHANSTATE_ACTIVE && FD_ISSET(ipt->sck_data, &fds)) + if (ipt->state==PICA_C2C_STATE_ACTIVE && FD_ISSET(ipt->sck_data, &fds)) { if (PICA_OK != (ret = PICA_read_c2c(ipt)) ) { puts("PICA_read_c2c() failed");//debug - callbacks.channel_closed_cb(ipt->peer_id, ret); + callbacks.c2c_closed_cb(ipt->peer_id, ret); kill_ptr = ipt; } @@ -1670,7 +1675,7 @@ if (ret>0) if (kill_ptr) { - PICA_close_channel(kill_ptr); + PICA_close_c2c(kill_ptr); kill_ptr = 0; } } @@ -1703,7 +1708,7 @@ while(ipt) if (PICA_OK != (ret = PICA_write_c2c(ipt))) { fprintf(stderr,"PICA_write_c2c() failed, ret = %i\n", ret);//debug - callbacks.channel_closed_cb(ipt->peer_id, ret); + callbacks.c2c_closed_cb(ipt->peer_id, ret); kill_ptr = ipt; } } @@ -1711,7 +1716,7 @@ while(ipt) { if (PICA_OK != (ret = PICA_send_file_fragment(ipt))) { - callbacks.channel_closed_cb(ipt->peer_id, ret); + callbacks.c2c_closed_cb(ipt->peer_id, ret); kill_ptr = ipt; } } @@ -1719,7 +1724,7 @@ while(ipt) if (kill_ptr) { - PICA_close_channel(kill_ptr); + PICA_close_c2c(kill_ptr); kill_ptr = 0; } } @@ -1800,9 +1805,9 @@ int PICA_write_c2n(struct PICA_c2n *ci) { int ret = PICA_ERRINVARG; -if (PICA_CONNSTATE_CONNECTING == ci->state) +if (PICA_C2N_STATE_CONNECTING == ci->state) ret = PICA_write_socket( ci->sck_comm, ci->write_buf, &ci->write_pos); -else if (PICA_CONNSTATE_CONNECTED == ci->state) +else if (PICA_C2N_STATE_CONNECTED == ci->state) ret = PICA_write_ssl( ci->ssl_comm, ci->write_buf, &ci->write_pos, &ci->write_sslbytestowrite); return ret; @@ -1812,7 +1817,7 @@ int PICA_write_c2c(struct PICA_c2c *chn) { int ret = PICA_ERRINVARG; -if (PICA_CHANSTATE_ACTIVE != chn->state) +if (PICA_C2C_STATE_ACTIVE != chn->state) ret = PICA_write_socket( chn->sck_data, chn->write_buf, &chn->write_pos); else ret = PICA_write_ssl( chn->ssl, chn->write_buf, &chn->write_pos, &chn->write_sslbytestowrite); @@ -1896,7 +1901,7 @@ int PICA_read_c2c(struct PICA_c2c *chn) { int ret; -if (chn->state != PICA_CHANSTATE_ACTIVE) +if (chn->state != PICA_C2C_STATE_ACTIVE) return PICA_OK;// ??? //ret = SSL_read(chn->ssl , chn->read_buf + chn->read_pos, PICA_CHANREADBUFSIZE - chn->read_pos); @@ -1918,20 +1923,20 @@ int ret; //ret=SSL_read(ci->ssl_comm, ci->read_buf + ci->read_pos, PICA_CONNREADBUFSIZE - ci->read_pos); -if (PICA_CONNSTATE_CONNECTING == ci->state) +if (PICA_C2N_STATE_CONNECTING == ci->state) ret = PICA_read_socket(ci->sck_comm, ci->read_buf, &ci->read_pos, PICA_CONNREADBUFSIZE); -else if (PICA_CONNSTATE_CONNECTED == ci->state) +else if (PICA_C2N_STATE_CONNECTED == ci->state) ret = PICA_read_ssl(ci->ssl_comm, ci->read_buf, &ci->read_pos, PICA_CONNREADBUFSIZE); if (ret == PICA_OK) { - if (PICA_CONNSTATE_CONNECTING == ci->state) + if (PICA_C2N_STATE_CONNECTING == ci->state) if(!PICA_processdatastream( ci->read_buf, &(ci->read_pos), ci, c2n_init_messages, MSGINFO_MSGSNUM(c2n_init_messages))) return PICA_ERRSERV; - if (PICA_CONNSTATE_CONNECTED == ci->state) + if (PICA_C2N_STATE_CONNECTED == ci->state) if(!PICA_processdatastream( ci->read_buf, &(ci->read_pos), ci, c2n_messages, MSGINFO_MSGSNUM(c2n_messages))) return PICA_ERRSERV; } @@ -2232,14 +2237,14 @@ if (chn->sendfile_pos > chn->sendfile_size) return PICA_OK; } -void PICA_close_channel(struct PICA_c2c *chn) +void PICA_close_c2c(struct PICA_c2c *chn) { struct PICA_c2c *ipt; -fprintf(stderr, "PICA_close_channel(%p)\n", chn);//debug +fprintf(stderr, "PICA_close_c2c(%p)\n", chn);//debug ipt=chn->conn->chan_list_head; -//puts("PICA_close_channel_chkp0");//debug +//puts("PICA_close_c2c_chkp0");//debug while(ipt) { if (ipt==chn) @@ -2259,7 +2264,7 @@ while(ipt) ipt=ipt->next; } -//puts("PICA_close_channel_chkp1");//debug +//puts("PICA_close_c2c_chkp1");//debug if (chn -> sendfile_stream) fclose(chn -> sendfile_stream); @@ -2276,11 +2281,11 @@ if (chn -> write_buf) if (chn->peer_cert) X509_free(chn->peer_cert); -//puts("PICA_close_channel_chkp2");//debug +//puts("PICA_close_c2c_chkp2");//debug if (chn->ssl) SSL_shutdown(chn->ssl); - //puts("PICA_close_channel_chkp3");//debug + //puts("PICA_close_c2c_chkp3");//debug if (chn->ssl) { @@ -2288,13 +2293,13 @@ if (chn->ssl) SSL_free(chn->ssl); } -//puts("PICA_close_channel_chkp4");//debug +//puts("PICA_close_c2c_chkp4");//debug SHUTDOWN(chn->sck_data); -//puts("PICA_close_channel_chkp5");//debug +//puts("PICA_close_c2c_chkp5");//debug CLOSE(chn->sck_data); -//puts("PICA_close_channel_chkp6");//debug +//puts("PICA_close_c2c_chkp6");//debug free(chn); -//puts("PICA_close_channel_chkp7");//debug +//puts("PICA_close_c2c_chkp7");//debug } void PICA_close_connection(struct PICA_c2n *cid) @@ -2302,7 +2307,7 @@ void PICA_close_connection(struct PICA_c2n *cid) struct PICA_c2c *ipt; while((ipt = cid->chan_list_head)) - PICA_close_channel(ipt); + PICA_close_c2c(ipt); SSL_shutdown(cid->ssl_comm); //printf("4 SSL_free(%X)\n",cid->ssl_comm);//debug diff --git a/PICA_client.h b/PICA_client.h index 8e1778f..6f2d6d5 100755 --- a/PICA_client.h +++ b/PICA_client.h @@ -111,8 +111,8 @@ typedef unsigned __int64 uint64_t; #define PICA_CHAN_ACTIVATE_TIMEOUT 30 -#define PICA_CHANNEL_INCOMING 0 -#define PICA_CHANNEL_OUTGOING 1 +#define PICA_c2c_INCOMING 0 +#define PICA_c2c_OUTGOING 1 struct PICA_c2n; struct PICA_c2c; @@ -125,11 +125,11 @@ SSL_CTX* ctx; enum PICA_c2n_state { -PICA_CONNSTATE_NONE = 0, -PICA_CONNSTATE_CONNECTING, -PICA_CONNSTATE_WAITINGREP, -PICA_CONNSTATE_WAITINGTLS, -PICA_CONNSTATE_CONNECTED +PICA_C2N_STATE_NEW = 0, +PICA_C2N_STATE_CONNECTING, +PICA_C2N_STATE_WAITINGREP, +PICA_C2N_STATE_WAITINGTLS, +PICA_C2N_STATE_CONNECTED }; struct PICA_c2n @@ -161,8 +161,8 @@ unsigned char node_ver_major, node_ver_minor; enum PICA_c2c_state { -PICA_CHANSTATE_NONE = 0, -PICA_CHANSTATE_ACTIVE +PICA_C2C_STATE_NEW = 0, +PICA_C2C_STATE_ACTIVE }; struct PICA_c2c @@ -218,16 +218,16 @@ void (*newmsg_cb)(const unsigned char *peer_id,const char* msgbuf,unsigned int n //получение подтверждения о доставке сообщения void (*msgok_cb)(const unsigned char *peer_id); //создание канала с собеседником -void (*channel_established_cb)(const unsigned char *peer_id); +void (*c2c_established_cb)(const unsigned char *peer_id); //создать канал не удалось -void (*channel_failed)(const unsigned char *peer_id); +void (*c2c_failed)(const unsigned char *peer_id); //входящий запрос на создание канала от пользователя с номером caller_id //возвращаемое значение: 0 - отклонить запрос, ненулевое значение - принять запрос int (*accept_cb)(const unsigned char *caller_id); //запрошенный пользователь не найден, в оффлайне или отказался от общения void (*notfound_cb)(const unsigned char *callee_id); // -void (*channel_closed_cb)(const unsigned char *peer_id, int reason); +void (*c2c_closed_cb)(const unsigned char *peer_id, int reason); void (*nodelist_cb)(int type, void *addr_bin, const char *addr_str, unsigned int port); //сертификат собеседника в формате PEM. Функция должна сравнить предъявленный сертификат с сохранённым (если есть) и вернуть 1 при успешной проверке, 0 - при неуспешной @@ -258,7 +258,7 @@ int PICA_get_id_from_cert_file(const char *cert_file, unsigned char *id); int PICA_get_id_from_cert_string(const char *cert_pem, unsigned char *id); int PICA_client_init(struct PICA_client_callbacks *clcbs); -int PICA_new_connection +int PICA_new_c2n (const struct PICA_acc *acc, const char *nodeaddr, unsigned int port, @@ -269,7 +269,7 @@ int PICA_new_connection int (*password_cb)(char *buf, int size, int rwflag, void *userdata), //move callback to PICA_client_callbacks? */ struct PICA_c2n **ci); -int PICA_create_channel(struct PICA_c2n *ci,const unsigned char *peer_id, struct PICA_listener *l,struct PICA_c2c **chn); +int PICA_new_c2c(struct PICA_c2n *ci,const unsigned char *peer_id, struct PICA_listener *l,struct PICA_c2c **chn); int PICA_new_listener(const struct PICA_acc *acc, const char *public_addr, int public_port, int local_port, struct PICA_listener **l); @@ -303,7 +303,7 @@ int PICA_pause_file(struct PICA_c2c *chan, int sending); int PICA_resume_file(struct PICA_c2c *chan, int sending); int PICA_cancel_file(struct PICA_c2c *chan, int sending); -void PICA_close_channel(struct PICA_c2c *chn); +void PICA_close_c2c(struct PICA_c2c *chn); void PICA_close_connection(struct PICA_c2n *cid); void PICA_close_listener(struct PICA_listener *l); void PICA_close_acc(struct PICA_acc *a); diff --git a/PICA_node.c b/PICA_node.c index 62dde61..c3b1d3e 100755 --- a/PICA_node.c +++ b/PICA_node.c @@ -389,13 +389,13 @@ if ((o = client_tree_search(callee_id))) { if (cclink_list_search(i->id, callee_id)) { - PICA_info("duplicate request for existing channel is ignored"); + PICA_info("duplicate request for existing c2c connection is ignored"); return 1; } if (memcmp(i->id, callee_id, PICA_ID_SIZE) == 0) { - PICA_info("request to create channel to self is ignored"); + PICA_info("request to create c2c connection to self is ignored"); return 1; } diff --git a/doc/bugtraq.txt b/doc/bugtraq.txt deleted file mode 100755 index bf312f7..0000000 --- a/doc/bugtraq.txt +++ /dev/null @@ -1,21 +0,0 @@ -1. [V] Падение test_client при вызове SSL_free: - -puts("CACA_close_channel_chkp3");//debug - -if (chn->ssl) -SSL_free(chn->ssl);<<<< - -после -verify result:10 // просроченный корневой сертификат -//////////// -причина - повторный вызов SSL_free -(сначала в функции establish_data_connection, затем в CACA_close_channel) - -Баг исправлен путем помещения вызова CACA_close_channel в establish_data_connection в случае ошибки при создании канала. Также добавлена новая callback функция channel_failed, вызываемая в случае ошибки при создании канала - -========================================================== -2. Авторизация клиента узлом без сертификата - -Клиент возможно может установить TLS соединение с узлом используя ADH схему. Узел -может выпасть с ошибкой, если не удается получить сертификат клиента. Надо явно задавать -набор разрешенных схем шифрования в клиенте и сервере diff --git a/doc/concepts.txt b/doc/concepts.txt deleted file mode 100755 index 2383e28..0000000 --- a/doc/concepts.txt +++ /dev/null @@ -1 +0,0 @@ -[Ïîèñê ñîáåñåäíèêà.Íåêîòîðûå ñîîáðàæåíèÿ ïî îáëåã÷åíèþ ïîèñêà] diff --git a/doc/glossary.txt b/doc/glossary.txt deleted file mode 100755 index 8d1c8b6..0000000 --- a/doc/glossary.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/pica-client/nodethread.cpp b/pica-client/nodethread.cpp index 579b84b..5969781 100644 --- a/pica-client/nodethread.cpp +++ b/pica-client/nodethread.cpp @@ -23,7 +23,7 @@ void NodeThread::run() int ret; exit = 0; - /*ret = PICA_new_connection(node_addr.address.toUtf8().constData(), + /*ret = PICA_new_c2n(node_addr.address.toUtf8().constData(), node_addr.port, user_account.CA_file.toUtf8().constData(), user_account.cert_file.toUtf8().constData(), @@ -31,7 +31,7 @@ void NodeThread::run() DHParam::GetDHParamFilename().toUtf8().constData(), AskPassword::ask_password_cb, &ci);*/ - ret = PICA_new_connection(user_account, node_addr.address.toUtf8().constData(), node_addr.port, &ci); + ret = PICA_new_c2n(user_account, node_addr.address.toUtf8().constData(), node_addr.port, &ci); switch(ret) { diff --git a/pica-client/skynet.cpp b/pica-client/skynet.cpp index 9d66377..55a4120 100644 --- a/pica-client/skynet.cpp +++ b/pica-client/skynet.cpp @@ -19,11 +19,11 @@ SkyNet::SkyNet() PICA_client_callbacks cbs = { newmsg_cb, msgok_cb, - channel_established_cb, - channel_failed, + c2c_established_cb, + c2c_failed, accept_cb, notfound_cb, - channel_closed_cb, + c2c_closed_cb, nodelist_cb, peer_cert_verify_cb, accept_file_cb, @@ -94,9 +94,9 @@ void SkyNet::nodethread_connected(QString addr, quint16 port, NodeThread *thread write_mutex.lock(); struct PICA_c2c *chan = NULL; - ret = PICA_create_channel(nodelink, (const unsigned char*)c2c_peer_ids[i].constData(), NULL, &chan); + ret = PICA_new_c2c(nodelink, (const unsigned char*)c2c_peer_ids[i].constData(), NULL, &chan); - qDebug()<<"restoring channel to "< l; l.append(filepath); @@ -435,7 +435,7 @@ if ( (iptr = find_active_chan(to)) ) { struct PICA_c2c *chan = NULL; - ret = PICA_create_channel(nodelink, (const unsigned char*)to.constData(), NULL, &chan); + ret = PICA_new_c2c(nodelink, (const unsigned char*)to.constData(), NULL, &chan); QList l; l.append(msg); @@ -509,7 +509,7 @@ struct PICA_c2c *iptr = nodelink->chan_list_head; while(iptr) { - if (iptr->state == PICA_CHANSTATE_ACTIVE && QByteArray((const char*)iptr->peer_id, PICA_ID_SIZE) == peer_id) + if (iptr->state == PICA_C2C_STATE_ACTIVE && QByteArray((const char*)iptr->peer_id, PICA_ID_SIZE) == peer_id) break; iptr = iptr->next; @@ -628,9 +628,9 @@ void SkyNet::emit_IncomingFileFinished(QByteArray peer_id) emit IncomingFileFinished(peer_id); } -void SkyNet::emit_ChannelClosed(QByteArray peer_id) +void SkyNet::emit_c2cClosed(QByteArray peer_id) { - emit ChannelClosed(peer_id); + emit c2cClosed(peer_id); } @@ -651,14 +651,14 @@ void SkyNet::msgok_cb(const unsigned char *peer_id) skynet->emit_Delivered(QByteArray((const char*)peer_id, PICA_ID_SIZE)); } -void SkyNet::channel_established_cb(const unsigned char *peer_id) +void SkyNet::c2c_established_cb(const unsigned char *peer_id) { skynet->flush_queues(QByteArray((const char*)peer_id, PICA_ID_SIZE)); } -void SkyNet::channel_failed(const unsigned char *peer_id) +void SkyNet::c2c_failed(const unsigned char *peer_id) { - qDebug()<<"channel failed ("<emit_ChannelClosed(QByteArray((const char*)peer_id, PICA_ID_SIZE)); + skynet->emit_c2cClosed(QByteArray((const char*)peer_id, PICA_ID_SIZE)); } void SkyNet::nodelist_cb(int type, void *addr_bin, const char *addr_str, unsigned int port) diff --git a/pica-client/skynet.h b/pica-client/skynet.h index 4df41db..0b2c84b 100644 --- a/pica-client/skynet.h +++ b/pica-client/skynet.h @@ -55,7 +55,7 @@ signals: void OutgoingFileFinished(QByteArray peer_id); void IncomingFileFinished(QByteArray peer_id); - void ChannelClosed(QByteArray peer_id); + void c2cClosed(QByteArray peer_id); private: Nodes nodes; @@ -98,22 +98,22 @@ private: void emit_OutgoingFileFinished(QByteArray peer_id); void emit_IncomingFileFinished(QByteArray peer_id); - void emit_ChannelClosed(QByteArray peer_id); + void emit_c2cClosed(QByteArray peer_id); //получение сообщения. static void newmsg_cb(const unsigned char *peer_id,const char* msgbuf,unsigned int nb,int type); //получение подтверждения о доставке сообщения static void msgok_cb(const unsigned char *peer_id); //создание канала с собеседником - static void channel_established_cb(const unsigned char *peer_id); + static void c2c_established_cb(const unsigned char *peer_id); //создать канал не удалось - static void channel_failed(const unsigned char *peer_id); + static void c2c_failed(const unsigned char *peer_id); //входящий запрос на создание канала от пользователя с номером caller_id static int accept_cb(const unsigned char *caller_id); //запрошенный пользователь не найден, в оффлайне или отказался от общения static void notfound_cb(const unsigned char *callee_id); - static void channel_closed_cb(const unsigned char *peer_id, int reason); + static void c2c_closed_cb(const unsigned char *peer_id, int reason); static void nodelist_cb(int type, void *addr_bin, const char *addr_str, unsigned int port); diff --git a/tests/test_client.c b/tests/test_client.c index a94951c..491154d 100755 --- a/tests/test_client.c +++ b/tests/test_client.c @@ -34,14 +34,14 @@ void msgok_cb(const unsigned char *peer_id) puts("[V]"); } //создание канала с собеседником -void channel_established_cb(const unsigned char *peer_id) +void c2c_established_cb(const unsigned char *peer_id) { -puts("channel_established_cb"); +puts("c2c_established_cb"); } -void channel_failed_cb(const unsigned char *peer_id) +void c2c_failed_cb(const unsigned char *peer_id) { -printf("Failed to create channel to %s\n",PICA_id_to_base64(peer_id, NULL)); +printf("Failed to create c2c to %s\n",PICA_id_to_base64(peer_id, NULL)); chn=0; } @@ -53,9 +53,9 @@ void notfound_cb(const unsigned char *callee_id) puts("notfound_cb"); } -void channel_closed_cb(const unsigned char *peer_id, int reason) +void c2c_closed_cb(const unsigned char *peer_id, int reason) { -printf("channel_closed_cb( peer_id = %s, reason = %i)\n", PICA_id_to_base64(peer_id, NULL), reason); +printf("c2c_closed_cb( peer_id = %s, reason = %i)\n", PICA_id_to_base64(peer_id, NULL), reason); } void nodelist_cb(int type, void *addr_bin, const char *addr_str, unsigned int port) @@ -89,11 +89,11 @@ int peer_cert_verify_cb(const unsigned char *peer_id, const char *cert_pem, unsi struct PICA_client_callbacks cbs = { newmsg_cb, msgok_cb, - channel_established_cb, - channel_failed_cb, + c2c_established_cb, + c2c_failed_cb, accept_cb, notfound_cb, - channel_closed_cb, + c2c_closed_cb, nodelist_cb, peer_cert_verify_cb }; @@ -133,8 +133,8 @@ if (ret != PICA_OK) printf("making connection...\n"); -//PICA_new_connection(const char *nodeaddr, unsigned int port, const char *CA_file, const char *cert_file, const char *pkey_file, const char* password, struct PICA_c2n **ci) -ret=PICA_new_connection(acc, argv[1], atoi(argv[2]), /*"trusted_CA.pem"*/ &c); +//PICA_new_c2n(const char *nodeaddr, unsigned int port, const char *CA_file, const char *cert_file, const char *pkey_file, const char* password, struct PICA_c2n **ci) +ret=PICA_new_c2n(acc, argv[1], atoi(argv[2]), /*"trusted_CA.pem"*/ &c); ERR_print_errors_fp(stdout); @@ -142,7 +142,7 @@ if (ret==PICA_OK) printf("PICA_OK Connected to server...\n"); else { -printf("PICA_new_connection: ret=%i\n",ret); +printf("PICA_new_c2n: ret=%i\n",ret); return 1; } @@ -154,9 +154,9 @@ if (argc==5) return 1; } - printf("Creating channel to %s...\n",PICA_id_to_base64(peer_id, NULL)); + printf("Creating c2c to %s...\n",PICA_id_to_base64(peer_id, NULL)); - ret=PICA_create_channel(c,peer_id,NULL,&chn); + ret=PICA_new_c2c(c,peer_id,NULL,&chn); //sleep(17);//timeout test if (ret!=PICA_OK) { @@ -214,14 +214,14 @@ if (buf[0]=='.') else { peer_id=atoi(buf); - printf("Creating channel to %u...\n",peer_id); + printf("Creating c2c to %u...\n",peer_id); - ret=PICA_create_channel(c,peer_id,&chn,1); + ret=PICA_new_c2c(c,peer_id,&chn,1); if (ret==PICA_OK) { unsigned int msglen; - puts("Channel established..."); + puts("c2c established..."); gets(buf); msglen=strlen(buf); @@ -239,7 +239,7 @@ sleep(10); if (chn) { puts("--------"); - PICA_close_channel(chn); + PICA_close_c2c(chn); } PICA_close_connection(c); -- cgit v1.2.1 From 55b17bd87fc0d695500574b188534014922cb2a4 Mon Sep 17 00:00:00 2001 From: Anton Date: Sat, 11 Apr 2015 23:54:35 +0400 Subject: renamed remaining PICA_close_connection() -> PICA_close_c2n() --- PICA_client.c | 4 ++-- PICA_client.h | 2 +- pica-client/nodethread.cpp | 4 ++-- tests/test_client.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 5433a4e..c10ca1d 100755 --- a/PICA_client.c +++ b/PICA_client.c @@ -1234,7 +1234,7 @@ return ret_err; //pkey_file - имя файла, содержащего приватный ключ в формате PEM //password_cb - callback-функция, запрашивающая пароль к приватному ключу, см. man 3 SSL_CTX_set_default_passwd_cb;в userdata передается указатель на id //ci -указатель на указатель на структуру PICA_c2n, который будет проинициализирован при успешном выполнении функции -//Память, выделенная под структуру, освобождается при вызове PICA_close_connection +//Память, выделенная под структуру, освобождается при вызове PICA_close_c2n //Возвращаемое значение - код завершения //PICA_OK - успешное завершение функции //.... @@ -2302,7 +2302,7 @@ free(chn); //puts("PICA_close_c2c_chkp7");//debug } -void PICA_close_connection(struct PICA_c2n *cid) +void PICA_close_c2n(struct PICA_c2n *cid) { struct PICA_c2c *ipt; diff --git a/PICA_client.h b/PICA_client.h index 6f2d6d5..4f01382 100755 --- a/PICA_client.h +++ b/PICA_client.h @@ -304,7 +304,7 @@ int PICA_resume_file(struct PICA_c2c *chan, int sending); int PICA_cancel_file(struct PICA_c2c *chan, int sending); void PICA_close_c2c(struct PICA_c2c *chn); -void PICA_close_connection(struct PICA_c2n *cid); +void PICA_close_c2n(struct PICA_c2n *cid); void PICA_close_listener(struct PICA_listener *l); void PICA_close_acc(struct PICA_acc *a); #ifdef __cplusplus diff --git a/pica-client/nodethread.cpp b/pica-client/nodethread.cpp index 5969781..ee6504f 100644 --- a/pica-client/nodethread.cpp +++ b/pica-client/nodethread.cpp @@ -42,7 +42,7 @@ void NodeThread::run() finished_mutex.lock(); if (*finished_flag) { - PICA_close_connection(ci); + PICA_close_c2n(ci); exit = 1; } else @@ -106,7 +106,7 @@ void NodeThread::run() while (!exit); write_mutex->lock(); - PICA_close_connection(ci); + PICA_close_c2n(ci); *connection = NULL; write_mutex->unlock(); } diff --git a/tests/test_client.c b/tests/test_client.c index 491154d..996639b 100755 --- a/tests/test_client.c +++ b/tests/test_client.c @@ -242,7 +242,7 @@ if (chn) PICA_close_c2c(chn); } -PICA_close_connection(c); +PICA_close_c2n(c); return 0; } -- cgit v1.2.1 From c0f121ab3484fdeb0da6a4f26b85bcf91932b818 Mon Sep 17 00:00:00 2001 From: Anton Date: Wed, 15 Apr 2015 01:59:53 +0400 Subject: callback functions for c2n status notifications --- PICA_client.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/PICA_client.h b/PICA_client.h index 4f01382..9b51b6f 100755 --- a/PICA_client.h +++ b/PICA_client.h @@ -244,6 +244,12 @@ void (*file_progress)(const unsigned char *peer_id, uint64_t sent, uint64_t rece void (*file_control)(const unsigned char *peer_id, unsigned int sender_cmd, unsigned int receiver_cmd); void (*file_finished)(const unsigned char *peer_id, int sending); + +void (*c2n_established_cb)(struct PICA_c2n *c2n); + +void (*c2n_failed_cb)(struct PICA_c2n *c2n); + +void (*c2n_closed_cb)(struct PICA_c2n *c2n); }; -- cgit v1.2.1 From 9147cd24d5b749d9e74ad308fb059f79c7abf115 Mon Sep 17 00:00:00 2001 From: Anton Date: Wed, 15 Apr 2015 02:05:07 +0400 Subject: callback for listener error notification --- PICA_client.c | 2 +- PICA_client.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/PICA_client.c b/PICA_client.c index c10ca1d..1f52e5c 100755 --- a/PICA_client.c +++ b/PICA_client.c @@ -1572,7 +1572,7 @@ while(ilst && *ilst) ret = process_listener(*ilst, &rfds); if (ret != PICA_OK) - return ret; + callbacks.listener_error(*ilst, ret); ilst++; } diff --git a/PICA_client.h b/PICA_client.h index 9b51b6f..96be77f 100755 --- a/PICA_client.h +++ b/PICA_client.h @@ -250,6 +250,8 @@ void (*c2n_established_cb)(struct PICA_c2n *c2n); void (*c2n_failed_cb)(struct PICA_c2n *c2n); void (*c2n_closed_cb)(struct PICA_c2n *c2n); + +void (*listener_error)(struct PICA_listener *lst, int errorcode); }; -- cgit v1.2.1 From 30b06d7d978120561f617271c0597763b864c934 Mon Sep 17 00:00:00 2001 From: Anton Date: Wed, 15 Apr 2015 02:17:43 +0400 Subject: PICA_event_loop() implementation, mostly completed --- PICA_client.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 1f52e5c..141d35c 100755 --- a/PICA_client.c +++ b/PICA_client.c @@ -1585,16 +1585,33 @@ while(ic2n && *ic2n) ret = process_c2n(*ic2n, &rfds, &wfds); - ic2c = (*ic2n)->chan_list_head; - - //processing c2c connections associated with current c2n - while(ic2c) + if (ret != PICA_OK) { - ret = process_c2c(ic2c, &rfds, &wfds); - - ic2c = ic2c->next; + PICA_close_c2n(*ic2n); } + else + { + struct PICA_c2c *kill_ptr = 0; + ic2c = (*ic2n)->chan_list_head; + + //processing c2c connections associated with current c2n + while(ic2c) + { + ret = process_c2c(ic2c, &rfds, &wfds); + + if (ret != PICA_OK) + kill_ptr = ic2c; + + ic2c = ic2c->next; + + if (kill_ptr) + { + PICA_close_c2c(kill_ptr); + kill_ptr = 0; + } + } + } ic2n++; } -- cgit v1.2.1 From f4f8d75ca055e3b53549cb0e23ef41c51620b699 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 11 May 2015 02:50:03 +0400 Subject: implemented asynchronous processing of c2n connections --- PICA_client.c | 253 ++++++++++++++++++++++++++++++++++++++++++++++++---------- PICA_common.h | 4 +- 2 files changed, 211 insertions(+), 46 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 141d35c..29b6955 100755 --- a/PICA_client.c +++ b/PICA_client.c @@ -390,11 +390,8 @@ BIO_free(mem); chnl->state=PICA_C2C_STATE_ACTIVE; -{ -unsigned long arg = 1; +IOCTLSETNONBLOCKINGSOCKET(chnl->sck_data, 1); -IOCTLSETNONBLOCKINGSOCKET(chnl->sck_data, &arg); -} return PICA_OK; @@ -1223,6 +1220,74 @@ free(a); return ret_err; } +static int c2n_stage2_sendreq(struct PICA_c2n *c2n) +{ +struct PICA_proto_msg *mp; + +puts("c2n_stage2_sendreq");//debug + +mp = c2n_writebuf_push(c2n, PICA_PROTO_INITREQ, PICA_PROTO_INITREQ_SIZE); + +if (mp) + { + mp->tail[0] = PICA_PROTO_VER_HIGH; + mp->tail[1] = PICA_PROTO_VER_LOW; + } +else + return PICA_ERRNOMEM; + +c2n->state = PICA_C2N_STATE_WAITINGREP; + +return PICA_OK; +} + +static int c2n_stage3_starttls(struct PICA_c2n *c2n) +{ +int ret; + +ret = SSL_set_fd(c2n->ssl_comm, c2n->sck_comm); + +if (ret != 1) + return PICA_ERRSSL; + +ret = SSL_accept(c2n->ssl_comm); + +if (ret == 0) + return PICA_ERRSSL; + +if (ret < 0) + { + ret = SSL_get_error(c2n->ssl_comm, ret); + + if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE) + return PICA_ERRSSL; + } + +c2n->state = PICA_C2N_STATE_WAITINGTLS; + +return PICA_OK; +} + +static int c2n_stage4_nodelistrequest(struct PICA_c2n *c2n) +{ +struct PICA_proto_msg *mp; + +mp = c2n_writebuf_push(c2n, PICA_PROTO_CLNODELISTREQ, PICA_PROTO_CLNODELISTREQ_SIZE); + +if (mp) + { + RAND_bytes(mp->tail, 2); + } +else + return PICA_ERRNOMEM; + +c2n->state = PICA_C2N_STATE_CONNECTED; + +callbacks.c2n_established_cb(c2n); + +return PICA_OK; +} + /*адрес сервера, сертификат клиента и закрытый ключ*/ //Осуществляет подключение к серверу по указанному адресу. @@ -1315,37 +1380,33 @@ if (cid->sck_comm==SOCKET_ERROR) goto error_ret_3; } +IOCTLSETNONBLOCKINGSOCKET(cid->sck_comm, 1); + cid->state = PICA_C2N_STATE_CONNECTING; -ret=connect(cid->sck_comm,(struct sockaddr*)&a,sizeof(struct sockaddr_in)); +ret=connect(cid->sck_comm,(struct sockaddr*)&cid->srv_addr,sizeof(cid->srv_addr)); /////////////////state_ +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; goto error_ret_4; } -{ -struct PICA_proto_msg *mp; - -mp = c2n_writebuf_push( cid, PICA_PROTO_INITREQ, PICA_PROTO_INITREQ_SIZE); - -if (mp) - { - mp->tail[0] = PICA_PROTO_VER_HIGH; - mp->tail[1] = PICA_PROTO_VER_LOW; - } -else - { - ret_err = PICA_ERRNOMEM; - goto error_ret_4; - } -} - -//cid->state = PICA_C2N_STATE_WAITINGREP; +/* do { ret = PICA_write_c2n(cid); @@ -1378,7 +1439,7 @@ if (cid->init_resp_ok != 1) } //printf("6\n");//debug - +*/ /* ret=SSL_set_fd(cid->ssl_comm,cid->sck_comm); //printf("SSL_set_fd=%i\n",ret); @@ -1392,7 +1453,7 @@ if (ret!=1) //ERR_CHECK ret_err=PICA_ERRSSL; goto error_ret_4; - } + }*/ /* cid->state = PICA_C2N_STATE_CONNECTED;//<<tail, 2); } } - -{ -unsigned long arg = 1; - -IOCTLSETNONBLOCKINGSOCKET(cid->sck_comm, &arg); -} +*/ return PICA_OK; @@ -1464,12 +1520,107 @@ return PICA_OK; static int process_c2n(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) { -//switch(c2n->state) -// { -// case PICA_C2N_STATE_CONNECTED: -// } +int ret = PICA_OK; -return PICA_OK; +//puts("process_c2n()");//debug + +switch(c2n->state) + { + case PICA_C2N_STATE_NEW: + break; + + case PICA_C2N_STATE_CONNECTING: + + if (FD_ISSET(c2n->sck_comm, wfds)) + { + ret = PICA_ERRSOCK; + + //check if connect() finished successfully +#ifndef WIN32 + int optval; + socklen_t optlen = sizeof(optval); + + if (0 == getsockopt(c2n->sck_comm, SOL_SOCKET, SO_ERROR, &optval, &optlen)) + { + if (optval == 0) + { + ret = c2n_stage2_sendreq(c2n); + } + } +#else + if (SOCKET_ERROR == connect(c2n->ssl_comm, (struct sockaddr*)&c2n->srv_addr, sizeof(c2n->srv_addr)) && + WSAEISCONN == WSAGetLastError()) + { + ret = c2n_stage2_sendreq(c2n); + } +#endif + } + + break; + + case PICA_C2N_STATE_WAITINGREP: + + if (FD_ISSET(c2n->sck_comm, wfds)) + { + ret = PICA_write_c2n(c2n); + } + + if (FD_ISSET(c2n->sck_comm, rfds)) + { + ret = PICA_read_c2n(c2n); + } + + if (ret == PICA_OK && c2n->init_resp_ok != 0) + { + if (c2n->init_resp_ok == 1) + ret = c2n_stage3_starttls(c2n); + else + { + if (c2n->node_ver_major > PICA_PROTO_VER_HIGH || + (c2n->node_ver_major == PICA_PROTO_VER_HIGH && c2n->node_ver_minor > PICA_PROTO_VER_LOW)) + ret = PICA_ERRPROTONEW; + else + ret = PICA_ERRPROTOOLD; + } + } + + break; + + case PICA_C2N_STATE_WAITINGTLS: + + if (FD_ISSET(c2n->sck_comm, wfds) || FD_ISSET(c2n->sck_comm, rfds)) + { + int sslret; + + sslret = SSL_accept(c2n->ssl_comm); + + if (sslret == 1) + ret = c2n_stage4_nodelistrequest(c2n); + else if (sslret == 0) + ret = PICA_ERRSSL; + else if (sslret < 0) + { + sslret = SSL_get_error(c2n->ssl_comm, sslret); + + if (sslret != SSL_ERROR_WANT_READ && sslret != SSL_ERROR_WANT_WRITE) + ret = PICA_ERRSSL; + } + } + + break; + + case PICA_C2N_STATE_CONNECTED: + + if (FD_ISSET(c2n->sck_comm, wfds)) + ret = PICA_write_c2n(c2n); + + if (FD_ISSET(c2n->sck_comm, rfds)) + ret = PICA_read_c2n(c2n); + + break; + } + +return ret; } static int process_c2c(struct PICA_c2c *c2c, fd_set *rfds, fd_set *wfds) @@ -1502,6 +1653,8 @@ int ret, nfds = 0; struct PICA_c2n **ic2n; struct PICA_listener **ilst; +//puts("PICA_event_loop");//debug + tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; @@ -1522,9 +1675,12 @@ while(ic2n && *ic2n) { struct PICA_c2c *ic2c; + //printf("event_loop: adding c2n %p\n", *ic2n);//debug + fdset_add(&rfds, (*ic2n)->sck_comm, &nfds); - if ((*ic2n)->write_pos) + if ((*ic2n)->write_pos || (*ic2n)->state == PICA_C2N_STATE_CONNECTING + || (*ic2n)->state == PICA_C2N_STATE_WAITINGTLS) fdset_add(&wfds, (*ic2n)->sck_comm, &nfds); ic2c = (*ic2n)->chan_list_head; @@ -1535,7 +1691,7 @@ while(ic2n && *ic2n) { fdset_add(&rfds, ic2c->sck_data, &nfds); - if (ic2c->write_pos) + if (ic2c->write_pos || ic2c->sendfilestate == PICA_CHANSENDFILESTATE_SENDING) fdset_add(&wfds, ic2c->sck_data, &nfds); } @@ -1548,9 +1704,6 @@ while(ic2n && *ic2n) ret = select(nfds + 1, &rfds, &wfds, NULL, &tv); -if (ret == 0) - return PICA_OK; - if (ret == -1) { #ifndef WIN32 @@ -1563,6 +1716,8 @@ if (ret == -1) #endif } +//printf("select() returned %i\n", ret);//debug + //processing listeners, c2n and c2c connections ilst = listeners; @@ -1572,11 +1727,16 @@ while(ilst && *ilst) ret = process_listener(*ilst, &rfds); if (ret != PICA_OK) + { callbacks.listener_error(*ilst, ret); + PICA_close_listener(*ilst); + } ilst++; } +ic2n = connections; + while(ic2n && *ic2n) { struct PICA_c2c *ic2c; @@ -1587,6 +1747,11 @@ while(ic2n && *ic2n) if (ret != PICA_OK) { + if ((*ic2n)->state == PICA_C2N_STATE_CONNECTED) + callbacks.c2n_closed_cb(*ic2n); + else + callbacks.c2n_failed_cb(*ic2n); + PICA_close_c2n(*ic2n); } else @@ -1822,7 +1987,7 @@ int PICA_write_c2n(struct PICA_c2n *ci) { int ret = PICA_ERRINVARG; -if (PICA_C2N_STATE_CONNECTING == ci->state) +if (PICA_C2N_STATE_WAITINGREP == ci->state) ret = PICA_write_socket( ci->sck_comm, ci->write_buf, &ci->write_pos); else if (PICA_C2N_STATE_CONNECTED == ci->state) ret = PICA_write_ssl( ci->ssl_comm, ci->write_buf, &ci->write_pos, &ci->write_sslbytestowrite); @@ -1940,7 +2105,7 @@ int ret; //ret=SSL_read(ci->ssl_comm, ci->read_buf + ci->read_pos, PICA_CONNREADBUFSIZE - ci->read_pos); -if (PICA_C2N_STATE_CONNECTING == ci->state) +if (PICA_C2N_STATE_WAITINGREP == ci->state) ret = PICA_read_socket(ci->sck_comm, ci->read_buf, &ci->read_pos, PICA_CONNREADBUFSIZE); else if (PICA_C2N_STATE_CONNECTED == ci->state) ret = PICA_read_ssl(ci->ssl_comm, ci->read_buf, &ci->read_pos, PICA_CONNREADBUFSIZE); @@ -1949,7 +2114,7 @@ else if (PICA_C2N_STATE_CONNECTED == ci->state) if (ret == PICA_OK) { - if (PICA_C2N_STATE_CONNECTING == ci->state) + if (PICA_C2N_STATE_WAITINGREP == ci->state) if(!PICA_processdatastream( ci->read_buf, &(ci->read_pos), ci, c2n_init_messages, MSGINFO_MSGSNUM(c2n_init_messages))) return PICA_ERRSERV; diff --git a/PICA_common.h b/PICA_common.h index dd92b32..db14f99 100644 --- a/PICA_common.h +++ b/PICA_common.h @@ -4,11 +4,11 @@ #ifdef WIN32 #define CLOSE closesocket #define SHUTDOWN(s) shutdown(s,SD_BOTH) -#define IOCTLSETNONBLOCKINGSOCKET(s, arg) ioctlsocket(s, FIONBIO, (unsigned long*)(arg)) +#define IOCTLSETNONBLOCKINGSOCKET(s, a) {unsigned long arg = (a); ioctlsocket(s, FIONBIO, (unsigned long*)&arg); } #else #define CLOSE close #define SHUTDOWN(s) shutdown(s,SHUT_RDWR) -#define IOCTLSETNONBLOCKINGSOCKET(s, arg) ioctl(s, FIONBIO, (int*)(arg)) +#define IOCTLSETNONBLOCKINGSOCKET(s, a) {int arg = (a); ioctl(s, FIONBIO, (int*)&arg); } #endif #ifdef WIN32 -- cgit v1.2.1 From 5f1eaf6ebf6ab1e12ebe27aa5432e1d305a7520e Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 11 May 2015 02:50:41 +0400 Subject: updated test client --- tests/test_client.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 4 deletions(-) diff --git a/tests/test_client.c b/tests/test_client.c index 996639b..5480eee 100755 --- a/tests/test_client.c +++ b/tests/test_client.c @@ -21,7 +21,7 @@ return 1; } //получение сообщения. -void newmsg_cb(const unsigned char *peer_id,char* msgbuf,unsigned int nb,int type) +void newmsg_cb(const unsigned char *peer_id, const char* msgbuf,unsigned int nb,int type) { memcpy(buf,msgbuf,nb); buf[nb]=0; @@ -86,6 +86,57 @@ int peer_cert_verify_cb(const unsigned char *peer_id, const char *cert_pem, unsi return 1; } +int accept_file_cb(const unsigned char *peer_id, uint64_t file_size, const char *filename, unsigned int filename_size) +{ + printf("accept_file_cb: peer_id %s\n", PICA_id_to_base64(peer_id, NULL)); + return 0; +} + +void accepted_file_cb(const unsigned char *peer_id) +{ + printf("accepted_file_cb: peer_id %s \n", PICA_id_to_base64(peer_id, NULL)); +} + +void denied_file_cb(const unsigned char *peer_id) +{ + printf("denied_file_cb: peer_id %s \n", PICA_id_to_base64(peer_id, NULL)); +} + +void file_progress(const unsigned char *peer_id, uint64_t sent, uint64_t received) +{ + printf("file_progress: peer_id %s\n", PICA_id_to_base64(peer_id, NULL)); +} + +void file_control(const unsigned char *peer_id, unsigned int sender_cmd, unsigned int receiver_cmd) +{ + printf("file_control: peer_id %s sender_cmd %u receiver_cmd %u \n", PICA_id_to_base64(peer_id, NULL), sender_cmd, receiver_cmd); +} + +void file_finished(const unsigned char *peer_id, int sending) +{ + printf("file_finished: peer_id %s\n", PICA_id_to_base64(peer_id, NULL)); +} + +void c2n_established_cb(struct PICA_c2n *c2n) +{ + printf("c2n_established_cb: %p\n peer_id %s\n", c2n, PICA_id_to_base64(c2n->acc->id, NULL)); +} + +void c2n_failed_cb(struct PICA_c2n *c2n) +{ + printf("c2n_failed_cb: %p\n", c2n); +} + +void c2n_closed_cb(struct PICA_c2n *c2n) +{ + printf("c2n_closed_cb: %p\n", c2n); +} + +void listener_error(struct PICA_listener *lst, int errorcode) +{ + printf("listener_error: %p error code %i\n", lst, errorcode); +} + struct PICA_client_callbacks cbs = { newmsg_cb, msgok_cb, @@ -95,13 +146,24 @@ struct PICA_client_callbacks cbs = { notfound_cb, c2c_closed_cb, nodelist_cb, - peer_cert_verify_cb + peer_cert_verify_cb, + accept_file_cb, + accepted_file_cb, + denied_file_cb, + file_progress, + file_control, + file_finished, + c2n_established_cb, + c2n_failed_cb, + c2n_closed_cb, + listener_error }; int main(int argc,char** argv) { int ret; unsigned char peer_id[PICA_ID_SIZE]; +struct PICA_c2n* c2ns[] = {NULL, NULL}; if (argc<4) { @@ -139,13 +201,15 @@ ret=PICA_new_c2n(acc, argv[1], atoi(argv[2]), /*"trusted_CA.pem"*/ &c); ERR_print_errors_fp(stdout); if (ret==PICA_OK) -printf("PICA_OK Connected to server...\n"); +printf("PICA_OK started c2n connection to node...\n"); else { printf("PICA_new_c2n: ret=%i\n",ret); return 1; } +c2ns[0] = c; + if (argc==5) { if (PICA_id_from_base64(argv[4], peer_id) == NULL) @@ -166,6 +230,8 @@ if (argc==5) } + while(PICA_event_loop(c2ns, NULL, 1500) == PICA_OK); +/* do { if (chn && chn->state==PICA_CHANSTATE_ACTIVE) @@ -180,7 +246,7 @@ do printf("PICA_send_msg ret=%i\n",ret); } } -while(PICA_read(c,100000) == PICA_OK && PICA_write(c) == PICA_OK); +while(PICA_read(c,100000) == PICA_OK && PICA_write(c) == PICA_OK);*/ /* puts("Enter peer_id to talk with or . for waiting incoming sessions:"); -- cgit v1.2.1 From ef3dd94a729da287aec1744d9135d522550d83f9 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 25 May 2015 21:07:46 +0400 Subject: generate new DH key on each handshake --- PICA_client.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/PICA_client.c b/PICA_client.c index 29b6955..979d274 100755 --- a/PICA_client.c +++ b/PICA_client.c @@ -1159,6 +1159,8 @@ if (1 != SSL_CTX_set_tmp_dh(a->ctx, dh)) DH_free(dh); +SSL_CTX_set_options(a->ctx, SSL_OP_SINGLE_DH_USE); + if (!PICA_get_id_from_cert_file(cert_file, a->id)) { ret_err = PICA_ERRINVCERT; -- cgit v1.2.1 From d56c7301b718754c7ec6b2baad603ff001d5a46a Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 7 Apr 2016 20:38:23 +0400 Subject: added skeleton of procmsg_C2CCONNREQ() - PICA_PROTO_C2CCONNREQ packet handler --- PICA_client.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/PICA_client.c b/PICA_client.c index 979d274..94ef553 100755 --- a/PICA_client.c +++ b/PICA_client.c @@ -47,6 +47,7 @@ static unsigned int procmsg_DENIEDFILE(unsigned char*,unsigned int,void*); static unsigned int procmsg_FILEFRAGMENT(unsigned char*,unsigned int,void*); static unsigned int procmsg_FILECONTROL(unsigned char*,unsigned int,void*); static unsigned int procmsg_INITRESP_c2c(unsigned char*,unsigned int,void*); +static unsigned int procmsg_C2CCONNREQ(unsigned char* buf, unsigned int nb,void* p); 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); @@ -76,6 +77,7 @@ struct PICA_msginfo c2n_init_messages[] = { }; struct PICA_msginfo c2c_init_messages[] = { + {PICA_PROTO_C2CCONNREQ, PICA_MSG_FIXED_SIZE,PICA_PROTO_C2CCONNREQ_SIZE, procmsg_C2CCONNREQ}, {PICA_PROTO_INITRESPOK, PICA_MSG_FIXED_SIZE, PICA_PROTO_INITRESPOK_SIZE, procmsg_INITRESP_c2c}, {PICA_PROTO_VERDIFFER, PICA_MSG_FIXED_SIZE, PICA_PROTO_VERDIFFER_SIZE, procmsg_INITRESP_c2c} }; @@ -402,6 +404,22 @@ PICA_close_c2c(chnl); return err_ret; } +static unsigned int procmsg_C2CCONNREQ(unsigned char* buf, unsigned int nb,void* p) +{ +struct PICA_c2c *cc=(struct PICA_c2n *)p; + +if (buf[2] == PICA_C2CPROTO_VER_HIGH && buf[3] == PICA_C2CPROTO_VER_LOW) + { + //send ok + } +else + { + //send verdiffer, disconnect after sending + } + +return 1; +} + static unsigned int procmsg_INITRESP_c2c(unsigned char* buf, unsigned int nb,void* p) { } -- cgit v1.2.1 From fff351c20da3294f9f8d13d94660fea099093738 Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 7 Apr 2016 21:17:57 +0400 Subject: fixed code style using "astyle --style=allman --lineend=linux --indent=tab --pad-oper *.c *.h" --- PICA_client.c | 2996 ++++++++++++++++++++++---------------------- PICA_client.h | 188 +-- PICA_id.c | 88 +- PICA_id.h | 2 +- PICA_log.c | 106 +- PICA_log.h | 14 +- PICA_msgproc.c | 92 +- PICA_msgproc.h | 16 +- PICA_node.c | 3426 ++++++++++++++++++++++++++------------------------- PICA_node.h | 136 +- PICA_nodeaddrlist.c | 258 ++-- PICA_nodeaddrlist.h | 36 +- PICA_nodeconfig.c | 24 +- PICA_nodeconfig.h | 16 +- PICA_nodewait.c | 220 ++-- PICA_nodewait.h | 14 +- PICA_proto.h | 4 +- 17 files changed, 3825 insertions(+), 3811 deletions(-) mode change 100755 => 100644 PICA_client.c mode change 100755 => 100644 PICA_client.h mode change 100755 => 100644 PICA_msgproc.c mode change 100755 => 100644 PICA_msgproc.h mode change 100755 => 100644 PICA_node.c mode change 100755 => 100644 PICA_node.h mode change 100755 => 100644 PICA_nodeaddrlist.c mode change 100755 => 100644 PICA_nodeaddrlist.h mode change 100755 => 100644 PICA_proto.h diff --git a/PICA_client.c b/PICA_client.c old mode 100755 new mode 100644 index 94ef553..0d728f4 --- a/PICA_client.c +++ b/PICA_client.c @@ -33,27 +33,28 @@ static int PICA_sendfile_open_read(struct PICA_c2c *chn, const char *filename_ut static int PICA_recvfile_open_write(struct PICA_c2c *chn, const char *filename_utf8, unsigned int filenamesize); static int PICA_send_filecontrol(struct PICA_c2c *chan, int senderctl, int receiverctl); -static unsigned int procmsg_INITRESP(unsigned char*,unsigned int,void*); -static unsigned int procmsg_CONNREQINC(unsigned char*,unsigned int,void*); -static unsigned int procmsg_NOTFOUND(unsigned char*,unsigned int,void*); -static unsigned int procmsg_FOUND(unsigned char*,unsigned int,void*); -static unsigned int procmsg_CLNODELIST(unsigned char*,unsigned int,void*); -static unsigned int procmsg_MSGUTF8(unsigned char*,unsigned int,void*); -static unsigned int procmsg_MSGOK(unsigned char*,unsigned int,void*); -static unsigned int procmsg_PINGREQ(unsigned char*,unsigned int,void*); -static unsigned int procmsg_SENDFILEREQUEST(unsigned char*,unsigned int,void*); -static unsigned int procmsg_ACCEPTEDFILE(unsigned char*,unsigned int,void*); -static unsigned int procmsg_DENIEDFILE(unsigned char*,unsigned int,void*); -static unsigned int procmsg_FILEFRAGMENT(unsigned char*,unsigned int,void*); -static unsigned int procmsg_FILECONTROL(unsigned char*,unsigned int,void*); -static unsigned int procmsg_INITRESP_c2c(unsigned char*,unsigned int,void*); -static unsigned int procmsg_C2CCONNREQ(unsigned char* buf, unsigned int nb,void* p); +static unsigned int procmsg_INITRESP(unsigned char*, unsigned int, void*); +static unsigned int procmsg_CONNREQINC(unsigned char*, unsigned int, void*); +static unsigned int procmsg_NOTFOUND(unsigned char*, unsigned int, void*); +static unsigned int procmsg_FOUND(unsigned char*, unsigned int, void*); +static unsigned int procmsg_CLNODELIST(unsigned char*, unsigned int, void*); +static unsigned int procmsg_MSGUTF8(unsigned char*, unsigned int, void*); +static unsigned int procmsg_MSGOK(unsigned char*, unsigned int, void*); +static unsigned int procmsg_PINGREQ(unsigned char*, unsigned int, void*); +static unsigned int procmsg_SENDFILEREQUEST(unsigned char*, unsigned int, void*); +static unsigned int procmsg_ACCEPTEDFILE(unsigned char*, unsigned int, void*); +static unsigned int procmsg_DENIEDFILE(unsigned char*, unsigned int, void*); +static unsigned int procmsg_FILEFRAGMENT(unsigned char*, unsigned int, void*); +static unsigned int procmsg_FILECONTROL(unsigned char*, unsigned int, void*); +static unsigned int procmsg_INITRESP_c2c(unsigned char*, unsigned int, void*); +static unsigned int procmsg_C2CCONNREQ(unsigned char* buf, unsigned int nb, void* p); 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); #define MSGINFO_MSGSNUM(arr) (sizeof(arr)/sizeof(struct PICA_msginfo)) -const struct PICA_msginfo c2n_messages[] = { +const struct PICA_msginfo c2n_messages[] = +{ {PICA_PROTO_CONNREQINC, PICA_MSG_FIXED_SIZE, PICA_PROTO_CONNREQINC_SIZE, procmsg_CONNREQINC}, {PICA_PROTO_NOTFOUND, PICA_MSG_FIXED_SIZE, PICA_PROTO_NOTFOUND_SIZE, procmsg_NOTFOUND}, {PICA_PROTO_FOUND, PICA_MSG_FIXED_SIZE, PICA_PROTO_FOUND_SIZE, procmsg_FOUND}, @@ -61,7 +62,8 @@ const struct PICA_msginfo c2n_messages[] = { {PICA_PROTO_PINGREQ, PICA_MSG_FIXED_SIZE, PICA_PROTO_PINGREQ_SIZE, procmsg_PINGREQ} };//---!!! PING!!! -const struct PICA_msginfo c2c_messages[] = { +const struct PICA_msginfo c2c_messages[] = +{ {PICA_PROTO_MSGUTF8, PICA_MSG_VAR_SIZE, PICA_MSG_VARSIZE_INT16, procmsg_MSGUTF8}, {PICA_PROTO_MSGOK, PICA_MSG_FIXED_SIZE, PICA_PROTO_MSGOK_SIZE, procmsg_MSGOK}, {PICA_PROTO_SENDFILEREQUEST, PICA_MSG_VAR_SIZE, PICA_MSG_VARSIZE_INT16, procmsg_SENDFILEREQUEST}, @@ -71,13 +73,15 @@ const struct PICA_msginfo c2c_messages[] = { {PICA_PROTO_FILECONTROL, PICA_MSG_FIXED_SIZE, PICA_PROTO_FILECONTROL_SIZE, procmsg_FILECONTROL} }; -struct PICA_msginfo c2n_init_messages[] = { +struct PICA_msginfo c2n_init_messages[] = +{ {PICA_PROTO_INITRESPOK, PICA_MSG_FIXED_SIZE, PICA_PROTO_INITRESPOK_SIZE, procmsg_INITRESP}, {PICA_PROTO_VERDIFFER, PICA_MSG_FIXED_SIZE, PICA_PROTO_VERDIFFER_SIZE, procmsg_INITRESP} }; -struct PICA_msginfo c2c_init_messages[] = { - {PICA_PROTO_C2CCONNREQ, PICA_MSG_FIXED_SIZE,PICA_PROTO_C2CCONNREQ_SIZE, procmsg_C2CCONNREQ}, +struct PICA_msginfo c2c_init_messages[] = +{ + {PICA_PROTO_C2CCONNREQ, PICA_MSG_FIXED_SIZE, PICA_PROTO_C2CCONNREQ_SIZE, procmsg_C2CCONNREQ}, {PICA_PROTO_INITRESPOK, PICA_MSG_FIXED_SIZE, PICA_PROTO_INITRESPOK_SIZE, procmsg_INITRESP_c2c}, {PICA_PROTO_VERDIFFER, PICA_MSG_FIXED_SIZE, PICA_PROTO_VERDIFFER_SIZE, procmsg_INITRESP_c2c} }; @@ -123,809 +127,811 @@ return 1; int PICA_get_id_from_cert_file(const char *cert_file, unsigned char *id) { -X509 *x; -FILE *f; + X509 *x; + FILE *f; -f=fopen(cert_file,"r"); + f = fopen(cert_file, "r"); -if (!f) -{ - perror(cert_file); - return 0; -} + if (!f) + { + perror(cert_file); + return 0; + } -x=PEM_read_X509(f,0,0,0); -fclose(f); + x = PEM_read_X509(f, 0, 0, 0); + fclose(f); -if (!x) -{ - return 0; -} + if (!x) + { + return 0; + } -return PICA_id_from_X509(x, id); + return PICA_id_from_X509(x, id); } int PICA_get_id_from_cert_string(const char *cert_pem, unsigned char *id) { -X509 *x; -BIO *biomem; + X509 *x; + BIO *biomem; -biomem = BIO_new_mem_buf(cert_pem, -1); + biomem = BIO_new_mem_buf(cert_pem, -1); -x = PEM_read_bio_X509(biomem, NULL, 0, NULL); + x = PEM_read_bio_X509(biomem, NULL, 0, NULL); -if (!x) -{ - return 0; -} + if (!x) + { + return 0; + } -return PICA_id_from_X509(x, id); + return PICA_id_from_X509(x, id); } static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) -{ //return 1 for self-signed certificates -char buf[256]; -X509 *err_cert; -int err, depth; -SSL *ssl; +{ + //return 1 for self-signed certificates + char buf[256]; + X509 *err_cert; + int err, depth; + SSL *ssl; -err_cert = X509_STORE_CTX_get_current_cert(ctx); -err = X509_STORE_CTX_get_error(ctx); -depth = X509_STORE_CTX_get_error_depth(ctx); + err_cert = X509_STORE_CTX_get_current_cert(ctx); + err = X509_STORE_CTX_get_error(ctx); + depth = X509_STORE_CTX_get_error_depth(ctx); -X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256); + X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256); -if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && depth == 0) - preverify_ok = 1; + if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && depth == 0) + preverify_ok = 1; -if (!preverify_ok) { - printf("verify error:num=%d:%s:depth=%d:%s\n", err, - X509_verify_cert_error_string(err), depth, buf); - } + if (!preverify_ok) + { + printf("verify error:num=%d:%s:depth=%d:%s\n", err, + X509_verify_cert_error_string(err), depth, buf); + } - /* - * At this point, err contains the last verification error. We can use - * it for something special - */ - if (!preverify_ok && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT)) - { - X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256); - printf("issuer= %s\n", buf); - } + /* + * At this point, err contains the last verification error. We can use + * it for something special + */ + if (!preverify_ok && (err == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT)) + { + X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256); + printf("issuer= %s\n", buf); + } - return preverify_ok; + return preverify_ok; } static int add_chaninfo(struct PICA_c2n *ci, struct PICA_c2c **chn, const unsigned char *peer_id, int is_outgoing) { -struct PICA_c2c *chnl,*ipt; + struct PICA_c2c *chnl, *ipt; -chnl=*chn=(struct PICA_c2c*)calloc(sizeof(struct PICA_c2c),1); + chnl = *chn = (struct PICA_c2c*)calloc(sizeof(struct PICA_c2c), 1); -if (!chnl) - return 0;//ERR_CHECK + if (!chnl) + return 0;//ERR_CHECK -chnl->conn = ci; -chnl->outgoing = is_outgoing; -memcpy(chnl->peer_id, peer_id, PICA_ID_SIZE); + chnl->conn = ci; + chnl->outgoing = is_outgoing; + memcpy(chnl->peer_id, peer_id, PICA_ID_SIZE); -chnl->acc = ci->acc; + chnl->acc = ci->acc; -chnl->timestamp = time(0); + chnl->timestamp = time(0); -chnl->sck_data = -1;//prevent closing stdin when closing non-active connection + chnl->sck_data = -1;//prevent closing stdin when closing non-active connection -chnl->read_buf = calloc(PICA_CHANREADBUFSIZE, 1); + chnl->read_buf = calloc(PICA_CHANREADBUFSIZE, 1); -if (ci->chan_list_head) + if (ci->chan_list_head) { - ci->chan_list_end->next=chnl; - chnl->prev=ci->chan_list_end; - ci->chan_list_end=chnl; + ci->chan_list_end->next = chnl; + chnl->prev = ci->chan_list_end; + ci->chan_list_end = chnl; } -else + else { - ci->chan_list_head=chnl; - ci->chan_list_end=chnl; + ci->chan_list_head = chnl; + ci->chan_list_end = chnl; } -return 1; + return 1; } static int establish_data_connection(struct PICA_c2c *chnl) { -char* DN_str; + char* DN_str; //unsigned char buf[12]; -int ret,err_ret; -unsigned int tmp_uid; -struct PICA_proto_msg *mp; + int ret, err_ret; + unsigned int tmp_uid; + struct PICA_proto_msg *mp; -chnl->sck_data=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + chnl->sck_data = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); -{ -struct sockaddr_in addr=chnl->conn->srv_addr; + { + struct sockaddr_in addr = chnl->conn->srv_addr; -addr.sin_port = htons(ntohs(addr.sin_port)); + addr.sin_port = htons(ntohs(addr.sin_port)); -ret=connect( chnl->sck_data, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)); + ret = connect( chnl->sck_data, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)); /////////////////state_ -if (ret==SOCKET_ERROR) - { - err_ret=PICA_ERRSOCK; - goto error_ret; + if (ret == SOCKET_ERROR) + { + err_ret = PICA_ERRSOCK; + goto error_ret; + } } -} -mp = c2c_writebuf_push( chnl, PICA_PROTO_CONNID, PICA_PROTO_CONNID_SIZE); -if (mp) + mp = c2c_writebuf_push( chnl, PICA_PROTO_CONNID, PICA_PROTO_CONNID_SIZE); + if (mp) { - if (chnl->outgoing) + if (chnl->outgoing) { - memcpy(mp->tail, chnl->acc->id, PICA_ID_SIZE);//вызвывающий - memcpy(mp->tail + PICA_ID_SIZE, chnl->peer_id, PICA_ID_SIZE);//вызываемый + memcpy(mp->tail, chnl->acc->id, PICA_ID_SIZE);//вызвывающий + memcpy(mp->tail + PICA_ID_SIZE, chnl->peer_id, PICA_ID_SIZE);//вызываемый } - else + else { - memcpy(mp->tail, chnl->peer_id, PICA_ID_SIZE);//вызвывающий - memcpy(mp->tail + PICA_ID_SIZE, chnl->acc->id, PICA_ID_SIZE);//вызываемый - } + memcpy(mp->tail, chnl->peer_id, PICA_ID_SIZE);//вызвывающий + memcpy(mp->tail + PICA_ID_SIZE, chnl->acc->id, PICA_ID_SIZE);//вызываемый + } } -else + else { - err_ret=PICA_ERRNOMEM; - goto error_ret; + err_ret = PICA_ERRNOMEM; + goto error_ret; } -do + do { - err_ret = PICA_write_c2c(chnl); - if (PICA_OK != err_ret) - goto error_ret; + err_ret = PICA_write_c2c(chnl); + if (PICA_OK != err_ret) + goto error_ret; } -while( chnl->write_pos > 0); + while( chnl->write_pos > 0); -chnl->ssl=SSL_new(chnl->acc->ctx); + chnl->ssl = SSL_new(chnl->acc->ctx); -if (!chnl->ssl) + if (!chnl->ssl) { - //puts("SSL_new !- 0");//debug - err_ret=PICA_ERRSSL; - goto error_ret; + //puts("SSL_new !- 0");//debug + err_ret = PICA_ERRSSL; + goto error_ret; } -ret=SSL_set_fd(chnl->ssl, chnl->sck_data); + ret = SSL_set_fd(chnl->ssl, chnl->sck_data); -if (!ret) + if (!ret) { - //puts("SSL_set_fd returned 0");//debug - err_ret=PICA_ERRSSL; - goto error_ret_; + //puts("SSL_set_fd returned 0");//debug + err_ret = PICA_ERRSSL; + goto error_ret_; } -SSL_set_verify(chnl->ssl, SSL_VERIFY_PEER, verify_callback); -SSL_set_verify_depth(chnl->ssl, 1);//peer certificate and one CA + SSL_set_verify(chnl->ssl, SSL_VERIFY_PEER, verify_callback); + SSL_set_verify_depth(chnl->ssl, 1);//peer certificate and one CA -if (chnl->outgoing) -ret=SSL_connect(chnl->ssl); -else -ret=SSL_accept(chnl->ssl); + if (chnl->outgoing) + ret = SSL_connect(chnl->ssl); + else + ret = SSL_accept(chnl->ssl); /////////////////state_ //printf("verify result:%i\n",(int)SSL_get_verify_result(chnl->ssl));//debug -if (ret!=1) + if (ret != 1) { - //printf("ret=%i of SSL_connect or accept\n",ret);//debug - //printf("SSL_get_error says:%i\n",SSL_get_error(chnl->ssl,ret));//debug - err_ret=PICA_ERRSSL; - goto error_ret_; + //printf("ret=%i of SSL_connect or accept\n",ret);//debug + //printf("SSL_get_error says:%i\n",SSL_get_error(chnl->ssl,ret));//debug + err_ret = PICA_ERRSSL; + goto error_ret_; } //проверить сертификат собеседника -chnl->peer_cert=SSL_get_peer_certificate(chnl->ssl); + chnl->peer_cert = SSL_get_peer_certificate(chnl->ssl); -if (!chnl->peer_cert) + if (!chnl->peer_cert) { - err_ret=PICA_ERRNOPEERCERT; - goto error_ret_; + err_ret = PICA_ERRNOPEERCERT; + goto error_ret_; } -{ -unsigned char temp_id[PICA_ID_SIZE]; - -if (PICA_id_from_X509(chnl->peer_cert, temp_id) == 0) { - err_ret=PICA_ERRNOPEERCERT; - goto error_ret_; - } + unsigned char temp_id[PICA_ID_SIZE]; -if (memcmp(temp_id, chnl->peer_id, PICA_ID_SIZE) != 0) - { - err_ret=PICA_ERRINVPEERCERT; - goto error_ret_; - } -} -/* -DN_str=X509_NAME_oneline(X509_get_subject_name(chnl->peer_cert), 0, 0); + if (PICA_id_from_X509(chnl->peer_cert, temp_id) == 0) + { + err_ret = PICA_ERRNOPEERCERT; + goto error_ret_; + } -if (!DN_str) - { - //puts("no DN_str");//debug - err_ret=PICA_ERRSSL; - goto error_ret_; + if (memcmp(temp_id, chnl->peer_id, PICA_ID_SIZE) != 0) + { + err_ret = PICA_ERRINVPEERCERT; + goto error_ret_; + } } + /* + DN_str=X509_NAME_oneline(X509_get_subject_name(chnl->peer_cert), 0, 0); -if (!get_id_fromsubjstr(DN_str,&tmp_uid) || tmp_uid!=chnl->peer_id) - { - err_ret=PICA_ERRINVPEERCERT; - goto error_ret_; - } -//puts(DN_str);//debug + if (!DN_str) + { + //puts("no DN_str");//debug + err_ret=PICA_ERRSSL; + goto error_ret_; + } + + if (!get_id_fromsubjstr(DN_str,&tmp_uid) || tmp_uid!=chnl->peer_id) + { + err_ret=PICA_ERRINVPEERCERT; + goto error_ret_; + } + //puts(DN_str);//debug -OPENSSL_free(DN_str);*/ + OPENSSL_free(DN_str);*/ -{ -BIO *mem = BIO_new(BIO_s_mem()); -char *cert_pem; -unsigned int cert_pem_nb; + { + BIO *mem = BIO_new(BIO_s_mem()); + char *cert_pem; + unsigned int cert_pem_nb; -PEM_write_bio_X509(mem, chnl->peer_cert); + PEM_write_bio_X509(mem, chnl->peer_cert); -cert_pem_nb = (unsigned int)BIO_get_mem_data(mem, &cert_pem); + cert_pem_nb = (unsigned int)BIO_get_mem_data(mem, &cert_pem); -if (callbacks.peer_cert_verify_cb(chnl->peer_id, (const char*)cert_pem, cert_pem_nb) == 0) - { - BIO_free(mem); - err_ret=PICA_ERRINVPEERCERT; - goto error_ret_; - } + if (callbacks.peer_cert_verify_cb(chnl->peer_id, (const char*)cert_pem, cert_pem_nb) == 0) + { + BIO_free(mem); + err_ret = PICA_ERRINVPEERCERT; + goto error_ret_; + } -BIO_free(mem); -} + BIO_free(mem); + } -chnl->state=PICA_C2C_STATE_ACTIVE; + chnl->state = PICA_C2C_STATE_ACTIVE; -IOCTLSETNONBLOCKINGSOCKET(chnl->sck_data, 1); + IOCTLSETNONBLOCKINGSOCKET(chnl->sck_data, 1); -return PICA_OK; + return PICA_OK; error_ret_: error_ret: -callbacks.c2c_failed(chnl->peer_id); -PICA_close_c2c(chnl); -return err_ret; + callbacks.c2c_failed(chnl->peer_id); + PICA_close_c2c(chnl); + return err_ret; } -static unsigned int procmsg_C2CCONNREQ(unsigned char* buf, unsigned int nb,void* p) +static unsigned int procmsg_C2CCONNREQ(unsigned char* buf, unsigned int nb, void* p) { -struct PICA_c2c *cc=(struct PICA_c2n *)p; + struct PICA_c2c *cc = (struct PICA_c2n *)p; -if (buf[2] == PICA_C2CPROTO_VER_HIGH && buf[3] == PICA_C2CPROTO_VER_LOW) - { - //send ok - } -else - { - //send verdiffer, disconnect after sending - } + if (buf[2] == PICA_C2CPROTO_VER_HIGH && buf[3] == PICA_C2CPROTO_VER_LOW) + { + //send ok + } + else + { + //send verdiffer, disconnect after sending + } -return 1; + return 1; } -static unsigned int procmsg_INITRESP_c2c(unsigned char* buf, unsigned int nb,void* p) +static unsigned int procmsg_INITRESP_c2c(unsigned char* buf, unsigned int nb, void* p) { } -static unsigned int procmsg_INITRESP(unsigned char* buf, unsigned int nb,void* p) +static unsigned int procmsg_INITRESP(unsigned char* buf, unsigned int nb, void* p) { -struct PICA_c2n *ci=(struct PICA_c2n *)p; + struct PICA_c2n *ci = (struct PICA_c2n *)p; -switch(buf[0]) + switch(buf[0]) { case PICA_PROTO_INITRESPOK: - ci -> init_resp_ok = 1; - break; - + ci -> init_resp_ok = 1; + break; + case PICA_PROTO_VERDIFFER: - ci->init_resp_ok = -1; - ci->node_ver_major = buf[2]; - ci->node_ver_minor = buf[3]; - break; - + ci->init_resp_ok = -1; + ci->node_ver_major = buf[2]; + ci->node_ver_minor = buf[3]; + break; + default: - return 0; - } + return 0; + } -return 1; + return 1; } -static unsigned int procmsg_CONNREQINC(unsigned char* buf,unsigned int nb,void* p) +static unsigned int procmsg_CONNREQINC(unsigned char* buf, unsigned int nb, void* p) { -int ret; -struct PICA_c2n *ci=(struct PICA_c2n *)p; -struct PICA_proto_msg *mp; -unsigned char *peer_id = buf + 2; + int ret; + struct PICA_c2n *ci = (struct PICA_c2n *)p; + struct PICA_proto_msg *mp; + unsigned char *peer_id = buf + 2; if (callbacks.accept_cb(peer_id)) - { + { struct PICA_c2c *_chnl; - + mp = c2n_writebuf_push( ci, PICA_PROTO_CONNALLOW, PICA_PROTO_CONNALLOW_SIZE); - + if (mp) - { + { memcpy(mp->tail, peer_id, PICA_ID_SIZE); - } + } else return 0; - + ret = add_chaninfo( ci, &_chnl, peer_id, 0); if (!ret) return 0; //ERR_CHECK - кончилась память - + do - { + { ret = PICA_write_c2n(ci); if (PICA_OK != ret) return 0; - } + } while( ci->write_pos > 0); ret = establish_data_connection(_chnl); - if (ret!=PICA_OK) + if (ret != PICA_OK) return 1; - callbacks.c2c_established_cb(_chnl->peer_id);//*nchn=_chnl; + callbacks.c2c_established_cb(_chnl->peer_id);//*nchn=_chnl; return 1; - } + } else - { + { mp = c2n_writebuf_push(ci, PICA_PROTO_CONNDENY, PICA_PROTO_CONNDENY_SIZE); - + if (mp) - { + { memcpy(mp->tail, peer_id, PICA_ID_SIZE); - } + } else return 0;//ERR_CHECK - } -return 1; + } + return 1; } -static unsigned int procmsg_NOTFOUND(unsigned char* buf,unsigned int nb,void* p) +static unsigned int procmsg_NOTFOUND(unsigned char* buf, unsigned int nb, void* p) { -struct PICA_c2n *ci=(struct PICA_c2n *)p; -struct PICA_c2c *ipt,*rq=0; -unsigned char *peer_id = buf + 2; + struct PICA_c2n *ci = (struct PICA_c2n *)p; + struct PICA_c2c *ipt, *rq = 0; + unsigned char *peer_id = buf + 2; //puts("procmsg_NOTFOUND");//debug -ipt=ci->chan_list_end; -while(ipt) + ipt = ci->chan_list_end; + while(ipt) { - if (memcmp(ipt->peer_id, peer_id, PICA_ID_SIZE) == 0) + if (memcmp(ipt->peer_id, peer_id, PICA_ID_SIZE) == 0) { - rq=ipt; - break; + rq = ipt; + break; } - ipt=ipt->prev; + ipt = ipt->prev; } -if (!rq) - return 0;// ERR_CHECK -левое сообщение, такой запрос не посылался + if (!rq) + return 0;// ERR_CHECK -левое сообщение, такой запрос не посылался //puts("procmsg_NOTFOUND_chkp0");//debug -PICA_close_c2c(rq); + PICA_close_c2c(rq); //puts("procmsg_NOTFOUND_chkp1");//debug -callbacks.notfound_cb(peer_id); -return 1; + callbacks.notfound_cb(peer_id); + return 1; } -static unsigned int procmsg_FOUND(unsigned char* buf,unsigned int nb,void* p) +static unsigned int procmsg_FOUND(unsigned char* buf, unsigned int nb, void* p) { -struct PICA_c2n *ci=(struct PICA_c2n *)p; -struct PICA_c2c *ipt,*rq=0; -unsigned char *peer_id = buf + 2; -int ret; + struct PICA_c2n *ci = (struct PICA_c2n *)p; + struct PICA_c2c *ipt, *rq = 0; + unsigned char *peer_id = buf + 2; + int ret; -ipt=ci->chan_list_end; -while(ipt) + ipt = ci->chan_list_end; + while(ipt) { - if (memcmp(ipt->peer_id, peer_id, PICA_ID_SIZE) == 0) + if (memcmp(ipt->peer_id, peer_id, PICA_ID_SIZE) == 0) { - rq=ipt; - break; + rq = ipt; + break; } - ipt=ipt->prev; - } + ipt = ipt->prev; + } -if (!rq) - return 0;// ERR_CHECK -левое сообщение, такой запрос не посылался + if (!rq) + return 0;// ERR_CHECK -левое сообщение, такой запрос не посылался -ret=establish_data_connection(rq); + ret = establish_data_connection(rq); -if (ret!=PICA_OK) - return 0; + if (ret != PICA_OK) + return 0; -callbacks.c2c_established_cb(rq->peer_id);//*nchn=_chnl; + callbacks.c2c_established_cb(rq->peer_id);//*nchn=_chnl; -return 1; + return 1; } static unsigned int procmsg_CLNODELIST(unsigned char* buf, unsigned int nb, void* p) { -unsigned int pos = 4; -char ipaddr_string[INET6_ADDRSTRLEN]; -char temp_zeroswap; -unsigned int port; + unsigned int pos = 4; + char ipaddr_string[INET6_ADDRSTRLEN]; + char temp_zeroswap; + unsigned int port; //puts("CLNODELIST");//debug //callbacks.nodelist_cb(buf + 4, nb - 4); -do + do { - switch(buf[pos]) + switch(buf[pos]) { - case PICA_PROTO_NEWNODE_IPV4: - - callbacks.nodelist_cb( - PICA_PROTO_NEWNODE_IPV4, - buf + pos +1, - inet_ntop(AF_INET, buf + pos +1, ipaddr_string, INET6_ADDRSTRLEN), - ntohs(*(uint16_t*)(buf + pos + 5)) - ); - - pos += PICA_PROTO_NODELIST_ITEM_IPV4_SIZE; - break; - - case PICA_PROTO_NEWNODE_IPV6: - - callbacks.nodelist_cb( - PICA_PROTO_NEWNODE_IPV6, - buf + pos +1, - inet_ntop(AF_INET6, buf + pos +1, ipaddr_string, INET6_ADDRSTRLEN), - ntohs(*(uint16_t*)(buf + pos + 17)) - ); - - pos += PICA_PROTO_NODELIST_ITEM_IPV6_SIZE; - break; - - case PICA_PROTO_NEWNODE_DNS: - - port = ntohs(*(uint16_t*)(buf + pos + buf[pos+1] + 2)); - - temp_zeroswap = buf[pos + 2 + buf[pos+1]]; //save byte after hostname string - buf[pos + 2 + buf[pos+1]] = '\0';// and replace it with string terminating zero - - callbacks.nodelist_cb( - PICA_PROTO_NEWNODE_DNS, - buf + pos +2, - buf + pos +2, - port - ); - - buf[pos + 2 + buf[pos+1]] = temp_zeroswap; - - pos += 4 + buf[pos+1]; - break; - - default: - //puts("unknown node address type");//debug - return 0; + case PICA_PROTO_NEWNODE_IPV4: + + callbacks.nodelist_cb( + PICA_PROTO_NEWNODE_IPV4, + buf + pos + 1, + inet_ntop(AF_INET, buf + pos + 1, ipaddr_string, INET6_ADDRSTRLEN), + ntohs(*(uint16_t*)(buf + pos + 5)) + ); + + pos += PICA_PROTO_NODELIST_ITEM_IPV4_SIZE; + break; + + case PICA_PROTO_NEWNODE_IPV6: + + callbacks.nodelist_cb( + PICA_PROTO_NEWNODE_IPV6, + buf + pos + 1, + inet_ntop(AF_INET6, buf + pos + 1, ipaddr_string, INET6_ADDRSTRLEN), + ntohs(*(uint16_t*)(buf + pos + 17)) + ); + + pos += PICA_PROTO_NODELIST_ITEM_IPV6_SIZE; + break; + + case PICA_PROTO_NEWNODE_DNS: + + port = ntohs(*(uint16_t*)(buf + pos + buf[pos + 1] + 2)); + + temp_zeroswap = buf[pos + 2 + buf[pos + 1]]; //save byte after hostname string + buf[pos + 2 + buf[pos + 1]] = '\0'; // and replace it with string terminating zero + + callbacks.nodelist_cb( + PICA_PROTO_NEWNODE_DNS, + buf + pos + 2, + buf + pos + 2, + port + ); + + buf[pos + 2 + buf[pos + 1]] = temp_zeroswap; + + pos += 4 + buf[pos + 1]; + break; + + default: + //puts("unknown node address type");//debug + return 0; } } -while(pos < nb); + while(pos < nb); -return 1; + return 1; } static unsigned int procmsg_MSGUTF8(unsigned char* buf, unsigned int nb, void* p) { -struct PICA_c2c *chan = (struct PICA_c2c *)p; -struct PICA_proto_msg *mp; + struct PICA_c2c *chan = (struct PICA_c2c *)p; + struct PICA_proto_msg *mp; -callbacks.newmsg_cb(chan->peer_id, buf + 4, nb - 4, buf[0]); + callbacks.newmsg_cb(chan->peer_id, buf + 4, nb - 4, buf[0]); //send PICA_PROTO_MSGOK -mp = c2c_writebuf_push( chan, PICA_PROTO_MSGOK, PICA_PROTO_MSGOK_SIZE); + mp = c2c_writebuf_push( chan, PICA_PROTO_MSGOK, PICA_PROTO_MSGOK_SIZE); -if (mp) + if (mp) { - RAND_bytes( mp->tail, 2); + RAND_bytes( mp->tail, 2); } -else - return 0; + else + return 0; -return 1; + return 1; } static unsigned int procmsg_MSGOK(unsigned char* buf, unsigned int nb, void* p) { -struct PICA_c2c *chan = (struct PICA_c2c *)p; + struct PICA_c2c *chan = (struct PICA_c2c *)p; -callbacks.msgok_cb(chan -> peer_id); -return 1; + callbacks.msgok_cb(chan -> peer_id); + return 1; } -unsigned int procmsg_PINGREQ(unsigned char* buf,unsigned int nb,void* p) +unsigned int procmsg_PINGREQ(unsigned char* buf, unsigned int nb, void* p) { -struct PICA_c2n *ci=(struct PICA_c2n *)p; -struct PICA_proto_msg *mp; + struct PICA_c2n *ci = (struct PICA_c2n *)p; + struct PICA_proto_msg *mp; -mp = c2n_writebuf_push(ci, PICA_PROTO_PINGREP, PICA_PROTO_PINGREP_SIZE); + mp = c2n_writebuf_push(ci, PICA_PROTO_PINGREP, PICA_PROTO_PINGREP_SIZE); -if (mp) - { - RAND_bytes(mp->tail, 2); - } -else - return 0; + if (mp) + { + RAND_bytes(mp->tail, 2); + } + else + return 0; -return 1; + return 1; } int PICA_deny_file(struct PICA_c2c *chan) { -struct PICA_proto_msg *mp; + struct PICA_proto_msg *mp; -if (chan->recvfilestate != PICA_CHANRECVFILESTATE_WAITACCEPT) - return PICA_ERRINVARG; + if (chan->recvfilestate != PICA_CHANRECVFILESTATE_WAITACCEPT) + return PICA_ERRINVARG; -chan->recvfilestate = PICA_CHANRECVFILESTATE_IDLE; + chan->recvfilestate = PICA_CHANRECVFILESTATE_IDLE; -mp = c2c_writebuf_push(chan, PICA_PROTO_DENIEDFILE, PICA_PROTO_DENIEDFILE_SIZE); + mp = c2c_writebuf_push(chan, PICA_PROTO_DENIEDFILE, PICA_PROTO_DENIEDFILE_SIZE); -if (mp) - { - RAND_bytes(mp->tail, 2); - } -else - return PICA_ERRNOMEM; + if (mp) + { + RAND_bytes(mp->tail, 2); + } + else + return PICA_ERRNOMEM; -return PICA_OK; + return PICA_OK; } int PICA_accept_file(struct PICA_c2c *chan, char *filename, unsigned int filenamesize) { -struct PICA_proto_msg *mp; -int ret; + struct PICA_proto_msg *mp; + int ret; -if (chan->recvfilestate != PICA_CHANRECVFILESTATE_WAITACCEPT) - return PICA_ERRINVARG; + if (chan->recvfilestate != PICA_CHANRECVFILESTATE_WAITACCEPT) + return PICA_ERRINVARG; //open file -ret = PICA_recvfile_open_write(chan, filename, filenamesize); + ret = PICA_recvfile_open_write(chan, filename, filenamesize); -if (ret != PICA_OK) - return ret; + if (ret != PICA_OK) + return ret; -mp = c2c_writebuf_push(chan, PICA_PROTO_ACCEPTEDFILE, PICA_PROTO_ACCEPTEDFILE_SIZE); + mp = c2c_writebuf_push(chan, PICA_PROTO_ACCEPTEDFILE, PICA_PROTO_ACCEPTEDFILE_SIZE); -if (mp) - { - RAND_bytes(mp->tail, 2); - } -else - return PICA_ERRNOMEM; + if (mp) + { + RAND_bytes(mp->tail, 2); + } + else + return PICA_ERRNOMEM; -chan->recvfilestate = PICA_CHANRECVFILESTATE_RECEIVING; + chan->recvfilestate = PICA_CHANRECVFILESTATE_RECEIVING; -return PICA_OK; + return PICA_OK; } static unsigned int procmsg_SENDFILEREQUEST(unsigned char* buf, unsigned int nb, void* p) { -struct PICA_c2c *chan = (struct PICA_c2c *)p; -struct PICA_proto_msg *mp; -int ret; + struct PICA_c2c *chan = (struct PICA_c2c *)p; + struct PICA_proto_msg *mp; + int ret; -char *filename = buf + 12; -unsigned int filenamesize = *(uint16_t*)(buf + 2) - 8; + char *filename = buf + 12; + unsigned int filenamesize = *(uint16_t*)(buf + 2) - 8; -if (chan->recvfilestate != PICA_CHANRECVFILESTATE_IDLE) - return 0; + if (chan->recvfilestate != PICA_CHANRECVFILESTATE_IDLE) + return 0; -chan->recvfilestate = PICA_CHANRECVFILESTATE_WAITACCEPT; -chan->recvfile_size = *(uint64_t*)(buf + 4); -chan->recvfile_pos = 0; + chan->recvfilestate = PICA_CHANRECVFILESTATE_WAITACCEPT; + chan->recvfile_size = *(uint64_t*)(buf + 4); + chan->recvfile_pos = 0; -ret = callbacks.accept_file_cb(chan->peer_id, *(uint64_t*)(buf + 4), filename, filenamesize); + ret = callbacks.accept_file_cb(chan->peer_id, *(uint64_t*)(buf + 4), filename, filenamesize); -if (ret > 0) + if (ret > 0) { - if (ret == 1) - { - if (PICA_accept_file(chan, filename, filenamesize) != PICA_OK) - if (PICA_deny_file(chan) != PICA_OK) - return 0; - } + if (ret == 1) + { + if (PICA_accept_file(chan, filename, filenamesize) != PICA_OK) + if (PICA_deny_file(chan) != PICA_OK) + return 0; + } } -else - { - if (PICA_deny_file(chan) != PICA_OK) - return 0; - } + else + { + if (PICA_deny_file(chan) != PICA_OK) + return 0; + } -return 1; + return 1; } static unsigned int procmsg_ACCEPTEDFILE(unsigned char* buf, unsigned int nb, void* p) { -struct PICA_c2c *chan = (struct PICA_c2c *)p; + struct PICA_c2c *chan = (struct PICA_c2c *)p; -if (chan->sendfilestate != PICA_CHANSENDFILESTATE_SENTREQ) - return 0; + if (chan->sendfilestate != PICA_CHANSENDFILESTATE_SENTREQ) + return 0; -callbacks.accepted_file_cb(chan->peer_id); + callbacks.accepted_file_cb(chan->peer_id); -chan->sendfilestate = PICA_CHANSENDFILESTATE_SENDING; + chan->sendfilestate = PICA_CHANSENDFILESTATE_SENDING; -return 1; + return 1; } static unsigned int procmsg_DENIEDFILE(unsigned char* buf, unsigned int nb, void* p) { -struct PICA_c2c *chan = (struct PICA_c2c *)p; + struct PICA_c2c *chan = (struct PICA_c2c *)p; -if (chan->sendfilestate != PICA_CHANSENDFILESTATE_SENTREQ) - return 0; + if (chan->sendfilestate != PICA_CHANSENDFILESTATE_SENTREQ) + return 0; -callbacks.denied_file_cb(chan->peer_id); + callbacks.denied_file_cb(chan->peer_id); -chan->sendfilestate = PICA_CHANSENDFILESTATE_IDLE; + chan->sendfilestate = PICA_CHANSENDFILESTATE_IDLE; -fclose(chan->sendfile_stream); -chan->sendfile_stream = NULL; + fclose(chan->sendfile_stream); + chan->sendfile_stream = NULL; -return 1; + return 1; } static unsigned int procmsg_FILEFRAGMENT(unsigned char* buf, unsigned int nb, void* p) { -struct PICA_c2c *chan = (struct PICA_c2c *)p; + struct PICA_c2c *chan = (struct PICA_c2c *)p; -/* - *Allow incoming FILEFRAGMENTs while paused - */ -if (chan->recvfilestate != PICA_CHANRECVFILESTATE_RECEIVING - && chan->recvfilestate != PICA_CHANRECVFILESTATE_PAUSED) - return 0; + /* + *Allow incoming FILEFRAGMENTs while paused + */ + if (chan->recvfilestate != PICA_CHANRECVFILESTATE_RECEIVING + && chan->recvfilestate != PICA_CHANRECVFILESTATE_PAUSED) + return 0; -if (nb - 4 != *(uint16_t*)(buf + 2)) - return 0; + if (nb - 4 != *(uint16_t*)(buf + 2)) + return 0; -if (fwrite(buf + 4, nb - 4, 1, chan->recvfile_stream) != 1) - { - struct PICA_proto_msg *mp; + if (fwrite(buf + 4, nb - 4, 1, chan->recvfile_stream) != 1) + { + struct PICA_proto_msg *mp; - fclose(chan->recvfile_stream); - chan->recvfile_stream = NULL; + fclose(chan->recvfile_stream); + chan->recvfile_stream = NULL; - chan->recvfilestate = PICA_CHANRECVFILESTATE_IDLE; + chan->recvfilestate = PICA_CHANRECVFILESTATE_IDLE; - if (PICA_OK != PICA_send_filecontrol(chan, PICA_PROTO_FILECONTROL_VOID, PICA_PROTO_FILECONTROL_IOERROR)) - return 0; - } + if (PICA_OK != PICA_send_filecontrol(chan, PICA_PROTO_FILECONTROL_VOID, PICA_PROTO_FILECONTROL_IOERROR)) + return 0; + } -chan->recvfile_pos += (nb - 4); + chan->recvfile_pos += (nb - 4); -if (chan->recvfile_pos > chan->recvfile_size) //received more than file_size - return 0; + if (chan->recvfile_pos > chan->recvfile_size) //received more than file_size + return 0; -callbacks.file_progress(chan->peer_id, 0, chan->recvfile_pos); + callbacks.file_progress(chan->peer_id, 0, chan->recvfile_pos); -if (chan->recvfile_pos == chan->recvfile_size) - { - chan->recvfilestate = PICA_CHANRECVFILESTATE_IDLE; - fclose(chan->recvfile_stream); - chan->recvfile_stream = NULL; + if (chan->recvfile_pos == chan->recvfile_size) + { + chan->recvfilestate = PICA_CHANRECVFILESTATE_IDLE; + fclose(chan->recvfile_stream); + chan->recvfile_stream = NULL; - callbacks.file_finished(chan->peer_id, 0); - } + callbacks.file_finished(chan->peer_id, 0); + } -return 1; + return 1; } static unsigned int procmsg_FILECONTROL(unsigned char* buf, unsigned int nb, void* p) { -struct PICA_c2c *chan = (struct PICA_c2c *)p; -unsigned int sender_cmd, receiver_cmd; - -sender_cmd = buf[2]; -receiver_cmd = buf[3]; - -fprintf(stderr, "procmsg_FILECONTROL sender_cmd = %i receiver_cmd = %i\n", sender_cmd, receiver_cmd);//debug - -if ((chan->sendfilestate == PICA_CHANSENDFILESTATE_IDLE || chan->sendfilestate == PICA_CHANSENDFILESTATE_SENTREQ) - && receiver_cmd != PICA_PROTO_FILECONTROL_VOID) - return 0; - -if (chan->recvfilestate == PICA_CHANRECVFILESTATE_IDLE && sender_cmd != PICA_PROTO_FILECONTROL_VOID) - return 0; - -fprintf(stderr, "procmsg_FILECONTROL switch(sender_cmd)\n"); - -switch(sender_cmd) - { - case PICA_PROTO_FILECONTROL_PAUSE: - if (chan->recvfilestate == PICA_CHANRECVFILESTATE_RECEIVING) - chan->recvfilestate = PICA_CHANRECVFILESTATE_PAUSED; - else - return 0; - break; - - case PICA_PROTO_FILECONTROL_RESUME: - if (chan->recvfilestate == PICA_CHANRECVFILESTATE_PAUSED) - chan->recvfilestate = PICA_CHANRECVFILESTATE_RECEIVING; - else - return 0; - break; - - case PICA_PROTO_FILECONTROL_CANCEL: - case PICA_PROTO_FILECONTROL_IOERROR: - chan->recvfilestate = PICA_CHANRECVFILESTATE_IDLE; - fclose(chan->recvfile_stream); - chan->recvfile_stream = NULL; - break; - - case PICA_PROTO_FILECONTROL_VOID: - break; - - default: - return 0; - } - -fprintf(stderr, "procmsg_FILECONTROL switch(receiver_cmd)\n"); -switch(receiver_cmd) - { - case PICA_PROTO_FILECONTROL_PAUSE: - if (chan->sendfilestate == PICA_CHANSENDFILESTATE_SENDING) - chan->sendfilestate = PICA_CHANSENDFILESTATE_PAUSED; - else - return 0; - break; - - case PICA_PROTO_FILECONTROL_RESUME: - if (chan->sendfilestate == PICA_CHANSENDFILESTATE_PAUSED) - chan->sendfilestate = PICA_CHANSENDFILESTATE_SENDING; - else - return 0; - break; - - case PICA_PROTO_FILECONTROL_CANCEL: - case PICA_PROTO_FILECONTROL_IOERROR: - chan->sendfilestate = PICA_CHANSENDFILESTATE_IDLE; - fclose(chan->sendfile_stream); - chan->sendfile_stream = NULL; - break; - - case PICA_PROTO_FILECONTROL_VOID: - break; - - default: - return 0; - } - -fprintf(stderr, "procmsg_FILECONTROL calling callback\n"); -callbacks.file_control(chan->peer_id, sender_cmd, receiver_cmd); + struct PICA_c2c *chan = (struct PICA_c2c *)p; + unsigned int sender_cmd, receiver_cmd; -return 1; + sender_cmd = buf[2]; + receiver_cmd = buf[3]; + + fprintf(stderr, "procmsg_FILECONTROL sender_cmd = %i receiver_cmd = %i\n", sender_cmd, receiver_cmd);//debug + + if ((chan->sendfilestate == PICA_CHANSENDFILESTATE_IDLE || chan->sendfilestate == PICA_CHANSENDFILESTATE_SENTREQ) + && receiver_cmd != PICA_PROTO_FILECONTROL_VOID) + return 0; + + if (chan->recvfilestate == PICA_CHANRECVFILESTATE_IDLE && sender_cmd != PICA_PROTO_FILECONTROL_VOID) + return 0; + + fprintf(stderr, "procmsg_FILECONTROL switch(sender_cmd)\n"); + + switch(sender_cmd) + { + case PICA_PROTO_FILECONTROL_PAUSE: + if (chan->recvfilestate == PICA_CHANRECVFILESTATE_RECEIVING) + chan->recvfilestate = PICA_CHANRECVFILESTATE_PAUSED; + else + return 0; + break; + + case PICA_PROTO_FILECONTROL_RESUME: + if (chan->recvfilestate == PICA_CHANRECVFILESTATE_PAUSED) + chan->recvfilestate = PICA_CHANRECVFILESTATE_RECEIVING; + else + return 0; + break; + + case PICA_PROTO_FILECONTROL_CANCEL: + case PICA_PROTO_FILECONTROL_IOERROR: + chan->recvfilestate = PICA_CHANRECVFILESTATE_IDLE; + fclose(chan->recvfile_stream); + chan->recvfile_stream = NULL; + break; + + case PICA_PROTO_FILECONTROL_VOID: + break; + + default: + return 0; + } + + fprintf(stderr, "procmsg_FILECONTROL switch(receiver_cmd)\n"); + switch(receiver_cmd) + { + case PICA_PROTO_FILECONTROL_PAUSE: + if (chan->sendfilestate == PICA_CHANSENDFILESTATE_SENDING) + chan->sendfilestate = PICA_CHANSENDFILESTATE_PAUSED; + else + return 0; + break; + + case PICA_PROTO_FILECONTROL_RESUME: + if (chan->sendfilestate == PICA_CHANSENDFILESTATE_PAUSED) + chan->sendfilestate = PICA_CHANSENDFILESTATE_SENDING; + else + return 0; + break; + + case PICA_PROTO_FILECONTROL_CANCEL: + case PICA_PROTO_FILECONTROL_IOERROR: + chan->sendfilestate = PICA_CHANSENDFILESTATE_IDLE; + fclose(chan->sendfile_stream); + chan->sendfile_stream = NULL; + break; + + case PICA_PROTO_FILECONTROL_VOID: + break; + + default: + return 0; + } + + fprintf(stderr, "procmsg_FILECONTROL calling callback\n"); + callbacks.file_control(chan->peer_id, sender_cmd, receiver_cmd); + + return 1; } #ifdef PICA_MULTITHREADED @@ -933,23 +939,23 @@ return 1; #ifdef WIN32 void locking_cb(int mode, int type, char *file, int line) { - if (mode & CRYPTO_LOCK) - WaitForSingleObject(mt_locks[type],INFINITE); - else - ReleaseMutex(mt_locks[type]); + if (mode & CRYPTO_LOCK) + WaitForSingleObject(mt_locks[type], INFINITE); + else + ReleaseMutex(mt_locks[type]); } #else unsigned long thread_id_cb(void) { - return (unsigned long)pthread_self(); + return (unsigned long)pthread_self(); } void locking_cb(int mode, int type, char *file, int line) { - if (mode & CRYPTO_LOCK) - pthread_mutex_lock(&mt_locks[type]); - else - pthread_mutex_unlock(&mt_locks[type]); + if (mode & CRYPTO_LOCK) + pthread_mutex_lock(&mt_locks[type]); + else + pthread_mutex_unlock(&mt_locks[type]); } #endif @@ -958,48 +964,48 @@ void locking_cb(int mode, int type, char *file, int line) int PICA_client_init(struct PICA_client_callbacks *clcbs) { -struct sockaddr_in sd; + struct sockaddr_in sd; #ifdef WIN32 -WSADATA wsd; -WSAStartup(MAKEWORD(2,2),&wsd); + WSADATA wsd; + WSAStartup(MAKEWORD(2, 2), &wsd); #endif -if (!clcbs) - return 0; + if (!clcbs) + return 0; -callbacks=*clcbs; + callbacks = *clcbs; -SSL_load_error_strings(); -SSL_library_init(); + SSL_load_error_strings(); + SSL_library_init(); -#ifdef NO_RAND_DEV -PICA_rand_seed(); +#ifdef NO_RAND_DEV + PICA_rand_seed(); #endif #ifdef PICA_MULTITHREADED -{ - int i; + { + int i; #ifdef WIN32 -mt_locks = malloc(CRYPTO_num_locks()*sizeof(HANDLE)); + mt_locks = malloc(CRYPTO_num_locks() * sizeof(HANDLE)); -for (i=0; i 65535 || local_port <= 0 || local_port > 65535 || !l) - return PICA_ERRINVARG; + if (!acc || !public_addr || public_port <= 0 || public_port > 65535 || local_port <= 0 || local_port > 65535 || !l) + return PICA_ERRINVARG; - lst = *l = (struct PICA_listener*)calloc(sizeof(struct PICA_listener), 1); + lst = *l = (struct PICA_listener*)calloc(sizeof(struct PICA_listener), 1); - if (!lst) - return PICA_ERRNOMEM; + if (!lst) + return PICA_ERRNOMEM; - lst->public_addr_dns = strdup(public_addr); + lst->public_addr_dns = strdup(public_addr); - if (!lst->public_addr_dns) - return PICA_ERRNOMEM; + if (!lst->public_addr_dns) + return PICA_ERRNOMEM; - lst->public_addr_ipv4 = inet_addr(public_addr); + lst->public_addr_ipv4 = inet_addr(public_addr); - lst->acc = acc; - lst->public_port = public_port; - lst->local_port = local_port; + lst->acc = acc; + lst->public_port = public_port; + lst->local_port = local_port; - lst->sck_listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //(1) + lst->sck_listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //(1) - if (lst->sck_listener == SOCKET_ERROR) - { - ret_err = PICA_ERRSOCK; - goto error_ret_1; - } + if (lst->sck_listener == SOCKET_ERROR) + { + ret_err = PICA_ERRSOCK; + goto error_ret_1; + } - flag = 1; - setsockopt(lst->sck_listener, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)); + flag = 1; + setsockopt(lst->sck_listener, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)); - memset(&s, 0, sizeof(s)); - s.sin_family = AF_INET; - s.sin_addr.s_addr = INADDR_ANY; - s.sin_port = htons(local_port); + memset(&s, 0, sizeof(s)); + s.sin_family = AF_INET; + s.sin_addr.s_addr = INADDR_ANY; + s.sin_port = htons(local_port); - ret = bind(lst->sck_listener, (const struct sockaddr*) &s, sizeof(s));//(2) + ret = bind(lst->sck_listener, (const struct sockaddr*) &s, sizeof(s));//(2) - if (ret == SOCKET_ERROR) - { - ret_err = PICA_ERRSOCK; - goto error_ret_2; - } + if (ret == SOCKET_ERROR) + { + ret_err = PICA_ERRSOCK; + goto error_ret_2; + } - ret = listen(lst->sck_listener, 10); + ret = listen(lst->sck_listener, 10); - if (ret == SOCKET_ERROR) - { - ret_err = PICA_ERRSOCK; - goto error_ret_2; - } + if (ret == SOCKET_ERROR) + { + ret_err = PICA_ERRSOCK; + goto error_ret_2; + } - return PICA_OK; + return PICA_OK; - error_ret_2: //(2) +error_ret_2: //(2) - CLOSE(lst->sck_listener); + CLOSE(lst->sck_listener); - error_ret_1: //(1) +error_ret_1: //(1) - free(lst->public_addr_dns); - free(lst); - *l = 0; + free(lst->public_addr_dns); + free(lst); + *l = 0; - return ret_err; + return ret_err; } int PICA_open_acc(const char *cert_file, @@ -1139,173 +1145,173 @@ int PICA_open_acc(const char *cert_file, int (*password_cb)(char *buf, int size, int rwflag, void *userdata), struct PICA_acc **acc) { -int ret,ret_err; -DH *dh = NULL; -FILE *dh_file = NULL; -struct PICA_acc *a = NULL; + int ret, ret_err; + DH *dh = NULL; + FILE *dh_file = NULL; + struct PICA_acc *a = NULL; -if (!(cert_file && pkey_file && dh_param_file && acc)) - return PICA_ERRINVARG; + if (!(cert_file && pkey_file && dh_param_file && acc)) + return PICA_ERRINVARG; -a = *acc = (struct PICA_acc*)calloc(sizeof(struct PICA_acc), 1);//(1) + a = *acc = (struct PICA_acc*)calloc(sizeof(struct PICA_acc), 1);//(1) -if (!a) - return PICA_ERRNOMEM; + if (!a) + return PICA_ERRNOMEM; -a->ctx = SSL_CTX_new(TLSv1_2_method());//(2) + a->ctx = SSL_CTX_new(TLSv1_2_method());//(2) -if (!a->ctx) - { - ret_err=PICA_ERRSSL; - goto error_ret_1; - } + if (!a->ctx) + { + ret_err = PICA_ERRSSL; + goto error_ret_1; + } -dh_file = fopen(dh_param_file, "r"); + dh_file = fopen(dh_param_file, "r"); -if (dh_file) - { - dh = PEM_read_DHparams(dh_file, NULL, NULL, NULL); - fclose(dh_file); - } + if (dh_file) + { + dh = PEM_read_DHparams(dh_file, NULL, NULL, NULL); + fclose(dh_file); + } -if (1 != SSL_CTX_set_tmp_dh(a->ctx, dh)) -{ - ret_err = PICA_ERRSSL; - goto error_ret_2; -} + if (1 != SSL_CTX_set_tmp_dh(a->ctx, dh)) + { + ret_err = PICA_ERRSSL; + goto error_ret_2; + } -DH_free(dh); + DH_free(dh); -SSL_CTX_set_options(a->ctx, SSL_OP_SINGLE_DH_USE); + SSL_CTX_set_options(a->ctx, SSL_OP_SINGLE_DH_USE); -if (!PICA_get_id_from_cert_file(cert_file, a->id)) - { - ret_err = PICA_ERRINVCERT; - goto error_ret_2; - } + if (!PICA_get_id_from_cert_file(cert_file, a->id)) + { + ret_err = PICA_ERRINVCERT; + goto error_ret_2; + } -ret = check_pkey_passphrase(pkey_file, password_cb, a->id); + ret = check_pkey_passphrase(pkey_file, password_cb, a->id); -if (ret != PICA_OK) - { - ret_err = ret; - goto error_ret_2; - } + if (ret != PICA_OK) + { + ret_err = ret; + goto error_ret_2; + } ////<< -if (password_cb) - { - SSL_CTX_set_default_passwd_cb(a->ctx, password_cb); - SSL_CTX_set_default_passwd_cb_userdata(a->ctx, a->id); - } - -ret = SSL_CTX_use_certificate_file(a->ctx, cert_file, SSL_FILETYPE_PEM); - -if (ret != 1) - { - ret_err=PICA_ERRSSL; - goto error_ret_2; - } - -ret = SSL_CTX_use_PrivateKey_file(a->ctx, pkey_file, SSL_FILETYPE_PEM); -if (ret != 1) - { - ret_err = PICA_ERRSSL; - goto error_ret_2; - } + if (password_cb) + { + SSL_CTX_set_default_passwd_cb(a->ctx, password_cb); + SSL_CTX_set_default_passwd_cb_userdata(a->ctx, a->id); + } + + ret = SSL_CTX_use_certificate_file(a->ctx, cert_file, SSL_FILETYPE_PEM); + + if (ret != 1) + { + ret_err = PICA_ERRSSL; + goto error_ret_2; + } + + ret = SSL_CTX_use_PrivateKey_file(a->ctx, pkey_file, SSL_FILETYPE_PEM); + if (ret != 1) + { + ret_err = PICA_ERRSSL; + goto error_ret_2; + } ////<< //ret=SSL_CTX_load_verify_locations(cid->ctx,CA_file,0/*"trustedCA/"*/); //printf("loadverifylocations ret=%i\n",ret);//debug //SSL_CTX_set_client_CA_list(cid->ctx,SSL_load_client_CA_file(CA_file)); -ret = SSL_CTX_set_cipher_list(a->ctx,"DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CAMELLIA256-SHA"); - -if (ret != 1) -{ - ret_err = PICA_ERRSSL; - goto error_ret_2; -} + ret = SSL_CTX_set_cipher_list(a->ctx, "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CAMELLIA256-SHA"); -return PICA_OK; + if (ret != 1) + { + ret_err = PICA_ERRSSL; + goto error_ret_2; + } + + return PICA_OK; error_ret_2: //(2) -SSL_CTX_free(a->ctx); + SSL_CTX_free(a->ctx); error_ret_1: //(1) -free(a); -*acc = 0; + free(a); + *acc = 0; -return ret_err; + return ret_err; } static int c2n_stage2_sendreq(struct PICA_c2n *c2n) { -struct PICA_proto_msg *mp; + struct PICA_proto_msg *mp; -puts("c2n_stage2_sendreq");//debug + puts("c2n_stage2_sendreq");//debug -mp = c2n_writebuf_push(c2n, PICA_PROTO_INITREQ, PICA_PROTO_INITREQ_SIZE); + mp = c2n_writebuf_push(c2n, PICA_PROTO_INITREQ, PICA_PROTO_INITREQ_SIZE); -if (mp) - { - mp->tail[0] = PICA_PROTO_VER_HIGH; - mp->tail[1] = PICA_PROTO_VER_LOW; - } -else - return PICA_ERRNOMEM; + if (mp) + { + mp->tail[0] = PICA_PROTO_VER_HIGH; + mp->tail[1] = PICA_PROTO_VER_LOW; + } + else + return PICA_ERRNOMEM; -c2n->state = PICA_C2N_STATE_WAITINGREP; + c2n->state = PICA_C2N_STATE_WAITINGREP; -return PICA_OK; + return PICA_OK; } static int c2n_stage3_starttls(struct PICA_c2n *c2n) { -int ret; + int ret; -ret = SSL_set_fd(c2n->ssl_comm, c2n->sck_comm); + ret = SSL_set_fd(c2n->ssl_comm, c2n->sck_comm); -if (ret != 1) - return PICA_ERRSSL; + if (ret != 1) + return PICA_ERRSSL; -ret = SSL_accept(c2n->ssl_comm); + ret = SSL_accept(c2n->ssl_comm); -if (ret == 0) - return PICA_ERRSSL; + if (ret == 0) + return PICA_ERRSSL; -if (ret < 0) - { - ret = SSL_get_error(c2n->ssl_comm, ret); + if (ret < 0) + { + ret = SSL_get_error(c2n->ssl_comm, ret); - if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE) - return PICA_ERRSSL; - } + if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE) + return PICA_ERRSSL; + } -c2n->state = PICA_C2N_STATE_WAITINGTLS; + c2n->state = PICA_C2N_STATE_WAITINGTLS; -return PICA_OK; + return PICA_OK; } static int c2n_stage4_nodelistrequest(struct PICA_c2n *c2n) { -struct PICA_proto_msg *mp; + struct PICA_proto_msg *mp; -mp = c2n_writebuf_push(c2n, PICA_PROTO_CLNODELISTREQ, PICA_PROTO_CLNODELISTREQ_SIZE); + mp = c2n_writebuf_push(c2n, PICA_PROTO_CLNODELISTREQ, PICA_PROTO_CLNODELISTREQ_SIZE); -if (mp) - { - RAND_bytes(mp->tail, 2); - } -else - return PICA_ERRNOMEM; + if (mp) + { + RAND_bytes(mp->tail, 2); + } + else + return PICA_ERRNOMEM; -c2n->state = PICA_C2N_STATE_CONNECTED; + c2n->state = PICA_C2N_STATE_CONNECTED; -callbacks.c2n_established_cb(c2n); + callbacks.c2n_established_cb(c2n); -return PICA_OK; + return PICA_OK; } /*адрес сервера, сертификат клиента и закрытый ключ*/ @@ -1325,141 +1331,141 @@ return PICA_OK; //.... int PICA_new_c2n(const struct PICA_acc *acc, const char *nodeaddr, - unsigned int port, - struct PICA_c2n **ci) + unsigned int port, + struct PICA_c2n **ci) { -int ret,ret_err; -struct PICA_c2n *cid; -struct sockaddr_in a; + int ret, ret_err; + struct PICA_c2n *cid; + struct sockaddr_in a; -if (!(nodeaddr && acc && port && ci)) - return PICA_ERRINVARG; + if (!(nodeaddr && acc && port && ci)) + return PICA_ERRINVARG; -cid=*ci=(struct PICA_c2n*)calloc(sizeof(struct PICA_c2n),1);//(1) -if (!cid) - return PICA_ERRNOMEM; + cid = *ci = (struct PICA_c2n*)calloc(sizeof(struct PICA_c2n), 1); //(1) + if (!cid) + return PICA_ERRNOMEM; -cid->acc = acc; + cid->acc = acc; -cid->read_buf = calloc(PICA_CONNREADBUFSIZE, 1);//(2) -if (!cid->read_buf) - { - ret_err = PICA_ERRNOMEM; - goto error_ret_1; - } + cid->read_buf = calloc(PICA_CONNREADBUFSIZE, 1);//(2) + if (!cid->read_buf) + { + ret_err = PICA_ERRNOMEM; + goto error_ret_1; + } -cid->ssl_comm=SSL_new(acc->ctx);//(3) + cid->ssl_comm = SSL_new(acc->ctx); //(3) -if (!cid->ssl_comm) + if (!cid->ssl_comm) { - ret_err=PICA_ERRSSL; - goto error_ret_2; + ret_err = PICA_ERRSSL; + goto error_ret_2; } //resolving name -{ - struct addrinfo h,*r; + { + struct addrinfo h, *r; - memset(&h,0,sizeof(struct addrinfo)); + memset(&h, 0, sizeof(struct addrinfo)); - h.ai_flags=0; + h.ai_flags = 0; #ifdef AI_IDN - h.ai_flags = h.ai_flags | AI_IDN; + h.ai_flags = h.ai_flags | AI_IDN; #endif #ifdef AI_ADDRCONFIG - h.ai_flags = h.ai_flags | AI_ADDRCONFIG; + h.ai_flags = h.ai_flags | AI_ADDRCONFIG; #endif - h.ai_family=AF_INET;//CONF - h.ai_socktype=SOCK_STREAM; - h.ai_protocol=IPPROTO_TCP; + h.ai_family = AF_INET; //CONF + h.ai_socktype = SOCK_STREAM; + h.ai_protocol = IPPROTO_TCP; - if (0!=getaddrinfo(nodeaddr,NULL,&h,&r)) - { - ret_err=PICA_ERRDNSRESOLVE; - goto error_ret_4; - } + if (0 != getaddrinfo(nodeaddr, NULL, &h, &r)) + { + ret_err = PICA_ERRDNSRESOLVE; + goto error_ret_4; + } - memset(&a,0,sizeof(a)); - memcpy(&a,r->ai_addr,r->ai_addrlen); - a.sin_family = AF_INET; - //a.sin_addr.s_addr = inet_addr (nodeaddr); - a.sin_port = htons(port); + memset(&a, 0, sizeof(a)); + memcpy(&a, r->ai_addr, r->ai_addrlen); + a.sin_family = AF_INET; + //a.sin_addr.s_addr = inet_addr (nodeaddr); + a.sin_port = htons(port); - freeaddrinfo(r); -} + freeaddrinfo(r); + } -cid->srv_addr=a; + cid->srv_addr = a; -cid->sck_comm=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//(5) -if (cid->sck_comm==SOCKET_ERROR) + cid->sck_comm = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //(5) + if (cid->sck_comm == SOCKET_ERROR) { - ret_err=PICA_ERRSOCK; - goto error_ret_3; + ret_err = PICA_ERRSOCK; + goto error_ret_3; } -IOCTLSETNONBLOCKINGSOCKET(cid->sck_comm, 1); + IOCTLSETNONBLOCKINGSOCKET(cid->sck_comm, 1); -cid->state = PICA_C2N_STATE_CONNECTING; + cid->state = PICA_C2N_STATE_CONNECTING; -ret=connect(cid->sck_comm,(struct sockaddr*)&cid->srv_addr,sizeof(cid->srv_addr)); + ret = connect(cid->sck_comm, (struct sockaddr*)&cid->srv_addr, sizeof(cid->srv_addr)); /////////////////state_ -if (ret == 0) - return c2n_stage2_sendreq(cid); + if (ret == 0) + return c2n_stage2_sendreq(cid); -if (ret==SOCKET_ERROR) + if (ret == SOCKET_ERROR) { #ifndef WIN32 - if (errno == EINPROGRESS || errno == EINTR) - return PICA_OK; + if (errno == EINPROGRESS || errno == EINTR) + return PICA_OK; #else - if (WSAGetLastError() == WSAEWOULDBLOCK) - return PICA_OK; + if (WSAGetLastError() == WSAEWOULDBLOCK) + return PICA_OK; #endif - ret_err=PICA_ERRSOCK; - goto error_ret_4; + ret_err = PICA_ERRSOCK; + goto error_ret_4; } -/* -do - { - ret = PICA_write_c2n(cid); - if (ret != PICA_OK) + /* + do { - ret_err = ret; - break; + ret = PICA_write_c2n(cid); + if (ret != PICA_OK) + { + ret_err = ret; + break; + } + ret = PICA_read_c2n(cid); + if (ret != PICA_OK) + { + ret_err = ret; + break; + } + //TODO Timeout } - ret = PICA_read_c2n(cid); - if (ret != PICA_OK) + while (cid->init_resp_ok == 0); + + if (cid->init_resp_ok != 1) { - ret_err = ret; - break; + if (cid->init_resp_ok == -1) + { + if (cid->node_ver_major > PICA_PROTO_VER_HIGH || + (cid->node_ver_major == PICA_PROTO_VER_HIGH && cid->node_ver_minor > PICA_PROTO_VER_LOW)) + ret_err = PICA_ERRPROTONEW; + else + ret_err = PICA_ERRPROTOOLD; + } + goto error_ret_4; } - //TODO Timeout - } -while (cid->init_resp_ok == 0); -if (cid->init_resp_ok != 1) - { - if (cid->init_resp_ok == -1) - { - if (cid->node_ver_major > PICA_PROTO_VER_HIGH || - (cid->node_ver_major == PICA_PROTO_VER_HIGH && cid->node_ver_minor > PICA_PROTO_VER_LOW)) - ret_err = PICA_ERRPROTONEW; - else - ret_err = PICA_ERRPROTOOLD; - } - goto error_ret_4; - } - -//printf("6\n");//debug -*/ /* + //printf("6\n");//debug + */ /* ret=SSL_set_fd(cid->ssl_comm,cid->sck_comm); //printf("SSL_set_fd=%i\n",ret); @@ -1480,167 +1486,167 @@ cid->state = PICA_C2N_STATE_CONNECTED;//<<tail, 2); - } + } } */ -return PICA_OK; + return PICA_OK; error_ret_4: //(4) - SHUTDOWN(cid->sck_comm); - CLOSE(cid->sck_comm); + SHUTDOWN(cid->sck_comm); + CLOSE(cid->sck_comm); error_ret_3: //(3) - SSL_free(cid->ssl_comm); + SSL_free(cid->ssl_comm); error_ret_2: //(2) - free(cid->read_buf); + free(cid->read_buf); error_ret_1: //(1) - free(cid); - *ci=0; + free(cid); + *ci = 0; -return ret_err; + return ret_err; } //создает ИСХОДЯЩИЙ логический зашифрованный канал связи с указанным собеседником, если тот доступен // в данный момент. -int PICA_new_c2c(struct PICA_c2n *ci,const unsigned char *peer_id, struct PICA_listener *l,struct PICA_c2c **chn) +int PICA_new_c2c(struct PICA_c2n *ci, const unsigned char *peer_id, struct PICA_listener *l, struct PICA_c2c **chn) { -struct PICA_proto_msg *mp; -struct PICA_c2c *chnl; + struct PICA_proto_msg *mp; + struct PICA_c2c *chnl; + + if (!(ci && chn)) + return PICA_ERRINVARG; -if (!(ci && chn)) - return PICA_ERRINVARG; + if (!add_chaninfo(ci, chn, peer_id, PICA_c2c_OUTGOING)) + return PICA_ERRNOMEM; -if (!add_chaninfo(ci, chn, peer_id, PICA_c2c_OUTGOING)) - return PICA_ERRNOMEM; + chnl = *chn; -chnl=*chn; + mp = c2n_writebuf_push( ci, PICA_PROTO_CONNREQOUTG, PICA_PROTO_CONNREQOUTG_SIZE); -mp = c2n_writebuf_push( ci, PICA_PROTO_CONNREQOUTG, PICA_PROTO_CONNREQOUTG_SIZE); - if (mp) - { + { memcpy(mp->tail, peer_id, PICA_ID_SIZE); - } + } else - return PICA_ERRNOMEM; + return PICA_ERRNOMEM; -return PICA_OK; + return PICA_OK; } static int process_c2n(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) { -int ret = PICA_OK; + int ret = PICA_OK; //puts("process_c2n()");//debug -switch(c2n->state) - { - case PICA_C2N_STATE_NEW: - break; + switch(c2n->state) + { + case PICA_C2N_STATE_NEW: + break; - case PICA_C2N_STATE_CONNECTING: + case PICA_C2N_STATE_CONNECTING: - if (FD_ISSET(c2n->sck_comm, wfds)) - { - ret = PICA_ERRSOCK; + if (FD_ISSET(c2n->sck_comm, wfds)) + { + ret = PICA_ERRSOCK; - //check if connect() finished successfully + //check if connect() finished successfully #ifndef WIN32 - int optval; - socklen_t optlen = sizeof(optval); - - if (0 == getsockopt(c2n->sck_comm, SOL_SOCKET, SO_ERROR, &optval, &optlen)) - { - if (optval == 0) - { - ret = c2n_stage2_sendreq(c2n); - } - } + int optval; + socklen_t optlen = sizeof(optval); + + if (0 == getsockopt(c2n->sck_comm, SOL_SOCKET, SO_ERROR, &optval, &optlen)) + { + if (optval == 0) + { + ret = c2n_stage2_sendreq(c2n); + } + } #else - if (SOCKET_ERROR == connect(c2n->ssl_comm, (struct sockaddr*)&c2n->srv_addr, sizeof(c2n->srv_addr)) && - WSAEISCONN == WSAGetLastError()) - { - ret = c2n_stage2_sendreq(c2n); - } + if (SOCKET_ERROR == connect(c2n->ssl_comm, (struct sockaddr*)&c2n->srv_addr, sizeof(c2n->srv_addr)) && + WSAEISCONN == WSAGetLastError()) + { + ret = c2n_stage2_sendreq(c2n); + } #endif - } + } - break; + break; - case PICA_C2N_STATE_WAITINGREP: + case PICA_C2N_STATE_WAITINGREP: - if (FD_ISSET(c2n->sck_comm, wfds)) - { - ret = PICA_write_c2n(c2n); - } + if (FD_ISSET(c2n->sck_comm, wfds)) + { + ret = PICA_write_c2n(c2n); + } - if (FD_ISSET(c2n->sck_comm, rfds)) - { - ret = PICA_read_c2n(c2n); - } + if (FD_ISSET(c2n->sck_comm, rfds)) + { + ret = PICA_read_c2n(c2n); + } - if (ret == PICA_OK && c2n->init_resp_ok != 0) - { - if (c2n->init_resp_ok == 1) - ret = c2n_stage3_starttls(c2n); - else - { - if (c2n->node_ver_major > PICA_PROTO_VER_HIGH || - (c2n->node_ver_major == PICA_PROTO_VER_HIGH && c2n->node_ver_minor > PICA_PROTO_VER_LOW)) - ret = PICA_ERRPROTONEW; - else - ret = PICA_ERRPROTOOLD; - } - } + if (ret == PICA_OK && c2n->init_resp_ok != 0) + { + if (c2n->init_resp_ok == 1) + ret = c2n_stage3_starttls(c2n); + else + { + if (c2n->node_ver_major > PICA_PROTO_VER_HIGH || + (c2n->node_ver_major == PICA_PROTO_VER_HIGH && c2n->node_ver_minor > PICA_PROTO_VER_LOW)) + ret = PICA_ERRPROTONEW; + else + ret = PICA_ERRPROTOOLD; + } + } - break; + break; - case PICA_C2N_STATE_WAITINGTLS: + case PICA_C2N_STATE_WAITINGTLS: - if (FD_ISSET(c2n->sck_comm, wfds) || FD_ISSET(c2n->sck_comm, rfds)) - { - int sslret; + if (FD_ISSET(c2n->sck_comm, wfds) || FD_ISSET(c2n->sck_comm, rfds)) + { + int sslret; - sslret = SSL_accept(c2n->ssl_comm); + sslret = SSL_accept(c2n->ssl_comm); - if (sslret == 1) - ret = c2n_stage4_nodelistrequest(c2n); - else if (sslret == 0) - ret = PICA_ERRSSL; - else if (sslret < 0) - { - sslret = SSL_get_error(c2n->ssl_comm, sslret); + if (sslret == 1) + ret = c2n_stage4_nodelistrequest(c2n); + else if (sslret == 0) + ret = PICA_ERRSSL; + else if (sslret < 0) + { + sslret = SSL_get_error(c2n->ssl_comm, sslret); - if (sslret != SSL_ERROR_WANT_READ && sslret != SSL_ERROR_WANT_WRITE) - ret = PICA_ERRSSL; - } - } + if (sslret != SSL_ERROR_WANT_READ && sslret != SSL_ERROR_WANT_WRITE) + ret = PICA_ERRSSL; + } + } - break; + break; - case PICA_C2N_STATE_CONNECTED: + case PICA_C2N_STATE_CONNECTED: - if (FD_ISSET(c2n->sck_comm, wfds)) - ret = PICA_write_c2n(c2n); + if (FD_ISSET(c2n->sck_comm, wfds)) + ret = PICA_write_c2n(c2n); - if (FD_ISSET(c2n->sck_comm, rfds)) - ret = PICA_read_c2n(c2n); + if (FD_ISSET(c2n->sck_comm, rfds)) + ret = PICA_read_c2n(c2n); - break; - } + break; + } -return ret; + return ret; } static int process_c2c(struct PICA_c2c *c2c, fd_set *rfds, fd_set *wfds) @@ -1649,355 +1655,355 @@ static int process_c2c(struct PICA_c2c *c2c, fd_set *rfds, fd_set *wfds) // { // // } -return PICA_OK; + return PICA_OK; } static int process_listener(struct PICA_listener *lst, fd_set *rfds) { -return PICA_OK; + return PICA_OK; } static void fdset_add(fd_set *fds, int fd, int *max) { -FD_SET(fd, fds); + FD_SET(fd, fds); -if (fd > *max) - *max = fd; + if (fd > *max) + *max = fd; } int PICA_event_loop(struct PICA_c2n **connections, struct PICA_listener **listeners, int timeout) { -fd_set rfds, wfds; -struct timeval tv; -int ret, nfds = 0; -struct PICA_c2n **ic2n; -struct PICA_listener **ilst; + fd_set rfds, wfds; + struct timeval tv; + int ret, nfds = 0; + struct PICA_c2n **ic2n; + struct PICA_listener **ilst; //puts("PICA_event_loop");//debug -tv.tv_sec = timeout / 1000; -tv.tv_usec = (timeout % 1000) * 1000; + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; -FD_ZERO(&rfds); -FD_ZERO(&wfds); + FD_ZERO(&rfds); + FD_ZERO(&wfds); -ilst = listeners; + ilst = listeners; -while(ilst && *ilst) - { - fdset_add(&rfds, (*ilst)->sck_listener, &nfds); - ilst++; - } + while(ilst && *ilst) + { + fdset_add(&rfds, (*ilst)->sck_listener, &nfds); + ilst++; + } -ic2n = connections; + ic2n = connections; -while(ic2n && *ic2n) - { - struct PICA_c2c *ic2c; + while(ic2n && *ic2n) + { + struct PICA_c2c *ic2c; - //printf("event_loop: adding c2n %p\n", *ic2n);//debug + //printf("event_loop: adding c2n %p\n", *ic2n);//debug - fdset_add(&rfds, (*ic2n)->sck_comm, &nfds); + fdset_add(&rfds, (*ic2n)->sck_comm, &nfds); - if ((*ic2n)->write_pos || (*ic2n)->state == PICA_C2N_STATE_CONNECTING - || (*ic2n)->state == PICA_C2N_STATE_WAITINGTLS) - fdset_add(&wfds, (*ic2n)->sck_comm, &nfds); + if ((*ic2n)->write_pos || (*ic2n)->state == PICA_C2N_STATE_CONNECTING + || (*ic2n)->state == PICA_C2N_STATE_WAITINGTLS) + fdset_add(&wfds, (*ic2n)->sck_comm, &nfds); - ic2c = (*ic2n)->chan_list_head; + ic2c = (*ic2n)->chan_list_head; - while(ic2c) - { - if (ic2c->state == PICA_C2C_STATE_ACTIVE) - { - fdset_add(&rfds, ic2c->sck_data, &nfds); + while(ic2c) + { + if (ic2c->state == PICA_C2C_STATE_ACTIVE) + { + fdset_add(&rfds, ic2c->sck_data, &nfds); - if (ic2c->write_pos || ic2c->sendfilestate == PICA_CHANSENDFILESTATE_SENDING) - fdset_add(&wfds, ic2c->sck_data, &nfds); - } + if (ic2c->write_pos || ic2c->sendfilestate == PICA_CHANSENDFILESTATE_SENDING) + fdset_add(&wfds, ic2c->sck_data, &nfds); + } - ic2c = ic2c->next; - } + ic2c = ic2c->next; + } - ic2n++; - } + ic2n++; + } -ret = select(nfds + 1, &rfds, &wfds, NULL, &tv); + ret = select(nfds + 1, &rfds, &wfds, NULL, &tv); -if (ret == -1) - { + if (ret == -1) + { #ifndef WIN32 - if (errno == EINTR) - return PICA_OK; - else - return PICA_ERRSOCK; + if (errno == EINTR) + return PICA_OK; + else + return PICA_ERRSOCK; #else #warning "implement handling of select() errors on Windows!" #endif - } + } //printf("select() returned %i\n", ret);//debug //processing listeners, c2n and c2c connections -ilst = listeners; + ilst = listeners; -while(ilst && *ilst) - { - ret = process_listener(*ilst, &rfds); + while(ilst && *ilst) + { + ret = process_listener(*ilst, &rfds); - if (ret != PICA_OK) - { - callbacks.listener_error(*ilst, ret); - PICA_close_listener(*ilst); - } + if (ret != PICA_OK) + { + callbacks.listener_error(*ilst, ret); + PICA_close_listener(*ilst); + } - ilst++; - } + ilst++; + } -ic2n = connections; + ic2n = connections; -while(ic2n && *ic2n) - { - struct PICA_c2c *ic2c; + while(ic2n && *ic2n) + { + struct PICA_c2c *ic2c; - //processing current c2n + //processing current c2n - ret = process_c2n(*ic2n, &rfds, &wfds); + ret = process_c2n(*ic2n, &rfds, &wfds); - if (ret != PICA_OK) - { - if ((*ic2n)->state == PICA_C2N_STATE_CONNECTED) - callbacks.c2n_closed_cb(*ic2n); - else - callbacks.c2n_failed_cb(*ic2n); + if (ret != PICA_OK) + { + if ((*ic2n)->state == PICA_C2N_STATE_CONNECTED) + callbacks.c2n_closed_cb(*ic2n); + else + callbacks.c2n_failed_cb(*ic2n); - PICA_close_c2n(*ic2n); - } - else - { - struct PICA_c2c *kill_ptr = 0; + PICA_close_c2n(*ic2n); + } + else + { + struct PICA_c2c *kill_ptr = 0; - ic2c = (*ic2n)->chan_list_head; + ic2c = (*ic2n)->chan_list_head; - //processing c2c connections associated with current c2n - while(ic2c) - { - ret = process_c2c(ic2c, &rfds, &wfds); + //processing c2c connections associated with current c2n + while(ic2c) + { + ret = process_c2c(ic2c, &rfds, &wfds); - if (ret != PICA_OK) - kill_ptr = ic2c; + if (ret != PICA_OK) + kill_ptr = ic2c; - ic2c = ic2c->next; + ic2c = ic2c->next; - if (kill_ptr) - { - PICA_close_c2c(kill_ptr); - kill_ptr = 0; - } - } - } - ic2n++; - } + if (kill_ptr) + { + PICA_close_c2c(kill_ptr); + kill_ptr = 0; + } + } + } + ic2n++; + } -return PICA_OK; + return PICA_OK; } -int PICA_read(struct PICA_c2n *ci,int timeout) +int PICA_read(struct PICA_c2n *ci, int timeout) { -fd_set fds; -struct timeval tv={0,1000}; -struct PICA_c2c *ipt, *kill_ptr = 0; -int ret,nfds; + fd_set fds; + struct timeval tv = {0, 1000}; + struct PICA_c2c *ipt, *kill_ptr = 0; + int ret, nfds; //puts("PICA_read<<");//debug -tv.tv_usec=timeout; + tv.tv_usec = timeout; -FD_ZERO(&fds); + FD_ZERO(&fds); -nfds=ci->sck_comm; -FD_SET(ci->sck_comm,&fds); + nfds = ci->sck_comm; + FD_SET(ci->sck_comm, &fds); -ipt=ci->chan_list_head; + ipt = ci->chan_list_head; -while(ipt) + while(ipt) { - if (ipt->state==PICA_C2C_STATE_ACTIVE) + if (ipt->state == PICA_C2C_STATE_ACTIVE) { - FD_SET(ipt->sck_data,&fds); + FD_SET(ipt->sck_data, &fds); - if (ipt->sck_data>nfds) - nfds=ipt->sck_data; - } + if (ipt->sck_data > nfds) + nfds = ipt->sck_data; + } - if (ipt->state != PICA_C2C_STATE_ACTIVE && (time(0) - ipt->timestamp) > PICA_CHAN_ACTIVATE_TIMEOUT) + if (ipt->state != PICA_C2C_STATE_ACTIVE && (time(0) - ipt->timestamp) > PICA_CHAN_ACTIVATE_TIMEOUT) { - kill_ptr = ipt; + kill_ptr = ipt; } - ipt=ipt->next; + ipt = ipt->next; - if (kill_ptr) + if (kill_ptr) { - PICA_close_c2c(kill_ptr); - kill_ptr = 0; + PICA_close_c2c(kill_ptr); + kill_ptr = 0; } } //#warning "make sockets non-blocking!!!!" -ret=select(nfds+1,&fds,0,0,&tv); + ret = select(nfds + 1, &fds, 0, 0, &tv); -if (ret>0) + if (ret > 0) { - - if (FD_ISSET(ci->sck_comm,&fds)) + + if (FD_ISSET(ci->sck_comm, &fds)) { - ret=PICA_read_c2n(ci); - if (ret!=PICA_OK) - return ret; + ret = PICA_read_c2n(ci); + if (ret != PICA_OK) + return ret; } - ipt=ci->chan_list_head; - while(ipt) + ipt = ci->chan_list_head; + while(ipt) { - if (ipt->state==PICA_C2C_STATE_ACTIVE && FD_ISSET(ipt->sck_data, &fds)) + if (ipt->state == PICA_C2C_STATE_ACTIVE && FD_ISSET(ipt->sck_data, &fds)) { - if (PICA_OK != (ret = PICA_read_c2c(ipt)) ) + if (PICA_OK != (ret = PICA_read_c2c(ipt)) ) { - puts("PICA_read_c2c() failed");//debug - callbacks.c2c_closed_cb(ipt->peer_id, ret); - kill_ptr = ipt; + puts("PICA_read_c2c() failed");//debug + callbacks.c2c_closed_cb(ipt->peer_id, ret); + kill_ptr = ipt; } - + } - - ipt=ipt->next; - if (kill_ptr) + ipt = ipt->next; + + if (kill_ptr) { - PICA_close_c2c(kill_ptr); - kill_ptr = 0; + PICA_close_c2c(kill_ptr); + kill_ptr = 0; } } } //puts("PICA_read>>");//debug -return PICA_OK; + return PICA_OK; } int PICA_write(struct PICA_c2n *ci) { -struct PICA_c2c *ipt, *kill_ptr = 0; -int ret = PICA_OK; + struct PICA_c2c *ipt, *kill_ptr = 0; + int ret = PICA_OK; //puts("PICA_write>>");//debug -if (ci->write_pos) - ret = PICA_write_c2n(ci); + if (ci->write_pos) + ret = PICA_write_c2n(ci); -if (PICA_OK != ret) - return ret; + if (PICA_OK != ret) + return ret; -ipt=ci->chan_list_head; + ipt = ci->chan_list_head; -while(ipt) + while(ipt) { - if (ipt->write_pos) + if (ipt->write_pos) { - if (PICA_OK != (ret = PICA_write_c2c(ipt))) + if (PICA_OK != (ret = PICA_write_c2c(ipt))) { - fprintf(stderr,"PICA_write_c2c() failed, ret = %i\n", ret);//debug - callbacks.c2c_closed_cb(ipt->peer_id, ret); - kill_ptr = ipt; + fprintf(stderr, "PICA_write_c2c() failed, ret = %i\n", ret); //debug + callbacks.c2c_closed_cb(ipt->peer_id, ret); + kill_ptr = ipt; + } + } + else if (ipt->sendfilestate == PICA_CHANSENDFILESTATE_SENDING) + { + if (PICA_OK != (ret = PICA_send_file_fragment(ipt))) + { + callbacks.c2c_closed_cb(ipt->peer_id, ret); + kill_ptr = ipt; } } - else if (ipt->sendfilestate == PICA_CHANSENDFILESTATE_SENDING) - { - if (PICA_OK != (ret = PICA_send_file_fragment(ipt))) - { - callbacks.c2c_closed_cb(ipt->peer_id, ret); - kill_ptr = ipt; - } - } - ipt = ipt->next; - - if (kill_ptr) + ipt = ipt->next; + + if (kill_ptr) { - PICA_close_c2c(kill_ptr); - kill_ptr = 0; + PICA_close_c2c(kill_ptr); + kill_ptr = 0; } } //puts("PICA_write<<");//debug -return PICA_OK; + return PICA_OK; } int PICA_write_socket(SOCKET s, unsigned char *buf, unsigned int *ppos) { -int ret; + int ret; -if (*ppos > 0 ) + if (*ppos > 0 ) { - ret = send( s, buf, *ppos, MSG_NOSIGNAL); + ret = send( s, buf, *ppos, MSG_NOSIGNAL); - if (ret > 0) + if (ret > 0) { - if (ret < *ppos) - memmove( buf, buf + ret, *ppos - ret); - *ppos -= ret; + if (ret < *ppos) + memmove( buf, buf + ret, *ppos - ret); + *ppos -= ret; } - - if (ret < 0) + + if (ret < 0) { #ifdef WIN32 - ret = WSAGetLastError(); - if (! (ret == WSAEWOULDBLOCK || ret == WSAENOBUFS)) + ret = WSAGetLastError(); + if (! (ret == WSAEWOULDBLOCK || ret == WSAENOBUFS)) #else - ret = errno; - if (! (ret == EAGAIN || ret == ENOBUFS || ret == EINTR)) + ret = errno; + if (! (ret == EAGAIN || ret == ENOBUFS || ret == EINTR)) #endif - return PICA_ERRSOCK; + return PICA_ERRSOCK; } - if (ret == 0) - return PICA_ERRSERV; - + if (ret == 0) + return PICA_ERRSERV; + } -return PICA_OK; + return PICA_OK; } int PICA_write_ssl(SSL *ssl, unsigned char *buf, unsigned int *ppos, unsigned int *btw) { -int ret; + int ret; -if (*ppos > 0 ) + if (*ppos > 0 ) { - if (*btw == 0) - *btw = *ppos; + if (*btw == 0) + *btw = *ppos; - ret = SSL_write( ssl, buf, *btw); - - if (ret > 0) + ret = SSL_write( ssl, buf, *btw); + + if (ret > 0) { - if (ret < *ppos) - memmove( buf, buf + ret, *ppos - ret); - *ppos -= ret; - *btw = 0; + if (ret < *ppos) + memmove( buf, buf + ret, *ppos - ret); + *ppos -= ret; + *btw = 0; } - - if (ret < 0) + + if (ret < 0) { - ret = SSL_get_error( ssl, ret); - if (! (ret == SSL_ERROR_WANT_WRITE || ret == SSL_ERROR_WANT_READ)) + ret = SSL_get_error( ssl, ret); + if (! (ret == SSL_ERROR_WANT_WRITE || ret == SSL_ERROR_WANT_READ)) return PICA_ERRSSL; } - if (ret == 0) - return PICA_ERRSERV; - + if (ret == 0) + return PICA_ERRSERV; + } -return PICA_OK; + return PICA_OK; } //int PICA_read_socket() @@ -2005,41 +2011,41 @@ return PICA_OK; int PICA_write_c2n(struct PICA_c2n *ci) { -int ret = PICA_ERRINVARG; + int ret = PICA_ERRINVARG; -if (PICA_C2N_STATE_WAITINGREP == ci->state) - ret = PICA_write_socket( ci->sck_comm, ci->write_buf, &ci->write_pos); -else if (PICA_C2N_STATE_CONNECTED == ci->state) - ret = PICA_write_ssl( ci->ssl_comm, ci->write_buf, &ci->write_pos, &ci->write_sslbytestowrite); + if (PICA_C2N_STATE_WAITINGREP == ci->state) + ret = PICA_write_socket( ci->sck_comm, ci->write_buf, &ci->write_pos); + else if (PICA_C2N_STATE_CONNECTED == ci->state) + ret = PICA_write_ssl( ci->ssl_comm, ci->write_buf, &ci->write_pos, &ci->write_sslbytestowrite); -return ret; + return ret; } int PICA_write_c2c(struct PICA_c2c *chn) { -int ret = PICA_ERRINVARG; + int ret = PICA_ERRINVARG; -if (PICA_C2C_STATE_ACTIVE != chn->state) - ret = PICA_write_socket( chn->sck_data, chn->write_buf, &chn->write_pos); -else - ret = PICA_write_ssl( chn->ssl, chn->write_buf, &chn->write_pos, &chn->write_sslbytestowrite); + if (PICA_C2C_STATE_ACTIVE != chn->state) + ret = PICA_write_socket( chn->sck_data, chn->write_buf, &chn->write_pos); + else + ret = PICA_write_ssl( chn->ssl, chn->write_buf, &chn->write_pos, &chn->write_sslbytestowrite); -return ret; + return ret; } int PICA_read_socket(SOCKET s, unsigned char *buf, unsigned int *ppos, unsigned int size) { -int ret; + int ret; -ret = recv(s, buf + *ppos, size - *ppos, 0); + ret = recv(s, buf + *ppos, size - *ppos, 0); -if (ret == 0) - return PICA_ERRDISCONNECT; + if (ret == 0) + return PICA_ERRDISCONNECT; -if (ret < 0) + if (ret < 0) { #ifdef WIN32 - switch(WSAGetLastError()) + switch(WSAGetLastError()) { case WSAEINTR: case WSAEINPROGRESS: @@ -2049,517 +2055,517 @@ if (ret < 0) return PICA_ERRSOCK; } #else - switch(errno) + switch(errno) { case EAGAIN : #if EAGAIN != EWOULDBLOCK case EWOULDBLOCK: #endif case EINTR: - break; - + break; + default: return PICA_ERRSOCK;//ERR_CHECK } #endif } - -if (ret > 0) + + if (ret > 0) { - *ppos += ret; + *ppos += ret; } - -return PICA_OK; + + return PICA_OK; } int PICA_read_ssl(SSL *ssl, unsigned char *buf, unsigned int *ppos, unsigned int size) { -int ret; + int ret; -ret = SSL_read(ssl, buf + *ppos, size - *ppos); + ret = SSL_read(ssl, buf + *ppos, size - *ppos); -if (!ret) - return PICA_ERRSSL; + if (!ret) + return PICA_ERRSSL; -if (ret < 0) - switch(SSL_get_error(ssl, ret)) + if (ret < 0) + switch(SSL_get_error(ssl, ret)) { case SSL_ERROR_WANT_WRITE: case SSL_ERROR_WANT_READ: - break; + break; default: - return PICA_ERRSSL; + return PICA_ERRSSL; }; - -if (ret > 0) + + if (ret > 0) { - *ppos += ret; + *ppos += ret; } - -return PICA_OK; + + return PICA_OK; } int PICA_read_c2c(struct PICA_c2c *chn) { -int ret; + int ret; -if (chn->state != PICA_C2C_STATE_ACTIVE) - return PICA_OK;// ??? + if (chn->state != PICA_C2C_STATE_ACTIVE) + return PICA_OK;// ??? //ret = SSL_read(chn->ssl , chn->read_buf + chn->read_pos, PICA_CHANREADBUFSIZE - chn->read_pos); -ret = PICA_read_ssl(chn->ssl, chn->read_buf, &chn->read_pos, PICA_CHANREADBUFSIZE); - -if (ret == PICA_OK) + ret = PICA_read_ssl(chn->ssl, chn->read_buf, &chn->read_pos, PICA_CHANREADBUFSIZE); + + if (ret == PICA_OK) { - if(!PICA_processdatastream(chn->read_buf, &(chn->read_pos ), chn, c2c_messages, MSGINFO_MSGSNUM(c2c_messages))) - return PICA_ERRSERV; + if(!PICA_processdatastream(chn->read_buf, &(chn->read_pos ), chn, c2c_messages, MSGINFO_MSGSNUM(c2c_messages))) + return PICA_ERRSERV; } -return ret; + return ret; } //функция читает и обрабатывает данные, приходящие от сервера по управляющему соединению. -int PICA_read_c2n(struct PICA_c2n *ci) +int PICA_read_c2n(struct PICA_c2n *ci) { -int ret; + int ret; //ret=SSL_read(ci->ssl_comm, ci->read_buf + ci->read_pos, PICA_CONNREADBUFSIZE - ci->read_pos); -if (PICA_C2N_STATE_WAITINGREP == ci->state) - ret = PICA_read_socket(ci->sck_comm, ci->read_buf, &ci->read_pos, PICA_CONNREADBUFSIZE); -else if (PICA_C2N_STATE_CONNECTED == ci->state) - ret = PICA_read_ssl(ci->ssl_comm, ci->read_buf, &ci->read_pos, PICA_CONNREADBUFSIZE); + if (PICA_C2N_STATE_WAITINGREP == ci->state) + ret = PICA_read_socket(ci->sck_comm, ci->read_buf, &ci->read_pos, PICA_CONNREADBUFSIZE); + else if (PICA_C2N_STATE_CONNECTED == ci->state) + ret = PICA_read_ssl(ci->ssl_comm, ci->read_buf, &ci->read_pos, PICA_CONNREADBUFSIZE); -if (ret == PICA_OK) + if (ret == PICA_OK) { - if (PICA_C2N_STATE_WAITINGREP == ci->state) - if(!PICA_processdatastream( ci->read_buf, &(ci->read_pos), ci, c2n_init_messages, MSGINFO_MSGSNUM(c2n_init_messages))) - return PICA_ERRSERV; - - if (PICA_C2N_STATE_CONNECTED == ci->state) - if(!PICA_processdatastream( ci->read_buf, &(ci->read_pos), ci, c2n_messages, MSGINFO_MSGSNUM(c2n_messages))) - return PICA_ERRSERV; + if (PICA_C2N_STATE_WAITINGREP == ci->state) + if(!PICA_processdatastream( ci->read_buf, &(ci->read_pos), ci, c2n_init_messages, MSGINFO_MSGSNUM(c2n_init_messages))) + return PICA_ERRSERV; + + if (PICA_C2N_STATE_CONNECTED == ci->state) + if(!PICA_processdatastream( ci->read_buf, &(ci->read_pos), ci, c2n_messages, MSGINFO_MSGSNUM(c2n_messages))) + return PICA_ERRSERV; } -return ret; -} + return ret; +} struct PICA_proto_msg* c2n_writebuf_push(struct PICA_c2n *ci, unsigned int msgid, unsigned int size) { -struct PICA_proto_msg *mp; - -if (! ci->write_buf) + struct PICA_proto_msg *mp; + + if (! ci->write_buf) { - ci->write_buf = calloc(PICA_CONNWRITEBUFSIZE, 1); - if (!ci->write_buf) - return 0; - ci->write_buflen = PICA_CONNWRITEBUFSIZE; + ci->write_buf = calloc(PICA_CONNWRITEBUFSIZE, 1); + if (!ci->write_buf) + return 0; + ci->write_buflen = PICA_CONNWRITEBUFSIZE; } - -if (ci->write_buflen - ci->write_pos < size) + + if (ci->write_buflen - ci->write_pos < size) { - unsigned char*p; - p = realloc(ci->write_buf, size + ci->write_pos); - - if (p) + unsigned char*p; + p = realloc(ci->write_buf, size + ci->write_pos); + + if (p) { - ci->write_buf = p; - ci->write_buflen = size + ci->write_pos; + ci->write_buf = p; + ci->write_buflen = size + ci->write_pos; } - else - return 0; + else + return 0; } - -mp = (struct PICA_proto_msg *)(ci->write_buf + ci->write_pos); -mp->head[0] = mp->head[1] = msgid; -ci->write_pos += size; -return mp; + mp = (struct PICA_proto_msg *)(ci->write_buf + ci->write_pos); + mp->head[0] = mp->head[1] = msgid; + ci->write_pos += size; + + return mp; } struct PICA_proto_msg* c2c_writebuf_push(struct PICA_c2c *chn, unsigned int msgid, unsigned int size) { -struct PICA_proto_msg *mp; - -if (! chn->write_buf) + struct PICA_proto_msg *mp; + + if (! chn->write_buf) { - chn->write_buf = calloc(PICA_CHANWRITEBUFSIZE, 1); - if (!chn->write_buf) - return 0; - chn->write_buflen = PICA_CHANWRITEBUFSIZE; + chn->write_buf = calloc(PICA_CHANWRITEBUFSIZE, 1); + if (!chn->write_buf) + return 0; + chn->write_buflen = PICA_CHANWRITEBUFSIZE; } - -if (chn->write_buflen - chn->write_pos < size) + + if (chn->write_buflen - chn->write_pos < size) { - unsigned char*p; - p = realloc(chn->write_buf, size + chn->write_pos); - - if (p) + unsigned char*p; + p = realloc(chn->write_buf, size + chn->write_pos); + + if (p) { - chn->write_buf = p; - chn->write_buflen = size + chn->write_pos; + chn->write_buf = p; + chn->write_buflen = size + chn->write_pos; } - else - return 0; + else + return 0; } - -mp = (struct PICA_proto_msg *)(chn->write_buf + chn->write_pos); -mp->head[0] = mp->head[1] = msgid; -chn->write_pos += size; -return mp; + mp = (struct PICA_proto_msg *)(chn->write_buf + chn->write_pos); + mp->head[0] = mp->head[1] = msgid; + chn->write_pos += size; + + return mp; } -int PICA_send_msg(struct PICA_c2c *chn, char *buf,unsigned int len) +int PICA_send_msg(struct PICA_c2c *chn, char *buf, unsigned int len) { -struct PICA_proto_msg *mp; + struct PICA_proto_msg *mp; -if (len > PICA_PROTO_C2CMSG_MAXDATASIZE) - return PICA_ERRMSGSIZE; + if (len > PICA_PROTO_C2CMSG_MAXDATASIZE) + return PICA_ERRMSGSIZE; -if ((mp = c2c_writebuf_push(chn, PICA_PROTO_MSGUTF8, len + 4))) + if ((mp = c2c_writebuf_push(chn, PICA_PROTO_MSGUTF8, len + 4))) { - *((uint16_t*)mp->tail) = len; - memcpy(mp->tail + 2, buf, len); + *((uint16_t*)mp->tail) = len; + memcpy(mp->tail + 2, buf, len); } -else - return PICA_ERRNOMEM; + else + return PICA_ERRNOMEM; -return PICA_OK; + return PICA_OK; } int PICA_send_file(struct PICA_c2c *chn, const char *filepath) { -struct PICA_proto_msg *mp; -size_t namelen; -uint64_t file_size; -int ret; -const char *filename;//file name part of the filepath + struct PICA_proto_msg *mp; + size_t namelen; + uint64_t file_size; + int ret; + const char *filename;//file name part of the filepath -if (chn->sendfilestate != PICA_CHANSENDFILESTATE_IDLE) - return PICA_ERRFILETRANSFERINPROGRESS; + if (chn->sendfilestate != PICA_CHANSENDFILESTATE_IDLE) + return PICA_ERRFILETRANSFERINPROGRESS; -if (filepath == NULL) - return PICA_ERRINVFILENAME; + if (filepath == NULL) + return PICA_ERRINVFILENAME; #ifndef WIN32 -filename = strrchr(filepath, '/'); + filename = strrchr(filepath, '/'); #else -filename = strrchr(filepath, '\\'); + filename = strrchr(filepath, '\\'); #endif -if (filename) - filename++; -else - filename = filepath; + if (filename) + filename++; + else + filename = filepath; -namelen = strlen(filename); + namelen = strlen(filename); -if (namelen == 0 || namelen > PICA_PROTO_C2CMSG_MAXFILENAMESIZE) - return PICA_ERRINVFILENAME; + if (namelen == 0 || namelen > PICA_PROTO_C2CMSG_MAXFILENAMESIZE) + return PICA_ERRINVFILENAME; -if ((ret = PICA_sendfile_open_read(chn, filepath, &file_size)) != PICA_OK) - return ret; + if ((ret = PICA_sendfile_open_read(chn, filepath, &file_size)) != PICA_OK) + return ret; -if ((mp = c2c_writebuf_push(chn, PICA_PROTO_SENDFILEREQUEST, namelen + 12))) + if ((mp = c2c_writebuf_push(chn, PICA_PROTO_SENDFILEREQUEST, namelen + 12))) { - *((uint16_t*)mp->tail) = namelen + 8; - *((uint64_t*)(mp->tail + 2)) = file_size; + *((uint16_t*)mp->tail) = namelen + 8; + *((uint64_t*)(mp->tail + 2)) = file_size; - memcpy(mp->tail + 10, filename, namelen); + memcpy(mp->tail + 10, filename, namelen); } -else - return PICA_ERRNOMEM; + else + return PICA_ERRNOMEM; -chn->sendfilestate = PICA_CHANSENDFILESTATE_SENTREQ; -chn->sendfile_size = file_size; -chn->sendfile_pos = 0; + chn->sendfilestate = PICA_CHANSENDFILESTATE_SENTREQ; + chn->sendfile_size = file_size; + chn->sendfile_pos = 0; -return PICA_OK; + return PICA_OK; } int PICA_pause_file(struct PICA_c2c *chan, int sending) { -int senderctl = PICA_PROTO_FILECONTROL_VOID; -int receiverctl = PICA_PROTO_FILECONTROL_VOID; + int senderctl = PICA_PROTO_FILECONTROL_VOID; + int receiverctl = PICA_PROTO_FILECONTROL_VOID; -fprintf(stderr, "PICA_pause_file(%p, %i)\n", chan, sending);//debug + fprintf(stderr, "PICA_pause_file(%p, %i)\n", chan, sending);//debug -if (sending) - { - if (chan->sendfilestate != PICA_CHANSENDFILESTATE_SENDING) - return PICA_ERRINVARG; + if (sending) + { + if (chan->sendfilestate != PICA_CHANSENDFILESTATE_SENDING) + return PICA_ERRINVARG; - chan->sendfilestate = PICA_CHANSENDFILESTATE_PAUSED; + chan->sendfilestate = PICA_CHANSENDFILESTATE_PAUSED; - senderctl = PICA_PROTO_FILECONTROL_PAUSE; - } - else - { - if (chan->recvfilestate != PICA_CHANRECVFILESTATE_RECEIVING) - return PICA_ERRINVARG; + senderctl = PICA_PROTO_FILECONTROL_PAUSE; + } + else + { + if (chan->recvfilestate != PICA_CHANRECVFILESTATE_RECEIVING) + return PICA_ERRINVARG; - chan->recvfilestate = PICA_CHANRECVFILESTATE_PAUSED; + chan->recvfilestate = PICA_CHANRECVFILESTATE_PAUSED; - receiverctl = PICA_PROTO_FILECONTROL_PAUSE; - } + receiverctl = PICA_PROTO_FILECONTROL_PAUSE; + } -return PICA_send_filecontrol(chan, senderctl, receiverctl); + return PICA_send_filecontrol(chan, senderctl, receiverctl); } int PICA_resume_file(struct PICA_c2c *chan, int sending) { -int senderctl = PICA_PROTO_FILECONTROL_VOID; -int receiverctl = PICA_PROTO_FILECONTROL_VOID; + int senderctl = PICA_PROTO_FILECONTROL_VOID; + int receiverctl = PICA_PROTO_FILECONTROL_VOID; -if (sending) - { - if (chan->sendfilestate != PICA_CHANSENDFILESTATE_PAUSED) - return PICA_ERRINVARG; + if (sending) + { + if (chan->sendfilestate != PICA_CHANSENDFILESTATE_PAUSED) + return PICA_ERRINVARG; - chan->sendfilestate = PICA_CHANSENDFILESTATE_SENDING; + chan->sendfilestate = PICA_CHANSENDFILESTATE_SENDING; - senderctl = PICA_PROTO_FILECONTROL_RESUME; - } - else - { - if (chan->recvfilestate != PICA_CHANRECVFILESTATE_PAUSED) - return PICA_ERRINVARG; + senderctl = PICA_PROTO_FILECONTROL_RESUME; + } + else + { + if (chan->recvfilestate != PICA_CHANRECVFILESTATE_PAUSED) + return PICA_ERRINVARG; - chan->recvfilestate = PICA_CHANRECVFILESTATE_RECEIVING; + chan->recvfilestate = PICA_CHANRECVFILESTATE_RECEIVING; - receiverctl = PICA_PROTO_FILECONTROL_RESUME; - } + receiverctl = PICA_PROTO_FILECONTROL_RESUME; + } -return PICA_send_filecontrol(chan, senderctl, receiverctl); + return PICA_send_filecontrol(chan, senderctl, receiverctl); } int PICA_cancel_file(struct PICA_c2c *chan, int sending) { -int senderctl = PICA_PROTO_FILECONTROL_VOID; -int receiverctl = PICA_PROTO_FILECONTROL_VOID; + int senderctl = PICA_PROTO_FILECONTROL_VOID; + int receiverctl = PICA_PROTO_FILECONTROL_VOID; -if (sending) - { - if (chan->sendfilestate != PICA_CHANSENDFILESTATE_SENDING - && chan->sendfilestate != PICA_CHANSENDFILESTATE_PAUSED) - return PICA_ERRINVARG; + if (sending) + { + if (chan->sendfilestate != PICA_CHANSENDFILESTATE_SENDING + && chan->sendfilestate != PICA_CHANSENDFILESTATE_PAUSED) + return PICA_ERRINVARG; - fclose(chan->sendfile_stream); - chan->sendfile_stream = NULL; - chan->sendfilestate = PICA_CHANSENDFILESTATE_IDLE; + fclose(chan->sendfile_stream); + chan->sendfile_stream = NULL; + chan->sendfilestate = PICA_CHANSENDFILESTATE_IDLE; - senderctl = PICA_PROTO_FILECONTROL_CANCEL; - } - else - { - if (chan->recvfilestate != PICA_CHANRECVFILESTATE_RECEIVING - && chan->recvfilestate != PICA_CHANRECVFILESTATE_PAUSED) - return PICA_ERRINVARG; + senderctl = PICA_PROTO_FILECONTROL_CANCEL; + } + else + { + if (chan->recvfilestate != PICA_CHANRECVFILESTATE_RECEIVING + && chan->recvfilestate != PICA_CHANRECVFILESTATE_PAUSED) + return PICA_ERRINVARG; - fclose(chan->recvfile_stream); - chan->recvfile_stream = NULL; - chan->recvfilestate = PICA_CHANRECVFILESTATE_IDLE; + fclose(chan->recvfile_stream); + chan->recvfile_stream = NULL; + chan->recvfilestate = PICA_CHANRECVFILESTATE_IDLE; - receiverctl = PICA_PROTO_FILECONTROL_CANCEL; - } + receiverctl = PICA_PROTO_FILECONTROL_CANCEL; + } -return PICA_send_filecontrol(chan, senderctl, receiverctl); + return PICA_send_filecontrol(chan, senderctl, receiverctl); } int PICA_send_filecontrol(struct PICA_c2c *chan, int senderctl, int receiverctl) { -struct PICA_proto_msg *mp; + struct PICA_proto_msg *mp; -fprintf(stderr, "PICA_send_filecontrol(%p, %i, %i)\n", chan, senderctl, receiverctl);//debug + fprintf(stderr, "PICA_send_filecontrol(%p, %i, %i)\n", chan, senderctl, receiverctl);//debug -if ((mp = c2c_writebuf_push(chan, PICA_PROTO_FILECONTROL, PICA_PROTO_FILECONTROL_SIZE))) - { - mp->tail[0] = senderctl; //sender's command - mp->tail[1] = receiverctl; //receiver's command - } -else - return PICA_ERRNOMEM; + if ((mp = c2c_writebuf_push(chan, PICA_PROTO_FILECONTROL, PICA_PROTO_FILECONTROL_SIZE))) + { + mp->tail[0] = senderctl; //sender's command + mp->tail[1] = receiverctl; //receiver's command + } + else + return PICA_ERRNOMEM; -return PICA_OK; + return PICA_OK; } int PICA_send_file_fragment(struct PICA_c2c *chn) { -struct PICA_proto_msg *mp; -char buf[PICA_FILEFRAGMENTSIZE]; -size_t fragment_size; + struct PICA_proto_msg *mp; + char buf[PICA_FILEFRAGMENTSIZE]; + size_t fragment_size; -if (chn->sendfilestate != PICA_CHANSENDFILESTATE_SENDING) - return PICA_ERRFILETRANSFERNOTINPROGRESS; + if (chn->sendfilestate != PICA_CHANSENDFILESTATE_SENDING) + return PICA_ERRFILETRANSFERNOTINPROGRESS; -fragment_size = fread(buf, 1, PICA_FILEFRAGMENTSIZE, chn->sendfile_stream); + fragment_size = fread(buf, 1, PICA_FILEFRAGMENTSIZE, chn->sendfile_stream); -if (fragment_size == 0) - { - fclose(chn->sendfile_stream); - chn->sendfile_stream = NULL; - chn->sendfilestate = PICA_CHANSENDFILESTATE_IDLE; + if (fragment_size == 0) + { + fclose(chn->sendfile_stream); + chn->sendfile_stream = NULL; + chn->sendfilestate = PICA_CHANSENDFILESTATE_IDLE; - PICA_send_filecontrol(chn, PICA_PROTO_FILECONTROL_IOERROR, PICA_PROTO_FILECONTROL_VOID); + PICA_send_filecontrol(chn, PICA_PROTO_FILECONTROL_IOERROR, PICA_PROTO_FILECONTROL_VOID); - return PICA_ERRFILEIO; - } + return PICA_ERRFILEIO; + } -if ((mp = c2c_writebuf_push(chn, PICA_PROTO_FILEFRAGMENT, fragment_size + 4))) - { - *((uint16_t*)mp->tail) = fragment_size; + if ((mp = c2c_writebuf_push(chn, PICA_PROTO_FILEFRAGMENT, fragment_size + 4))) + { + *((uint16_t*)mp->tail) = fragment_size; - memcpy(mp->tail + 2, buf, fragment_size); - } -else - { - return PICA_ERRNOMEM; - } + memcpy(mp->tail + 2, buf, fragment_size); + } + else + { + return PICA_ERRNOMEM; + } -chn->sendfile_pos += fragment_size; + chn->sendfile_pos += fragment_size; -callbacks.file_progress(chn->peer_id, chn->sendfile_pos, 0); + callbacks.file_progress(chn->peer_id, chn->sendfile_pos, 0); -if (chn->sendfile_pos >= chn->sendfile_size) - { - chn->sendfilestate = PICA_CHANSENDFILESTATE_IDLE; - fclose(chn->sendfile_stream); - chn->sendfile_stream = NULL; + if (chn->sendfile_pos >= chn->sendfile_size) + { + chn->sendfilestate = PICA_CHANSENDFILESTATE_IDLE; + fclose(chn->sendfile_stream); + chn->sendfile_stream = NULL; - callbacks.file_finished(chn->peer_id, 1); - } + callbacks.file_finished(chn->peer_id, 1); + } -if (chn->sendfile_pos > chn->sendfile_size) - return PICA_ERRFILEFRAGMENTCROSSEDSIZE; + if (chn->sendfile_pos > chn->sendfile_size) + return PICA_ERRFILEFRAGMENTCROSSEDSIZE; -return PICA_OK; + return PICA_OK; } void PICA_close_c2c(struct PICA_c2c *chn) { -struct PICA_c2c *ipt; + struct PICA_c2c *ipt; -fprintf(stderr, "PICA_close_c2c(%p)\n", chn);//debug - -ipt=chn->conn->chan_list_head; + fprintf(stderr, "PICA_close_c2c(%p)\n", chn);//debug + + ipt = chn->conn->chan_list_head; //puts("PICA_close_c2c_chkp0");//debug -while(ipt) + while(ipt) { - if (ipt==chn) + if (ipt == chn) { - if (ipt->next) - ipt->next->prev=ipt->prev; - else - chn->conn->chan_list_end=ipt->prev; + if (ipt->next) + ipt->next->prev = ipt->prev; + else + chn->conn->chan_list_end = ipt->prev; - if (ipt->prev) - ipt->prev->next=ipt->next; - else - chn->conn->chan_list_head=ipt->next; + if (ipt->prev) + ipt->prev->next = ipt->next; + else + chn->conn->chan_list_head = ipt->next; - break; + break; } - ipt=ipt->next; + ipt = ipt->next; } //puts("PICA_close_c2c_chkp1");//debug -if (chn -> sendfile_stream) - fclose(chn -> sendfile_stream); + if (chn -> sendfile_stream) + fclose(chn -> sendfile_stream); -if (chn -> recvfile_stream) - fclose(chn -> recvfile_stream); + if (chn -> recvfile_stream) + fclose(chn -> recvfile_stream); -if (chn -> read_buf) - free(chn -> read_buf); + if (chn -> read_buf) + free(chn -> read_buf); -if (chn -> write_buf) - free(chn -> write_buf); + if (chn -> write_buf) + free(chn -> write_buf); -if (chn->peer_cert) - X509_free(chn->peer_cert); + if (chn->peer_cert) + X509_free(chn->peer_cert); //puts("PICA_close_c2c_chkp2");//debug -if (chn->ssl) - SSL_shutdown(chn->ssl); - //puts("PICA_close_c2c_chkp3");//debug + if (chn->ssl) + SSL_shutdown(chn->ssl); + //puts("PICA_close_c2c_chkp3");//debug -if (chn->ssl) + if (chn->ssl) { - //printf("3 SSL_free(%X)\n",chn->ssl);//debug - SSL_free(chn->ssl); + //printf("3 SSL_free(%X)\n",chn->ssl);//debug + SSL_free(chn->ssl); } //puts("PICA_close_c2c_chkp4");//debug -SHUTDOWN(chn->sck_data); + SHUTDOWN(chn->sck_data); //puts("PICA_close_c2c_chkp5");//debug -CLOSE(chn->sck_data); + CLOSE(chn->sck_data); //puts("PICA_close_c2c_chkp6");//debug -free(chn); + free(chn); //puts("PICA_close_c2c_chkp7");//debug } void PICA_close_c2n(struct PICA_c2n *cid) { -struct PICA_c2c *ipt; + struct PICA_c2c *ipt; -while((ipt = cid->chan_list_head)) - PICA_close_c2c(ipt); + while((ipt = cid->chan_list_head)) + PICA_close_c2c(ipt); -SSL_shutdown(cid->ssl_comm); + SSL_shutdown(cid->ssl_comm); //printf("4 SSL_free(%X)\n",cid->ssl_comm);//debug -SSL_free(cid->ssl_comm); -SHUTDOWN(cid->sck_comm); -CLOSE(cid->sck_comm); + SSL_free(cid->ssl_comm); + SHUTDOWN(cid->sck_comm); + CLOSE(cid->sck_comm); -free(cid->read_buf); + free(cid->read_buf); -if (cid->write_buf) - free(cid->write_buf); + if (cid->write_buf) + free(cid->write_buf); -free(cid); + free(cid); } void PICA_close_acc(struct PICA_acc *a) { -SSL_CTX_free(a->ctx); -free(a); + SSL_CTX_free(a->ctx); + free(a); } void PICA_close_listener(struct PICA_listener *l) { -CLOSE(l->sck_listener); -free(l->public_addr_dns); -free(l); + CLOSE(l->sck_listener); + free(l->public_addr_dns); + free(l); } #ifdef WIN32 - const char *PICA_inet_ntop(int af, const void *src, char *dst, size_t size) +const char *PICA_inet_ntop(int af, const void *src, char *dst, size_t size) { - unsigned char *chsrc = (unsigned char*)src; - switch(af) - { - case AF_INET: - sprintf(dst, "%u.%u.%u.%u", chsrc[0], chsrc[1], chsrc[2], chsrc[3]); - break; + unsigned char *chsrc = (unsigned char*)src; + switch(af) + { + case AF_INET: + sprintf(dst, "%u.%u.%u.%u", chsrc[0], chsrc[1], chsrc[2], chsrc[3]); + break; - case AF_INET6: - sprintf(dst, "%x%02x:%x%02x:%x%02x:%x%02x:%x%02x:%x%02x:%x%02x:%x%02x", chsrc[0], chsrc[1], chsrc[2], chsrc[3], - chsrc[4], chsrc[5], chsrc[6], chsrc[7], - chsrc[8], chsrc[9], chsrc[10], chsrc[11], - chsrc[12],chsrc[13], chsrc[14], chsrc[15]); - break; + case AF_INET6: + sprintf(dst, "%x%02x:%x%02x:%x%02x:%x%02x:%x%02x:%x%02x:%x%02x:%x%02x", chsrc[0], chsrc[1], chsrc[2], chsrc[3], + chsrc[4], chsrc[5], chsrc[6], chsrc[7], + chsrc[8], chsrc[9], chsrc[10], chsrc[11], + chsrc[12], chsrc[13], chsrc[14], chsrc[15]); + break; - default: - return NULL; - } + default: + return NULL; + } - return dst; + return dst; } #endif @@ -2567,93 +2573,93 @@ free(l); int PICA_sendfile_open_read(struct PICA_c2c *chn, const char *filename_utf8, uint64_t *file_size) { #ifdef WIN32 -{ -wchar_t *wfilename = NULL; -int wlen; + { + wchar_t *wfilename = NULL; + int wlen; -wlen = MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, NULL, 0); + wlen = MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, NULL, 0); -if (wlen == 0 || wlen == 0xFFFD) - return PICA_ERRINVFILENAME; + if (wlen == 0 || wlen == 0xFFFD) + return PICA_ERRINVFILENAME; -wfilename = (wchar_t*)malloc(wlen * sizeof(wchar_t)); + wfilename = (wchar_t*)malloc(wlen * sizeof(wchar_t)); -if (!wfilename) - return PICA_ERRNOMEM; + if (!wfilename) + return PICA_ERRNOMEM; -MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, wfilename, wlen); + MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, wfilename, wlen); -chn->sendfile_stream = _wfopen(wfilename, L"rb"); + chn->sendfile_stream = _wfopen(wfilename, L"rb"); -free(wfilename); + free(wfilename); -if (chn->sendfile_stream == NULL) - return PICA_ERRFILEOPEN; + if (chn->sendfile_stream == NULL) + return PICA_ERRFILEOPEN; -if (_fseeki64(chn->sendfile_stream, 0, SEEK_END) != 0) - return PICA_ERRFILEOPEN; + if (_fseeki64(chn->sendfile_stream, 0, SEEK_END) != 0) + return PICA_ERRFILEOPEN; -*file_size = _ftelli64(chn->sendfile_stream); + *file_size = _ftelli64(chn->sendfile_stream); -if (_fseeki64(chn->sendfile_stream, 0, SEEK_SET) != 0) - return PICA_ERRFILEOPEN; -} + if (_fseeki64(chn->sendfile_stream, 0, SEEK_SET) != 0) + return PICA_ERRFILEOPEN; + } #else -chn->sendfile_stream = fopen(filename_utf8, "rb"); + chn->sendfile_stream = fopen(filename_utf8, "rb"); -if (chn->sendfile_stream == NULL) - return PICA_ERRFILEOPEN; + if (chn->sendfile_stream == NULL) + return PICA_ERRFILEOPEN; -if (fseeko(chn->sendfile_stream, 0, SEEK_END) != 0) - return PICA_ERRFILEOPEN; + if (fseeko(chn->sendfile_stream, 0, SEEK_END) != 0) + return PICA_ERRFILEOPEN; -*file_size = ftello(chn->sendfile_stream); + *file_size = ftello(chn->sendfile_stream); -if (fseeko(chn->sendfile_stream, 0, SEEK_SET) != 0) - return PICA_ERRFILEOPEN; + if (fseeko(chn->sendfile_stream, 0, SEEK_SET) != 0) + return PICA_ERRFILEOPEN; #endif -return PICA_OK; + return PICA_OK; } int PICA_recvfile_open_write(struct PICA_c2c *chn, const char *filename_utf8, unsigned int filenamesize) { ///////////// #ifdef WIN32 -{ -wchar_t *rfilename = NULL; -int rlen; + { + wchar_t *rfilename = NULL; + int rlen; -rlen = MultiByteToWideChar(CP_UTF8, 0, filename_utf8, filenamesize, NULL, 0); + rlen = MultiByteToWideChar(CP_UTF8, 0, filename_utf8, filenamesize, NULL, 0); -if (rlen == 0 || rlen == 0xFFFD) - return PICA_ERRINVFILENAME; + if (rlen == 0 || rlen == 0xFFFD) + return PICA_ERRINVFILENAME; -rlen++;//space for terminating zero character + rlen++;//space for terminating zero character -rfilename = malloc(rlen * sizeof(wchar_t)); + rfilename = malloc(rlen * sizeof(wchar_t)); -if (!rfilename) - return PICA_ERRNOMEM; + if (!rfilename) + return PICA_ERRNOMEM; -MultiByteToWideChar(CP_UTF8, 0, filename_utf8, filenamesize, rfilename, rlen); + MultiByteToWideChar(CP_UTF8, 0, filename_utf8, filenamesize, rfilename, rlen); -rfilename[rlen - 1] = L'\0'; + rfilename[rlen - 1] = L'\0'; -chn->recvfile_stream = _wfopen(rfilename, L"wb"); + chn->recvfile_stream = _wfopen(rfilename, L"wb"); -free(rfilename); + free(rfilename); -if (chn->recvfile_stream == NULL) - return PICA_ERRFILEOPEN; + if (chn->recvfile_stream == NULL) + return PICA_ERRFILEOPEN; -} + } #else -chn->recvfile_stream = fopen(filename_utf8, "wb"); + chn->recvfile_stream = fopen(filename_utf8, "wb"); -if (chn->recvfile_stream == NULL) - return PICA_ERRFILEOPEN; + if (chn->recvfile_stream == NULL) + return PICA_ERRFILEOPEN; #endif ///////////// -return PICA_OK; + return PICA_OK; } diff --git a/PICA_client.h b/PICA_client.h old mode 100755 new mode 100644 index 96be77f..421861a --- a/PICA_client.h +++ b/PICA_client.h @@ -53,7 +53,7 @@ typedef unsigned __int64 uint64_t; #define OPENSSL_THREAD_DEFINES #include #if defined(OPENSSL_THREADS) - // thread support enabled +// thread support enabled #else #error "THREAD SUPPORT IS NOT ENABLED IN OPENSSL!" #endif @@ -119,165 +119,165 @@ struct PICA_c2c; struct PICA_acc { -unsigned char id[PICA_ID_SIZE]; //SHA224 hash of user's certificate in DER format -SSL_CTX* ctx; + unsigned char id[PICA_ID_SIZE]; //SHA224 hash of user's certificate in DER format + SSL_CTX* ctx; }; enum PICA_c2n_state { -PICA_C2N_STATE_NEW = 0, -PICA_C2N_STATE_CONNECTING, -PICA_C2N_STATE_WAITINGREP, -PICA_C2N_STATE_WAITINGTLS, -PICA_C2N_STATE_CONNECTED + PICA_C2N_STATE_NEW = 0, + PICA_C2N_STATE_CONNECTING, + PICA_C2N_STATE_WAITINGREP, + PICA_C2N_STATE_WAITINGTLS, + PICA_C2N_STATE_CONNECTED }; struct PICA_c2n { -struct PICA_acc *acc; + struct PICA_acc *acc; //#warning "sockaddr!" -struct sockaddr_in srv_addr; // sockaddr !! + struct sockaddr_in srv_addr; // sockaddr !! //unsigned char id[PICA_ID_SIZE]; //SHA224 hash of user's certificate in DER format //SSL_CTX* ctx; -SOCKET sck_comm; -SSL* ssl_comm; + SOCKET sck_comm; + SSL* ssl_comm; -enum PICA_c2n_state state; + enum PICA_c2n_state state; -unsigned char *read_buf; -unsigned char *write_buf; -unsigned int read_pos; -unsigned int write_pos; -unsigned int write_buflen; -unsigned int write_sslbytestowrite; + unsigned char *read_buf; + unsigned char *write_buf; + unsigned int read_pos; + unsigned int write_pos; + unsigned int write_buflen; + unsigned int write_sslbytestowrite; -struct PICA_c2c *chan_list_head; -struct PICA_c2c *chan_list_end; + struct PICA_c2c *chan_list_head; + struct PICA_c2c *chan_list_end; -int init_resp_ok; -unsigned char node_ver_major, node_ver_minor; + int init_resp_ok; + unsigned char node_ver_major, node_ver_minor; }; enum PICA_c2c_state { -PICA_C2C_STATE_NEW = 0, -PICA_C2C_STATE_ACTIVE + PICA_C2C_STATE_NEW = 0, + PICA_C2C_STATE_ACTIVE }; struct PICA_c2c { -struct PICA_acc *acc; -struct PICA_c2n *conn;//соединение с сервером, через которое установлен данный логический канал связи -unsigned char peer_id[PICA_ID_SIZE]; -SOCKET sck_data; -SSL *ssl; -int outgoing;//1 если создание канала инициировано локальным клиентом, 0 - если собеседником -X509 *peer_cert; + struct PICA_acc *acc; + struct PICA_c2n *conn;//соединение с сервером, через которое установлен данный логический канал связи + unsigned char peer_id[PICA_ID_SIZE]; + SOCKET sck_data; + SSL *ssl; + int outgoing;//1 если создание канала инициировано локальным клиентом, 0 - если собеседником + X509 *peer_cert; //unsigned char msgbuf[PICA_CHNMSGBUFLEN]; -unsigned char *read_buf; -unsigned char *write_buf; -unsigned int read_pos; -unsigned int write_pos; -unsigned int write_buflen; -unsigned int write_sslbytestowrite; - -struct PICA_c2c *next; -struct PICA_c2c *prev; -enum PICA_c2c_state state; -time_t timestamp; -int sendfilestate; -uint64_t sendfile_size; -uint64_t sendfile_pos; -FILE *sendfile_stream; - -int recvfilestate; -uint64_t recvfile_size; -uint64_t recvfile_pos; -FILE *recvfile_stream; + unsigned char *read_buf; + unsigned char *write_buf; + unsigned int read_pos; + unsigned int write_pos; + unsigned int write_buflen; + unsigned int write_sslbytestowrite; + + struct PICA_c2c *next; + struct PICA_c2c *prev; + enum PICA_c2c_state state; + time_t timestamp; + int sendfilestate; + uint64_t sendfile_size; + uint64_t sendfile_pos; + FILE *sendfile_stream; + + int recvfilestate; + uint64_t recvfile_size; + uint64_t recvfile_pos; + FILE *recvfile_stream; }; struct PICA_listener { -struct PICA_acc *acc; -SOCKET sck_listener; + struct PICA_acc *acc; + SOCKET sck_listener; -int public_port; -int local_port; + int public_port; + int local_port; -in_addr_t public_addr_ipv4; -const char *public_addr_dns; + in_addr_t public_addr_ipv4; + const char *public_addr_dns; }; struct PICA_client_callbacks { //получение сообщения. -void (*newmsg_cb)(const unsigned char *peer_id,const char* msgbuf,unsigned int nb,int type); + void (*newmsg_cb)(const unsigned char *peer_id, const char* msgbuf, unsigned int nb, int type); //получение подтверждения о доставке сообщения -void (*msgok_cb)(const unsigned char *peer_id); + void (*msgok_cb)(const unsigned char *peer_id); //создание канала с собеседником -void (*c2c_established_cb)(const unsigned char *peer_id); -//создать канал не удалось -void (*c2c_failed)(const unsigned char *peer_id); + void (*c2c_established_cb)(const unsigned char *peer_id); +//создать канал не удалось + void (*c2c_failed)(const unsigned char *peer_id); //входящий запрос на создание канала от пользователя с номером caller_id //возвращаемое значение: 0 - отклонить запрос, ненулевое значение - принять запрос -int (*accept_cb)(const unsigned char *caller_id); + int (*accept_cb)(const unsigned char *caller_id); //запрошенный пользователь не найден, в оффлайне или отказался от общения -void (*notfound_cb)(const unsigned char *callee_id); + void (*notfound_cb)(const unsigned char *callee_id); // -void (*c2c_closed_cb)(const unsigned char *peer_id, int reason); + void (*c2c_closed_cb)(const unsigned char *peer_id, int reason); -void (*nodelist_cb)(int type, void *addr_bin, const char *addr_str, unsigned int port); + void (*nodelist_cb)(int type, void *addr_bin, const char *addr_str, unsigned int port); //сертификат собеседника в формате PEM. Функция должна сравнить предъявленный сертификат с сохранённым (если есть) и вернуть 1 при успешной проверке, 0 - при неуспешной -int (*peer_cert_verify_cb)(const unsigned char *peer_id, const char *cert_pem, unsigned int nb); + int (*peer_cert_verify_cb)(const unsigned char *peer_id, const char *cert_pem, unsigned int nb); // returns 0 if file is rejected, 1 if accepted, 2 if decision is postponed -int (*accept_file_cb)(const unsigned char *peer_id, uint64_t file_size, const char *filename, unsigned int filename_size); + int (*accept_file_cb)(const unsigned char *peer_id, uint64_t file_size, const char *filename, unsigned int filename_size); -void (*accepted_file_cb)(const unsigned char *peer_id); + void (*accepted_file_cb)(const unsigned char *peer_id); -void (*denied_file_cb)(const unsigned char *peer_id); + void (*denied_file_cb)(const unsigned char *peer_id); -void (*file_progress)(const unsigned char *peer_id, uint64_t sent, uint64_t received); + void (*file_progress)(const unsigned char *peer_id, uint64_t sent, uint64_t received); -void (*file_control)(const unsigned char *peer_id, unsigned int sender_cmd, unsigned int receiver_cmd); + void (*file_control)(const unsigned char *peer_id, unsigned int sender_cmd, unsigned int receiver_cmd); -void (*file_finished)(const unsigned char *peer_id, int sending); + void (*file_finished)(const unsigned char *peer_id, int sending); -void (*c2n_established_cb)(struct PICA_c2n *c2n); + void (*c2n_established_cb)(struct PICA_c2n *c2n); -void (*c2n_failed_cb)(struct PICA_c2n *c2n); + void (*c2n_failed_cb)(struct PICA_c2n *c2n); -void (*c2n_closed_cb)(struct PICA_c2n *c2n); + void (*c2n_closed_cb)(struct PICA_c2n *c2n); -void (*listener_error)(struct PICA_listener *lst, int errorcode); + void (*listener_error)(struct PICA_listener *lst, int errorcode); }; - + #ifdef __cplusplus extern "C" { #endif -//read certificate from cert_file in PEM format, store id in buffer pointed by id +//read certificate from cert_file in PEM format, store id in buffer pointed by id int PICA_get_id_from_cert_file(const char *cert_file, unsigned char *id); //read certificate from C string in PEM format, store id in buffer pointed by id int PICA_get_id_from_cert_string(const char *cert_pem, unsigned char *id); int PICA_client_init(struct PICA_client_callbacks *clcbs); int PICA_new_c2n - (const struct PICA_acc *acc, - const char *nodeaddr, - unsigned int port, -/* const char *CA_file, - const char *cert_file, - const char *pkey_file, - const char *dh_param_file, - int (*password_cb)(char *buf, int size, int rwflag, void *userdata), //move callback to PICA_client_callbacks? */ - struct PICA_c2n **ci); - -int PICA_new_c2c(struct PICA_c2n *ci,const unsigned char *peer_id, struct PICA_listener *l,struct PICA_c2c **chn); +(const struct PICA_acc *acc, + const char *nodeaddr, + unsigned int port, + /* const char *CA_file, + const char *cert_file, + const char *pkey_file, + const char *dh_param_file, + int (*password_cb)(char *buf, int size, int rwflag, void *userdata), //move callback to PICA_client_callbacks? */ + struct PICA_c2n **ci); + +int PICA_new_c2c(struct PICA_c2n *ci, const unsigned char *peer_id, struct PICA_listener *l, struct PICA_c2c **chn); int PICA_new_listener(const struct PICA_acc *acc, const char *public_addr, int public_port, int local_port, struct PICA_listener **l); @@ -292,15 +292,15 @@ int PICA_open_acc(const char *cert_file, int PICA_read_c2n(struct PICA_c2n *ci); -int PICA_read(struct PICA_c2n *ci,int timeout); +int PICA_read(struct PICA_c2n *ci, int timeout); int PICA_write(struct PICA_c2n *ci); //connections, listeners - NULL-terminated arrays of pointers to appropriate structures // timeout - timeout in milliseconds int PICA_event_loop(struct PICA_c2n **connections, struct PICA_listener **listeners, int timeout); -int PICA_send_msg(struct PICA_c2c *chn, char *buf,unsigned int len); -int PICA_read_msg(struct PICA_c2c *chn,char *buf,unsigned int *n); +int PICA_send_msg(struct PICA_c2c *chn, char *buf, unsigned int len); +int PICA_read_msg(struct PICA_c2c *chn, char *buf, unsigned int *n); //filename - ASCII or UTF-8 encoded string int PICA_send_file(struct PICA_c2c *chn, const char *filepath); diff --git a/PICA_id.c b/PICA_id.c index 1e7309a..3271dc9 100644 --- a/PICA_id.c +++ b/PICA_id.c @@ -1,77 +1,77 @@ - + #include "PICA_id.h" #include #include - + int PICA_id_from_X509(X509 *x, unsigned char *id) { -unsigned char *der = NULL; -int len; + unsigned char *der = NULL; + int len; -len = i2d_X509(x, &der); + len = i2d_X509(x, &der); -if (len <= 0) -{ - return 0; -} + if (len <= 0) + { + return 0; + } -SHA224(der, len, id); + SHA224(der, len, id); -OPENSSL_free(der); + OPENSSL_free(der); -return 1; + return 1; } unsigned char *PICA_id_from_base64(const unsigned char *buf, unsigned char *id) { -BIO *biomem, *b64; -static char localidbuf[PICA_ID_SIZE]; -int inlen, bread = 0; -unsigned char *idbuf = id; + BIO *biomem, *b64; + static char localidbuf[PICA_ID_SIZE]; + int inlen, bread = 0; + unsigned char *idbuf = id; -b64 = BIO_new(BIO_f_base64()); -BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); -biomem = BIO_new_mem_buf(buf, -1); -biomem = BIO_push(b64, biomem); + b64 = BIO_new(BIO_f_base64()); + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); + biomem = BIO_new_mem_buf(buf, -1); + biomem = BIO_push(b64, biomem); -if (idbuf == NULL) - idbuf = localidbuf; + if (idbuf == NULL) + idbuf = localidbuf; -bread = BIO_read(biomem, idbuf, PICA_ID_SIZE); + bread = BIO_read(biomem, idbuf, PICA_ID_SIZE); -if (bread != PICA_ID_SIZE) - idbuf = NULL; + if (bread != PICA_ID_SIZE) + idbuf = NULL; -BIO_free_all(biomem); + BIO_free_all(biomem); -return idbuf; + return idbuf; } char *PICA_id_to_base64(const unsigned char *id, char *buf) { -BIO *biomem, *b64; -static char localbuf[PICA_ID_SIZE*2]; + BIO *biomem, *b64; + static char localbuf[PICA_ID_SIZE * 2]; -char *sourcebuf, *outputbuf = buf; -long b64len; + char *sourcebuf, *outputbuf = buf; + long b64len; -b64 = BIO_new(BIO_f_base64()); -biomem = BIO_new(BIO_s_mem()); -biomem = BIO_push(b64, biomem); -BIO_write(biomem, id, PICA_ID_SIZE); -BIO_flush(biomem); + b64 = BIO_new(BIO_f_base64()); + biomem = BIO_new(BIO_s_mem()); + biomem = BIO_push(b64, biomem); + BIO_write(biomem, id, PICA_ID_SIZE); + BIO_flush(biomem); -b64len = BIO_get_mem_data(biomem, &sourcebuf); + b64len = BIO_get_mem_data(biomem, &sourcebuf); -if (outputbuf == NULL) - outputbuf = localbuf; + if (outputbuf == NULL) + outputbuf = localbuf; -memcpy(outputbuf, sourcebuf, b64len); + memcpy(outputbuf, sourcebuf, b64len); -*strchr(outputbuf, '\n')='\0'; -outputbuf[b64len] = '\0'; + *strchr(outputbuf, '\n') = '\0'; + outputbuf[b64len] = '\0'; -BIO_free_all(biomem); + BIO_free_all(biomem); -return outputbuf; + return outputbuf; } diff --git a/PICA_id.h b/PICA_id.h index 5972655..aa7fe50 100644 --- a/PICA_id.h +++ b/PICA_id.h @@ -1,4 +1,4 @@ - + #ifndef PICA_ID_H #define PICA_ID_H diff --git a/PICA_log.c b/PICA_log.c index 51fa42f..7586d69 100644 --- a/PICA_log.c +++ b/PICA_log.c @@ -8,102 +8,102 @@ static int PICA_loglevel = PICA_LOG_INFO; -void PICA_fatal(const char *fmt,...) +void PICA_fatal(const char *fmt, ...) { -va_list args; + va_list args; -va_start(args, fmt); -PICA_log_entry(PICA_LOG_FATAL, fmt, args); -va_end(args); -exit(-1); + va_start(args, fmt); + PICA_log_entry(PICA_LOG_FATAL, fmt, args); + va_end(args); + exit(-1); } -void PICA_error(const char *fmt,...) +void PICA_error(const char *fmt, ...) { -va_list args; + va_list args; -va_start(args, fmt); -PICA_log_entry(PICA_LOG_ERROR, fmt, args); -va_end(args); + va_start(args, fmt); + PICA_log_entry(PICA_LOG_ERROR, fmt, args); + va_end(args); } -void PICA_warn(const char *fmt,...) +void PICA_warn(const char *fmt, ...) { -va_list args; + va_list args; -va_start(args, fmt); -PICA_log_entry(PICA_LOG_WARN, fmt, args); -va_end(args); + va_start(args, fmt); + PICA_log_entry(PICA_LOG_WARN, fmt, args); + va_end(args); } -void PICA_info(const char *fmt,...) +void PICA_info(const char *fmt, ...) { -va_list args; + va_list args; -va_start(args, fmt); -PICA_log_entry(PICA_LOG_INFO, fmt, args); -va_end(args); + va_start(args, fmt); + PICA_log_entry(PICA_LOG_INFO, fmt, args); + va_end(args); } -void PICA_debug1(const char *fmt,...) +void PICA_debug1(const char *fmt, ...) { -if (PICA_loglevel >= PICA_LOG_DBG1) + if (PICA_loglevel >= PICA_LOG_DBG1) { - va_list args; + va_list args; - va_start(args, fmt); - PICA_log_entry(PICA_LOG_DBG1, fmt, args); - va_end(args); + va_start(args, fmt); + PICA_log_entry(PICA_LOG_DBG1, fmt, args); + va_end(args); } } -void PICA_debug2(const char *fmt,...) +void PICA_debug2(const char *fmt, ...) { -if (PICA_loglevel >= PICA_LOG_DBG2) + if (PICA_loglevel >= PICA_LOG_DBG2) { - va_list args; + va_list args; - va_start(args, fmt); - PICA_log_entry(PICA_LOG_DBG2, fmt, args); - va_end(args); + va_start(args, fmt); + PICA_log_entry(PICA_LOG_DBG2, fmt, args); + va_end(args); } } -void PICA_debug3(const char *fmt,...) +void PICA_debug3(const char *fmt, ...) { -if (PICA_loglevel >= PICA_LOG_DBG3) + if (PICA_loglevel >= PICA_LOG_DBG3) { - va_list args; + va_list args; - va_start(args, fmt); - PICA_log_entry(PICA_LOG_DBG3, fmt, args); - va_end(args); + va_start(args, fmt); + PICA_log_entry(PICA_LOG_DBG3, fmt, args); + va_end(args); } } void PICA_log_entry(int loglevel, const char *fmt, va_list args) { -static char buf[1024]; -static const char *loglevel_txt[] = {"fatal", "error", "warning", "info", "debug1", "debug2", "debug3"}; -FILE *log_file = stdout; -time_t log_time; -static char timebuf[32]; + static char buf[1024]; + static const char *loglevel_txt[] = {"fatal", "error", "warning", "info", "debug1", "debug2", "debug3"}; + FILE *log_file = stdout; + time_t log_time; + static char timebuf[32]; -if (loglevel <= PICA_LOG_WARN) - log_file = stderr; + if (loglevel <= PICA_LOG_WARN) + log_file = stderr; -log_time = time(NULL); -strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", localtime(&log_time)); + log_time = time(NULL); + strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", localtime(&log_time)); -sprintf(buf, "[%.32s] %s: %.1000s\n", timebuf, loglevel_txt[loglevel - PICA_LOG_FATAL], fmt); + sprintf(buf, "[%.32s] %s: %.1000s\n", timebuf, loglevel_txt[loglevel - PICA_LOG_FATAL], fmt); -vfprintf(log_file, buf, args); -fflush(log_file); + vfprintf(log_file, buf, args); + fflush(log_file); } void PICA_set_loglevel(int loglevel) { -if (loglevel >= PICA_LOG_FATAL && loglevel <= PICA_LOG_DBG3) - PICA_loglevel = loglevel; + if (loglevel >= PICA_LOG_FATAL && loglevel <= PICA_LOG_DBG3) + PICA_loglevel = loglevel; } \ No newline at end of file diff --git a/PICA_log.h b/PICA_log.h index 46c80a4..5950253 100644 --- a/PICA_log.h +++ b/PICA_log.h @@ -11,13 +11,13 @@ #define PICA_LOG_DBG2 31342 #define PICA_LOG_DBG3 31343 -void PICA_fatal(const char *fmt,...); -void PICA_error(const char *fmt,...); -void PICA_warn(const char *fmt,...); -void PICA_info(const char *fmt,...); -void PICA_debug1(const char *fmt,...); -void PICA_debug2(const char *fmt,...); -void PICA_debug3(const char *fmt,...); +void PICA_fatal(const char *fmt, ...); +void PICA_error(const char *fmt, ...); +void PICA_warn(const char *fmt, ...); +void PICA_info(const char *fmt, ...); +void PICA_debug1(const char *fmt, ...); +void PICA_debug2(const char *fmt, ...); +void PICA_debug3(const char *fmt, ...); void PICA_log_entry(int loglevel, const char *fmt, va_list args); diff --git a/PICA_msgproc.c b/PICA_msgproc.c old mode 100755 new mode 100644 index 1564af7..00d19c0 --- a/PICA_msgproc.c +++ b/PICA_msgproc.c @@ -6,81 +6,81 @@ //возвращает размер сообщения либо UINT_MAX,если количество прочитанных байт недостаточно для определения размера //либо 0 при ошибочных данных -unsigned int PICA_msggetsize(unsigned char *buf,unsigned int nb,struct PICA_msginfo *msgs,unsigned int nmsg) +unsigned int PICA_msggetsize(unsigned char *buf, unsigned int nb, struct PICA_msginfo *msgs, unsigned int nmsg) { -unsigned int i; + unsigned int i; -if (nb<2) - return UINT_MAX; + if (nb < 2) + return UINT_MAX; -if (buf[0]!=buf[1]) - return 0; + if (buf[0] != buf[1]) + return 0; -for (i=0;i=(msgs[i].sz+2)) + if (nb >= (msgs[i].sz + 2)) { - unsigned int tail_len=0; - int j; + unsigned int tail_len = 0; + int j; #if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ - for (j=0;j *read_pos) - break; + if (uret > *read_pos) + break; - if (!PICA_processmsg(buf,uret,arg,msgs,nmsg)) - return 0; + if (!PICA_processmsg(buf, uret, arg, msgs, nmsg)) + return 0; - *read_pos-=uret; - - memmove(buf,buf+uret,*read_pos);//сдвиг содержимого буфера к началу - } + *read_pos -= uret; + + memmove(buf, buf + uret, *read_pos); //сдвиг содержимого буфера к началу + } -return 1; + return 1; } diff --git a/PICA_msgproc.h b/PICA_msgproc.h old mode 100755 new mode 100644 index 0bf144e..5c8311c --- a/PICA_msgproc.h +++ b/PICA_msgproc.h @@ -1,4 +1,4 @@ -// структуры и функции для обработки сообщений протокола +// структуры и функции для обработки сообщений протокола // #ifndef PICA_MSGPROC_H #define PICA_MSGPROC_H @@ -10,15 +10,15 @@ struct PICA_msginfo { -unsigned int msgid; -unsigned int fixedsz;//фиксированный или переменный размер -unsigned int sz;//фиксированный размер всего пакета либо кол-во байт, определяющих размер хвостовой части пакета -unsigned int (*msgprocfn)(unsigned char*,unsigned int,void*);//функция-обработчик данного типа сообщений + unsigned int msgid; + unsigned int fixedsz;//фиксированный или переменный размер + unsigned int sz;//фиксированный размер всего пакета либо кол-во байт, определяющих размер хвостовой части пакета + unsigned int (*msgprocfn)(unsigned char*, unsigned int, void*); //функция-обработчик данного типа сообщений }; -unsigned int PICA_msggetsize(unsigned char *buf,unsigned int nb,struct PICA_msginfo *msgs,unsigned int nmsg); +unsigned int PICA_msggetsize(unsigned char *buf, unsigned int nb, struct PICA_msginfo *msgs, unsigned int nmsg); -unsigned int PICA_processmsg(unsigned char *buf,unsigned int size,void* arg,struct PICA_msginfo *msgs,unsigned int nmsg); +unsigned int PICA_processmsg(unsigned char *buf, unsigned int size, void* arg, struct PICA_msginfo *msgs, unsigned int nmsg); -unsigned int PICA_processdatastream(unsigned char *buf,unsigned int *read_pos,void* arg,const struct PICA_msginfo *msgs,unsigned int nmsg); +unsigned int PICA_processdatastream(unsigned char *buf, unsigned int *read_pos, void* arg, const struct PICA_msginfo *msgs, unsigned int nmsg); #endif diff --git a/PICA_node.c b/PICA_node.c old mode 100755 new mode 100644 index c3b1d3e..6b63b71 --- a/PICA_node.c +++ b/PICA_node.c @@ -1,4 +1,4 @@ -//Программа является узлом сети +//Программа является узлом сети // #include #include @@ -37,7 +37,7 @@ typedef u_short uint16_t; time_t skynet_refresh_tmst; -clock_t TMO_CCLINK_WAITACTIVE=15;//CONF //таймаут ожидания перехода соединения в активное состояние +clock_t TMO_CCLINK_WAITACTIVE = 15; //CONF //таймаут ожидания перехода соединения в активное состояние char *my_addr;//TEMP CONF FIXME собственный ip-адрес узла, на котором он ожидает соединения @@ -45,7 +45,7 @@ SOCKET listen_comm_sck;//* SSL_CTX* ctx; struct newconn newconns[MAX_NEWCONNS]; -unsigned int newconns_pos=0; +unsigned int newconns_pos = 0; struct client *client_tree_root;//корень дерева клиентов @@ -63,42 +63,42 @@ 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; +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; -unsigned int procmsg_INITREQ(unsigned char* buf,unsigned int size,void* ptr); -unsigned int procmsg_CONNID(unsigned char* buf,unsigned int size,void* ptr); -unsigned int procmsg_NODECONNREQ(unsigned char* buf,unsigned int size,void* ptr); +unsigned int procmsg_INITREQ(unsigned char* buf, unsigned int size, void* ptr); +unsigned int procmsg_CONNID(unsigned char* buf, unsigned int size, void* ptr); +unsigned int procmsg_NODECONNREQ(unsigned char* buf, unsigned int size, void* ptr); -unsigned int procmsg_CONNREQOUTG(unsigned char* buf,unsigned int size,void* ptr); -unsigned int procmsg_CONNALLOW(unsigned char* buf,unsigned int size,void* ptr); -unsigned int procmsg_CONNDENY(unsigned char* buf,unsigned int size,void* ptr); -unsigned int procmsg_NODERESP(unsigned char* buf,unsigned int size,void* ptr); -unsigned int procmsg_NEWNODE(unsigned char* buf,unsigned int size,void* ptr); -unsigned int procmsg_NODELISTREQ(unsigned char* buf,unsigned int size,void* ptr); -unsigned int procmsg_NODELIST(unsigned char* buf,unsigned int size,void* ptr); -unsigned int procmsg_N2NFOUND(unsigned char* buf,unsigned int size,void* ptr); -unsigned int procmsg_SEARCH(unsigned char* buf,unsigned int size,void* ptr); -unsigned int procmsg_N2NCONNREQOUTG(unsigned char* buf,unsigned int size,void* ptr); -unsigned int procmsg_N2NALLOW(unsigned char* buf,unsigned int size,void* ptr); -unsigned int procmsg_N2NNOTFOUND(unsigned char* buf,unsigned int size,void* ptr); -unsigned int procmsg_N2NMSG(unsigned char* buf,unsigned int size,void* ptr); +unsigned int procmsg_CONNREQOUTG(unsigned char* buf, unsigned int size, void* ptr); +unsigned int procmsg_CONNALLOW(unsigned char* buf, unsigned int size, void* ptr); +unsigned int procmsg_CONNDENY(unsigned char* buf, unsigned int size, void* ptr); +unsigned int procmsg_NODERESP(unsigned char* buf, unsigned int size, void* ptr); +unsigned int procmsg_NEWNODE(unsigned char* buf, unsigned int size, void* ptr); +unsigned int procmsg_NODELISTREQ(unsigned char* buf, unsigned int size, void* ptr); +unsigned int procmsg_NODELIST(unsigned char* buf, unsigned int size, void* ptr); +unsigned int procmsg_N2NFOUND(unsigned char* buf, unsigned int size, void* ptr); +unsigned int procmsg_SEARCH(unsigned char* buf, unsigned int size, void* ptr); +unsigned int procmsg_N2NCONNREQOUTG(unsigned char* buf, unsigned int size, void* ptr); +unsigned int procmsg_N2NALLOW(unsigned char* buf, unsigned int size, void* ptr); +unsigned int procmsg_N2NNOTFOUND(unsigned char* buf, unsigned int size, void* ptr); +unsigned int procmsg_N2NMSG(unsigned char* buf, unsigned int size, void* ptr); -unsigned int procmsg_PINGREQ_client(unsigned char* buf,unsigned int size,void* ptr); -unsigned int procmsg_PINGREP_client(unsigned char* buf,unsigned int size,void* ptr); -unsigned int procmsg_PINGREQ_node(unsigned char* buf,unsigned int size,void* ptr); -unsigned int procmsg_PINGREP_node(unsigned char* buf,unsigned int size,void* ptr); +unsigned int procmsg_PINGREQ_client(unsigned char* buf, unsigned int size, void* ptr); +unsigned int procmsg_PINGREP_client(unsigned char* buf, unsigned int size, void* ptr); +unsigned int procmsg_PINGREQ_node(unsigned char* buf, unsigned int size, void* ptr); +unsigned int procmsg_PINGREP_node(unsigned char* buf, unsigned int size, void* ptr); -struct cclink* cclink_list_add(struct client *clr,struct client *cle); +struct cclink* cclink_list_add(struct client *clr, struct client *cle); struct cclink* cclink_list_search(const unsigned char *caller_id, const unsigned char *callee_id); struct cclink* cclink_list_findwaitsearch(const unsigned char *callee_id); -void cclink_list_addlocal(struct client *clr,struct client *cle); +void cclink_list_addlocal(struct client *clr, struct client *cle); 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, SOCKET s); void cclink_attach_remotecle_node(struct cclink *ccl, struct nodelink *callee_node); void cclink_list_delete_by_client(struct client *cl); @@ -106,10 +106,10 @@ void cclink_list_delete_by_nodelink(struct nodelink *node); struct client* client_tree_search(const unsigned char *id);// struct client *client_list_addnew(struct newconn *nc); -struct PICA_proto_msg* client_wbuf_push(struct client *c,unsigned int msgid,unsigned int size); +struct PICA_proto_msg* client_wbuf_push(struct client *c, unsigned int msgid, unsigned int size); int client_rbuf_grow(struct client *c); -struct PICA_proto_msg* nodelink_wbuf_push(struct nodelink *nl,unsigned int msgid,unsigned int size); +struct PICA_proto_msg* nodelink_wbuf_push(struct nodelink *nl, unsigned int msgid, unsigned int size); int nodelink_rbuf_grow(struct nodelink *nl); int nodelink_attach_nodeaddr(struct nodelink *nl, unsigned int addr_type, void* nodeaddr, unsigned int nodeaddr_size); struct nodelink *nodelink_list_addnew(struct newconn *nc); @@ -118,681 +118,687 @@ struct nodelink *nodelink_search_by_ipv4addr(in_addr_t addr, in_port_t port); /* void newconn_close(struct newconn* nc); void newconn_free(struct newconn* nc); -struct newconn* newconn_add(struct newconn *ncs,int *pos); +struct newconn* newconn_add(struct newconn *ncs, int *pos); void PICA_node_joinskynet(const char* addrlistfilename, const char *my_addr); -//описание формата сообщений, которые могут приходить _ОТ_ клиентов по управляющему защищенному соединению +//описание формата сообщений, которые могут приходить _ОТ_ клиентов по управляющему защищенному соединению #define MSGINFO_MSGSNUM(arr) (sizeof(arr)/sizeof(struct PICA_msginfo)) -struct PICA_msginfo _msginfo_comm[]={ -{PICA_PROTO_CONNREQOUTG, PICA_MSG_FIXED_SIZE, PICA_PROTO_CONNREQOUTG_SIZE, procmsg_CONNREQOUTG}, -{PICA_PROTO_CONNALLOW, PICA_MSG_FIXED_SIZE, PICA_PROTO_CONNALLOW_SIZE, procmsg_CONNALLOW}, -{PICA_PROTO_CONNDENY, PICA_MSG_FIXED_SIZE, PICA_PROTO_CONNDENY_SIZE, procmsg_CONNDENY}, -{PICA_PROTO_CLNODELISTREQ, PICA_MSG_FIXED_SIZE, PICA_PROTO_CLNODELISTREQ_SIZE, procmsg_NODELISTREQ}, -{PICA_PROTO_PINGREQ, PICA_MSG_FIXED_SIZE,PICA_PROTO_PINGREQ_SIZE, procmsg_PINGREQ_client}, -{PICA_PROTO_PINGREP, PICA_MSG_FIXED_SIZE,PICA_PROTO_PINGREP_SIZE, procmsg_PINGREP_client} +struct PICA_msginfo _msginfo_comm[] = +{ + {PICA_PROTO_CONNREQOUTG, PICA_MSG_FIXED_SIZE, PICA_PROTO_CONNREQOUTG_SIZE, procmsg_CONNREQOUTG}, + {PICA_PROTO_CONNALLOW, PICA_MSG_FIXED_SIZE, PICA_PROTO_CONNALLOW_SIZE, procmsg_CONNALLOW}, + {PICA_PROTO_CONNDENY, PICA_MSG_FIXED_SIZE, PICA_PROTO_CONNDENY_SIZE, procmsg_CONNDENY}, + {PICA_PROTO_CLNODELISTREQ, PICA_MSG_FIXED_SIZE, PICA_PROTO_CLNODELISTREQ_SIZE, procmsg_NODELISTREQ}, + {PICA_PROTO_PINGREQ, PICA_MSG_FIXED_SIZE, PICA_PROTO_PINGREQ_SIZE, procmsg_PINGREQ_client}, + {PICA_PROTO_PINGREP, PICA_MSG_FIXED_SIZE, PICA_PROTO_PINGREP_SIZE, procmsg_PINGREP_client} }; -struct PICA_msginfo _msginfo_node[]={ -{PICA_PROTO_INITRESPOK,PICA_MSG_FIXED_SIZE,PICA_PROTO_INITRESPOK_SIZE,procmsg_NODERESP}, -{PICA_PROTO_VERDIFFER ,PICA_MSG_FIXED_SIZE,PICA_PROTO_VERDIFFER_SIZE,procmsg_NODERESP}, -{PICA_PROTO_NEWNODE_IPV4 ,PICA_MSG_FIXED_SIZE,PICA_PROTO_NEWNODE_IPV4_SIZE,procmsg_NEWNODE}, -{PICA_PROTO_NODELISTREQ,PICA_MSG_FIXED_SIZE,PICA_PROTO_NODELISTREQ_SIZE,procmsg_NODELISTREQ}, -{PICA_PROTO_NODELIST,PICA_MSG_VAR_SIZE,PICA_MSG_VARSIZE_INT16,procmsg_NODELIST}, - -{PICA_PROTO_SEARCH,PICA_MSG_FIXED_SIZE,PICA_PROTO_SEARCH_SIZE,procmsg_SEARCH}, -{PICA_PROTO_N2NFOUND,PICA_MSG_FIXED_SIZE,PICA_PROTO_N2NFOUND_SIZE,procmsg_N2NFOUND}, -{PICA_PROTO_N2NFOUNDCACHE,PICA_MSG_VAR_SIZE,PICA_MSG_VARSIZE_INT16,procmsg_N2NFOUND}, -{PICA_PROTO_N2NCONNREQOUTG,PICA_MSG_FIXED_SIZE,PICA_PROTO_N2NCONNREQOUTG_SIZE,procmsg_N2NCONNREQOUTG}, -{PICA_PROTO_N2NALLOW,PICA_MSG_FIXED_SIZE,PICA_PROTO_N2NALLOW_SIZE,procmsg_N2NALLOW}, -{PICA_PROTO_N2NNOTFOUND,PICA_MSG_FIXED_SIZE,PICA_PROTO_N2NNOTFOUND_SIZE,procmsg_N2NNOTFOUND}, -{PICA_PROTO_N2NMSG,PICA_MSG_VAR_SIZE,PICA_MSG_VARSIZE_INT16,procmsg_N2NMSG}, -{PICA_PROTO_PINGREQ, PICA_MSG_FIXED_SIZE,PICA_PROTO_PINGREQ_SIZE, procmsg_PINGREQ_node}, -{PICA_PROTO_PINGREP, PICA_MSG_FIXED_SIZE,PICA_PROTO_PINGREP_SIZE, procmsg_PINGREP_node} +struct PICA_msginfo _msginfo_node[] = +{ + {PICA_PROTO_INITRESPOK, PICA_MSG_FIXED_SIZE, PICA_PROTO_INITRESPOK_SIZE, procmsg_NODERESP}, + {PICA_PROTO_VERDIFFER , PICA_MSG_FIXED_SIZE, PICA_PROTO_VERDIFFER_SIZE, procmsg_NODERESP}, + {PICA_PROTO_NEWNODE_IPV4 , PICA_MSG_FIXED_SIZE, PICA_PROTO_NEWNODE_IPV4_SIZE, procmsg_NEWNODE}, + {PICA_PROTO_NODELISTREQ, PICA_MSG_FIXED_SIZE, PICA_PROTO_NODELISTREQ_SIZE, procmsg_NODELISTREQ}, + {PICA_PROTO_NODELIST, PICA_MSG_VAR_SIZE, PICA_MSG_VARSIZE_INT16, procmsg_NODELIST}, + + {PICA_PROTO_SEARCH, PICA_MSG_FIXED_SIZE, PICA_PROTO_SEARCH_SIZE, procmsg_SEARCH}, + {PICA_PROTO_N2NFOUND, PICA_MSG_FIXED_SIZE, PICA_PROTO_N2NFOUND_SIZE, procmsg_N2NFOUND}, + {PICA_PROTO_N2NFOUNDCACHE, PICA_MSG_VAR_SIZE, PICA_MSG_VARSIZE_INT16, procmsg_N2NFOUND}, + {PICA_PROTO_N2NCONNREQOUTG, PICA_MSG_FIXED_SIZE, PICA_PROTO_N2NCONNREQOUTG_SIZE, procmsg_N2NCONNREQOUTG}, + {PICA_PROTO_N2NALLOW, PICA_MSG_FIXED_SIZE, PICA_PROTO_N2NALLOW_SIZE, procmsg_N2NALLOW}, + {PICA_PROTO_N2NNOTFOUND, PICA_MSG_FIXED_SIZE, PICA_PROTO_N2NNOTFOUND_SIZE, procmsg_N2NNOTFOUND}, + {PICA_PROTO_N2NMSG, PICA_MSG_VAR_SIZE, PICA_MSG_VARSIZE_INT16, procmsg_N2NMSG}, + {PICA_PROTO_PINGREQ, PICA_MSG_FIXED_SIZE, PICA_PROTO_PINGREQ_SIZE, procmsg_PINGREQ_node}, + {PICA_PROTO_PINGREP, PICA_MSG_FIXED_SIZE, PICA_PROTO_PINGREP_SIZE, procmsg_PINGREP_node} }; -struct PICA_msginfo _msginfo_newconn[]={ -{PICA_PROTO_INITREQ,PICA_MSG_FIXED_SIZE,PICA_PROTO_INITREQ_SIZE,procmsg_INITREQ}, -{PICA_PROTO_CONNID,PICA_MSG_FIXED_SIZE,PICA_PROTO_CONNID_SIZE,procmsg_CONNID}, -{PICA_PROTO_NODECONNREQ,PICA_MSG_FIXED_SIZE,PICA_PROTO_NODECONNREQ_SIZE,procmsg_NODECONNREQ} +struct PICA_msginfo _msginfo_newconn[] = +{ + {PICA_PROTO_INITREQ, PICA_MSG_FIXED_SIZE, PICA_PROTO_INITREQ_SIZE, procmsg_INITREQ}, + {PICA_PROTO_CONNID, PICA_MSG_FIXED_SIZE, PICA_PROTO_CONNID_SIZE, procmsg_CONNID}, + {PICA_PROTO_NODECONNREQ, PICA_MSG_FIXED_SIZE, PICA_PROTO_NODECONNREQ_SIZE, procmsg_NODECONNREQ} }; static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) -{ //return 1 for self-signed certificates -char buf[256]; -X509 *err_cert; -int err, depth; +{ + //return 1 for self-signed certificates + char buf[256]; + X509 *err_cert; + int err, depth; -err_cert = X509_STORE_CTX_get_current_cert(ctx); -err = X509_STORE_CTX_get_error(ctx); -depth = X509_STORE_CTX_get_error_depth(ctx); + err_cert = X509_STORE_CTX_get_current_cert(ctx); + err = X509_STORE_CTX_get_error(ctx); + depth = X509_STORE_CTX_get_error_depth(ctx); -X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256); + X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256); -if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && depth == 0) - preverify_ok = 1; + if (err == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT && depth == 0) + preverify_ok = 1; -if (!preverify_ok) -{ -PICA_info("certificate verification error:num=%d:%s:depth=%d:%s\n", err, X509_verify_cert_error_string(err), depth, buf); -} + if (!preverify_ok) + { + PICA_info("certificate verification error:num=%d:%s:depth=%d:%s\n", err, X509_verify_cert_error_string(err), depth, buf); + } - return preverify_ok; + return preverify_ok; } -unsigned int procmsg_INITREQ(unsigned char* buf,unsigned int size,void* ptr) +unsigned int procmsg_INITREQ(unsigned char* buf, unsigned int size, void* ptr) { -struct newconn *nc=(struct newconn*)ptr; -struct PICA_proto_msg *mp; + struct newconn *nc = (struct newconn*)ptr; + struct PICA_proto_msg *mp; -PICA_debug1("received INITREQ"); + PICA_debug1("received INITREQ"); -if (buf[2]==PICA_PROTO_VER_HIGH && buf[3]==PICA_PROTO_VER_LOW) + if (buf[2] == PICA_PROTO_VER_HIGH && buf[3] == PICA_PROTO_VER_LOW) { - struct client *c; - c=client_list_addnew(nc); - if (!c) - return 0; - - newconn_free(nc); + struct client *c; + c = client_list_addnew(nc); + if (!c) + return 0; + + newconn_free(nc); - if ((mp = client_wbuf_push(c,PICA_PROTO_INITRESPOK,PICA_PROTO_INITRESPOK_SIZE))) + if ((mp = client_wbuf_push(c, PICA_PROTO_INITRESPOK, PICA_PROTO_INITRESPOK_SIZE))) { - mp->tail[0]='O'; - mp->tail[1]='K'; + mp->tail[0] = 'O'; + mp->tail[1] = 'K'; } - - c->state=PICA_CLSTATE_SENDINGRESP; + + c->state = PICA_CLSTATE_SENDINGRESP; }///////---------<<<<<<<<<<< new client -else + else { - //// PICA_PROTO_VERDIFFER - send(nc->sck,msg_VERDIFFER,msg_VERDIFFER_len,0); + //// PICA_PROTO_VERDIFFER + send(nc->sck, msg_VERDIFFER, msg_VERDIFFER_len, 0); - if (buf[2] > PICA_PROTO_VER_HIGH || (buf[2] == PICA_PROTO_VER_HIGH && buf[3] > PICA_PROTO_VER_LOW)) + if (buf[2] > PICA_PROTO_VER_HIGH || (buf[2] == PICA_PROTO_VER_HIGH && buf[3] > PICA_PROTO_VER_LOW)) { - PICA_warn("Client has newer protocol version than node. Please check if update for pica-node is available"); + PICA_warn("Client has newer protocol version than node. Please check if update for pica-node is available"); } - else + else { - PICA_info("Client has older protocol version. Disconnecting ..."); + PICA_info("Client has older protocol version. Disconnecting ..."); } - return 0; + return 0; } -return 1; + return 1; } -unsigned int procmsg_CONNID(unsigned char* buf,unsigned int size,void* ptr) +unsigned int procmsg_CONNID(unsigned char* buf, unsigned int size, void* ptr) { -struct PICA_proto_msg *mp; -struct newconn *nc=(struct newconn*)ptr; -unsigned char *caller_id, *callee_id; -struct cclink *link; + struct PICA_proto_msg *mp; + struct newconn *nc = (struct newconn*)ptr; + unsigned char *caller_id, *callee_id; + struct cclink *link; -PICA_debug1("received CONNID"); + PICA_debug1("received CONNID"); -caller_id = buf + 2; -callee_id = buf + 2 + PICA_ID_SIZE; + caller_id = buf + 2; + callee_id = buf + 2 + PICA_ID_SIZE; -{ -char caller_id_buf[2 * PICA_ID_SIZE], callee_id_buf[2 * PICA_ID_SIZE]; -PICA_debug1("CONNID: caller_id=%s callee_id=%s",PICA_id_to_base64(caller_id, caller_id_buf),PICA_id_to_base64(callee_id, callee_id_buf)); -} + { + char caller_id_buf[2 * PICA_ID_SIZE], callee_id_buf[2 * PICA_ID_SIZE]; + PICA_debug1("CONNID: caller_id=%s callee_id=%s", PICA_id_to_base64(caller_id, caller_id_buf), PICA_id_to_base64(callee_id, callee_id_buf)); + } -link=cclink_list_search(caller_id, callee_id); + link = cclink_list_search(caller_id, callee_id); -if (!link) + if (!link) { - PICA_debug3("corresponding cclink not found"); - return 0; + PICA_debug3("corresponding cclink not found"); + return 0; } -if (link->state!=PICA_CCLINK_LOCAL_WAITCONNCLE && link->state!=PICA_CCLINK_LOCAL_WAITCONNCLR - && link->state!=PICA_CCLINK_N2NCLR_WAITCONNCLR && link->state!=PICA_CCLINK_N2NCLE_WAITCONNCLE) + if (link->state != PICA_CCLINK_LOCAL_WAITCONNCLE && link->state != PICA_CCLINK_LOCAL_WAITCONNCLR + && link->state != PICA_CCLINK_N2NCLR_WAITCONNCLR && link->state != PICA_CCLINK_N2NCLE_WAITCONNCLE) { - PICA_debug2("found cclink is not in expected state"); - return 0; + PICA_debug2("found cclink is not in expected state"); + return 0; } - -{ -struct client *c; + + { + struct client *c; //проверка IP адреса. //IP адрес должен совпадать с адресом клиента в управляющем соединении -if (link->state==PICA_CCLINK_LOCAL_WAITCONNCLE || link->state==PICA_CCLINK_N2NCLE_WAITCONNCLE) - c = link->p2; -else if (link->state==PICA_CCLINK_LOCAL_WAITCONNCLR || link->state==PICA_CCLINK_N2NCLR_WAITCONNCLR) - c = link->p1; + if (link->state == PICA_CCLINK_LOCAL_WAITCONNCLE || link->state == PICA_CCLINK_N2NCLE_WAITCONNCLE) + c = link->p2; + else if (link->state == PICA_CCLINK_LOCAL_WAITCONNCLR || link->state == PICA_CCLINK_N2NCLR_WAITCONNCLR) + c = link->p1; -if (nc->addr.sin_addr.s_addr!=c->addr.sin_addr.s_addr) - { - PICA_warn("CONNID: IP check failed. IP address of sender does not match IP in c2n connection"); - return 0; + if (nc->addr.sin_addr.s_addr != c->addr.sin_addr.s_addr) + { + PICA_warn("CONNID: IP check failed. IP address of sender does not match IP in c2n connection"); + return 0; + } } -} -if (link->state==PICA_CCLINK_LOCAL_WAITCONNCLE) + if (link->state == PICA_CCLINK_LOCAL_WAITCONNCLE) { - if((mp = client_wbuf_push(link->p1,PICA_PROTO_FOUND,PICA_PROTO_FOUND_SIZE))) + if((mp = client_wbuf_push(link->p1, PICA_PROTO_FOUND, PICA_PROTO_FOUND_SIZE))) { - memcpy(mp->tail, callee_id, PICA_ID_SIZE); + memcpy(mp->tail, callee_id, PICA_ID_SIZE); } - else + else { - cclink_list_delete(link); - return 0; + cclink_list_delete(link); + return 0; } } -if (link->state==PICA_CCLINK_N2NCLE_WAITCONNCLE) + if (link->state == PICA_CCLINK_N2NCLE_WAITCONNCLE) { - if((mp = nodelink_wbuf_push(link->caller_node,PICA_PROTO_N2NALLOW,PICA_PROTO_N2NALLOW_SIZE))) + 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); + memcpy(mp->tail, caller_id, PICA_ID_SIZE); + memcpy(mp->tail + PICA_ID_SIZE, callee_id, PICA_ID_SIZE); } - else + else { - cclink_list_delete(link); - return 0; + cclink_list_delete(link); + return 0; } } -PICA_debug3("CONNID processed successfully"); -cclink_activate(link,nc->sck); -newconn_free(nc); -return 1; + PICA_debug3("CONNID processed successfully"); + cclink_activate(link, nc->sck); + newconn_free(nc); + return 1; } -unsigned int procmsg_NODECONNREQ(unsigned char* buf,unsigned int size,void* ptr) +unsigned int procmsg_NODECONNREQ(unsigned char* buf, unsigned int size, void* ptr) { -struct newconn *nc=(struct newconn*)ptr; -struct PICA_proto_msg *mp; + struct newconn *nc = (struct newconn*)ptr; + struct PICA_proto_msg *mp; -PICA_debug1("received NODECONNREQ"); + PICA_debug1("received NODECONNREQ"); -if (buf[2]==PICA_PROTO_VER_HIGH && - buf[3]==PICA_PROTO_VER_LOW) + if (buf[2] == PICA_PROTO_VER_HIGH && + buf[3] == PICA_PROTO_VER_LOW) { - ////-прием входящего подключения - //-------------------------- - struct nodelink *nl; - nl=nodelink_list_addnew(nc); - newconn_free(nc); - if (!nl) - return 0; + ////-прием входящего подключения + //-------------------------- + struct nodelink *nl; + nl = nodelink_list_addnew(nc); + newconn_free(nc); + if (!nl) + return 0; - if ((mp = nodelink_wbuf_push(nl,PICA_PROTO_INITRESPOK,PICA_PROTO_INITRESPOK_SIZE))) + if ((mp = nodelink_wbuf_push(nl, PICA_PROTO_INITRESPOK, PICA_PROTO_INITRESPOK_SIZE))) { - mp->tail[0]='O'; - mp->tail[1]='K'; + mp->tail[0] = 'O'; + mp->tail[1] = 'K'; } } -else + else { - //// PICA_PROTO_VERDIFFER - send(nc->sck,msg_VERDIFFER,msg_VERDIFFER_len,0); + //// PICA_PROTO_VERDIFFER + send(nc->sck, msg_VERDIFFER, msg_VERDIFFER_len, 0); - if (buf[2] > PICA_PROTO_VER_HIGH || (buf[2] == PICA_PROTO_VER_HIGH && buf[3] > PICA_PROTO_VER_LOW)) + if (buf[2] > PICA_PROTO_VER_HIGH || (buf[2] == PICA_PROTO_VER_HIGH && buf[3] > PICA_PROTO_VER_LOW)) { - PICA_warn("Node %s has newer protocol version [%u, %u]. Please check if update for pica-node is available", - inet_ntoa(nc->addr.sin_addr), buf[2], buf[3]); + PICA_warn("Node %s has newer protocol version [%u, %u]. Please check if update for pica-node is available", + inet_ntoa(nc->addr.sin_addr), buf[2], buf[3]); } - else + else { - PICA_info("Node %s has older protocol version. Disconnecting ...", inet_ntoa(nc->addr.sin_addr)); + PICA_info("Node %s has older protocol version. Disconnecting ...", inet_ntoa(nc->addr.sin_addr)); } - return 0; + return 0; } -return 1; + return 1; } void mapfunc_sendsearchreq(struct nodelink *p, const unsigned char *id) { -struct PICA_proto_msg *mp; + struct PICA_proto_msg *mp; -mp=nodelink_wbuf_push(p,PICA_PROTO_SEARCH,PICA_PROTO_SEARCH_SIZE); + mp = nodelink_wbuf_push(p, PICA_PROTO_SEARCH, PICA_PROTO_SEARCH_SIZE); -if (mp) - memcpy(mp->tail, id, PICA_ID_SIZE); + if (mp) + memcpy(mp->tail, id, PICA_ID_SIZE); } int nodelink_send_searchreq(const unsigned char *id) { -if (!nodelink_list_count) - return 0; + if (!nodelink_list_count) + return 0; -LISTMAP(nodelink,nodelink,mapfunc_sendsearchreq,id); - -return 1; + LISTMAP(nodelink, nodelink, mapfunc_sendsearchreq, id); + + return 1; } -unsigned int procmsg_CONNREQOUTG(unsigned char* buf,unsigned int size,void* ptr) +unsigned int procmsg_CONNREQOUTG(unsigned char* buf, unsigned int size, void* ptr) { -struct client *i,*o;//i - указатель на вызывающего клиента, o - вызываемого(если найден) -unsigned char *callee_id; -struct PICA_proto_msg *mp; + struct client *i, *o; //i - указатель на вызывающего клиента, o - вызываемого(если найден) + unsigned char *callee_id; + struct PICA_proto_msg *mp; -i=(struct client *)ptr; + i = (struct client *)ptr; -PICA_debug1("received CONNREQOUTG from %s", PICA_id_to_base64(i->id, NULL)); + PICA_debug1("received CONNREQOUTG from %s", PICA_id_to_base64(i->id, NULL)); -callee_id = buf+2; + callee_id = buf + 2; -if ((o = client_tree_search(callee_id))) + if ((o = client_tree_search(callee_id))) { - if (cclink_list_search(i->id, callee_id)) + if (cclink_list_search(i->id, callee_id)) { - PICA_info("duplicate request for existing c2c connection is ignored"); - return 1; + PICA_info("duplicate request for existing c2c connection is ignored"); + return 1; } - if (memcmp(i->id, callee_id, PICA_ID_SIZE) == 0) + if (memcmp(i->id, callee_id, PICA_ID_SIZE) == 0) { - PICA_info("request to create c2c connection to self is ignored"); - return 1; + PICA_info("request to create c2c connection to self is ignored"); + return 1; } - //отправить o _CONNREQINC - if ((mp = client_wbuf_push(o,PICA_PROTO_CONNREQINC,PICA_PROTO_CONNREQINC_SIZE))) + //отправить o _CONNREQINC + if ((mp = client_wbuf_push(o, PICA_PROTO_CONNREQINC, PICA_PROTO_CONNREQINC_SIZE))) { - memcpy(mp->tail, i->id, PICA_ID_SIZE); - cclink_list_addlocal(i,o); - - o->tmst = time(0); - o->disconnect_ticking = 1;//if client does not reply in given time period, client is disconnected - return 1; + memcpy(mp->tail, i->id, PICA_ID_SIZE); + cclink_list_addlocal(i, o); + + o->tmst = time(0); + o->disconnect_ticking = 1;//if client does not reply in given time period, client is disconnected + return 1; } - - return 1;//сообщение отправить не удалось, но все равно возвращаем 1 + + return 1;//сообщение отправить не удалось, но все равно возвращаем 1 } - -if (cclink_list_findwaitsearch(callee_id)/*search request for this id is already in progress*/ - || nodelink_send_searchreq(callee_id) /*make new search*/) + + if (cclink_list_findwaitsearch(callee_id)/*search request for this id is already in progress*/ + || nodelink_send_searchreq(callee_id) /*make new search*/) { - cclink_list_addn2nclr(i,callee_id); - return 1; + cclink_list_addn2nclr(i, callee_id); + return 1; } - + //отправить i _NOTFOUND -if ((mp = client_wbuf_push(i,PICA_PROTO_NOTFOUND,PICA_PROTO_NOTFOUND_SIZE))) + if ((mp = client_wbuf_push(i, PICA_PROTO_NOTFOUND, PICA_PROTO_NOTFOUND_SIZE))) { - memcpy(mp->tail, callee_id, PICA_ID_SIZE); + memcpy(mp->tail, callee_id, PICA_ID_SIZE); } -return 1; + return 1; } -unsigned int procmsg_CONNALLOW(unsigned char* buf,unsigned int size,void* ptr) +unsigned int procmsg_CONNALLOW(unsigned char* buf, unsigned int size, void* ptr) { -struct client *callee; -struct cclink *link; -unsigned char *caller_id; + struct client *callee; + struct cclink *link; + unsigned char *caller_id; -PICA_debug1("received CONALLOW"); + PICA_debug1("received CONALLOW"); -callee=(struct client *)ptr; -caller_id = buf+2; + callee = (struct client *)ptr; + caller_id = buf + 2; -callee->disconnect_ticking = 0; -callee->tmst = time(0); + callee->disconnect_ticking = 0; + callee->tmst = time(0); -link=cclink_list_search(caller_id, callee->id); + link = cclink_list_search(caller_id, callee->id); -if (!link) - return 0; + if (!link) + return 0; -if (link->state!=PICA_CCLINK_LOCAL_WAITREP && - link->state!=PICA_CCLINK_N2NCLE_WAITREP) - return 0; + if (link->state != PICA_CCLINK_LOCAL_WAITREP && + link->state != PICA_CCLINK_N2NCLE_WAITREP) + return 0; -cclink_setwaitconn(link); + cclink_setwaitconn(link); -return 1; + return 1; } -unsigned int procmsg_CONNDENY(unsigned char* buf,unsigned int size,void* ptr) +unsigned int procmsg_CONNDENY(unsigned char* buf, unsigned int size, void* ptr) { -struct client *caller,*callee; -struct cclink *link; -unsigned char *caller_id; -struct PICA_proto_msg *mp; + struct client *caller, *callee; + struct cclink *link; + unsigned char *caller_id; + struct PICA_proto_msg *mp; -PICA_debug1("received CONNDENY"); + PICA_debug1("received CONNDENY"); -callee=(struct client *)ptr; -caller_id = buf+2; + callee = (struct client *)ptr; + caller_id = buf + 2; -callee->disconnect_ticking = 0; -callee->tmst = time(0); + callee->disconnect_ticking = 0; + callee->tmst = time(0); -link=cclink_list_search(caller_id,callee->id); + link = cclink_list_search(caller_id, callee->id); -if (!link) - return 0; + if (!link) + return 0; -caller = link -> p1;//check for NULL if not LOCAL + caller = link -> p1;//check for NULL if not LOCAL -if (link->state!=PICA_CCLINK_LOCAL_WAITREP && - link->state!=PICA_CCLINK_N2NCLE_WAITREP) + if (link->state != PICA_CCLINK_LOCAL_WAITREP && + link->state != PICA_CCLINK_N2NCLE_WAITREP) { - cclink_list_delete(link); - return 0; + cclink_list_delete(link); + return 0; } -if (link->state==PICA_CCLINK_LOCAL_WAITREP) + if (link->state == PICA_CCLINK_LOCAL_WAITREP) { - //отправить caller _NOTFOUND - if ((mp = client_wbuf_push(caller,PICA_PROTO_NOTFOUND,PICA_PROTO_NOTFOUND_SIZE))) + //отправить caller _NOTFOUND + if ((mp = client_wbuf_push(caller, PICA_PROTO_NOTFOUND, PICA_PROTO_NOTFOUND_SIZE))) { - memcpy(mp->tail, callee->id, PICA_ID_SIZE); + memcpy(mp->tail, callee->id, PICA_ID_SIZE); } } -else if (link->state==PICA_CCLINK_N2NCLE_WAITREP) + else if (link->state == PICA_CCLINK_N2NCLE_WAITREP) { - //отправить caller N2NNOTFOUND - if ((mp = nodelink_wbuf_push(link->caller_node,PICA_PROTO_N2NNOTFOUND,PICA_PROTO_N2NNOTFOUND_SIZE))) + //отправить caller N2NNOTFOUND + if ((mp = nodelink_wbuf_push(link->caller_node, PICA_PROTO_N2NNOTFOUND, PICA_PROTO_N2NNOTFOUND_SIZE))) { - memcpy(mp->tail, caller_id, PICA_ID_SIZE); - memcpy(mp->tail + PICA_ID_SIZE, callee->id, PICA_ID_SIZE); + memcpy(mp->tail, caller_id, PICA_ID_SIZE); + memcpy(mp->tail + PICA_ID_SIZE, callee->id, PICA_ID_SIZE); } } -cclink_list_delete(link); + cclink_list_delete(link); -return 1; + return 1; } -unsigned int procmsg_PINGREQ_client(unsigned char* buf,unsigned int size,void* ptr) +unsigned int procmsg_PINGREQ_client(unsigned char* buf, unsigned int size, void* ptr) { -struct client *c = (struct client*)ptr; -struct PICA_proto_msg *mp; + struct client *c = (struct client*)ptr; + struct PICA_proto_msg *mp; -PICA_debug3("PINGREQ"); + PICA_debug3("PINGREQ"); -if ((mp = client_wbuf_push(c, PICA_PROTO_PINGREP, PICA_PROTO_PINGREP_SIZE))) + if ((mp = client_wbuf_push(c, PICA_PROTO_PINGREP, PICA_PROTO_PINGREP_SIZE))) { - RAND_bytes(mp->tail, 2); + RAND_bytes(mp->tail, 2); } -else - return 0; + else + return 0; -return 1; + return 1; } -unsigned int procmsg_PINGREP_client(unsigned char* buf,unsigned int size,void* ptr) +unsigned int procmsg_PINGREP_client(unsigned char* buf, unsigned int size, void* ptr) { -struct client *c = (struct client*)ptr; + struct client *c = (struct client*)ptr; -PICA_debug3("PINGREP c2n"); + PICA_debug3("PINGREP c2n"); -c->disconnect_ticking = 0; -c->tmst = time(0); + c->disconnect_ticking = 0; + c->tmst = time(0); -return 1; + return 1; } -unsigned int procmsg_PINGREQ_node(unsigned char* buf,unsigned int size,void* ptr) +unsigned int procmsg_PINGREQ_node(unsigned char* buf, unsigned int size, void* ptr) { -struct nodelink *n=(struct nodelink *)ptr; -struct PICA_proto_msg *mp; + struct nodelink *n = (struct nodelink *)ptr; + struct PICA_proto_msg *mp; -PICA_debug3("PINGREQ"); + PICA_debug3("PINGREQ"); -if ((mp = nodelink_wbuf_push(n, PICA_PROTO_PINGREP, PICA_PROTO_PINGREP_SIZE))) + if ((mp = nodelink_wbuf_push(n, PICA_PROTO_PINGREP, PICA_PROTO_PINGREP_SIZE))) { - RAND_bytes(mp->tail, 2); + RAND_bytes(mp->tail, 2); } -else - return 0; + else + return 0; -return 1; + return 1; } -unsigned int procmsg_PINGREP_node(unsigned char* buf,unsigned int size,void* ptr) +unsigned int procmsg_PINGREP_node(unsigned char* buf, unsigned int size, void* ptr) { -struct nodelink *n=(struct nodelink *)ptr; + struct nodelink *n = (struct nodelink *)ptr; -PICA_debug3("PINGREP n2n"); + PICA_debug3("PINGREP n2n"); -n->disconnect_ticking = 0; -n->tmst = time(0); + n->disconnect_ticking = 0; + n->tmst = time(0); -return 1; + return 1; } -unsigned int procmsg_NODERESP(unsigned char* buf,unsigned int size,void* ptr) +unsigned int procmsg_NODERESP(unsigned char* buf, unsigned int size, void* ptr) { -struct nodelink *n=(struct nodelink *)ptr; -struct PICA_proto_msg *mp; + struct nodelink *n = (struct nodelink *)ptr; + struct PICA_proto_msg *mp; -PICA_debug1("received NODERESP"); + PICA_debug1("received NODERESP"); -switch(buf[0]) + switch(buf[0]) { case PICA_PROTO_INITRESPOK: - if (buf[2]!='O' || buf[3]!='K') - return 0; + if (buf[2] != 'O' || buf[3] != 'K') + return 0; - -mp = nodelink_wbuf_push(n, PICA_PROTO_NEWNODE_IPV4, PICA_PROTO_NEWNODE_IPV4_SIZE);//IPv6 -if (mp) - { - *((in_addr_t*)(mp->tail))=inet_addr(nodecfg.announced_addr); - *((in_port_t*)(mp->tail+4))=(nodecfg.listen_port ? htons(atoi(nodecfg.listen_port)) : htons(PICA_COMM_PORT));//CONF; - } -else - return 0; -mp = nodelink_wbuf_push(n, PICA_PROTO_NODELISTREQ, PICA_PROTO_NODELISTREQ_SIZE); -if (mp) - { - RAND_bytes(mp->tail, 2); - } -else - return 0; - - break; + mp = nodelink_wbuf_push(n, PICA_PROTO_NEWNODE_IPV4, PICA_PROTO_NEWNODE_IPV4_SIZE);//IPv6 + if (mp) + { + *((in_addr_t*)(mp->tail)) = inet_addr(nodecfg.announced_addr); + *((in_port_t*)(mp->tail + 4)) = (nodecfg.listen_port ? htons(atoi(nodecfg.listen_port)) : htons(PICA_COMM_PORT)); //CONF; + } + else + return 0; + + mp = nodelink_wbuf_push(n, PICA_PROTO_NODELISTREQ, PICA_PROTO_NODELISTREQ_SIZE); + if (mp) + { + RAND_bytes(mp->tail, 2); + } + else + return 0; + + break; case PICA_PROTO_VERDIFFER: - if (buf[2]> PICA_PROTO_VER_HIGH || (buf[3]> PICA_PROTO_VER_LOW && buf[2]== PICA_PROTO_VER_HIGH)) + if (buf[2] > PICA_PROTO_VER_HIGH || (buf[3] > PICA_PROTO_VER_LOW && buf[2] == PICA_PROTO_VER_HIGH)) { - PICA_warn("make update of node software - peer node has newer protocol version"); + PICA_warn("make update of node software - peer node has newer protocol version"); } - else - {//peer node has older software version - PICA_info("peer node has older protocol version"); + else + { + //peer node has older software version + PICA_info("peer node has older protocol version"); } - return 0; - break; + return 0; + break; } -return 1; + return 1; } -unsigned int procmsg_NEWNODE(unsigned char* buf,unsigned int size,void* ptr) +unsigned int procmsg_NEWNODE(unsigned char* buf, unsigned int size, void* ptr) { -struct nodelink *n=(struct nodelink *)ptr; -struct PICA_nodeaddr na; + struct nodelink *n = (struct nodelink *)ptr; + struct PICA_nodeaddr na; -PICA_debug1("received NEWNODE"); + PICA_debug1("received NEWNODE"); -switch (buf[0]) - { - case PICA_PROTO_NEWNODE_IPV4: - PICA_debug1("NEWNODE_IPV4: ip %.16s port %hu\n",inet_ntoa(*(struct in_addr*)(buf+2)),ntohs(*(in_port_t*)(buf+6))); + switch (buf[0]) { - struct PICA_nodeaddr_ipv4 na_ipv4; - - na_ipv4.magick=PICA_PROTO_NEWNODE_IPV4; - na_ipv4.addr=*(in_addr_t*)(buf+2); - na_ipv4.port=*(in_port_t*)(buf+6); - - if (nodelink_search_by_ipv4addr(na_ipv4.addr, na_ipv4.port)) //connection with this node is already established - { - PICA_debug1("disconnecting node %.16s:%hu - connection with this node is already established", inet_ntoa(*(struct in_addr*)&na_ipv4.addr), ntohs(na_ipv4.port)); - return 0; - } - - if (nodecfg.disable_reserved_addrs && PICA_is_reserved_addr_ipv4(na_ipv4.addr)) + case PICA_PROTO_NEWNODE_IPV4: + PICA_debug1("NEWNODE_IPV4: ip %.16s port %hu\n", inet_ntoa(*(struct in_addr*)(buf + 2)), ntohs(*(in_port_t*)(buf + 6))); { - PICA_debug1("disconnecting node %.16s:%hu - private IP ranges are rejected by node configuration", - inet_ntoa(*(struct in_addr*)&na_ipv4.addr), ntohs(na_ipv4.port) - ); - return 0; + struct PICA_nodeaddr_ipv4 na_ipv4; + + na_ipv4.magick = PICA_PROTO_NEWNODE_IPV4; + na_ipv4.addr = *(in_addr_t*)(buf + 2); + na_ipv4.port = *(in_port_t*)(buf + 6); + + if (nodelink_search_by_ipv4addr(na_ipv4.addr, na_ipv4.port)) //connection with this node is already established + { + PICA_debug1("disconnecting node %.16s:%hu - connection with this node is already established", inet_ntoa(*(struct in_addr*)&na_ipv4.addr), ntohs(na_ipv4.port)); + return 0; + } + + if (nodecfg.disable_reserved_addrs && PICA_is_reserved_addr_ipv4(na_ipv4.addr)) + { + PICA_debug1("disconnecting node %.16s:%hu - private IP ranges are rejected by node configuration", + inet_ntoa(*(struct in_addr*)&na_ipv4.addr), ntohs(na_ipv4.port) + ); + return 0; + } + + sprintf(na.addr, "%.16s", inet_ntoa(*(struct in_addr*)&na_ipv4.addr)); + na.port = ntohs(na_ipv4.port); + + //int nodelink_attach_nodeaddr(struct nodelink *nl, unsigned int addr_type, void* nodeaddr, unsigned int nodeaddr_size) + nodelink_attach_nodeaddr(n, na_ipv4.magick, &na_ipv4, sizeof(struct PICA_nodeaddr_ipv4)); } - - sprintf(na.addr,"%.16s",inet_ntoa(*(struct in_addr*)&na_ipv4.addr)); - na.port = ntohs(na_ipv4.port); - - //int nodelink_attach_nodeaddr(struct nodelink *nl, unsigned int addr_type, void* nodeaddr, unsigned int nodeaddr_size) - nodelink_attach_nodeaddr(n,na_ipv4.magick,&na_ipv4,sizeof(struct PICA_nodeaddr_ipv4)); - } - break; + break; case PICA_PROTO_NEWNODE_IPV6: - #warning "TO DO" - break; +#warning "TO DO" + break; case PICA_PROTO_NEWNODE_DNS: - #warning "TODO" - break; +#warning "TODO" + break; } -PICA_nodeaddr_save(nodecfg.nodes_db_file, &na);//CONF filename + PICA_nodeaddr_save(nodecfg.nodes_db_file, &na);//CONF filename -return 1; + return 1; } -unsigned int procmsg_NODELISTREQ(unsigned char* buf,unsigned int size,void* ptr) +unsigned int procmsg_NODELISTREQ(unsigned char* buf, unsigned int size, void* ptr) { -struct PICA_proto_msg *mp; -struct nodelink *nlp; -unsigned int nl_size=0; -struct nodelink *n=0; -struct client *c=0; -unsigned char *nl_buf = 0; + struct PICA_proto_msg *mp; + struct nodelink *nlp; + unsigned int nl_size = 0; + struct nodelink *n = 0; + struct client *c = 0; + unsigned char *nl_buf = 0; -PICA_debug1("received NODELISTREQ"); + PICA_debug1("received NODELISTREQ"); -switch(buf[0]) + switch(buf[0]) { case PICA_PROTO_CLNODELISTREQ: - c = (struct client *)ptr; - break; + c = (struct client *)ptr; + break; case PICA_PROTO_NODELISTREQ: - n = (struct nodelink *)ptr; - break; + n = (struct nodelink *)ptr; + break; } -nl_buf = (unsigned char*)malloc(65536); + nl_buf = (unsigned char*)malloc(65536); -if (!nl_buf) - return 0;//ERR + if (!nl_buf) + return 0;//ERR -{//TEMP FIXME CONF + { + //TEMP FIXME CONF //собственный адрес узла -nl_buf[nl_size]=PICA_PROTO_NEWNODE_IPV4; -*((in_addr_t*)(nl_buf+nl_size+1))=inet_addr(my_addr); -*((in_port_t*)(nl_buf+nl_size+5))=(nodecfg.listen_port ? htons(atoi(nodecfg.listen_port)) : htons(PICA_COMM_PORT));//CONF -nl_size+=PICA_PROTO_NODELIST_ITEM_IPV4_SIZE; -} - -nlp=nodelink_list_head; -while(nlp && nl_size < 65532)//MAP - { - switch(nlp->addr_type) - { - case PICA_PROTO_NEWNODE_IPV4: - if ( PICA_PROTO_NODELISTREQ == buf[0] && - ((struct PICA_nodeaddr_ipv4*)nlp->node_addr)->addr==((struct PICA_nodeaddr_ipv4*)n->node_addr)->addr && - ((struct PICA_nodeaddr_ipv4*)nlp->node_addr)->port==((struct PICA_nodeaddr_ipv4*)n->node_addr)->port ) - break;//exclude requester's address - - nl_buf[nl_size]=PICA_PROTO_NEWNODE_IPV4; - *((in_addr_t*)(nl_buf+nl_size+1)) = ((struct PICA_nodeaddr_ipv4*)nlp->node_addr)->addr; - *((in_port_t*)(nl_buf+nl_size+5)) = ((struct PICA_nodeaddr_ipv4*)nlp->node_addr)->port; - nl_size += PICA_PROTO_NODELIST_ITEM_IPV4_SIZE;//CONF - break; + nl_buf[nl_size] = PICA_PROTO_NEWNODE_IPV4; + *((in_addr_t*)(nl_buf + nl_size + 1)) = inet_addr(my_addr); + *((in_port_t*)(nl_buf + nl_size + 5)) = (nodecfg.listen_port ? htons(atoi(nodecfg.listen_port)) : htons(PICA_COMM_PORT)); //CONF + nl_size += PICA_PROTO_NODELIST_ITEM_IPV4_SIZE; + } + + nlp = nodelink_list_head; + while(nlp && nl_size < 65532)//MAP + { + switch(nlp->addr_type) + { + case PICA_PROTO_NEWNODE_IPV4: + if ( PICA_PROTO_NODELISTREQ == buf[0] && + ((struct PICA_nodeaddr_ipv4*)nlp->node_addr)->addr == ((struct PICA_nodeaddr_ipv4*)n->node_addr)->addr && + ((struct PICA_nodeaddr_ipv4*)nlp->node_addr)->port == ((struct PICA_nodeaddr_ipv4*)n->node_addr)->port ) + break;//exclude requester's address + + nl_buf[nl_size] = PICA_PROTO_NEWNODE_IPV4; + *((in_addr_t*)(nl_buf + nl_size + 1)) = ((struct PICA_nodeaddr_ipv4*)nlp->node_addr)->addr; + *((in_port_t*)(nl_buf + nl_size + 5)) = ((struct PICA_nodeaddr_ipv4*)nlp->node_addr)->port; + nl_size += PICA_PROTO_NODELIST_ITEM_IPV4_SIZE;//CONF + break; } -//#warning "set limit on list size, <65532 bytes!!!" - nlp = nlp->next; +//#warning "set limit on list size, <65532 bytes!!!" + nlp = nlp->next; } -switch(buf[0]) + switch(buf[0]) { case PICA_PROTO_CLNODELISTREQ: - mp = client_wbuf_push( c, PICA_PROTO_CLNODELIST, nl_size+4); - break; + mp = client_wbuf_push( c, PICA_PROTO_CLNODELIST, nl_size + 4); + break; case PICA_PROTO_NODELISTREQ: - mp = nodelink_wbuf_push( n, PICA_PROTO_NODELIST, nl_size+4); - break; + mp = nodelink_wbuf_push( n, PICA_PROTO_NODELIST, nl_size + 4); + break; } -if (mp) + if (mp) { - *((uint16_t*)mp->tail)=nl_size; - memcpy(mp->tail+2,nl_buf,nl_size); + *((uint16_t*)mp->tail) = nl_size; + memcpy(mp->tail + 2, nl_buf, nl_size); } -free(nl_buf); -return 1; + free(nl_buf); + return 1; } -unsigned int procmsg_NODELIST(unsigned char* buf,unsigned int size,void* ptr) +unsigned int procmsg_NODELIST(unsigned char* buf, unsigned int size, void* ptr) { -struct PICA_nodeaddr_ipv4 na_ipv4; + struct PICA_nodeaddr_ipv4 na_ipv4; -struct nodelink *n=(struct nodelink *)ptr; -unsigned int listsize=size-2-PICA_MSG_VARSIZE_INT16; -unsigned int listleft=listsize; + struct nodelink *n = (struct nodelink *)ptr; + unsigned int listsize = size - 2 - PICA_MSG_VARSIZE_INT16; + unsigned int listleft = listsize; -PICA_debug1("received NODELIST"); + PICA_debug1("received NODELIST"); -while(listleft) + while(listleft) { #warning "strict error checking!!! -- listleft overflow, unknown list items, check listleft >= possible item size" - if (listleft==listsize) //first entry, sender node's address + if (listleft == listsize) //first entry, sender node's address { - switch(buf[size-listleft]) + switch(buf[size - listleft]) { case PICA_PROTO_NEWNODE_IPV4: - na_ipv4.magick=PICA_PROTO_NEWNODE_IPV4; - na_ipv4.addr=*(in_addr_t*)(buf+size-listleft+1); - na_ipv4.port=*(in_port_t*)(buf+size-listleft+5); - nodelink_attach_nodeaddr(n,na_ipv4.magick,&na_ipv4,sizeof(struct PICA_nodeaddr_ipv4)); + na_ipv4.magick = PICA_PROTO_NEWNODE_IPV4; + na_ipv4.addr = *(in_addr_t*)(buf + size - listleft + 1); + na_ipv4.port = *(in_port_t*)(buf + size - listleft + 5); + nodelink_attach_nodeaddr(n, na_ipv4.magick, &na_ipv4, sizeof(struct PICA_nodeaddr_ipv4)); - listleft-=PICA_PROTO_NODELIST_ITEM_IPV4_SIZE; - break; + listleft -= PICA_PROTO_NODELIST_ITEM_IPV4_SIZE; + break; } - continue; + continue; } - else + else { - struct PICA_nodeaddr na; - //char addr[256]; - struct newconn nc; - struct nodelink *nlp; - int skip_save = 0; + struct PICA_nodeaddr na; + //char addr[256]; + struct newconn nc; + struct nodelink *nlp; + int skip_save = 0; - memset(na.addr,0,256); - memset(&nc,0,sizeof(struct newconn)); + memset(na.addr, 0, 256); + memset(&nc, 0, sizeof(struct newconn)); - switch(buf[size-listleft]) + switch(buf[size - listleft]) { case PICA_PROTO_NEWNODE_IPV4: - na_ipv4.magick=PICA_PROTO_NEWNODE_IPV4; - na_ipv4.addr=*(in_addr_t*)(buf+size-listleft+1); - na_ipv4.port=*(in_port_t*)(buf+size-listleft+5); + na_ipv4.magick = PICA_PROTO_NEWNODE_IPV4; + na_ipv4.addr = *(in_addr_t*)(buf + size - listleft + 1); + na_ipv4.port = *(in_port_t*)(buf + size - listleft + 5); - sprintf(na.addr,"%.16s",inet_ntoa(*(struct in_addr*)&na_ipv4.addr)); - na.port = ntohs(na_ipv4.port); - - //nodewait_start_connection(&na); + sprintf(na.addr, "%.16s", inet_ntoa(*(struct in_addr*)&na_ipv4.addr)); + na.port = ntohs(na_ipv4.port); + + //nodewait_start_connection(&na); // if (try_connect_to_node(na.addr,ntohs(na_ipv4.port),&nc)) // if (try_get_reply(&nc)) // { @@ -801,302 +807,302 @@ while(listleft) // nodelink_attach_nodeaddr(nlp,na_ipv4.magick,&na_ipv4,sizeof(struct PICA_nodeaddr_ipv4)); // PICA_debug1("LINKED NODE:%s\n",inet_ntoa(*(struct in_addr*)&na_ipv4.addr)); // } - - PICA_debug3("NODELIST item %.16s:%hu", inet_ntoa(*(struct in_addr*)&na_ipv4.addr), ntohs(na_ipv4.port)); - - if (nodecfg.disable_reserved_addrs && PICA_is_reserved_addr_ipv4(na_ipv4.addr)) - { - skip_save = 1; - PICA_debug1("Received NODELIST item %.16s:%hu is in private range, skipping", - inet_ntoa(*(struct in_addr*)&na_ipv4.addr), ntohs(na_ipv4.port) - ); - } - listleft-=PICA_PROTO_NODELIST_ITEM_IPV4_SIZE; - break; + + PICA_debug3("NODELIST item %.16s:%hu", inet_ntoa(*(struct in_addr*)&na_ipv4.addr), ntohs(na_ipv4.port)); + + if (nodecfg.disable_reserved_addrs && PICA_is_reserved_addr_ipv4(na_ipv4.addr)) + { + skip_save = 1; + PICA_debug1("Received NODELIST item %.16s:%hu is in private range, skipping", + inet_ntoa(*(struct in_addr*)&na_ipv4.addr), ntohs(na_ipv4.port) + ); + } + listleft -= PICA_PROTO_NODELIST_ITEM_IPV4_SIZE; + break; } - if (!skip_save) - PICA_nodeaddr_save(nodecfg.nodes_db_file, &na);//CONF filename + if (!skip_save) + PICA_nodeaddr_save(nodecfg.nodes_db_file, &na);//CONF filename } } -return 1; + return 1; } -unsigned int procmsg_N2NFOUND(unsigned char* buf,unsigned int size,void* ptr) +unsigned int procmsg_N2NFOUND(unsigned char* buf, unsigned int size, void* ptr) { -struct cclink *cc; -struct nodelink *n=(struct nodelink *)ptr; -unsigned char *callee_id = buf+2; -struct PICA_proto_msg *mp; + struct cclink *cc; + struct nodelink *n = (struct nodelink *)ptr; + unsigned char *callee_id = buf + 2; + struct PICA_proto_msg *mp; -PICA_debug1("received N2NFOUND"); + PICA_debug1("received N2NFOUND"); -while((cc = cclink_list_findwaitsearch(callee_id))) + while((cc = cclink_list_findwaitsearch(callee_id))) { - cclink_attach_remotecle_node(cc,n); - if((mp = nodelink_wbuf_push(n,PICA_PROTO_N2NCONNREQOUTG,PICA_PROTO_N2NCONNREQOUTG_SIZE))) + cclink_attach_remotecle_node(cc, n); + if((mp = nodelink_wbuf_push(n, PICA_PROTO_N2NCONNREQOUTG, PICA_PROTO_N2NCONNREQOUTG_SIZE))) { - memcpy(mp->tail, cc->caller_id, PICA_ID_SIZE); - memcpy(mp->tail + PICA_ID_SIZE, callee_id, PICA_ID_SIZE); - - } + memcpy(mp->tail, cc->caller_id, PICA_ID_SIZE); + memcpy(mp->tail + PICA_ID_SIZE, callee_id, PICA_ID_SIZE); + + } } -return 1; + return 1; } -unsigned int procmsg_SEARCH(unsigned char* buf,unsigned int size,void* ptr) +unsigned int procmsg_SEARCH(unsigned char* buf, unsigned int size, void* ptr) { -struct nodelink *n=(struct nodelink *)ptr; -unsigned char *callee_id = buf+2; -struct PICA_proto_msg *mp; -struct client *callee; + struct nodelink *n = (struct nodelink *)ptr; + unsigned char *callee_id = buf + 2; + struct PICA_proto_msg *mp; + struct client *callee; -PICA_debug1("received SEARCH"); + PICA_debug1("received SEARCH"); -if ((callee = client_tree_search(callee_id))) + if ((callee = client_tree_search(callee_id))) { - if ((mp = nodelink_wbuf_push(n,PICA_PROTO_N2NFOUND,PICA_PROTO_N2NFOUND_SIZE))) + if ((mp = nodelink_wbuf_push(n, PICA_PROTO_N2NFOUND, PICA_PROTO_N2NFOUND_SIZE))) { - memcpy(mp->tail, callee_id, PICA_ID_SIZE); + memcpy(mp->tail, callee_id, PICA_ID_SIZE); } } -return 1; + return 1; } -unsigned int procmsg_N2NCONNREQOUTG(unsigned char* buf,unsigned int size,void* ptr) +unsigned int procmsg_N2NCONNREQOUTG(unsigned char* buf, unsigned int size, void* ptr) { -struct nodelink *n=(struct nodelink *)ptr; -unsigned char *caller_id, *callee_id; -struct PICA_proto_msg *mp; -struct client *callee; + struct nodelink *n = (struct nodelink *)ptr; + unsigned char *caller_id, *callee_id; + struct PICA_proto_msg *mp; + struct client *callee; -PICA_debug1("received N2NCONNREQOUTG"); + PICA_debug1("received N2NCONNREQOUTG"); -caller_id = buf + 2; -callee_id = buf + 2 + PICA_ID_SIZE; + caller_id = buf + 2; + callee_id = buf + 2 + PICA_ID_SIZE; -if ((callee = client_tree_search(callee_id))) + if ((callee = client_tree_search(callee_id))) { - if ((mp = client_wbuf_push(callee,PICA_PROTO_CONNREQINC,PICA_PROTO_CONNREQINC_SIZE))) + if ((mp = client_wbuf_push(callee, PICA_PROTO_CONNREQINC, PICA_PROTO_CONNREQINC_SIZE))) { - memcpy(mp->tail, caller_id, PICA_ID_SIZE); - cclink_list_addn2ncle(caller_id, n, callee); + memcpy(mp->tail, caller_id, PICA_ID_SIZE); + cclink_list_addn2ncle(caller_id, n, callee); } } -else + else { - if ((mp = nodelink_wbuf_push(n,PICA_PROTO_N2NNOTFOUND,PICA_PROTO_N2NNOTFOUND_SIZE))) + if ((mp = nodelink_wbuf_push(n, PICA_PROTO_N2NNOTFOUND, PICA_PROTO_N2NNOTFOUND_SIZE))) { - memcpy(mp->tail, caller_id, PICA_ID_SIZE); - memcpy(mp->tail + PICA_ID_SIZE, callee_id, PICA_ID_SIZE); + memcpy(mp->tail, caller_id, PICA_ID_SIZE); + memcpy(mp->tail + PICA_ID_SIZE, callee_id, PICA_ID_SIZE); } } -return 1; + return 1; } -unsigned int procmsg_N2NALLOW(unsigned char* buf,unsigned int size,void* ptr) +unsigned int procmsg_N2NALLOW(unsigned char* buf, unsigned int size, void* ptr) { -struct nodelink *n=(struct nodelink *)ptr; -unsigned char *caller_id, *callee_id; -struct PICA_proto_msg *mp; -struct cclink *cc; + struct nodelink *n = (struct nodelink *)ptr; + unsigned char *caller_id, *callee_id; + struct PICA_proto_msg *mp; + struct cclink *cc; -PICA_debug1("received N2NALLOW"); + PICA_debug1("received N2NALLOW"); -caller_id = buf + 2; -callee_id = buf + 2 + PICA_ID_SIZE; + caller_id = buf + 2; + callee_id = buf + 2 + PICA_ID_SIZE; -cc = cclink_list_search(caller_id,callee_id); + cc = cclink_list_search(caller_id, callee_id); -if (cc) + if (cc) { - if ((mp = client_wbuf_push(cc->p1,PICA_PROTO_FOUND,PICA_PROTO_FOUND_SIZE))) + if ((mp = client_wbuf_push(cc->p1, PICA_PROTO_FOUND, PICA_PROTO_FOUND_SIZE))) { - memcpy(mp->tail, callee_id, PICA_ID_SIZE); - cclink_setwaitconn(cc); + memcpy(mp->tail, callee_id, PICA_ID_SIZE); + cclink_setwaitconn(cc); } } -return 1; + return 1; } -unsigned int procmsg_N2NNOTFOUND(unsigned char* buf,unsigned int size,void* ptr) +unsigned int procmsg_N2NNOTFOUND(unsigned char* buf, unsigned int size, void* ptr) { -struct nodelink *n=(struct nodelink *)ptr; -unsigned char *caller_id, *callee_id; -struct PICA_proto_msg *mp; -struct cclink *cc; + struct nodelink *n = (struct nodelink *)ptr; + unsigned char *caller_id, *callee_id; + struct PICA_proto_msg *mp; + struct cclink *cc; -PICA_debug1("received N2NNOTFOUND"); + PICA_debug1("received N2NNOTFOUND"); -caller_id = buf + 2; -callee_id = buf + 2 + PICA_ID_SIZE; + caller_id = buf + 2; + callee_id = buf + 2 + PICA_ID_SIZE; -cc=cclink_list_search(caller_id,callee_id); + cc = cclink_list_search(caller_id, callee_id); -if (cc) + if (cc) { - if ((mp = client_wbuf_push(cc->p1,PICA_PROTO_NOTFOUND,PICA_PROTO_NOTFOUND_SIZE))) + if ((mp = client_wbuf_push(cc->p1, PICA_PROTO_NOTFOUND, PICA_PROTO_NOTFOUND_SIZE))) { - memcpy(mp->tail, callee_id, PICA_ID_SIZE); + memcpy(mp->tail, callee_id, PICA_ID_SIZE); } - cclink_list_delete(cc); + cclink_list_delete(cc); } -return 1; + return 1; } -unsigned int procmsg_N2NMSG(unsigned char* buf,unsigned int size,void* ptr) +unsigned int procmsg_N2NMSG(unsigned char* buf, unsigned int size, void* ptr) { -struct nodelink *n=(struct nodelink *)ptr; -struct PICA_proto_msg *mp; -unsigned char *sender_id, *receiver_id; -struct cclink *cc; -unsigned int len,datalen; + struct nodelink *n = (struct nodelink *)ptr; + struct PICA_proto_msg *mp; + unsigned char *sender_id, *receiver_id; + struct cclink *cc; + unsigned int len, datalen; -PICA_debug1("received N2NMSG"); + PICA_debug1("received N2NMSG"); -len=*(unsigned short*)(buf+2); -sender_id = buf + 4; -receiver_id = buf + 4 + PICA_ID_SIZE; + len = *(unsigned short*)(buf + 2); + sender_id = buf + 4; + receiver_id = buf + 4 + PICA_ID_SIZE; -if (len < 2 * PICA_ID_SIZE) - return 0; + if (len < 2 * PICA_ID_SIZE) + return 0; -datalen = len - 2 * PICA_ID_SIZE; + datalen = len - 2 * PICA_ID_SIZE; -cc=cclink_list_search(sender_id,receiver_id); + cc = cclink_list_search(sender_id, receiver_id); -if (cc && cc->state==PICA_CCLINK_N2NCLE_ACTIVE) + if (cc && cc->state == PICA_CCLINK_N2NCLE_ACTIVE) { - if (datalen + cc->bufpos_p1p2 > cc->buflen_p1p2) + if (datalen + cc->bufpos_p1p2 > cc->buflen_p1p2) { - cclink_list_delete(cc);//CLOSING CCLINK DUE TO BUFER OVERRUN --------- FIXME FIX FIX FIX - return 1; + cclink_list_delete(cc);//CLOSING CCLINK DUE TO BUFER OVERRUN --------- FIXME FIX FIX FIX + return 1; } - memcpy(cc->buf_p1p2 + cc->bufpos_p1p2, buf + 4 + 2 * PICA_ID_SIZE, datalen); - cc->bufpos_p1p2 += datalen; - return 1; + memcpy(cc->buf_p1p2 + cc->bufpos_p1p2, buf + 4 + 2 * PICA_ID_SIZE, datalen); + cc->bufpos_p1p2 += datalen; + return 1; } /////////////// -cc=cclink_list_search(receiver_id,sender_id); + cc = cclink_list_search(receiver_id, sender_id); -if (cc && cc->state==PICA_CCLINK_N2NCLR_ACTIVE) + if (cc && cc->state == PICA_CCLINK_N2NCLR_ACTIVE) { - if (datalen + cc->bufpos_p2p1 > cc->buflen_p2p1) + if (datalen + cc->bufpos_p2p1 > cc->buflen_p2p1) { - cclink_list_delete(cc);//CLOSING CCLINK DUE TO BUFER OVERRUN --------- FIXME FIX FIX FIX - return 1; + cclink_list_delete(cc);//CLOSING CCLINK DUE TO BUFER OVERRUN --------- FIXME FIX FIX FIX + return 1; } - memcpy(cc->buf_p2p1 + cc->bufpos_p2p1, buf + 4 + 2 * PICA_ID_SIZE,datalen); - cc->bufpos_p2p1 += datalen; - return 1; + memcpy(cc->buf_p2p1 + cc->bufpos_p2p1, buf + 4 + 2 * PICA_ID_SIZE, datalen); + cc->bufpos_p2p1 += datalen; + return 1; } -if ((mp = nodelink_wbuf_push(n,PICA_PROTO_N2NNOTFOUND,PICA_PROTO_N2NNOTFOUND_SIZE))) + if ((mp = nodelink_wbuf_push(n, PICA_PROTO_N2NNOTFOUND, PICA_PROTO_N2NNOTFOUND_SIZE))) { - memcpy(mp->tail, sender_id, PICA_ID_SIZE); - memcpy(mp->tail + PICA_ID_SIZE, receiver_id, PICA_ID_SIZE); + memcpy(mp->tail, sender_id, PICA_ID_SIZE); + memcpy(mp->tail + PICA_ID_SIZE, receiver_id, PICA_ID_SIZE); } -return 1; + return 1; } struct cclink* cclink_list_findwaitsearch(const unsigned char *callee_id) { -struct cclink *c; -c = cclink_list_head; -while(c) + struct cclink *c; + c = cclink_list_head; + while(c) { - if (memcmp(c->callee_id, callee_id, PICA_ID_SIZE) == 0 - && c->state==PICA_CCLINK_N2NCLR_WAITSEARCH) - return c; - c=c->next; + if (memcmp(c->callee_id, callee_id, PICA_ID_SIZE) == 0 + && c->state == PICA_CCLINK_N2NCLR_WAITSEARCH) + return c; + c = c->next; } -return 0; + return 0; } struct cclink* cclink_list_search(const unsigned char *caller_id, const unsigned char *callee_id) { -struct cclink *c; -c= cclink_list_head; + struct cclink *c; + c = cclink_list_head; -while(c) + while(c) { - if (memcmp(c->caller_id, caller_id, PICA_ID_SIZE) == 0 - && memcmp(c->callee_id, callee_id, PICA_ID_SIZE) == 0) - return c; - c=c->next; + if (memcmp(c->caller_id, caller_id, PICA_ID_SIZE) == 0 + && memcmp(c->callee_id, callee_id, PICA_ID_SIZE) == 0) + return c; + c = c->next; } -return 0; + return 0; } -void cclink_list_delete(struct cclink *l) +void cclink_list_delete(struct cclink *l) { -PICA_debug1("cclink_list_delete(%p)", (void*)l); -//удаление из глобального списка -if (l->prev) - l->prev->next=l->next; -else - cclink_list_head=l->next; + PICA_debug1("cclink_list_delete(%p)", (void*)l); +//удаление из глобального списка + if (l->prev) + l->prev->next = l->next; + else + cclink_list_head = l->next; -if (l->next) - l->next->prev=l->prev; -else - cclink_list_end=l->prev; + if (l->next) + l->next->prev = l->prev; + else + cclink_list_end = l->prev; -if (l->p1) + if (l->p1) { - if (l->sck_p1) + if (l->sck_p1) { - SHUTDOWN(l->sck_p1); - CLOSE(l->sck_p1); - PICA_debug2("closed socket %i", l->sck_p1); + SHUTDOWN(l->sck_p1); + CLOSE(l->sck_p1); + PICA_debug2("closed socket %i", l->sck_p1); } }//caller_id is stored in p1 structure -else - free(l->caller_id);//caller_id was allocated by malloc + else + free(l->caller_id);//caller_id was allocated by malloc -if (l->p2) + if (l->p2) { - if (l->sck_p2) + if (l->sck_p2) { - SHUTDOWN(l->sck_p2); - CLOSE(l->sck_p2); - PICA_debug2("closed socket %i", l->sck_p2); + SHUTDOWN(l->sck_p2); + CLOSE(l->sck_p2); + PICA_debug2("closed socket %i", l->sck_p2); } } -else - free(l->callee_id); + else + free(l->callee_id); -if (l->buf_p1p2) - free(l->buf_p1p2); + if (l->buf_p1p2) + free(l->buf_p1p2); -if (l->buf_p2p1) - free(l->buf_p2p1); + if (l->buf_p2p1) + free(l->buf_p2p1); -free(l); -cclink_list_count--; + free(l); + cclink_list_count--; } void cclink_list_delete_by_client(struct client *cl) { -struct cclink *kill_ptr = 0, *l = cclink_list_head; -PICA_debug1("cclink_list_delete_by_client(%p)", (void*)cl); + struct cclink *kill_ptr = 0, *l = cclink_list_head; + PICA_debug1("cclink_list_delete_by_client(%p)", (void*)cl); -while(l) + while(l) { - if (l->p1 == cl || l->p2 == cl) - kill_ptr = l; - - l = l->next; + if (l->p1 == cl || l->p2 == cl) + kill_ptr = l; + + l = l->next; - if (kill_ptr) + if (kill_ptr) { - cclink_list_delete(kill_ptr); - kill_ptr = 0; + cclink_list_delete(kill_ptr); + kill_ptr = 0; } } @@ -1104,21 +1110,21 @@ while(l) void cclink_list_delete_by_nodelink(struct nodelink *node) { -struct cclink *kill_ptr = 0, *l = cclink_list_head; + struct cclink *kill_ptr = 0, *l = cclink_list_head; -PICA_debug1("cclink_list_delete_by_nodelink(%p)", (void*)node); + PICA_debug1("cclink_list_delete_by_nodelink(%p)", (void*)node); -while(l) + while(l) { - if (l->caller_node == node || l->callee_node == node) - kill_ptr = l; - - l = l->next; + if (l->caller_node == node || l->callee_node == node) + kill_ptr = l; - if (kill_ptr) + l = l->next; + + if (kill_ptr) { - cclink_list_delete(kill_ptr); - kill_ptr = 0; + cclink_list_delete(kill_ptr); + kill_ptr = 0; } } } @@ -1127,258 +1133,258 @@ while(l) //clr - caller //cle - callee // null value of clr or cle means that corresponding client is on remote node, is not local client -struct cclink* cclink_list_add(struct client *clr,struct client *cle) +struct cclink* cclink_list_add(struct client *clr, struct client *cle) { -struct cclink *l; + struct cclink *l; -l=(struct cclink*)calloc(sizeof(struct cclink),1); + l = (struct cclink*)calloc(sizeof(struct cclink), 1); -if (!l) - return 0; + if (!l) + return 0; //l->state=PICA_LINKSTATE_WAITREP; -l->p1=clr; -l->p2=cle; + l->p1 = clr; + l->p2 = cle; //добавление в глобальный список -if (cclink_list_head) + if (cclink_list_head) { - cclink_list_end->next=l; - l->prev=cclink_list_end; - cclink_list_end=l; + cclink_list_end->next = l; + l->prev = cclink_list_end; + cclink_list_end = l; } -else + else { - cclink_list_head=l; - cclink_list_end=l; + cclink_list_head = l; + cclink_list_end = l; } //timestamp -l->tmst=time(0); + l->tmst = time(0); -cclink_list_count++; + cclink_list_count++; -return l; + return l; } -void cclink_list_addlocal(struct client *clr,struct client *cle) +void cclink_list_addlocal(struct client *clr, struct client *cle) { -struct cclink *l; + struct cclink *l; -l=cclink_list_add(clr,cle); + l = cclink_list_add(clr, cle); -if (l) + if (l) { - l->state=PICA_CCLINK_LOCAL_WAITREP; - l->caller_id = l->p1->id; - l->callee_id = l->p2->id; + l->state = PICA_CCLINK_LOCAL_WAITREP; + l->caller_id = l->p1->id; + l->callee_id = l->p2->id; } } void cclink_list_addn2nclr(struct client *clr, const unsigned char *callee_id) { -struct cclink *l; + struct cclink *l; -l=cclink_list_add(clr,0); + l = cclink_list_add(clr, 0); -if (l) + if (l) { - l->state=PICA_CCLINK_N2NCLR_WAITSEARCH; - l->caller_id = l->p1->id; - l->callee_id = (unsigned char*)malloc(PICA_ID_SIZE); + l->state = PICA_CCLINK_N2NCLR_WAITSEARCH; + l->caller_id = l->p1->id; + l->callee_id = (unsigned char*)malloc(PICA_ID_SIZE); - if (l->callee_id == NULL) - PICA_fatal("memory allocation failed"); + if (l->callee_id == NULL) + PICA_fatal("memory allocation failed"); - memcpy(l->callee_id, callee_id, PICA_ID_SIZE); + memcpy(l->callee_id, callee_id, PICA_ID_SIZE); } } void cclink_attach_remotecle_node(struct cclink *ccl, struct nodelink *callee_node) { -if (ccl && ccl->state==PICA_CCLINK_N2NCLR_WAITSEARCH) + if (ccl && ccl->state == PICA_CCLINK_N2NCLR_WAITSEARCH) { - ccl->state=PICA_CCLINK_N2NCLR_WAITREP; - ccl->callee_node=callee_node; + ccl->state = PICA_CCLINK_N2NCLR_WAITREP; + ccl->callee_node = callee_node; } } void cclink_list_addn2ncle(const unsigned char *caller_id, struct nodelink *caller_node, struct client *cle) { -struct cclink *l; + struct cclink *l; -l=cclink_list_add(0,cle); + l = cclink_list_add(0, cle); -if (l) + if (l) { - l->state=PICA_CCLINK_N2NCLE_WAITREP; - l->caller_id = (unsigned char*)malloc(PICA_ID_SIZE); + l->state = PICA_CCLINK_N2NCLE_WAITREP; + l->caller_id = (unsigned char*)malloc(PICA_ID_SIZE); - if (l->caller_id == NULL) - PICA_fatal("memory allocation failed"); + if (l->caller_id == NULL) + PICA_fatal("memory allocation failed"); - memcpy(l->caller_id, caller_id, PICA_ID_SIZE); - l->callee_id = l->p2->id; - l->caller_node = caller_node; + memcpy(l->caller_id, caller_id, PICA_ID_SIZE); + l->callee_id = l->p2->id; + l->caller_node = caller_node; } } void cclink_setwaitconn(struct cclink *ccl) { -switch (ccl->state) + switch (ccl->state) { case PICA_CCLINK_LOCAL_WAITREP: - ccl->state=PICA_CCLINK_LOCAL_WAITCONNCLE; - // - break; + ccl->state = PICA_CCLINK_LOCAL_WAITCONNCLE; + // + break; case PICA_CCLINK_N2NCLR_WAITREP: - ccl->state=PICA_CCLINK_N2NCLR_WAITCONNCLR; - break; + ccl->state = PICA_CCLINK_N2NCLR_WAITCONNCLR; + break; case PICA_CCLINK_N2NCLE_WAITREP: - ccl->state=PICA_CCLINK_N2NCLE_WAITCONNCLE; - break; + ccl->state = PICA_CCLINK_N2NCLE_WAITCONNCLE; + break; default: - ; + ; } } int cclink_allocbufs(struct cclink *ccl) { -ccl->buf_p1p2 = malloc(DEFAULT_BUF_SIZE); -ccl->buf_p2p1 = malloc(DEFAULT_BUF_SIZE); -if (!ccl->buf_p1p2 || !ccl->buf_p2p1) + ccl->buf_p1p2 = malloc(DEFAULT_BUF_SIZE); + ccl->buf_p2p1 = malloc(DEFAULT_BUF_SIZE); + if (!ccl->buf_p1p2 || !ccl->buf_p2p1) { - if (ccl->buf_p1p2) - free(ccl->buf_p1p2); - if (ccl->buf_p2p1) - free(ccl->buf_p2p1); - return 0; + if (ccl->buf_p1p2) + free(ccl->buf_p1p2); + if (ccl->buf_p2p1) + free(ccl->buf_p2p1); + return 0; } -ccl->buflen_p1p2 = DEFAULT_BUF_SIZE; -ccl->buflen_p2p1 = DEFAULT_BUF_SIZE; -return 1; + ccl->buflen_p1p2 = DEFAULT_BUF_SIZE; + ccl->buflen_p2p1 = DEFAULT_BUF_SIZE; + return 1; } -void cclink_activate(struct cclink *ccl,SOCKET s) +void cclink_activate(struct cclink *ccl, SOCKET s) { -switch(ccl->state) + switch(ccl->state) { case PICA_CCLINK_LOCAL_WAITCONNCLE: - ccl->sck_p2 = s; - ccl->state = PICA_CCLINK_LOCAL_WAITCONNCLR; - break; + ccl->sck_p2 = s; + ccl->state = PICA_CCLINK_LOCAL_WAITCONNCLR; + break; case PICA_CCLINK_LOCAL_WAITCONNCLR: - ccl->sck_p1 = s; - if (!cclink_allocbufs(ccl)) + ccl->sck_p1 = s; + if (!cclink_allocbufs(ccl)) { - cclink_list_delete(ccl); - return; + cclink_list_delete(ccl); + return; } - ccl->state = PICA_CCLINK_LOCAL_ACTIVE; - break; + ccl->state = PICA_CCLINK_LOCAL_ACTIVE; + break; case PICA_CCLINK_N2NCLR_WAITCONNCLR: - ccl->sck_p1 = s; - if (!cclink_allocbufs(ccl)) + ccl->sck_p1 = s; + if (!cclink_allocbufs(ccl)) { - cclink_list_delete(ccl); - return; + cclink_list_delete(ccl); + return; } - ccl->state = PICA_CCLINK_N2NCLR_ACTIVE; - break; + ccl->state = PICA_CCLINK_N2NCLR_ACTIVE; + break; case PICA_CCLINK_N2NCLE_WAITCONNCLE: - ccl->sck_p2 = s; - if (!cclink_allocbufs(ccl)) + ccl->sck_p2 = s; + if (!cclink_allocbufs(ccl)) { - cclink_list_delete(ccl); - return; + cclink_list_delete(ccl); + return; } - ccl->state = PICA_CCLINK_N2NCLE_ACTIVE; - break; + ccl->state = PICA_CCLINK_N2NCLE_ACTIVE; + break; } } int PICA_node_init() { -struct sockaddr_in sd; -int ret; -int flag; + struct sockaddr_in sd; + int ret; + int flag; -SSL_load_error_strings(); -SSL_library_init(); + SSL_load_error_strings(); + SSL_library_init(); #ifdef WIN32 -WSADATA wsd; -WSAStartup(MAKEWORD(2,2),&wsd); + WSADATA wsd; + WSAStartup(MAKEWORD(2, 2), &wsd); #endif //CONF -AF_INET6 ???? -listen_comm_sck=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + listen_comm_sck = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); -if (listen_comm_sck == -1) - PICA_fatal("unable to get socket - %s", strerror(errno)); + if (listen_comm_sck == -1) + PICA_fatal("unable to get socket - %s", strerror(errno)); -flag = 1; //enable SO_REUSEADDR -if (0 != setsockopt(listen_comm_sck, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag))) -{ - PICA_error("failed to set SO_REUSEADDR on socket: %s", strerror(errno)); -} + flag = 1; //enable SO_REUSEADDR + if (0 != setsockopt(listen_comm_sck, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag))) + { + PICA_error("failed to set SO_REUSEADDR on socket: %s", strerror(errno)); + } -memset(&sd,0,sizeof(sd)); + memset(&sd, 0, sizeof(sd)); -sd.sin_family=AF_INET; -sd.sin_addr.s_addr=INADDR_ANY;//CONF -sd.sin_port = (nodecfg.listen_port ? htons(atoi(nodecfg.listen_port)) : htons(PICA_COMM_PORT));//CONF + sd.sin_family = AF_INET; + sd.sin_addr.s_addr = INADDR_ANY; //CONF + sd.sin_port = (nodecfg.listen_port ? htons(atoi(nodecfg.listen_port)) : htons(PICA_COMM_PORT));//CONF -ret = bind(listen_comm_sck,(struct sockaddr*)&sd,sizeof(sd)); + ret = bind(listen_comm_sck, (struct sockaddr*)&sd, sizeof(sd)); -if (ret == -1) - PICA_fatal("unable to bind socket - %s", strerror(errno)); + if (ret == -1) + PICA_fatal("unable to bind socket - %s", strerror(errno)); -ret = listen(listen_comm_sck,20); -if (ret == -1) - PICA_fatal("unable to listen socket - %s", strerror(errno)); + ret = listen(listen_comm_sck, 20); + if (ret == -1) + PICA_fatal("unable to listen socket - %s", strerror(errno)); -{ -int ret_comm; -unsigned long arg=1; + { + int ret_comm; + unsigned long arg = 1; #ifdef WIN32 -ret_comm=ioctlsocket(listen_comm_sck,FIONBIO,&arg); + ret_comm = ioctlsocket(listen_comm_sck, FIONBIO, &arg); // ret_data=ioctlsocket(listen_data_sck,FIONBIO,&arg); // ret_data=ioctlsocket(listen_node_sck,FIONBIO,&arg); #else -ret_comm=ioctl(listen_comm_sck,FIONBIO,(int*)&arg); + ret_comm = ioctl(listen_comm_sck, FIONBIO, (int*)&arg); // ret_data=ioctl(listen_data_sck,FIONBIO,(int*)&arg); // ret_data=ioctl(listen_node_sck,FIONBIO,(int*)&arg); #endif -if (ret_comm == -1) - PICA_fatal("unable to set non-blocking mode on socket - %s", strerror(errno)); -} + if (ret_comm == -1) + PICA_fatal("unable to set non-blocking mode on socket - %s", strerror(errno)); + } -//#ifdef NO_RAND_DEV +//#ifdef NO_RAND_DEV //PICA_rand_seed(); //#endif -ctx = SSL_CTX_new(TLSv1_2_method()); + ctx = SSL_CTX_new(TLSv1_2_method()); -if (!ctx) - PICA_fatal("unable to create SSL_CTX object"); + if (!ctx) + PICA_fatal("unable to create SSL_CTX object"); -ret = SSL_CTX_load_verify_locations(ctx, nodecfg.CA_cert_file, 0); + ret = SSL_CTX_load_verify_locations(ctx, nodecfg.CA_cert_file, 0); -if (!ret) - PICA_fatal("call to SSL_CTX_load_verify_locations failed(). Check if %s exists and is accesible", nodecfg.CA_cert_file); + if (!ret) + PICA_fatal("call to SSL_CTX_load_verify_locations failed(). Check if %s exists and is accesible", nodecfg.CA_cert_file); -SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback); + SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, verify_callback); -return 1; + return 1; } /* //функция возвращает номер клиента id в бинарном виде, извлекая его из строки, @@ -1414,515 +1420,515 @@ return 1; void newconn_close(struct newconn* nc) { -CLOSE(nc->sck); -PICA_debug3("newconn_close(): nc = %p closed socket %i", nc, nc->sck); + CLOSE(nc->sck); + PICA_debug3("newconn_close(): nc = %p closed socket %i", nc, nc->sck); -nc->sck=0; -nc->pos=0; + nc->sck = 0; + nc->pos = 0; } //функция ищет свободный элемент в массиве структур newconn и возвращает на него указатель //В случае, если свободный элемент не найден, возвращается элемент с наиболее поздней отметкой времени, //при этом соединение закрывается -struct newconn* newconn_add(struct newconn *ncs,int *pos) +struct newconn* newconn_add(struct newconn *ncs, int *pos) { -time_t min; -int min_pos=0; -if (*postmst; - while(ncs[*pos].sck && *postmst; + while(ncs[*pos].sck && *pos < MAX_NEWCONNS) { - if (ncs[*pos].tmstsck=0; + nc->sck = 0; //nc->pos=0; - pos value is being used in processmsgdatastream } int client_tree_add(struct client *ci) { -struct client *i; -if (client_tree_root) + struct client *i; + if (client_tree_root) { - i=client_tree_root; - - do + i = client_tree_root; + + do { - if (memcmp(i->id, ci->id, PICA_ID_SIZE) == 0) - return 0; + if (memcmp(i->id, ci->id, PICA_ID_SIZE) == 0) + return 0; - if (memcmp(ci->id, i->id, PICA_ID_SIZE) < 0) // ci->id < i->id + if (memcmp(ci->id, i->id, PICA_ID_SIZE) < 0) // ci->id < i->id { - if (i->left) - i=i->left; - else + if (i->left) + i = i->left; + else { - i->left=ci; - ci->up=i; - return 1; + i->left = ci; + ci->up = i; + return 1; } } - else - { - if (i->right) - i=i->right; else + { + if (i->right) + i = i->right; + else { - i->right=ci; - ci->up=i; - return 1; + i->right = ci; + ci->up = i; + return 1; } } } - while(1); + while(1); } -else - client_tree_root=ci; + else + client_tree_root = ci; -return 1; + return 1; } struct client* client_tree_search(const unsigned char *id) { -struct client* i_ptr; -i_ptr=client_tree_root; + struct client* i_ptr; + i_ptr = client_tree_root; //PICA_debug1("client_tree_search: searching for %u...",id); -while(i_ptr) + while(i_ptr) { - if (memcmp(i_ptr->id, id, PICA_ID_SIZE) == 0) - return i_ptr; + if (memcmp(i_ptr->id, id, PICA_ID_SIZE) == 0) + return i_ptr; - if (memcmp(id, i_ptr->id, PICA_ID_SIZE) < 0) //id < i_ptr->id - i_ptr=i_ptr->left; - else - i_ptr=i_ptr->right; + if (memcmp(id, i_ptr->id, PICA_ID_SIZE) < 0) //id < i_ptr->id + i_ptr = i_ptr->left; + else + i_ptr = i_ptr->right; } -PICA_debug1("client_tree_search- id not found"); -return 0; + PICA_debug1("client_tree_search- id not found"); + return 0; } void client_tree_print(struct client *c) { -if (!c) + if (!c) { - puts("NULL"); - return; + puts("NULL"); + return; } -printf("%p: %u LEFT: %p, RIGHT: %p\n", (void*)c, c->id, (void*)c->left, (void*)c->right); + printf("%p: %u LEFT: %p, RIGHT: %p\n", (void*)c, c->id, (void*)c->left, (void*)c->right); -if (c->left) - client_tree_print(c->left); + if (c->left) + client_tree_print(c->left); -if (c->right) - client_tree_print(c->right); + if (c->right) + client_tree_print(c->right); } -//удаление структуры из дерева +//удаление структуры из дерева void client_tree_remove(struct client* ci) { -struct client** p_link;//указывает на left или right в родительском узле + struct client** p_link;//указывает на left или right в родительском узле -if (!ci->up) + if (!ci->up) { - p_link = &client_tree_root; + p_link = &client_tree_root; } -else - { - if (ci==ci->up->left) - p_link=&(ci->up->left); else - p_link=&(ci->up->right); + { + if (ci == ci->up->left) + p_link = &(ci->up->left); + else + p_link = &(ci->up->right); } - - -if (!ci->left && !ci->right) + + + if (!ci->left && !ci->right) { - *p_link=0; - return; + *p_link = 0; + return; } -if (ci->left && !ci->right) + if (ci->left && !ci->right) { - ci->left->up=ci->up; - *p_link=ci->left; - return; + ci->left->up = ci->up; + *p_link = ci->left; + return; } -if (!ci->left && ci->right) + if (!ci->left && ci->right) { - ci->right->up=ci->up; - *p_link=ci->right; - return; + ci->right->up = ci->up; + *p_link = ci->right; + return; } { - struct client *lm; - lm=ci->right; - while(lm->left) lm=lm->left;//поиск самого левого узла правого поддерева + struct client *lm; + lm = ci->right; + while(lm->left) lm = lm->left; //поиск самого левого узла правого поддерева - if (lm!=ci->right) - { - lm->up->left=lm->right; - lm->right=ci->right; + if (lm != ci->right) + { + lm->up->left = lm->right; + lm->right = ci->right; } - lm->left=ci->left; - lm->up=ci->up; - *p_link=lm; + lm->left = ci->left; + lm->up = ci->up; + *p_link = lm; } } struct client *client_list_addnew(struct newconn *nc) { -struct client* ci; + struct client* ci; -ci=(struct client *)calloc(1,sizeof(struct client)); + ci = (struct client *)calloc(1, sizeof(struct client)); -if (!ci) return 0; + if (!ci) return 0; -ci->ssl_comm =SSL_new (ctx); + ci->ssl_comm = SSL_new (ctx); -if (!ci->ssl_comm) + if (!ci->ssl_comm) { - free(ci); - return 0; + free(ci); + return 0; } -if (client_list_end) + if (client_list_end) { - client_list_end->next=ci; - ci->prev=client_list_end; - client_list_end=ci; + client_list_end->next = ci; + ci->prev = client_list_end; + client_list_end = ci; } -else + else { - client_list_head=ci; - client_list_end=ci; + client_list_head = ci; + client_list_end = ci; } -ci->sck_comm=nc->sck; -ci->addr=nc->addr; + ci->sck_comm = nc->sck; + ci->addr = nc->addr; -SSL_set_fd(ci->ssl_comm,ci->sck_comm); + SSL_set_fd(ci->ssl_comm, ci->sck_comm); -ci->r_buf = calloc(1,DEFAULT_BUF_SIZE); -if (!ci->r_buf) + ci->r_buf = calloc(1, DEFAULT_BUF_SIZE); + if (!ci->r_buf) { - free(ci); - return 0; + free(ci); + return 0; } -ci->buflen_r = DEFAULT_BUF_SIZE; + ci->buflen_r = DEFAULT_BUF_SIZE; -ci->tmst = time(0); + ci->tmst = time(0); -return ci; + return ci; } void client_list_delete(struct client* ci) { -PICA_debug1("client_list_delete(%p)", (void*)ci); -SSL_free(ci->ssl_comm); + PICA_debug1("client_list_delete(%p)", (void*)ci); + SSL_free(ci->ssl_comm); //удаление из списка -if (ci->prev) - ci->prev->next=ci->next; -else - client_list_head=ci->next; + if (ci->prev) + ci->prev->next = ci->next; + else + client_list_head = ci->next; -if (ci->next) - ci->next->prev=ci->prev; -else - client_list_end=ci->prev; + if (ci->next) + ci->next->prev = ci->prev; + else + client_list_end = ci->prev; //удаление из дерева -if (client_tree_search(ci->id) == ci) + if (client_tree_search(ci->id) == ci) { - client_tree_remove(ci); - client_tree_print(client_tree_root); + client_tree_remove(ci); + client_tree_print(client_tree_root); } -cclink_list_delete_by_client(ci); + cclink_list_delete_by_client(ci); -if (ci->r_buf) - free(ci->r_buf); + if (ci->r_buf) + free(ci->r_buf); -if (ci->w_buf) - free(ci->w_buf); + if (ci->w_buf) + free(ci->w_buf); -CLOSE(ci->sck_comm); -PICA_debug2("closed socket %i", ci->sck_comm); + CLOSE(ci->sck_comm); + PICA_debug2("closed socket %i", ci->sck_comm); -free(ci); + free(ci); } struct PICA_proto_msg* client_wbuf_push - (struct client *c,unsigned int msgid,unsigned int size) +(struct client *c, unsigned int msgid, unsigned int size) { -if (!c->w_buf) - { - c->w_buf = calloc(1,DEFAULT_BUF_SIZE + (size/DEFAULT_BUF_SIZE)*DEFAULT_BUF_SIZE ); if (!c->w_buf) + { + c->w_buf = calloc(1, DEFAULT_BUF_SIZE + (size / DEFAULT_BUF_SIZE) * DEFAULT_BUF_SIZE ); + if (!c->w_buf) { - PICA_error("calloc() failed. Out of memory"); - return 0; + PICA_error("calloc() failed. Out of memory"); + return 0; } - c->buflen_w = DEFAULT_BUF_SIZE + (size/DEFAULT_BUF_SIZE)*DEFAULT_BUF_SIZE; + c->buflen_w = DEFAULT_BUF_SIZE + (size / DEFAULT_BUF_SIZE) * DEFAULT_BUF_SIZE; } -if ((c->buflen_w - c->w_pos) < size) + if ((c->buflen_w - c->w_pos) < size) { - unsigned char *p; - p=realloc(c->w_buf,size + c->w_pos); + unsigned char *p; + p = realloc(c->w_buf, size + c->w_pos); - if (p) + if (p) { - c->w_buf=p; - c->buflen_w=size + c->w_pos; + c->w_buf = p; + c->buflen_w = size + c->w_pos; } - else - return 0; + else + return 0; } - -struct PICA_proto_msg *mp=(struct PICA_proto_msg *)(c->w_buf + c->w_pos); -mp->head[0]=mp->head[1]=msgid; -c->w_pos+=size; -return mp; + + struct PICA_proto_msg *mp = (struct PICA_proto_msg *)(c->w_buf + c->w_pos); + mp->head[0] = mp->head[1] = msgid; + c->w_pos += size; + return mp; } int client_rbuf_grow(struct client *c) { -unsigned char *p; + unsigned char *p; -p=realloc(c->r_buf, c->buflen_r + DEFAULT_BUF_SIZE); + p = realloc(c->r_buf, c->buflen_r + DEFAULT_BUF_SIZE); -if (!p) + if (!p) { - PICA_error("realloc() failed"); - return 0; + PICA_error("realloc() failed"); + return 0; } -c->r_buf = p; -c->buflen_r +=DEFAULT_BUF_SIZE; + c->r_buf = p; + c->buflen_r += DEFAULT_BUF_SIZE; -return 1; + return 1; } struct nodelink *nodelink_list_addnew(struct newconn *nc) { -struct nodelink *nl; + struct nodelink *nl; -nl=(struct nodelink*)calloc(1,sizeof(struct nodelink)); + nl = (struct nodelink*)calloc(1, sizeof(struct nodelink)); -if (!nl) - return 0; + if (!nl) + return 0; -if (nodelink_list_end) + if (nodelink_list_end) { - nodelink_list_end->next=nl; - nl->prev=nodelink_list_end; - nodelink_list_end=nl; + nodelink_list_end->next = nl; + nl->prev = nodelink_list_end; + nodelink_list_end = nl; } -else + else { - nodelink_list_head=nl; - nodelink_list_end=nl; + nodelink_list_head = nl; + nodelink_list_end = nl; } -nl->sck=nc->sck; -nl->addr=nc->addr; + nl->sck = nc->sck; + nl->addr = nc->addr; -nl->r_buf=calloc(1,DEFAULT_BUF_SIZE); -if (!nl->r_buf) + nl->r_buf = calloc(1, DEFAULT_BUF_SIZE); + if (!nl->r_buf) { - free(nl); - return 0; + free(nl); + return 0; } -nl->buflen_r=DEFAULT_BUF_SIZE; + nl->buflen_r = DEFAULT_BUF_SIZE; -nl->tmst = time(0); + nl->tmst = time(0); -nodelink_list_count++; -return nl; + nodelink_list_count++; + return nl; } void nodelink_list_delete(struct nodelink *n) { -PICA_debug1("nodelink_list_delete(%p)", (void*)n); - -if (n->r_buf) - free(n->r_buf); + PICA_debug1("nodelink_list_delete(%p)", (void*)n); -if (n->w_buf) - free(n->w_buf); + if (n->r_buf) + free(n->r_buf); -if (n->node_addr) - free(n->node_addr); + if (n->w_buf) + free(n->w_buf); -CLOSE(n->sck); -PICA_debug2("closed socket %i", n->sck); + if (n->node_addr) + free(n->node_addr); -if (n->prev) - n->prev->next=n->next; -else - nodelink_list_head=n->next; + CLOSE(n->sck); + PICA_debug2("closed socket %i", n->sck); + + if (n->prev) + n->prev->next = n->next; + else + nodelink_list_head = n->next; -if (n->next) - n->next->prev=n->prev; -else - nodelink_list_end=n->prev; + if (n->next) + n->next->prev = n->prev; + else + nodelink_list_end = n->prev; -cclink_list_delete_by_nodelink(n); + cclink_list_delete_by_nodelink(n); -nodelink_list_count--; -free(n); + nodelink_list_count--; + free(n); } int nodelink_attach_nodeaddr(struct nodelink *nl, unsigned int addr_type, void* nodeaddr, unsigned int nodeaddr_size) { -if (nl && nodeaddr) + if (nl && nodeaddr) { - if (nl->node_addr) - free(nl->node_addr); - - nl->node_addr=malloc(nodeaddr_size); - if (!nl->node_addr) - return 0;//ERR_CHECK - memcpy(nl->node_addr,nodeaddr,nodeaddr_size); + if (nl->node_addr) + free(nl->node_addr); - nl->addr_type=addr_type; - return 1; + nl->node_addr = malloc(nodeaddr_size); + if (!nl->node_addr) + return 0;//ERR_CHECK + memcpy(nl->node_addr, nodeaddr, nodeaddr_size); + + nl->addr_type = addr_type; + return 1; } -return 0; + return 0; } int nodelink_rbuf_grow(struct nodelink *nl) { -unsigned char *p; + unsigned char *p; -p=realloc(nl->r_buf,nl->buflen_r + DEFAULT_BUF_SIZE); + p = realloc(nl->r_buf, nl->buflen_r + DEFAULT_BUF_SIZE); -if (!p) + if (!p) { - PICA_error("realloc() failed"); - return 0; + PICA_error("realloc() failed"); + return 0; } -nl->r_buf = p; -nl->buflen_r +=DEFAULT_BUF_SIZE; + nl->r_buf = p; + nl->buflen_r += DEFAULT_BUF_SIZE; -return 1; + return 1; } struct PICA_proto_msg* nodelink_wbuf_push - (struct nodelink *nl,unsigned int msgid,unsigned int size) +(struct nodelink *nl, unsigned int msgid, unsigned int size) { -struct PICA_proto_msg *mp; - -if (!nl->w_buf) - { - nl->w_buf=calloc(1,DEFAULT_BUF_SIZE ); + struct PICA_proto_msg *mp; + if (!nl->w_buf) + { + nl->w_buf = calloc(1, DEFAULT_BUF_SIZE ); + if (!nl->w_buf) { - PICA_error("calloc() failed. Out of memory"); - return 0; + PICA_error("calloc() failed. Out of memory"); + return 0; } - nl->buflen_w=DEFAULT_BUF_SIZE; + nl->buflen_w = DEFAULT_BUF_SIZE; } -if ((nl->buflen_w - nl->w_pos) < size) + if ((nl->buflen_w - nl->w_pos) < size) { - unsigned char *p; - p=realloc(nl->w_buf,size + nl->w_pos); + unsigned char *p; + p = realloc(nl->w_buf, size + nl->w_pos); - if (p) + if (p) { - nl->w_buf=p; - nl->buflen_w=size + nl->w_pos; + nl->w_buf = p; + nl->buflen_w = size + nl->w_pos; } - else - return 0; + else + return 0; } - -mp=(struct PICA_proto_msg *)(nl->w_buf + nl->w_pos); -mp->head[0]=mp->head[1]=msgid; -nl->w_pos+=size; -return mp; + + mp = (struct PICA_proto_msg *)(nl->w_buf + nl->w_pos); + mp->head[0] = mp->head[1] = msgid; + nl->w_pos += size; + return mp; } struct nodelink *nodelink_search_by_ipv4addr(in_addr_t ip, in_port_t port) { -struct nodelink *nl; + struct nodelink *nl; -nl = nodelink_list_head; + nl = nodelink_list_head; -while(nl && !( - (nl->addr.sin_addr.s_addr == ip && nl->addr.sin_port == port) || - (nl->node_addr && nl->addr_type == PICA_PROTO_NEWNODE_IPV4 && - ((struct PICA_nodeaddr_ipv4*)nl->node_addr) ->addr == ip && - ((struct PICA_nodeaddr_ipv4*)nl->node_addr) ->port == port - ) - ) - ) + while(nl && !( + (nl->addr.sin_addr.s_addr == ip && nl->addr.sin_port == port) || + (nl->node_addr && nl->addr_type == PICA_PROTO_NEWNODE_IPV4 && + ((struct PICA_nodeaddr_ipv4*)nl->node_addr) ->addr == ip && + ((struct PICA_nodeaddr_ipv4*)nl->node_addr) ->port == port + ) + ) + ) { - nl = nl->next; + nl = nl->next; } -return nl; + return nl; } // обработка различных таймаутов. Отправка пингов void process_timeouts_newconn() { -clock_t t; -int i; + clock_t t; + int i; -t=time(0); + t = time(0); -for (i=0;iNEWCONN_TIMEOUT) + if (t - newconns[i].tmst > NEWCONN_TIMEOUT) { - newconn_close(newconns+i); + newconn_close(newconns + i); } } - else if ( newconns[i].tmst-t>NEWCONN_TIMEOUT) + else if ( newconns[i].tmst - t > NEWCONN_TIMEOUT) { - newconn_close(newconns+i); + newconn_close(newconns + i); } } } @@ -1930,251 +1936,253 @@ for (i=0;istate) + switch(il->state) { - case PICA_CCLINK_LOCAL_ACTIVE: + case PICA_CCLINK_LOCAL_ACTIVE: case PICA_CCLINK_N2NCLR_ACTIVE: case PICA_CCLINK_N2NCLE_ACTIVE: - //idle timeout (>=60sec), update timestamp at process_c2c + //idle timeout (>=60sec), update timestamp at process_c2c - break; + break; default: - if ((time(0)- il->tmst)>TMO_CCLINK_WAITACTIVE) + if ((time(0) - il->tmst) > TMO_CCLINK_WAITACTIVE) { - struct cclink *dl; - dl=il; - il=il->next; - cclink_list_delete(dl); - continue; + struct cclink *dl; + dl = il; + il = il->next; + cclink_list_delete(dl); + continue; } } - il=il->next; + il = il->next; } } void process_timeouts_c2n() { -struct client *i_ptr, *kill_ptr; -int ret; + struct client *i_ptr, *kill_ptr; + int ret; -i_ptr = client_list_head; -kill_ptr = 0; + i_ptr = client_list_head; + kill_ptr = 0; -clock_t cur_time = time(0); + clock_t cur_time = time(0); -while(i_ptr) + while(i_ptr) { - if (i_ptr->disconnect_ticking) + if (i_ptr->disconnect_ticking) { - if (cur_time >= i_ptr->tmst) + if (cur_time >= i_ptr->tmst) { - if ((cur_time - i_ptr->tmst) > NOREPLY_TIMEOUT) - kill_ptr = i_ptr; + if ((cur_time - i_ptr->tmst) > NOREPLY_TIMEOUT) + kill_ptr = i_ptr; } - else - {//2038 year has come, and this code is still working somewhere with 32bit Unix timestamps :) - if ((i_ptr->tmst - cur_time ) > NOREPLY_TIMEOUT) - kill_ptr = i_ptr; + else + { + //2038 year has come, and this code is still working somewhere with 32bit Unix timestamps :) + if ((i_ptr->tmst - cur_time ) > NOREPLY_TIMEOUT) + kill_ptr = i_ptr; } } - else + else { - if (cur_time >= i_ptr->tmst) + if (cur_time >= i_ptr->tmst) { - if ((cur_time - i_ptr->tmst) > KEEPALIVE_TIMEOUT) + if ((cur_time - i_ptr->tmst) > KEEPALIVE_TIMEOUT) { - struct PICA_proto_msg *mp; - - if ((mp = client_wbuf_push(i_ptr, PICA_PROTO_PINGREQ, PICA_PROTO_PINGREQ_SIZE))) + struct PICA_proto_msg *mp; + + if ((mp = client_wbuf_push(i_ptr, PICA_PROTO_PINGREQ, PICA_PROTO_PINGREQ_SIZE))) { - PICA_debug3("sending PINGREQ to %p", i_ptr); - RAND_bytes(mp->tail, 2); - - i_ptr->tmst = time(0); - i_ptr->disconnect_ticking = 1; + PICA_debug3("sending PINGREQ to %p", i_ptr); + RAND_bytes(mp->tail, 2); + + i_ptr->tmst = time(0); + i_ptr->disconnect_ticking = 1; } - else - kill_ptr = i_ptr; + else + kill_ptr = i_ptr; } } } - - i_ptr = i_ptr->next; - if (kill_ptr) + i_ptr = i_ptr->next; + + if (kill_ptr) { - PICA_info("Disconnecting user %u due to noreply timeout", kill_ptr -> id); - client_list_delete(kill_ptr); - kill_ptr=0; + PICA_info("Disconnecting user %u due to noreply timeout", kill_ptr -> id); + client_list_delete(kill_ptr); + kill_ptr = 0; } } } void process_timeouts_n2n() { -struct nodelink *i_ptr, *kill_ptr; -int ret; + struct nodelink *i_ptr, *kill_ptr; + int ret; -i_ptr = nodelink_list_head; -kill_ptr = 0; + i_ptr = nodelink_list_head; + kill_ptr = 0; -clock_t cur_time = time(0); + clock_t cur_time = time(0); -while(i_ptr) + while(i_ptr) { - if (i_ptr->disconnect_ticking) + if (i_ptr->disconnect_ticking) { - if (cur_time >= i_ptr->tmst) + if (cur_time >= i_ptr->tmst) { - if ((cur_time - i_ptr->tmst) > NOREPLY_TIMEOUT) - kill_ptr = i_ptr; + if ((cur_time - i_ptr->tmst) > NOREPLY_TIMEOUT) + kill_ptr = i_ptr; } - else - {//2038 year has come, and this code is still working somewhere with 32bit Unix timestamps :) - if ((i_ptr->tmst - cur_time ) > NOREPLY_TIMEOUT) - kill_ptr = i_ptr; + else + { + //2038 year has come, and this code is still working somewhere with 32bit Unix timestamps :) + if ((i_ptr->tmst - cur_time ) > NOREPLY_TIMEOUT) + kill_ptr = i_ptr; } } - else + else { - if (cur_time >= i_ptr->tmst) + if (cur_time >= i_ptr->tmst) { - if ((cur_time - i_ptr->tmst) > KEEPALIVE_TIMEOUT) + if ((cur_time - i_ptr->tmst) > KEEPALIVE_TIMEOUT) { - struct PICA_proto_msg *mp; - - if ((mp = nodelink_wbuf_push(i_ptr, PICA_PROTO_PINGREQ, PICA_PROTO_PINGREQ_SIZE))) + struct PICA_proto_msg *mp; + + if ((mp = nodelink_wbuf_push(i_ptr, PICA_PROTO_PINGREQ, PICA_PROTO_PINGREQ_SIZE))) { - PICA_debug3("sending PINGREQ to node %p", i_ptr); - RAND_bytes(mp->tail, 2); - - i_ptr->tmst = time(0); - i_ptr->disconnect_ticking = 1; + PICA_debug3("sending PINGREQ to node %p", i_ptr); + RAND_bytes(mp->tail, 2); + + i_ptr->tmst = time(0); + i_ptr->disconnect_ticking = 1; } - else - kill_ptr = i_ptr; + else + kill_ptr = i_ptr; } } } - - i_ptr = i_ptr->next; - if (kill_ptr) + i_ptr = i_ptr->next; + + if (kill_ptr) { - PICA_info("Disconnecting node %p due to noreply timeout", kill_ptr); - nodelink_list_delete(kill_ptr); - kill_ptr=0; + PICA_info("Disconnecting node %p due to noreply timeout", kill_ptr); + nodelink_list_delete(kill_ptr); + kill_ptr = 0; } } } int process_timeouts() { -process_timeouts_newconn(); -process_timeouts_c2n(); -process_timeouts_c2c(); -process_timeouts_n2n(); + process_timeouts_newconn(); + process_timeouts_c2n(); + process_timeouts_c2c(); + process_timeouts_n2n(); -if (time(0) - skynet_refresh_tmst > SKYNET_REFRESH_TIMEOUT && !nodewait_list) + if (time(0) - skynet_refresh_tmst > SKYNET_REFRESH_TIMEOUT && !nodewait_list) { - PICA_debug3("refreshing nodelist database"); - PICA_node_joinskynet(nodecfg.nodes_db_file, nodecfg.announced_addr); + PICA_debug3("refreshing nodelist database"); + PICA_node_joinskynet(nodecfg.nodes_db_file, nodecfg.announced_addr); } -return 1; + return 1; } void set_select_fd(SOCKET s, fd_set *readfds, int *nfds) { -FD_SET(s,readfds); + FD_SET(s, readfds); -if (s > *nfds) - *nfds=s; + if (s > *nfds) + *nfds = s; } -void listen_set_fds(fd_set *readfds,int *nfds) +void listen_set_fds(fd_set *readfds, int *nfds) { -set_select_fd(listen_comm_sck,readfds,nfds); + set_select_fd(listen_comm_sck, readfds, nfds); } -void newconn_set_fds(fd_set *readfds,int *nfds) +void newconn_set_fds(fd_set *readfds, int *nfds) { -int i; + int i; -for (i=0;isck_comm,readfds,nfds); + set_select_fd(i_ptr->sck_comm, readfds, nfds); - i_ptr=i_ptr->next; + i_ptr = i_ptr->next; } } -void c2c_set_fds(fd_set *readfds,int *nfds) +void c2c_set_fds(fd_set *readfds, int *nfds) { -struct cclink *cc; + struct cclink *cc; -cc=cclink_list_head; -while(cc) + cc = cclink_list_head; + while(cc) { - if ( !cc->jam_p1p2 && (cc->state==PICA_CCLINK_LOCAL_ACTIVE || cc->state==PICA_CCLINK_N2NCLR_ACTIVE) ) - set_select_fd(cc->sck_p1,readfds,nfds); - - if ( !cc->jam_p2p1 && (cc->state==PICA_CCLINK_LOCAL_ACTIVE || cc->state==PICA_CCLINK_N2NCLE_ACTIVE) ) - set_select_fd(cc->sck_p2,readfds,nfds); + if ( !cc->jam_p1p2 && (cc->state == PICA_CCLINK_LOCAL_ACTIVE || cc->state == PICA_CCLINK_N2NCLR_ACTIVE) ) + set_select_fd(cc->sck_p1, readfds, nfds); + + if ( !cc->jam_p2p1 && (cc->state == PICA_CCLINK_LOCAL_ACTIVE || cc->state == PICA_CCLINK_N2NCLE_ACTIVE) ) + set_select_fd(cc->sck_p2, readfds, nfds); - cc=cc->next; + cc = cc->next; } } -void n2n_set_fds(fd_set *readfds,int *nfds) +void n2n_set_fds(fd_set *readfds, int *nfds) { -struct nodelink *nl; -nl=nodelink_list_head; + struct nodelink *nl; + nl = nodelink_list_head; -while(nl) + while(nl) { - set_select_fd(nl->sck,readfds,nfds); - nl=nl->next; + set_select_fd(nl->sck, readfds, nfds); + nl = nl->next; } } void process_listen_read(fd_set *readfds) { -struct newconn *nc; -SOCKET s; -struct sockaddr_in addr; -int addrsize = sizeof(struct sockaddr_in); -if (FD_ISSET(listen_comm_sck,readfds)) + struct newconn *nc; + SOCKET s; + struct sockaddr_in addr; + int addrsize = sizeof(struct sockaddr_in); + if (FD_ISSET(listen_comm_sck, readfds)) { - s = accept(listen_comm_sck,(struct sockaddr*)&addr,&addrsize); + s = accept(listen_comm_sck, (struct sockaddr*)&addr, &addrsize); - if (s >= 0) + if (s >= 0) { - nc = newconn_add(newconns,&newconns_pos); - - nc->sck = s; - nc->addr = addr; - PICA_debug1("accepted connection from %.16s, new socket %i", inet_ntoa(addr.sin_addr), s);//IPv6 + nc = newconn_add(newconns, &newconns_pos); + + nc->sck = s; + nc->addr = addr; + PICA_debug1("accepted connection from %.16s, new socket %i", inet_ntoa(addr.sin_addr), s);//IPv6 } - else + else { - PICA_error("unable to accept connection: %s", strerror(errno)); + PICA_error("unable to accept connection: %s", strerror(errno)); } } @@ -2183,26 +2191,26 @@ if (FD_ISSET(listen_comm_sck,readfds)) void process_newconn_read(fd_set *readfds) { -int i,ret; + int i, ret; -for (i=0;isck_comm,readfds)) - switch(i_ptr->state) - { - case PICA_CLSTATE_CONNECTED: - ret=SSL_read(i_ptr->ssl_comm, i_ptr->r_buf + i_ptr->r_pos, i_ptr->buflen_r - i_ptr->r_pos); - - if (!ret) - kill_ptr=i_ptr; + if (FD_ISSET(i_ptr->sck_comm, readfds)) + switch(i_ptr->state) + { + case PICA_CLSTATE_CONNECTED: + ret = SSL_read(i_ptr->ssl_comm, i_ptr->r_buf + i_ptr->r_pos, i_ptr->buflen_r - i_ptr->r_pos); + + if (!ret) + kill_ptr = i_ptr; - if (ret<0) - switch(SSL_get_error(i_ptr->ssl_comm,ret)) + if (ret < 0) + switch(SSL_get_error(i_ptr->ssl_comm, ret)) + { + case SSL_ERROR_WANT_WRITE: + case SSL_ERROR_WANT_READ: + break; + default: + kill_ptr = i_ptr; + } + + if (ret > 0) { - case SSL_ERROR_WANT_WRITE: - case SSL_ERROR_WANT_READ: - break; - default: - kill_ptr=i_ptr; + i_ptr->r_pos += ret; + if(!PICA_processdatastream(i_ptr->r_buf, &(i_ptr->r_pos), i_ptr, _msginfo_comm, MSGINFO_MSGSNUM(_msginfo_comm) )) + kill_ptr = i_ptr; + + if (i_ptr->buflen_r == i_ptr->r_pos) + if (!client_rbuf_grow(i_ptr)) + kill_ptr = i_ptr; + } - - if (ret>0) - { - i_ptr->r_pos+=ret; - if(!PICA_processdatastream(i_ptr->r_buf,&(i_ptr->r_pos),i_ptr,_msginfo_comm, MSGINFO_MSGSNUM(_msginfo_comm) )) - kill_ptr=i_ptr; - - if (i_ptr->buflen_r == i_ptr->r_pos) - if (!client_rbuf_grow(i_ptr)) - kill_ptr = i_ptr; + break; + case PICA_CLSTATE_TLSNEGOTIATION: + i_ptr->w_pos = 1; //???? + //-------------- <<<<<<<<<<<<<<<<<<<<<<<<---------------------------------------- + break; + }; - } - break; - case PICA_CLSTATE_TLSNEGOTIATION: - i_ptr->w_pos=1;//???? - //-------------- <<<<<<<<<<<<<<<<<<<<<<<<---------------------------------------- - break; - }; - - i_ptr=i_ptr->next; - - if (kill_ptr) + i_ptr = i_ptr->next; + + if (kill_ptr) { - client_list_delete(kill_ptr); - kill_ptr=0; + client_list_delete(kill_ptr); + kill_ptr = 0; } } @@ -2268,512 +2276,512 @@ while (i_ptr) void process_c2c_read(fd_set *readfds) { -int i,ret; -struct cclink *cc,*kill_ptr; + int i, ret; + struct cclink *cc, *kill_ptr; -cc=cclink_list_head; -kill_ptr=0; + cc = cclink_list_head; + kill_ptr = 0; -while(cc) + while(cc) { - if ((cc->state==PICA_CCLINK_LOCAL_ACTIVE || cc->state==PICA_CCLINK_N2NCLR_ACTIVE) - && FD_ISSET(cc->sck_p1,readfds) && !cc->jam_p1p2 ) + if ((cc->state == PICA_CCLINK_LOCAL_ACTIVE || cc->state == PICA_CCLINK_N2NCLR_ACTIVE) + && FD_ISSET(cc->sck_p1, readfds) && !cc->jam_p1p2 ) { - ret=recv(cc->sck_p1,cc->buf_p1p2 + cc->bufpos_p1p2,cc->buflen_p1p2 - cc->bufpos_p1p2,0); - PICA_debug3("process_c2c_read: recv p1p2: ret=%i",ret); - if (ret>0) + ret = recv(cc->sck_p1, cc->buf_p1p2 + cc->bufpos_p1p2, cc->buflen_p1p2 - cc->bufpos_p1p2, 0); + PICA_debug3("process_c2c_read: recv p1p2: ret=%i", ret); + if (ret > 0) { - cc->bufpos_p1p2+=ret; + cc->bufpos_p1p2 += ret; } - else - kill_ptr=cc; + else + kill_ptr = cc; } - if ((cc->state==PICA_CCLINK_LOCAL_ACTIVE || cc->state==PICA_CCLINK_N2NCLE_ACTIVE) - && FD_ISSET(cc->sck_p2,readfds) && !cc->jam_p2p1 ) + if ((cc->state == PICA_CCLINK_LOCAL_ACTIVE || cc->state == PICA_CCLINK_N2NCLE_ACTIVE) + && FD_ISSET(cc->sck_p2, readfds) && !cc->jam_p2p1 ) { - ret=recv(cc->sck_p2,cc->buf_p2p1 + cc->bufpos_p2p1,cc->buflen_p2p1 - cc->bufpos_p2p1,0); - PICA_debug3("process_c2c_read: recv p2p1: ret=%i\n",ret); - if (ret>0) + ret = recv(cc->sck_p2, cc->buf_p2p1 + cc->bufpos_p2p1, cc->buflen_p2p1 - cc->bufpos_p2p1, 0); + PICA_debug3("process_c2c_read: recv p2p1: ret=%i\n", ret); + if (ret > 0) { - cc->bufpos_p2p1+=ret; + cc->bufpos_p2p1 += ret; } - else - kill_ptr=cc; + else + kill_ptr = cc; } - cc=cc->next; - - if (kill_ptr) + cc = cc->next; + + if (kill_ptr) { - cclink_list_delete(kill_ptr); - kill_ptr=0; + cclink_list_delete(kill_ptr); + kill_ptr = 0; } } } void process_n2n_read(fd_set *readfds) { -int i,ret; -struct nodelink *nl,*kill_ptr; + int i, ret; + struct nodelink *nl, *kill_ptr; -nl=nodelink_list_head; -kill_ptr=0; + nl = nodelink_list_head; + kill_ptr = 0; -while(nl) + while(nl) { - if (FD_ISSET(nl->sck,readfds)) + if (FD_ISSET(nl->sck, readfds)) { - ret=recv(nl->sck,nl->r_buf+nl->r_pos,nl->buflen_r - nl->r_pos,0); - - if (ret<=0) + ret = recv(nl->sck, nl->r_buf + nl->r_pos, nl->buflen_r - nl->r_pos, 0); + + if (ret <= 0) { - if (ret < 0) - PICA_debug3("recv() failed in process_n2n_read(): %s", strerror(errno)); - kill_ptr=nl; + if (ret < 0) + PICA_debug3("recv() failed in process_n2n_read(): %s", strerror(errno)); + kill_ptr = nl; } - else + else { - nl->r_pos+=ret; - - if(!PICA_processdatastream(nl->r_buf,&(nl->r_pos),nl,_msginfo_node, MSGINFO_MSGSNUM(_msginfo_node) )) - kill_ptr=nl; - - if (nl->buflen_r == nl->r_pos) - if (!nodelink_rbuf_grow(nl)) - kill_ptr=nl; + nl->r_pos += ret; + + if(!PICA_processdatastream(nl->r_buf, &(nl->r_pos), nl, _msginfo_node, MSGINFO_MSGSNUM(_msginfo_node) )) + kill_ptr = nl; + + if (nl->buflen_r == nl->r_pos) + if (!nodelink_rbuf_grow(nl)) + kill_ptr = nl; } } - - nl=nl->next; - - if (kill_ptr) + + nl = nl->next; + + if (kill_ptr) { - nodelink_list_delete(kill_ptr); - kill_ptr=0; + nodelink_list_delete(kill_ptr); + kill_ptr = 0; } } } void process_c2n_write() { -struct client *i_ptr,*kill_ptr; -int ret; + struct client *i_ptr, *kill_ptr; + int ret; -i_ptr=client_list_head; -kill_ptr=0; + i_ptr = client_list_head; + kill_ptr = 0; -while(i_ptr) + while(i_ptr) { - //--------- - switch(i_ptr->state) + //--------- + switch(i_ptr->state) { case PICA_CLSTATE_CONNECTED: - if (!i_ptr->w_pos) - break; - - if (!i_ptr->btw_ssl) - i_ptr->btw_ssl=i_ptr->w_pos; - - ret=SSL_write(i_ptr->ssl_comm,i_ptr->w_buf,i_ptr->btw_ssl); - - PICA_debug3("process_c2n_write: ret of SSL_write()=%i",ret); - - if (ret==i_ptr->btw_ssl) + if (!i_ptr->w_pos) + break; + + if (!i_ptr->btw_ssl) + i_ptr->btw_ssl = i_ptr->w_pos; + + ret = SSL_write(i_ptr->ssl_comm, i_ptr->w_buf, i_ptr->btw_ssl); + + PICA_debug3("process_c2n_write: ret of SSL_write()=%i", ret); + + if (ret == i_ptr->btw_ssl) { - i_ptr->w_pos-=i_ptr->btw_ssl; - i_ptr->btw_ssl=0; + i_ptr->w_pos -= i_ptr->btw_ssl; + i_ptr->btw_ssl = 0; } - if (!ret) - kill_ptr=i_ptr; + if (!ret) + kill_ptr = i_ptr; - if (ret<0) + if (ret < 0) { - ret=SSL_get_error(i_ptr->ssl_comm,ret); - if (ret!=SSL_ERROR_WANT_WRITE && ret!=SSL_ERROR_WANT_READ) - kill_ptr=i_ptr; + ret = SSL_get_error(i_ptr->ssl_comm, ret); + if (ret != SSL_ERROR_WANT_WRITE && ret != SSL_ERROR_WANT_READ) + kill_ptr = i_ptr; } - break; + 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; - - if (ret==SOCKET_ERROR) - ;//ERR_CHECK - - if (ret < i_ptr->w_pos) - memmove(i_ptr->w_buf,i_ptr->w_buf+ret,i_ptr->w_pos - ret); //ring buffer is better (??) - - i_ptr->w_pos-=ret; - - - if (!i_ptr->w_pos) - i_ptr->state=PICA_CLSTATE_TLSNEGOTIATION; - - break; + ret = send(i_ptr->sck_comm, i_ptr->w_buf, i_ptr->w_pos, 0); + if (!ret) + kill_ptr = i_ptr; + + if (ret == SOCKET_ERROR) + ;//ERR_CHECK + + if (ret < i_ptr->w_pos) + memmove(i_ptr->w_buf, i_ptr->w_buf + ret, i_ptr->w_pos - ret); //ring buffer is better (??) + + i_ptr->w_pos -= ret; + + + if (!i_ptr->w_pos) + i_ptr->state = PICA_CLSTATE_TLSNEGOTIATION; + + break; case PICA_CLSTATE_TLSNEGOTIATION: - i_ptr->w_pos=0; - ret=SSL_connect(i_ptr->ssl_comm); - - PICA_debug3("process_c2n_write: SSL_connect()=%i",ret); - - if (!ret) - kill_ptr=i_ptr; - - if (ret<0) + i_ptr->w_pos = 0; + ret = SSL_connect(i_ptr->ssl_comm); + + PICA_debug3("process_c2n_write: SSL_connect()=%i", ret); + + if (!ret) + kill_ptr = i_ptr; + + if (ret < 0) { - int eret; - eret=SSL_get_error(i_ptr->ssl_comm,ret); - switch(eret) + int eret; + eret = SSL_get_error(i_ptr->ssl_comm, ret); + switch(eret) { case SSL_ERROR_WANT_WRITE: - i_ptr->w_pos=1; - PICA_debug3("SSL_ERROR_WANT_WRITE"); - break; + i_ptr->w_pos = 1; + PICA_debug3("SSL_ERROR_WANT_WRITE"); + break; case SSL_ERROR_WANT_READ: - PICA_debug3("SSL_ERROR_WANT_READ"); - break; + PICA_debug3("SSL_ERROR_WANT_READ"); + break; default: - PICA_debug3("SSL_get_error() = %i", eret); - kill_ptr=i_ptr; + PICA_debug3("SSL_get_error() = %i", eret); + kill_ptr = i_ptr; } } - if (ret==1) - //проверить сертификат пользователя - { - X509* client_cert; + if (ret == 1) + //проверить сертификат пользователя + { + X509* client_cert; - PICA_info("SSL c2n connection established using %s cipher", SSL_get_cipher(i_ptr->ssl_comm)); + PICA_info("SSL c2n connection established using %s cipher", SSL_get_cipher(i_ptr->ssl_comm)); - client_cert=SSL_get_peer_certificate (i_ptr->ssl_comm); - if (!client_cert) - { - //ERR_CHECK //нет сертификата - kill_ptr=i_ptr; - } + client_cert = SSL_get_peer_certificate (i_ptr->ssl_comm); + if (!client_cert) + { + //ERR_CHECK //нет сертификата + kill_ptr = i_ptr; + } - ret = PICA_id_from_X509(client_cert, i_ptr->id); - - if (ret == 0) - { - PICA_error("Unable to get client id from certificate"); - kill_ptr=i_ptr; - } - //PICA_debug2("user id=%u",i_ptr->id); - #warning "see comments below" - //сделать проверку названия сети!!!!---------------------------<<<<<<<<<<<<<<<<<<<<<< - - X509_free(client_cert); - //прицепить структуру к дереву - if (client_tree_search(i_ptr->id)) - { - PICA_info("Disconnecting client %p because other user with same ID = %u is already connected", i_ptr, i_ptr->id); - ret = 0;//id already exists in tree - } - else - { - ret=client_tree_add(i_ptr); - client_tree_print(client_tree_root); - } - if (!ret) - { - //ERR_CHECK //не уникальный id - kill_ptr=i_ptr; + ret = PICA_id_from_X509(client_cert, i_ptr->id); + + if (ret == 0) + { + PICA_error("Unable to get client id from certificate"); + kill_ptr = i_ptr; + } + //PICA_debug2("user id=%u",i_ptr->id); +#warning "see comments below" + //сделать проверку названия сети!!!!---------------------------<<<<<<<<<<<<<<<<<<<<<< + + X509_free(client_cert); + //прицепить структуру к дереву + if (client_tree_search(i_ptr->id)) + { + PICA_info("Disconnecting client %p because other user with same ID = %u is already connected", i_ptr, i_ptr->id); + ret = 0;//id already exists in tree + } + else + { + ret = client_tree_add(i_ptr); + client_tree_print(client_tree_root); + } + if (!ret) + { + //ERR_CHECK //не уникальный id + kill_ptr = i_ptr; + } + i_ptr->state = PICA_CLSTATE_CONNECTED; } - i_ptr->state=PICA_CLSTATE_CONNECTED; - } - break; + break; } - //--------- + //--------- - i_ptr=i_ptr->next; + i_ptr = i_ptr->next; - if (kill_ptr) + if (kill_ptr) { - client_list_delete(kill_ptr); - kill_ptr=0; + client_list_delete(kill_ptr); + kill_ptr = 0; } } } void process_c2c_write() { -int i,ret; -struct cclink *cc,*kill_ptr; + int i, ret; + struct cclink *cc, *kill_ptr; -cc=cclink_list_head; -kill_ptr=0; + cc = cclink_list_head; + kill_ptr = 0; -while(cc) + while(cc) { - if (cc->bufpos_p1p2/* && (cc->state==PICA_CCLINK_LOCAL_ACTIVE || cc->state==PICA_CCLINK_N2NCLE_ACTIVE)*/) + if (cc->bufpos_p1p2/* && (cc->state==PICA_CCLINK_LOCAL_ACTIVE || cc->state==PICA_CCLINK_N2NCLE_ACTIVE)*/) { - if (cc->state==PICA_CCLINK_N2NCLR_ACTIVE)//receiver is on remote node + if (cc->state == PICA_CCLINK_N2NCLR_ACTIVE) //receiver is on remote node { - int sendlen; - struct PICA_proto_msg *mp; - - sendlen = (cc->bufpos_p1p2 > PICA_PROTO_N2NMSG_MAXDATASIZE) ? PICA_PROTO_N2NMSG_MAXDATASIZE : cc->bufpos_p1p2; + int sendlen; + struct PICA_proto_msg *mp; - if(mp=nodelink_wbuf_push(cc->callee_node,PICA_PROTO_N2NMSG,sendlen + 4 + 2 * PICA_ID_SIZE)) + sendlen = (cc->bufpos_p1p2 > PICA_PROTO_N2NMSG_MAXDATASIZE) ? PICA_PROTO_N2NMSG_MAXDATASIZE : cc->bufpos_p1p2; + + if(mp = nodelink_wbuf_push(cc->callee_node, PICA_PROTO_N2NMSG, sendlen + 4 + 2 * PICA_ID_SIZE)) { - *((unsigned short*)mp->tail) = 2 * PICA_ID_SIZE + sendlen; - memcpy(mp->tail + 2, cc->caller_id, PICA_ID_SIZE); - memcpy(mp->tail + 2 + PICA_ID_SIZE, cc->callee_id, PICA_ID_SIZE); - memcpy(mp->tail + 2 + 2 * PICA_ID_SIZE, cc->buf_p1p2, sendlen); - ret=sendlen; + *((unsigned short*)mp->tail) = 2 * PICA_ID_SIZE + sendlen; + memcpy(mp->tail + 2, cc->caller_id, PICA_ID_SIZE); + memcpy(mp->tail + 2 + PICA_ID_SIZE, cc->callee_id, PICA_ID_SIZE); + memcpy(mp->tail + 2 + 2 * PICA_ID_SIZE, cc->buf_p1p2, sendlen); + ret = sendlen; } - else - ret=0; + else + ret = 0; } - else - ret=send(cc->sck_p2,cc->buf_p1p2,cc->bufpos_p1p2,MSG_NOSIGNAL); + else + ret = send(cc->sck_p2, cc->buf_p1p2, cc->bufpos_p1p2, MSG_NOSIGNAL); - PICA_debug3("process_c2c_write: send p1p2: ret=%i",ret); - if (ret>0) + PICA_debug3("process_c2c_write: send p1p2: ret=%i", ret); + if (ret > 0) { - if (ret < cc->bufpos_p1p2) - memmove(cc->buf_p1p2,cc->buf_p1p2+ret,cc->bufpos_p1p2-ret);//may be it's better to implement ring buffer here - cc->bufpos_p1p2-=ret; - cc->jam_p1p2=0; + if (ret < cc->bufpos_p1p2) + memmove(cc->buf_p1p2, cc->buf_p1p2 + ret, cc->bufpos_p1p2 - ret); //may be it's better to implement ring buffer here + cc->bufpos_p1p2 -= ret; + cc->jam_p1p2 = 0; } - if (ret==0) + if (ret == 0) { - kill_ptr=cc; + kill_ptr = cc; } - if (ret==-1) + if (ret == -1) { - #ifdef WIN32 - ret=WSAGetLastError(); - if (ret==WSAEWOULDBLOCK || ret==WSAENOBUFS) - cc->jam_p1p2=1; - else +#ifdef WIN32 + ret = WSAGetLastError(); + if (ret == WSAEWOULDBLOCK || ret == WSAENOBUFS) + cc->jam_p1p2 = 1; + else { - kill_ptr=cc; + kill_ptr = cc; } - #else - ret=errno; - if (ret==EAGAIN || ret==ENOBUFS) - cc->jam_p1p2=1; - else +#else + ret = errno; + if (ret == EAGAIN || ret == ENOBUFS) + cc->jam_p1p2 = 1; + else { - kill_ptr=cc; + kill_ptr = cc; } - #endif +#endif } - + } - if (cc->bufpos_p2p1 /*&& (cc->state==PICA_CCLINK_LOCAL_ACTIVE || cc->state==PICA_CCLINK_N2NCLR_ACTIVE)*/) + if (cc->bufpos_p2p1 /*&& (cc->state==PICA_CCLINK_LOCAL_ACTIVE || cc->state==PICA_CCLINK_N2NCLR_ACTIVE)*/) { - if (cc->state==PICA_CCLINK_N2NCLE_ACTIVE)//receiver is on remote node + if (cc->state == PICA_CCLINK_N2NCLE_ACTIVE) //receiver is on remote node { - int sendlen; - struct PICA_proto_msg *mp; - - sendlen = (cc->bufpos_p2p1 > PICA_PROTO_N2NMSG_MAXDATASIZE) ? PICA_PROTO_N2NMSG_MAXDATASIZE : cc->bufpos_p2p1; + int sendlen; + struct PICA_proto_msg *mp; + + sendlen = (cc->bufpos_p2p1 > PICA_PROTO_N2NMSG_MAXDATASIZE) ? PICA_PROTO_N2NMSG_MAXDATASIZE : cc->bufpos_p2p1; - if(mp=nodelink_wbuf_push(cc->caller_node,PICA_PROTO_N2NMSG,sendlen + 4 + 2 * PICA_ID_SIZE)) + if(mp = nodelink_wbuf_push(cc->caller_node, PICA_PROTO_N2NMSG, sendlen + 4 + 2 * PICA_ID_SIZE)) { - *((unsigned short*)mp->tail) = 2 * PICA_ID_SIZE + sendlen; - memcpy(mp->tail + 2, cc->callee_id, PICA_ID_SIZE); - memcpy(mp->tail + 2 + PICA_ID_SIZE, cc->caller_id, PICA_ID_SIZE); - memcpy(mp->tail +2 + 2 * PICA_ID_SIZE, cc->buf_p2p1, sendlen); - ret=sendlen; + *((unsigned short*)mp->tail) = 2 * PICA_ID_SIZE + sendlen; + memcpy(mp->tail + 2, cc->callee_id, PICA_ID_SIZE); + memcpy(mp->tail + 2 + PICA_ID_SIZE, cc->caller_id, PICA_ID_SIZE); + memcpy(mp->tail + 2 + 2 * PICA_ID_SIZE, cc->buf_p2p1, sendlen); + ret = sendlen; } - else - ret=0; + else + ret = 0; } - else - ret=send(cc->sck_p1,cc->buf_p2p1,cc->bufpos_p2p1,MSG_NOSIGNAL); + else + ret = send(cc->sck_p1, cc->buf_p2p1, cc->bufpos_p2p1, MSG_NOSIGNAL); - PICA_debug3("process_c2c_write: send p2p1: ret=%i",ret); - if (ret>0) + PICA_debug3("process_c2c_write: send p2p1: ret=%i", ret); + if (ret > 0) { - if (ret < cc->bufpos_p2p1) - memmove(cc->buf_p2p1,cc->buf_p2p1+ret,cc->bufpos_p2p1-ret);//may be it's better to implement ring buffer here - cc->bufpos_p2p1-=ret; - cc->jam_p2p1=0; + if (ret < cc->bufpos_p2p1) + memmove(cc->buf_p2p1, cc->buf_p2p1 + ret, cc->bufpos_p2p1 - ret); //may be it's better to implement ring buffer here + cc->bufpos_p2p1 -= ret; + cc->jam_p2p1 = 0; } - if (ret==0) + if (ret == 0) { - kill_ptr=cc; + kill_ptr = cc; } - if (ret==-1) + if (ret == -1) { - #ifdef WIN32 - ret=WSAGetLastError(); - if (ret==WSAEWOULDBLOCK || ret==WSAENOBUFS) - cc->jam_p2p1=1; - else +#ifdef WIN32 + ret = WSAGetLastError(); + if (ret == WSAEWOULDBLOCK || ret == WSAENOBUFS) + cc->jam_p2p1 = 1; + else { - kill_ptr=cc; + kill_ptr = cc; } - #else - ret=errno; - if (ret==EAGAIN || ret==ENOBUFS) - cc->jam_p2p1=1; - else +#else + ret = errno; + if (ret == EAGAIN || ret == ENOBUFS) + cc->jam_p2p1 = 1; + else { - kill_ptr=cc; + kill_ptr = cc; } - #endif - +#endif + } - + } - - cc=cc->next; - - if (kill_ptr) + + cc = cc->next; + + if (kill_ptr) { - cclink_list_delete(kill_ptr); - kill_ptr=0; + cclink_list_delete(kill_ptr); + kill_ptr = 0; } } } void process_n2n_write() { -int ret; -struct nodelink *nl,*kill_ptr; + int ret; + struct nodelink *nl, *kill_ptr; -nl=nodelink_list_head; -kill_ptr=0; + nl = nodelink_list_head; + kill_ptr = 0; -while(nl) + while(nl) { - if (nl->w_pos>0) + if (nl->w_pos > 0) { - ret=send(nl->sck,nl->w_buf,nl->w_pos,MSG_NOSIGNAL); + ret = send(nl->sck, nl->w_buf, nl->w_pos, MSG_NOSIGNAL); - if (ret>0) + if (ret > 0) { - 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; + 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; } - if (ret<0) + if (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 +#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; + if (ret == 0) + kill_ptr = nl; } - nl=nl->next; - - if (kill_ptr) + nl = nl->next; + + if (kill_ptr) { - nodelink_list_delete(kill_ptr); - kill_ptr=0; + nodelink_list_delete(kill_ptr); + kill_ptr = 0; } } } void process_nodewait() { -struct nodewait *kill_ptr = 0, *nw = nodewait_list; + struct nodewait *kill_ptr = 0, *nw = nodewait_list; -while(nw) - { - //PICA_debug3("checking nodewait pointer %p", nw); - switch(nw->state) + while(nw) { - case PICA_NODEWAIT_RESOLVED: + //PICA_debug3("checking nodewait pointer %p", nw); + switch(nw->state) { - int skip = 0; - struct nodelink *nl; - - nl = nodelink_list_head; + case PICA_NODEWAIT_RESOLVED: + { + int skip = 0; + struct nodelink *nl; + + nl = nodelink_list_head; - while(nl && !skip)//check existing connections + while(nl && !skip)//check existing connections { - struct addrinfo *p_ai = nw->ai; + struct addrinfo *p_ai = nw->ai; - while(p_ai) //IPv6 + while(p_ai) //IPv6 { - struct sockaddr_in in = *(struct sockaddr_in*)p_ai->ai_addr; + struct sockaddr_in in = *(struct sockaddr_in*)p_ai->ai_addr; - if (nl->addr.sin_family == in.sin_family && nl->addr.sin_addr.s_addr == in.sin_addr.s_addr && nl->addr.sin_port == in.sin_port) + if (nl->addr.sin_family == in.sin_family && nl->addr.sin_addr.s_addr == in.sin_addr.s_addr && nl->addr.sin_port == in.sin_port) { - skip = 1; - break; + skip = 1; + break; } - p_ai = p_ai->ai_next; + p_ai = p_ai->ai_next; } - nl = nl->next; + nl = nl->next; } - if (!skip) - nodewait_start_connect(nw); - else + if (!skip) + nodewait_start_connect(nw); + else { - PICA_debug3("skipping node %.255s %u , connection already exist", nw->addr.addr, nw->addr.port); - kill_ptr = nw; + PICA_debug3("skipping node %.255s %u , connection already exist", nw->addr.addr, nw->addr.port); + kill_ptr = nw; } } - break; + break; - case PICA_NODEWAIT_CONNECTED: + case PICA_NODEWAIT_CONNECTED: { - struct nodelink *nlp; - - PICA_debug1("connected to %.255s %u, sending request ", nw->addr.addr, nw->addr.port); - PICA_debug2("connection socket is %i", nw->nc.sck); - nlp=nodelink_list_addnew(&nw->nc); - if (nlp) + struct nodelink *nlp; + + PICA_debug1("connected to %.255s %u, sending request ", nw->addr.addr, nw->addr.port); + PICA_debug2("connection socket is %i", nw->nc.sck); + nlp = nodelink_list_addnew(&nw->nc); + if (nlp) { - struct PICA_proto_msg *mp; - mp = nodelink_wbuf_push(nlp, PICA_PROTO_NODECONNREQ, PICA_PROTO_NODECONNREQ_SIZE); - if (mp) + struct PICA_proto_msg *mp; + mp = nodelink_wbuf_push(nlp, PICA_PROTO_NODECONNREQ, PICA_PROTO_NODECONNREQ_SIZE); + if (mp) { - mp->tail[0] = PICA_PROTO_VER_HIGH; - mp->tail[1] = PICA_PROTO_VER_LOW; + mp->tail[0] = PICA_PROTO_VER_HIGH; + mp->tail[1] = PICA_PROTO_VER_LOW; } } - PICA_nodeaddr_update(nodecfg.nodes_db_file, &nw->addr, 1); - kill_ptr = nw; + PICA_nodeaddr_update(nodecfg.nodes_db_file, &nw->addr, 1); + kill_ptr = nw; } - break; + break; - case PICA_NODEWAIT_RESOLVING_FAILED: + case PICA_NODEWAIT_RESOLVING_FAILED: { - PICA_debug1("resolving %.255s %u failed: %s", nw->addr.addr, nw->addr.port, gai_strerror(nw->ai_errorcode)); - PICA_nodeaddr_update(nodecfg.nodes_db_file, &nw->addr, 0); - kill_ptr = nw; + PICA_debug1("resolving %.255s %u failed: %s", nw->addr.addr, nw->addr.port, gai_strerror(nw->ai_errorcode)); + PICA_nodeaddr_update(nodecfg.nodes_db_file, &nw->addr, 0); + kill_ptr = nw; } - break; + break; - case PICA_NODEWAIT_CONNECT_FAILED: + case PICA_NODEWAIT_CONNECT_FAILED: { - PICA_debug1("connection to %.255s %u failed", nw->addr.addr, nw->addr.port); - PICA_debug2("socket %i is closed", nw->nc.sck); - PICA_nodeaddr_update(nodecfg.nodes_db_file, &nw->addr, 0); - kill_ptr = nw; + PICA_debug1("connection to %.255s %u failed", nw->addr.addr, nw->addr.port); + PICA_debug2("socket %i is closed", nw->nc.sck); + PICA_nodeaddr_update(nodecfg.nodes_db_file, &nw->addr, 0); + kill_ptr = nw; } - break; - } - - nw = nw->next; + break; + } + + nw = nw->next; - if (kill_ptr) + if (kill_ptr) { - nodewait_list_delete(kill_ptr); - kill_ptr = 0; + nodewait_list_delete(kill_ptr); + kill_ptr = 0; } } @@ -2781,57 +2789,57 @@ while(nw) int node_loop() { -fd_set fds; -struct timeval tv; -int nfds, ret; - -do - { - nfds = 0; - - FD_ZERO(&fds); - tv.tv_sec=SELECT_TIMEOUT; - tv.tv_usec=0; - - listen_set_fds(&fds,&nfds); - newconn_set_fds(&fds,&nfds); - c2n_set_fds(&fds,&nfds); - c2c_set_fds(&fds,&nfds); - n2n_set_fds(&fds,&nfds); - - ret=select(nfds+1,&fds,0,0,&tv); - - if (ret<0) - { - perror("node_loop-select error "); - //ERR_CHECK - return -1; + fd_set fds; + struct timeval tv; + int nfds, ret; + + do + { + nfds = 0; + + FD_ZERO(&fds); + tv.tv_sec = SELECT_TIMEOUT; + tv.tv_usec = 0; + + listen_set_fds(&fds, &nfds); + newconn_set_fds(&fds, &nfds); + c2n_set_fds(&fds, &nfds); + c2c_set_fds(&fds, &nfds); + n2n_set_fds(&fds, &nfds); + + ret = select(nfds + 1, &fds, 0, 0, &tv); + + if (ret < 0) + { + perror("node_loop-select error "); + //ERR_CHECK + return -1; } - if (ret>0) + if (ret > 0) { - process_c2n_read(&fds); - process_c2c_read(&fds); - process_n2n_read(&fds); - process_newconn_read(&fds); - process_listen_read(&fds); + process_c2n_read(&fds); + process_c2c_read(&fds); + process_n2n_read(&fds); + process_newconn_read(&fds); + process_listen_read(&fds); } - - - process_c2n_write(); - process_c2c_write(); - process_n2n_write(); - - process_timeouts(); - process_nodewait(); + + + process_c2n_write(); + process_c2c_write(); + process_n2n_write(); + + process_timeouts(); + process_nodewait(); } -while(1);////<<<<<<<<<< -return 0; + while(1);////<<<<<<<<<< + return 0; } void print_usage() { -puts("Usage: pica-node [-f config-file]\n\ + puts("Usage: pica-node [-f config-file]\n\ \n\ Options:\n\ -f configuration file\n\ @@ -2842,167 +2850,167 @@ Options:\n\ void print_version() { -puts("Pica Pica Node v"PACKAGE_VERSION" \n(c) 2012 - 2014 Anton Sviridenko\n"); -puts("protocol version "PICA_PROTO_VER_STRING"\n"); + puts("Pica Pica Node v"PACKAGE_VERSION" \n(c) 2012 - 2014 Anton Sviridenko\n"); + puts("protocol version "PICA_PROTO_VER_STRING"\n"); ////----include this only if OpenSSL is statically linked -puts("This product includes software developed by the OpenSSL Project\n\ + puts("This product includes software developed by the OpenSSL Project\n\ for use in the OpenSSL Toolkit (http://www.openssl.org/)\n"); -puts("This product includes cryptographic software written by\n\ + puts("This product includes cryptographic software written by\n\ Eric Young (eay@cryptsoft.com)\n"); -puts(SSLeay_version(SSLEAY_VERSION)); + puts(SSLeay_version(SSLEAY_VERSION)); ////--- -puts("\nThis product includes iniParser\n\ + puts("\nThis product includes iniParser\n\ Copyright (c) 2000-2012 by Nicolas Devillard.\n\ MIT License"); } -void process_cmdline(int argc,char** argv) +void process_cmdline(int argc, char** argv) { -int opt; -int verbosity = 0; + int opt; + int verbosity = 0; -while((opt = getopt(argc, argv, "f:hvV")) != -1) + while((opt = getopt(argc, argv, "f:hvV")) != -1) { - switch(opt) + switch(opt) { case 'f': - nodecfg.config_file = strdup(optarg); - break; - + nodecfg.config_file = strdup(optarg); + break; + case 'h': - print_usage(); - exit(0); - break; - + print_usage(); + exit(0); + break; + case 'v': - verbosity++; - - break; - + verbosity++; + + break; + case 'V': - print_version(); - exit(0); - break; - + print_version(); + exit(0); + break; + default: - PICA_error("unknown option - %c", optopt); - print_usage(); - exit(-1); + PICA_error("unknown option - %c", optopt); + print_usage(); + exit(-1); } } -if (verbosity > 3) - verbosity = 3; + if (verbosity > 3) + verbosity = 3; -PICA_set_loglevel(PICA_LOG_INFO + verbosity); + PICA_set_loglevel(PICA_LOG_INFO + verbosity); } void PICA_node_joinskynet(const char* addrlistfilename, const char *my_addr) { -struct PICA_nodeaddr *nap,*addrlist_h=0; -struct nodelink *nl; -int ret; + struct PICA_nodeaddr *nap, *addrlist_h = 0; + struct nodelink *nl; + int ret; -skynet_refresh_tmst = time(0); + skynet_refresh_tmst = time(0); -ret = PICA_nodeaddr_list_load(addrlistfilename, &addrlist_h);//MEM -if (ret <= 0) - return; + ret = PICA_nodeaddr_list_load(addrlistfilename, &addrlist_h);//MEM + if (ret <= 0) + return; -nap = addrlist_h; + nap = addrlist_h; -while(nap) + while(nap) { - int skip = 0; + int skip = 0; - if (0 == strncmp(nap->addr, my_addr, 256) && nap->port == atoi(nodecfg.listen_port)) + if (0 == strncmp(nap->addr, my_addr, 256) && nap->port == atoi(nodecfg.listen_port)) { - PICA_debug3("Skipping self address %.255s port %u", nap->addr, nap->port); - skip = 1; + PICA_debug3("Skipping self address %.255s port %u", nap->addr, nap->port); + skip = 1; } - - if (nodecfg.disable_reserved_addrs && INADDR_NONE != inet_addr(nap->addr) && PICA_is_reserved_addr_ipv4(inet_addr(nap->addr))) + + if (nodecfg.disable_reserved_addrs && INADDR_NONE != inet_addr(nap->addr) && PICA_is_reserved_addr_ipv4(inet_addr(nap->addr))) { - PICA_debug3("Skipping IP from private range %.255s port %u", nap->addr, nap->port); - skip = 1; + PICA_debug3("Skipping IP from private range %.255s port %u", nap->addr, nap->port); + skip = 1; } - - nl = nodelink_list_head; - //check if connection to node with current address is already established - while(nl && !skip) + + nl = nodelink_list_head; + //check if connection to node with current address is already established + while(nl && !skip) { - if (nl->node_addr) + if (nl->node_addr) { - switch(nl->addr_type) + switch(nl->addr_type) { - case PICA_PROTO_NEWNODE_IPV4: - if (0 == strncmp(nap->addr, inet_ntoa(*(struct in_addr*)&(((struct PICA_nodeaddr_ipv4*)nl->node_addr)->addr)) , 16) - && - nap->port == ntohs(((struct PICA_nodeaddr_ipv4*)nl->node_addr)->port)) - skip = 1; - break; - //IPv6 + case PICA_PROTO_NEWNODE_IPV4: + if (0 == strncmp(nap->addr, inet_ntoa(*(struct in_addr*) & (((struct PICA_nodeaddr_ipv4*)nl->node_addr)->addr)) , 16) + && + nap->port == ntohs(((struct PICA_nodeaddr_ipv4*)nl->node_addr)->port)) + skip = 1; + break; + //IPv6 } } - - if (0 == strncmp(nap->addr, inet_ntoa(nl->addr.sin_addr),16) && nap->port == ntohs(nl->addr.sin_port)) - skip = 1; - - - nl = nl->next; + + if (0 == strncmp(nap->addr, inet_ntoa(nl->addr.sin_addr), 16) && nap->port == ntohs(nl->addr.sin_port)) + skip = 1; + + + nl = nl->next; } - - if (!skip) - nodewait_start_resolve(nap); - - nap=nap->next; + + if (!skip) + nodewait_start_resolve(nap); + + nap = nap->next; } -PICA_nodeaddr_list_free(addrlist_h); + PICA_nodeaddr_list_free(addrlist_h); } -int main(int argc,char** argv) +int main(int argc, char** argv) { -process_cmdline(argc, argv); + process_cmdline(argc, argv); -nodecfg.config_file = (nodecfg.config_file ? nodecfg.config_file :PICA_NODECONFIG_DEF_CONFIG_FILE); + nodecfg.config_file = (nodecfg.config_file ? nodecfg.config_file : PICA_NODECONFIG_DEF_CONFIG_FILE); -if (!PICA_nodeconfig_load(nodecfg.config_file)) + if (!PICA_nodeconfig_load(nodecfg.config_file)) { - PICA_fatal("Unable to load configuration. Please check if config file %s exists and has correct permissions", nodecfg.config_file); + PICA_fatal("Unable to load configuration. Please check if config file %s exists and has correct permissions", nodecfg.config_file); } -PICA_debug1("nodecfg.config_file = %s", nodecfg.config_file); -PICA_debug1("nodecfg.announced_addr = %s",nodecfg.announced_addr); -PICA_debug1("nodecfg.listen_port = %s",nodecfg.listen_port); -PICA_debug1("nodecfg.nodes_db_file = %s",nodecfg.nodes_db_file); -PICA_debug1("nodecfg.disable_reserved_addrs = %s", nodecfg.disable_reserved_addrs ? "yes" : "no"); + PICA_debug1("nodecfg.config_file = %s", nodecfg.config_file); + PICA_debug1("nodecfg.announced_addr = %s", nodecfg.announced_addr); + PICA_debug1("nodecfg.listen_port = %s", nodecfg.listen_port); + PICA_debug1("nodecfg.nodes_db_file = %s", nodecfg.nodes_db_file); + PICA_debug1("nodecfg.disable_reserved_addrs = %s", nodecfg.disable_reserved_addrs ? "yes" : "no"); -if (!PICA_node_init()) - return -1; + if (!PICA_node_init()) + return -1; -if (INADDR_NONE == inet_addr(nodecfg.announced_addr) || INADDR_ANY == inet_addr(nodecfg.announced_addr)) + if (INADDR_NONE == inet_addr(nodecfg.announced_addr) || INADDR_ANY == inet_addr(nodecfg.announced_addr)) { - PICA_fatal("announced_addr (%.16s) is invalid or not configured. Please set correct public IP address of your pica-node instance in config file.", - nodecfg.announced_addr - ); + PICA_fatal("announced_addr (%.16s) is invalid or not configured. Please set correct public IP address of your pica-node instance in config file.", + nodecfg.announced_addr + ); } - -if (nodecfg.disable_reserved_addrs && PICA_is_reserved_addr_ipv4(inet_addr(nodecfg.announced_addr))) + + if (nodecfg.disable_reserved_addrs && PICA_is_reserved_addr_ipv4(inet_addr(nodecfg.announced_addr))) { - PICA_fatal("announced_addr (%.16s) is in private range and is unacceptable for global Internet. Private ranges are disabled by node configuration.", - nodecfg.announced_addr - ); + PICA_fatal("announced_addr (%.16s) is in private range and is unacceptable for global Internet. Private ranges are disabled by node configuration.", + nodecfg.announced_addr + ); } -PICA_node_joinskynet(nodecfg.nodes_db_file, nodecfg.announced_addr);//CONF-CONF имя файла с адресами узлов, свой адрес + PICA_node_joinskynet(nodecfg.nodes_db_file, nodecfg.announced_addr);//CONF-CONF имя файла с адресами узлов, свой адрес -my_addr = nodecfg.announced_addr;//TEMP FIXME + my_addr = nodecfg.announced_addr;//TEMP FIXME -return node_loop(); + return node_loop(); } diff --git a/PICA_node.h b/PICA_node.h old mode 100755 new mode 100644 index e635df2..4d95417 --- a/PICA_node.h +++ b/PICA_node.h @@ -68,8 +68,8 @@ #define PICA_NETWORKNAME "TESTNET" // TEMP //CONF #define NEWCONN_BUFSIZE 58 //FIXME this is the size of CONNID packet, this packet is followed by TLS session negotiation data. - //TLS data must not be interpreted as some PICA packet by PICA_processdatastream(), - //so buffer size is limited by the size of CONNID. +//TLS data must not be interpreted as some PICA packet by PICA_processdatastream(), +//so buffer size is limited by the size of CONNID. #define DEFAULT_BUF_SIZE 4096 @@ -78,92 +78,92 @@ struct nodelink; struct client { -unsigned char id[PICA_ID_SIZE]; -struct client *up; -struct client *left; -struct client *right; -SOCKET sck_comm; -struct sockaddr_in addr; -SSL *ssl_comm; -unsigned char *r_buf; -unsigned char *w_buf; -unsigned int buflen_r; -unsigned int buflen_w; -unsigned int r_pos; -unsigned int w_pos; - -unsigned int btw_ssl;//кол-во отправляемых байтов, передаваемое функции SSL_write + unsigned char id[PICA_ID_SIZE]; + struct client *up; + struct client *left; + struct client *right; + SOCKET sck_comm; + struct sockaddr_in addr; + SSL *ssl_comm; + unsigned char *r_buf; + unsigned char *w_buf; + unsigned int buflen_r; + unsigned int buflen_w; + unsigned int r_pos; + unsigned int w_pos; + + unsigned int btw_ssl;//кол-во отправляемых байтов, передаваемое функции SSL_write //Если требуется повторный вызов SSL_write,то нужно передавать те же значения аргументов,а w_pos может быть увеличен // -int state; -struct client* next;//структура client может быть одновременно в составе дерева и линейного списка -struct client* prev; + int state; + struct client* next;//структура client может быть одновременно в составе дерева и линейного списка + struct client* prev; -time_t tmst; -int disconnect_ticking;//on sending message TO client this var is set to 1, on receiving some message FROM client this var is reset to 0 + time_t tmst; + int disconnect_ticking;//on sending message TO client this var is set to 1, on receiving some message FROM client this var is reset to 0 }; struct cclink //структура, описывающая соединение двух клиентов между собой через сервер { //unsigned int cclink_id; -unsigned int state; - -time_t tmst; -struct client *p1;//caller -struct client *p2;//callee - -unsigned char *caller_id; -unsigned char *callee_id; - -struct nodelink *caller_node; -struct nodelink *callee_node; - -SOCKET sck_p1; -SOCKET sck_p2; -int jam_p1p2; -int jam_p2p1; -char* buf_p1p2; -char* buf_p2p1; -unsigned int buflen_p1p2; -unsigned int buflen_p2p1; -unsigned int bufpos_p1p2; -unsigned int bufpos_p2p1; -struct cclink *next; -struct cclink *prev; - -int disconnect_ticking; + unsigned int state; + + time_t tmst; + struct client *p1;//caller + struct client *p2;//callee + + unsigned char *caller_id; + unsigned char *callee_id; + + struct nodelink *caller_node; + struct nodelink *callee_node; + + SOCKET sck_p1; + SOCKET sck_p2; + int jam_p1p2; + int jam_p2p1; + char* buf_p1p2; + char* buf_p2p1; + unsigned int buflen_p1p2; + unsigned int buflen_p2p1; + unsigned int bufpos_p1p2; + unsigned int bufpos_p2p1; + struct cclink *next; + struct cclink *prev; + + int disconnect_ticking; }; struct newconn //структура, описывающая новое подключение (клиента) { -SOCKET sck; -struct sockaddr_in addr; -time_t tmst; -int pos; -unsigned char buf[NEWCONN_BUFSIZE]; + SOCKET sck; + struct sockaddr_in addr; + time_t tmst; + int pos; + unsigned char buf[NEWCONN_BUFSIZE]; }; struct nodelink { -struct sockaddr_in addr; -SOCKET sck; -SSL *ssl; + struct sockaddr_in addr; + SOCKET sck; + SSL *ssl; -unsigned int addr_type;//тип адреса узла - PICA_PROTO_NEWNODE_IPV4,PICA_PROTE_NEWNODE_IPV6,... -void *node_addr;//указатель на структуру адреса {PICA_nodeaddr_ipv4, PICA_nodeaddr_ipv6,PICA_nodeaddr_dns,..} + unsigned int addr_type;//тип адреса узла - PICA_PROTO_NEWNODE_IPV4,PICA_PROTE_NEWNODE_IPV6,... + void *node_addr;//указатель на структуру адреса {PICA_nodeaddr_ipv4, PICA_nodeaddr_ipv6,PICA_nodeaddr_dns,..} -unsigned char *r_buf; -unsigned char *w_buf; -unsigned int buflen_r; -unsigned int buflen_w; -unsigned int r_pos; -unsigned int w_pos; + unsigned char *r_buf; + unsigned char *w_buf; + unsigned int buflen_r; + unsigned int buflen_w; + unsigned int r_pos; + unsigned int w_pos; -struct nodelink *next; -struct nodelink *prev; + struct nodelink *next; + struct nodelink *prev; -time_t tmst; -int disconnect_ticking; + time_t tmst; + int disconnect_ticking; }; diff --git a/PICA_nodeaddrlist.c b/PICA_nodeaddrlist.c old mode 100755 new mode 100644 index 6e262f9..52e4f29 --- a/PICA_nodeaddrlist.c +++ b/PICA_nodeaddrlist.c @@ -16,224 +16,224 @@ struct cb_param { -struct PICA_nodeaddr **n_addr; -int *N; + struct PICA_nodeaddr **n_addr; + int *N; }; int PICA_is_reserved_addr_ipv4(in_addr_t addr) { if ((addr & PREFIX8) == 0 //0.0.0.0/8 - || (addr & PREFIX8) == MAKEIP(10, 0, 0, 0) //10.0.0.0/8 - || (addr & PREFIX8) == MAKEIP(127, 0, 0, 0)//127.0.0.0/8 - || (addr & PREFIX16) == MAKEIP(169, 254, 0, 0) //169.254.0.0/16 - || (addr & PREFIX12) == MAKEIP(172, 16, 0, 0) //172.16.0.0/12 - || (addr & PREFIX16) == MAKEIP(192, 168, 0, 0) //192.168.0.0/16 - || (addr & PREFIX4) == MAKEIP(224, 0, 0, 0) //224.0.0.0/4 - || (addr & PREFIX4) == MAKEIP(240, 0, 0, 0) //240.0.0.0/4 - || addr == INADDR_BROADCAST - ) - return 1; - -return 0; + || (addr & PREFIX8) == MAKEIP(10, 0, 0, 0) //10.0.0.0/8 + || (addr & PREFIX8) == MAKEIP(127, 0, 0, 0)//127.0.0.0/8 + || (addr & PREFIX16) == MAKEIP(169, 254, 0, 0) //169.254.0.0/16 + || (addr & PREFIX12) == MAKEIP(172, 16, 0, 0) //172.16.0.0/12 + || (addr & PREFIX16) == MAKEIP(192, 168, 0, 0) //192.168.0.0/16 + || (addr & PREFIX4) == MAKEIP(224, 0, 0, 0) //224.0.0.0/4 + || (addr & PREFIX4) == MAKEIP(240, 0, 0, 0) //240.0.0.0/4 + || addr == INADDR_BROADCAST + ) + return 1; + + return 0; } static int nodeaddr_load_sqlite_cb(void *p, int argc, char **argv, char **ColName) { -struct cb_param *cp = (struct cb_param*)p; -struct PICA_nodeaddr *na; + struct cb_param *cp = (struct cb_param*)p; + struct PICA_nodeaddr *na; -if (argc != 4) - return 1; + if (argc != 4) + return 1; -na = (struct PICA_nodeaddr *)malloc(sizeof(struct PICA_nodeaddr)); + na = (struct PICA_nodeaddr *)malloc(sizeof(struct PICA_nodeaddr)); -if (!na) - return 1; + if (!na) + return 1; -PICA_debug1("node address loaded: addr: %s port %s\n", argv[0], argv[1]);//debug + PICA_debug1("node address loaded: addr: %s port %s\n", argv[0], argv[1]);//debug -strncpy(na->addr, argv[0], 255); -na->addr[255] = '\0'; + strncpy(na->addr, argv[0], 255); + na->addr[255] = '\0'; -na->port = atoi(argv[1]); + na->port = atoi(argv[1]); -na->inactive_count = atoi(argv[2]); + na->inactive_count = atoi(argv[2]); -na->last_active = atoi(argv[3]); + na->last_active = atoi(argv[3]); -na->next = *(cp->n_addr); + na->next = *(cp->n_addr); -*(cp->n_addr) = na; -(*(cp->N))++; + *(cp->n_addr) = na; + (*(cp->N))++; -return 0; + return 0; } -int PICA_nodeaddr_list_load(const char* dbfilename,struct PICA_nodeaddr **list_head) +int PICA_nodeaddr_list_load(const char* dbfilename, struct PICA_nodeaddr **list_head) { - int N=0, ret; -sqlite3 *db; -char *zErrMsg = 0; -const char query[] = "select address, port, inactive_count, last_active from nodes order by inactive_count desc, last_active asc"; -struct cb_param p = {list_head, &N}; + int N = 0, ret; + sqlite3 *db; + char *zErrMsg = 0; + const char query[] = "select address, port, inactive_count, last_active from nodes order by inactive_count desc, last_active asc"; + struct cb_param p = {list_head, &N}; -ret = sqlite3_open_v2(dbfilename, &db, SQLITE_OPEN_READWRITE, NULL); + ret = sqlite3_open_v2(dbfilename, &db, SQLITE_OPEN_READWRITE, NULL); -if (ret != SQLITE_OK) + if (ret != SQLITE_OK) { - PICA_fatal( "Can't open nodelist database (%s): %s\n", dbfilename, sqlite3_errmsg(db)); - sqlite3_close(db); - return -1; + PICA_fatal( "Can't open nodelist database (%s): %s\n", dbfilename, sqlite3_errmsg(db)); + sqlite3_close(db); + return -1; } -ret = sqlite3_exec(db, query, nodeaddr_load_sqlite_cb, &p, &zErrMsg); + ret = sqlite3_exec(db, query, nodeaddr_load_sqlite_cb, &p, &zErrMsg); -if( ret != SQLITE_OK ) + if( ret != SQLITE_OK ) { - PICA_error("SQL error: %s\n", zErrMsg); - sqlite3_free(zErrMsg); + PICA_error("SQL error: %s\n", zErrMsg); + sqlite3_free(zErrMsg); } -sqlite3_close(db); -return N; + sqlite3_close(db); + return N; } int PICA_nodeaddr_update(const char* dbfilename, struct PICA_nodeaddr *naddr, int is_alive) { -sqlite3 *db; -sqlite3_stmt *stmt; -int ret; -const char q1[] = "update nodes set last_active = strftime('%s','now'), inactive_count = 0 where address = :addr and port = :port"; -const char q2[] = "update nodes set inactive_count = inactive_count + 1 where address = :addr and port = :port"; -char *query; + sqlite3 *db; + sqlite3_stmt *stmt; + int ret; + const char q1[] = "update nodes set last_active = strftime('%s','now'), inactive_count = 0 where address = :addr and port = :port"; + const char q2[] = "update nodes set inactive_count = inactive_count + 1 where address = :addr and port = :port"; + char *query; -query = is_alive ? q1 : q2; + query = is_alive ? q1 : q2; -ret = sqlite3_open(dbfilename, &db); + ret = sqlite3_open(dbfilename, &db); -if (ret != SQLITE_OK) + if (ret != SQLITE_OK) { - PICA_error("Can't open nodelist database: %s\n", sqlite3_errmsg(db)); - sqlite3_close(db); - return -1; + PICA_error("Can't open nodelist database: %s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + return -1; } -ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL); + ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL); -if (ret != SQLITE_OK) + if (ret != SQLITE_OK) { - PICA_error("Can't prepare SQLite statement: %s\n", sqlite3_errmsg(db)); - sqlite3_close(db); - return -1; + PICA_error("Can't prepare SQLite statement: %s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + return -1; } -ret = sqlite3_bind_text(stmt, 1, naddr->addr, -1, SQLITE_STATIC); + ret = sqlite3_bind_text(stmt, 1, naddr->addr, -1, SQLITE_STATIC); -if (ret != SQLITE_OK) + if (ret != SQLITE_OK) { - PICA_error("Can't bind address value: %s\n", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - sqlite3_close(db); - return -1; + PICA_error("Can't bind address value: %s\n", sqlite3_errmsg(db)); + sqlite3_finalize(stmt); + sqlite3_close(db); + return -1; } -ret = sqlite3_bind_int(stmt, 2, naddr->port); + ret = sqlite3_bind_int(stmt, 2, naddr->port); -if (ret != SQLITE_OK) + if (ret != SQLITE_OK) { - PICA_error("Can't bind port value: %s\n", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - sqlite3_close(db); - return -1; + PICA_error("Can't bind port value: %s\n", sqlite3_errmsg(db)); + sqlite3_finalize(stmt); + sqlite3_close(db); + return -1; } -ret = sqlite3_step(stmt); + ret = sqlite3_step(stmt); + + if (ret != SQLITE_DONE) + { + PICA_error( "Can't execute query: %s\n", sqlite3_errmsg(db)); + sqlite3_finalize(stmt); + sqlite3_close(db); + return -1; + } -if (ret !=SQLITE_DONE) -{ - PICA_error( "Can't execute query: %s\n", sqlite3_errmsg(db)); sqlite3_finalize(stmt); sqlite3_close(db); - return -1; -} -sqlite3_finalize(stmt); -sqlite3_close(db); - -return 1; + return 1; } int PICA_nodeaddr_save(const char* dbfilename, struct PICA_nodeaddr *naddr) { -sqlite3 *db; -sqlite3_stmt *stmt; -int ret; -const char query[] = "insert into nodes (address, port, last_active, inactive_count) values(:addr, :port, strftime('%s','now'), 0);"; + sqlite3 *db; + sqlite3_stmt *stmt; + int ret; + const char query[] = "insert into nodes (address, port, last_active, inactive_count) values(:addr, :port, strftime('%s','now'), 0);"; -ret = sqlite3_open(dbfilename, &db); + ret = sqlite3_open(dbfilename, &db); -if (ret != SQLITE_OK) + if (ret != SQLITE_OK) { - PICA_error("Can't open nodelist database: %s\n", sqlite3_errmsg(db)); - sqlite3_close(db); - return -1; + PICA_error("Can't open nodelist database: %s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + return -1; } -ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL); + ret = sqlite3_prepare_v2(db, query, -1, &stmt, NULL); -if (ret != SQLITE_OK) + if (ret != SQLITE_OK) { - PICA_error("Can't prepare SQLite statement: %s\n", sqlite3_errmsg(db)); - sqlite3_close(db); - return -1; + PICA_error("Can't prepare SQLite statement: %s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + return -1; } -ret = sqlite3_bind_text(stmt, 1, naddr->addr, -1, SQLITE_STATIC); + ret = sqlite3_bind_text(stmt, 1, naddr->addr, -1, SQLITE_STATIC); -if (ret != SQLITE_OK) + if (ret != SQLITE_OK) { - PICA_error("Can't bind address value: %s\n", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - sqlite3_close(db); - return -1; + PICA_error("Can't bind address value: %s\n", sqlite3_errmsg(db)); + sqlite3_finalize(stmt); + sqlite3_close(db); + return -1; } -ret = sqlite3_bind_int(stmt, 2, naddr->port); + ret = sqlite3_bind_int(stmt, 2, naddr->port); -if (ret != SQLITE_OK) + if (ret != SQLITE_OK) { - PICA_error("Can't bind port value: %s\n", sqlite3_errmsg(db)); - sqlite3_finalize(stmt); - sqlite3_close(db); - return -1; + PICA_error("Can't bind port value: %s\n", sqlite3_errmsg(db)); + sqlite3_finalize(stmt); + sqlite3_close(db); + return -1; } -ret = sqlite3_step(stmt); + ret = sqlite3_step(stmt); + + if (ret != SQLITE_DONE) + { + PICA_error( "Can't execute query: %s\n", sqlite3_errmsg(db)); + sqlite3_finalize(stmt); + sqlite3_close(db); + return -1; + } -if (ret !=SQLITE_DONE) -{ - PICA_error( "Can't execute query: %s\n", sqlite3_errmsg(db)); sqlite3_finalize(stmt); sqlite3_close(db); - return -1; -} - -sqlite3_finalize(stmt); -sqlite3_close(db); -return 1; + return 1; } void PICA_nodeaddr_list_free(struct PICA_nodeaddr *list_head) { -struct PICA_nodeaddr *pp,*pn; -pp=list_head; + struct PICA_nodeaddr *pp, *pn; + pp = list_head; -while(pp) + while(pp) { - pn=pp->next; - free(pp); - pp=pn; + pn = pp->next; + free(pp); + pp = pn; } } \ No newline at end of file diff --git a/PICA_nodeaddrlist.h b/PICA_nodeaddrlist.h old mode 100755 new mode 100644 index 7200cc7..b90de8f --- a/PICA_nodeaddrlist.h +++ b/PICA_nodeaddrlist.h @@ -1,5 +1,5 @@ -// Описание структур и функций для работы со списком адресов узлов -// +// Описание структур и функций для работы со списком адресов узлов +// #ifndef PICA_NODEADDRLIST_H #define PICA_NODEADDRLIST_H @@ -21,37 +21,37 @@ typedef u_short in_port_t; struct PICA_nodeaddr_ipv4 { -int magick; -in_addr_t addr; -in_port_t port;//network byte order + int magick; + in_addr_t addr; + in_port_t port;//network byte order }; struct PICA_nodeaddr_ipv6 { -int magick; -struct in6_addr addr; -in_port_t port;//network byte order + int magick; + struct in6_addr addr; + in_port_t port;//network byte order }; struct PICA_nodeaddr_dns { -int magick; -unsigned int addr_len; -char addr[256]; -in_port_t port;//network byte order + int magick; + unsigned int addr_len; + char addr[256]; + in_port_t port;//network byte order }; struct PICA_nodeaddr { -char addr[256];//макс. длина DNS имени 255 символов -int inactive_count;//кол-во зафиксированных подряд случаев недоступности узла -time_t last_active;// -in_port_t port;//номер порта - host byte order + char addr[256];//макс. длина DNS имени 255 символов + int inactive_count;//кол-во зафиксированных подряд случаев недоступности узла + time_t last_active;// + in_port_t port;//номер порта - host byte order -struct PICA_nodeaddr *next; + struct PICA_nodeaddr *next; }; int PICA_is_reserved_addr_ipv4(in_addr_t); -int PICA_nodeaddr_list_load(const char* dbfilename,struct PICA_nodeaddr **list_head); +int PICA_nodeaddr_list_load(const char* dbfilename, struct PICA_nodeaddr **list_head); int PICA_nodeaddr_save(const char* dbfilename, struct PICA_nodeaddr *naddr); int PICA_nodeaddr_update(const char* dbfilename, struct PICA_nodeaddr *naddr, int is_alive); int PICA_nodeaddr_list_add();// diff --git a/PICA_nodeconfig.c b/PICA_nodeconfig.c index 3e7e851..01abecf 100644 --- a/PICA_nodeconfig.c +++ b/PICA_nodeconfig.c @@ -1,4 +1,4 @@ - + #include "PICA_nodeconfig.h" #include "iniparser/src/iniparser.h" @@ -10,20 +10,20 @@ struct nodeconfig nodecfg; int PICA_nodeconfig_load(const char *config_file) { -dictionary *d; + dictionary *d; -d = iniparser_load(config_file); + d = iniparser_load(config_file); -if (!d) - return 0; + if (!d) + return 0; -nodecfg.announced_addr = strdup(iniparser_getstring(d, "pica-node:announced_addr", PICA_NODECONFIG_DEF_ANNOUNCED_ADDR)); -nodecfg.listen_port = strdup(iniparser_getstring(d, "pica-node:listen_port", PICA_NODECONFIG_DEF_LISTEN_PORT)); -nodecfg.nodes_db_file = strdup(iniparser_getstring(d, "pica-node:nodes_db_file", PICA_NODECONFIG_DEF_NODES_DB_FILE)); -nodecfg.CA_cert_file = strdup(iniparser_getstring(d, "pica-node:CA_cert_file", PICA_NODECONFIG_DEF_CA_CERT_FILE)); -nodecfg.disable_reserved_addrs = iniparser_getboolean(d, "pica-node:disable_reserved_addrs", 1); + nodecfg.announced_addr = strdup(iniparser_getstring(d, "pica-node:announced_addr", PICA_NODECONFIG_DEF_ANNOUNCED_ADDR)); + nodecfg.listen_port = strdup(iniparser_getstring(d, "pica-node:listen_port", PICA_NODECONFIG_DEF_LISTEN_PORT)); + nodecfg.nodes_db_file = strdup(iniparser_getstring(d, "pica-node:nodes_db_file", PICA_NODECONFIG_DEF_NODES_DB_FILE)); + nodecfg.CA_cert_file = strdup(iniparser_getstring(d, "pica-node:CA_cert_file", PICA_NODECONFIG_DEF_CA_CERT_FILE)); + nodecfg.disable_reserved_addrs = iniparser_getboolean(d, "pica-node:disable_reserved_addrs", 1); -iniparser_freedict(d); + iniparser_freedict(d); -return 1; + return 1; } \ No newline at end of file diff --git a/PICA_nodeconfig.h b/PICA_nodeconfig.h index 2c63cc3..708b103 100644 --- a/PICA_nodeconfig.h +++ b/PICA_nodeconfig.h @@ -1,4 +1,4 @@ - + #ifndef PICA_NODECONFIG_H #define PICA_NODECONFIG_H @@ -8,7 +8,7 @@ #ifndef PICA_SYSCONFDIR #define PICA_SYSCONFDIR "/etc" -#endif +#endif #ifndef PICA_LOCALSTATEDIR #define PICA_LOCALSTATEDIR "/var" @@ -22,12 +22,12 @@ struct nodeconfig { -char *announced_addr; -char *listen_port; -char *nodes_db_file; -char *config_file; -char *CA_cert_file; -int disable_reserved_addrs; + char *announced_addr; + char *listen_port; + char *nodes_db_file; + char *config_file; + char *CA_cert_file; + int disable_reserved_addrs; //int conn_speed_limit; }; diff --git a/PICA_nodewait.c b/PICA_nodewait.c index d9b49b0..4be919b 100644 --- a/PICA_nodewait.c +++ b/PICA_nodewait.c @@ -1,4 +1,4 @@ - + #include "PICA_nodewait.h" #include "PICA_log.h" #include "PICA_common.h" @@ -26,45 +26,45 @@ struct nodewait *nodewait_list; struct nodewait *nodewait_list_addnew() { -struct nodewait *nw; - -nw = (struct nodewait*)calloc(1, sizeof(struct nodewait)); - -if (!nw) - return 0; + struct nodewait *nw; + + nw = (struct nodewait*)calloc(1, sizeof(struct nodewait)); + + if (!nw) + return 0; -nw->next = nodewait_list; -nodewait_list = nw; + nw->next = nodewait_list; + nodewait_list = nw; -nw->state = PICA_NODEWAIT_NEW; -return nw; + nw->state = PICA_NODEWAIT_NEW; + return nw; } void nodewait_list_delete(struct nodewait *nw) { -struct nodewait **pp = &nodewait_list; -struct nodewait *p = nodewait_list; + struct nodewait **pp = &nodewait_list; + struct nodewait *p = nodewait_list; -PICA_debug3("nodewait_list_delete(%p)", nw); + PICA_debug3("nodewait_list_delete(%p)", nw); -while(p) + while(p) { - if (p == nw) + if (p == nw) { - *pp = nw->next; - // - //free resources - // - if (nw->ai) - freeaddrinfo(nw->ai); - - free(nw); - - return; + *pp = nw->next; + // + //free resources + // + if (nw->ai) + freeaddrinfo(nw->ai); + + free(nw); + + return; } - - pp = &p->next; - p = p->next; + + pp = &p->next; + p = p->next; } } @@ -74,15 +74,15 @@ static DWORD WINAPI nodewait_resolve_thread (void *arg) static void *nodewait_resolve_thread (void *arg) #endif { -/* -* DO NOT CALL LOGGING FUNCTIONS HERE, THEY ARE NOT THREAD-SAFE -*/ -struct nodewait *nw = (struct nodewait *)arg; -struct addrinfo h; -char portbuf[8]; + /* + * DO NOT CALL LOGGING FUNCTIONS HERE, THEY ARE NOT THREAD-SAFE + */ + struct nodewait *nw = (struct nodewait *)arg; + struct addrinfo h; + char portbuf[8]; -memset(&h,0,sizeof(struct addrinfo)); + memset(&h, 0, sizeof(struct addrinfo)); #ifdef AI_ADDRCONFIG #ifdef AI_IDN @@ -94,21 +94,21 @@ memset(&h,0,sizeof(struct addrinfo)); #define H_AI_FLAGS 0 #endif -h.ai_flags=H_AI_FLAGS; -h.ai_family=AF_INET;//CONF - IPv4, IPv6, IPv4 then IPv6, IPv6 then IPv4 -h.ai_socktype=SOCK_STREAM; -h.ai_protocol=IPPROTO_TCP; + h.ai_flags = H_AI_FLAGS; + h.ai_family = AF_INET; //CONF - IPv4, IPv6, IPv4 then IPv6, IPv6 then IPv4 + h.ai_socktype = SOCK_STREAM; + h.ai_protocol = IPPROTO_TCP; -sprintf(portbuf,"%u",nw->addr.port); + sprintf(portbuf, "%u", nw->addr.port); -nw->ai_errorcode = getaddrinfo(nw->addr.addr, portbuf, &h, &nw->ai); + nw->ai_errorcode = getaddrinfo(nw->addr.addr, portbuf, &h, &nw->ai); -if (nw->ai_errorcode) - nw->state = PICA_NODEWAIT_RESOLVING_FAILED; -else - nw->state = PICA_NODEWAIT_RESOLVED; + if (nw->ai_errorcode) + nw->state = PICA_NODEWAIT_RESOLVING_FAILED; + else + nw->state = PICA_NODEWAIT_RESOLVED; -return 0; + return 0; } @@ -118,121 +118,121 @@ static DWORD WINAPI nodewait_connect_thread (void *arg) static void *nodewait_connect_thread (void *arg) #endif { -/* -* DO NOT CALL LOGGING FUNCTIONS HERE, THEY ARE NOT THREAD-SAFE -*/ -struct nodewait *nw = (struct nodewait *)arg; -struct addrinfo *ap; + /* + * DO NOT CALL LOGGING FUNCTIONS HERE, THEY ARE NOT THREAD-SAFE + */ + struct nodewait *nw = (struct nodewait *)arg; + struct addrinfo *ap; -ap = nw->ai; + ap = nw->ai; -while(ap) + while(ap) { - nw->nc.sck=socket(ap->ai_family,ap->ai_socktype,ap->ai_protocol); - if (nw->nc.sck==SOCKET_ERROR) + nw->nc.sck = socket(ap->ai_family, ap->ai_socktype, ap->ai_protocol); + if (nw->nc.sck == SOCKET_ERROR) { - ap=ap->ai_next; - continue; + ap = ap->ai_next; + continue; } - if (0 != connect(nw->nc.sck,ap->ai_addr,ap->ai_addrlen)) + if (0 != connect(nw->nc.sck, ap->ai_addr, ap->ai_addrlen)) { - ap=ap->ai_next; - - CLOSE(nw->nc.sck); - continue; + ap = ap->ai_next; + + CLOSE(nw->nc.sck); + continue; } - else + else { - break; + break; } } -if (ap) + if (ap) { - nw->nc.addr=*((struct sockaddr_in*)(ap->ai_addr)); + nw->nc.addr = *((struct sockaddr_in*)(ap->ai_addr)); - nw->state = PICA_NODEWAIT_CONNECTED; - return 1; + nw->state = PICA_NODEWAIT_CONNECTED; + return 1; } -nw->state = PICA_NODEWAIT_CONNECT_FAILED; -return 0; + nw->state = PICA_NODEWAIT_CONNECT_FAILED; + return 0; } void nodewait_start_resolve(struct PICA_nodeaddr *a) { -struct nodewait *nw; + struct nodewait *nw; #ifndef WIN32 -pthread_t thr; -pthread_attr_t attr; + pthread_t thr; + pthread_attr_t attr; #else -DWORD thread_id; -HANDLE thread_h; + DWORD thread_id; + HANDLE thread_h; #endif -nw = nodewait_list_addnew(); + nw = nodewait_list_addnew(); -if (!nw) - return; + if (!nw) + return; -nw ->addr = *a; + nw ->addr = *a; -PICA_debug1("starting to resolve node address %.255s %u ...", nw->addr.addr, nw->addr.port); + PICA_debug1("starting to resolve node address %.255s %u ...", nw->addr.addr, nw->addr.port); -nw->state = PICA_NODEWAIT_RESOLVING; + nw->state = PICA_NODEWAIT_RESOLVING; #ifndef WIN32 -if (0 != pthread_attr_init(&attr)) - PICA_error("pthread_attr_init() call failed."); + if (0 != pthread_attr_init(&attr)) + PICA_error("pthread_attr_init() call failed."); -pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); -if (0 != pthread_create(&thr, &attr, nodewait_resolve_thread, (void*)nw)) - PICA_error("unable to create thread: %s", strerror(errno)); + if (0 != pthread_create(&thr, &attr, nodewait_resolve_thread, (void*)nw)) + PICA_error("unable to create thread: %s", strerror(errno)); -pthread_attr_destroy(&attr); + pthread_attr_destroy(&attr); #else -thread_h = CreateThread(NULL, 4096, nodewait_resolve_thread, (void*)nw, 0, &thread_id); + thread_h = CreateThread(NULL, 4096, nodewait_resolve_thread, (void*)nw, 0, &thread_id); -if (NULL != thread_h) - CloseHandle(thread_h); -else - PICA_error("unable to create thread: %u", GetLastError()); + if (NULL != thread_h) + CloseHandle(thread_h); + else + PICA_error("unable to create thread: %u", GetLastError()); #endif } void nodewait_start_connect(struct nodewait *nw) { #ifndef WIN32 -pthread_t thr; -pthread_attr_t attr; + pthread_t thr; + pthread_attr_t attr; #else -DWORD thread_id; -HANDLE thread_h; + DWORD thread_id; + HANDLE thread_h; #endif -PICA_debug1("connecting to node %.255s %u ...", nw->addr.addr, nw->addr.port); + PICA_debug1("connecting to node %.255s %u ...", nw->addr.addr, nw->addr.port); -nw->state = PICA_NODEWAIT_CONNECTING; + nw->state = PICA_NODEWAIT_CONNECTING; #ifndef WIN32 -if (0 != pthread_attr_init(&attr)) - PICA_error("pthread_attr_init() call failed."); + if (0 != pthread_attr_init(&attr)) + PICA_error("pthread_attr_init() call failed."); -pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); -if (0 != pthread_create(&thr, &attr, nodewait_connect_thread, (void*)nw)) - PICA_error("unable to create thread: %s", strerror(errno)); + if (0 != pthread_create(&thr, &attr, nodewait_connect_thread, (void*)nw)) + PICA_error("unable to create thread: %s", strerror(errno)); -pthread_attr_destroy(&attr); + pthread_attr_destroy(&attr); #else -thread_h = CreateThread(NULL, 4096, nodewait_connect_thread, (void*)nw, 0, &thread_id); + thread_h = CreateThread(NULL, 4096, nodewait_connect_thread, (void*)nw, 0, &thread_id); -if (NULL != thread_h) - CloseHandle(thread_h); -else - PICA_error("unable to create thread: %u", GetLastError()); + if (NULL != thread_h) + CloseHandle(thread_h); + else + PICA_error("unable to create thread: %u", GetLastError()); #endif } diff --git a/PICA_nodewait.h b/PICA_nodewait.h index e471c18..d7df39b 100644 --- a/PICA_nodewait.h +++ b/PICA_nodewait.h @@ -14,9 +14,9 @@ struct nodewait { -struct newconn nc; -int state; -time_t tmst; + struct newconn nc; + int state; + time_t tmst; //unsigned int addr_type; // union address_ptr @@ -26,12 +26,12 @@ time_t tmst; // struct PICA_nodeaddr_dns *dns; // } addrptr; -struct PICA_nodeaddr addr; + struct PICA_nodeaddr addr; -struct addrinfo *ai; -int ai_errorcode; + struct addrinfo *ai; + int ai_errorcode; -struct nodewait *next; + struct nodewait *next; }; extern struct nodewait *nodewait_list; diff --git a/PICA_proto.h b/PICA_proto.h old mode 100755 new mode 100644 index 71450e8..be162c3 --- a/PICA_proto.h +++ b/PICA_proto.h @@ -122,8 +122,8 @@ struct PICA_proto_msg { -unsigned char head[2]; -unsigned char tail[0]; + unsigned char head[2]; + unsigned char tail[0]; }; -- cgit v1.2.1 From c736cd472eac74b65b5a0ef67ba6acfdcf1b19c2 Mon Sep 17 00:00:00 2001 From: Anton Date: Wed, 13 Apr 2016 22:20:48 +0400 Subject: asynchronous processing of c2c connections, work in progress --- PICA_client.c | 210 +++++++++++++++++++++++++++++++++++++++++++++------------- PICA_client.h | 7 ++ 2 files changed, 170 insertions(+), 47 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 0d728f4..3d199b9 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -206,7 +206,7 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) return preverify_ok; } -static int add_chaninfo(struct PICA_c2n *ci, struct PICA_c2c **chn, const unsigned char *peer_id, int is_outgoing) +static int c2n_alloc_c2c(struct PICA_c2n *ci, struct PICA_c2c **chn, const unsigned char *peer_id, int is_outgoing) { struct PICA_c2c *chnl, *ipt; @@ -239,34 +239,16 @@ static int add_chaninfo(struct PICA_c2n *ci, struct PICA_c2c **chn, const unsign ci->chan_list_end = chnl; } + chnl->state = PICA_C2C_STATE_NEW; + return 1; } -static int establish_data_connection(struct PICA_c2c *chnl) +static int c2c_stage2_connid(struct PICA_c2c *chnl) { - char* DN_str; -//unsigned char buf[12]; - int ret, err_ret; - unsigned int tmp_uid; struct PICA_proto_msg *mp; - chnl->sck_data = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - - { - struct sockaddr_in addr = chnl->conn->srv_addr; - - addr.sin_port = htons(ntohs(addr.sin_port)); - - ret = connect( chnl->sck_data, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)); -/////////////////state_ - if (ret == SOCKET_ERROR) - { - err_ret = PICA_ERRSOCK; - goto error_ret; - } - } - - mp = c2c_writebuf_push( chnl, PICA_PROTO_CONNID, PICA_PROTO_CONNID_SIZE); + mp = c2c_writebuf_push(chnl, PICA_PROTO_CONNID, PICA_PROTO_CONNID_SIZE); if (mp) { if (chnl->outgoing) @@ -279,6 +261,8 @@ static int establish_data_connection(struct PICA_c2c *chnl) memcpy(mp->tail, chnl->peer_id, PICA_ID_SIZE);//вызвывающий memcpy(mp->tail + PICA_ID_SIZE, chnl->acc->id, PICA_ID_SIZE);//вызываемый } + + chnl->state = PICA_C2C_STATE_CONNID; } else { @@ -286,14 +270,11 @@ static int establish_data_connection(struct PICA_c2c *chnl) goto error_ret; } - do - { - err_ret = PICA_write_c2c(chnl); - if (PICA_OK != err_ret) - goto error_ret; - } - while( chnl->write_pos > 0); + return PICA_OK; +} +static int c2c_stage3_starttls(struct PICA_c2c *chnl) +{ chnl->ssl = SSL_new(chnl->acc->ctx); if (!chnl->ssl) @@ -315,22 +296,29 @@ static int establish_data_connection(struct PICA_c2c *chnl) SSL_set_verify(chnl->ssl, SSL_VERIFY_PEER, verify_callback); SSL_set_verify_depth(chnl->ssl, 1);//peer certificate and one CA - if (chnl->outgoing) ret = SSL_connect(chnl->ssl); else ret = SSL_accept(chnl->ssl); -/////////////////state_ -//printf("verify result:%i\n",(int)SSL_get_verify_result(chnl->ssl));//debug - if (ret != 1) + if (ret == 0) + return PICA_ERRSSL; + + if (ret < 0) { - //printf("ret=%i of SSL_connect or accept\n",ret);//debug - //printf("SSL_get_error says:%i\n",SSL_get_error(chnl->ssl,ret));//debug - err_ret = PICA_ERRSSL; - goto error_ret_; + ret = SSL_get_error(chnl->ssl, ret); + + if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE) + return PICA_ERRSSL; } + chnl->state = PICA_C2C_STATE_WAITINGTLS; + + return PICA_OK; +} + +static int c2c_verify_peer_cert(struct PICA_c2c *chnl) +{ //проверить сертификат собеседника chnl->peer_cert = SSL_get_peer_certificate(chnl->ssl); @@ -396,6 +384,89 @@ static int establish_data_connection(struct PICA_c2c *chnl) BIO_free(mem); } + return PICA_OK; +} + +static int c2c_stage4_sendc2cconnreq(struct PICA_c2c *chnl) +{ + struct PICA_proto_msg *mp; + + mp = c2c_writebuf_push(chnl, PICA_PROTO_C2CCONNREQ, PICA_PROTO_C2CCONNREQ_SIZE); + + if (!mp) + return PICA_ERRNOMEM; + + mp->tail[0] = PICA_C2CPROTO_VER_HIGH; + mp->tail[1] = PICA_C2CPROTO_VER_LOW; + + chnl->state = PICA_C2C_STATE_WAITINGREP; + + return PICA_OK; +} + +static int c2c_start(struct PICA_c2c *chnl) +{ + char* DN_str; + int ret, err_ret; + unsigned int tmp_uid; + + + chnl->sck_data = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + + IOCTLSETNONBLOCKINGSOCKET(chnl->sck_data, 1); + + { + struct sockaddr_in addr = chnl->conn->srv_addr; + + addr.sin_port = htons(ntohs(addr.sin_port)); + + chnl->state = PICA_C2C_STATE_CONNECTING; + + ret = connect(chnl->sck_data, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)); + + if (ret == 0) + return c2c_stage2_connid(chnl); + +/////////////////state_ + 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; + goto error_ret; + } + } + + +/* --- move to process_c2c + do + { + err_ret = PICA_write_c2c(chnl); + if (PICA_OK != err_ret) + goto error_ret; + } + while( chnl->write_pos > 0); +*/ + +/////////////////state_ +//printf("verify result:%i\n",(int)SSL_get_verify_result(chnl->ssl));//debug + + if (ret != 1) + { + //printf("ret=%i of SSL_connect or accept\n",ret);//debug + //printf("SSL_get_error says:%i\n",SSL_get_error(chnl->ssl,ret));//debug + err_ret = PICA_ERRSSL; + goto error_ret_; + } + + + chnl->state = PICA_C2C_STATE_ACTIVE; IOCTLSETNONBLOCKINGSOCKET(chnl->sck_data, 1); @@ -413,14 +484,33 @@ error_ret: static unsigned int procmsg_C2CCONNREQ(unsigned char* buf, unsigned int nb, void* p) { struct PICA_c2c *cc = (struct PICA_c2n *)p; + struct PICA_proto_msg *mp; if (buf[2] == PICA_C2CPROTO_VER_HIGH && buf[3] == PICA_C2CPROTO_VER_LOW) { //send ok + mp = c2c_writebuf_push(cc, PICA_PROTO_INITRESPOK, PICA_PROTO_INITRESPOK_SIZE); + + if (!mp) + return 0; + + mp->tail[0] = 'O'; + mp->tail[1] = 'K'; + + cc->state = PICA_C2C_STATE_ACTIVE; } else { //send verdiffer, disconnect after sending + mp = c2c_writebuf_push(cc, PICA_PROTO_VERDIFFER, PICA_PROTO_VERDIFFER_SIZE); + + if (!mp) + return 0; + + mp->tail[0] = PICA_C2CPROTO_VER_HIGH; + mp->tail[1] = PICA_C2CPROTO_VER_LOW; + + cc->disconnect_on_empty_write_buf = 1; } return 1; @@ -428,6 +518,7 @@ static unsigned int procmsg_C2CCONNREQ(unsigned char* buf, unsigned int nb, void static unsigned int procmsg_INITRESP_c2c(unsigned char* buf, unsigned int nb, void* p) { + -- } static unsigned int procmsg_INITRESP(unsigned char* buf, unsigned int nb, void* p) @@ -474,7 +565,7 @@ static unsigned int procmsg_CONNREQINC(unsigned char* buf, unsigned int nb, void else return 0; - ret = add_chaninfo( ci, &_chnl, peer_id, 0); + ret = c2n_alloc_c2c( ci, &_chnl, peer_id, 0); if (!ret) return 0; //ERR_CHECK - кончилась память @@ -487,7 +578,7 @@ static unsigned int procmsg_CONNREQINC(unsigned char* buf, unsigned int nb, void } while( ci->write_pos > 0); - ret = establish_data_connection(_chnl); + ret = c2c_start(_chnl); if (ret != PICA_OK) return 1; @@ -562,7 +653,7 @@ static unsigned int procmsg_FOUND(unsigned char* buf, unsigned int nb, void* p) if (!rq) return 0;// ERR_CHECK -левое сообщение, такой запрос не посылался - ret = establish_data_connection(rq); + ret = c2c_start(rq); if (ret != PICA_OK) return 0; @@ -1526,7 +1617,7 @@ int PICA_new_c2c(struct PICA_c2n *ci, const unsigned char *peer_id, struct PICA_ if (!(ci && chn)) return PICA_ERRINVARG; - if (!add_chaninfo(ci, chn, peer_id, PICA_c2c_OUTGOING)) + if (!c2n_alloc_c2c(ci, chn, peer_id, PICA_c2c_OUTGOING)) return PICA_ERRNOMEM; chnl = *chn; @@ -1651,11 +1742,30 @@ static int process_c2n(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) static int process_c2c(struct PICA_c2c *c2c, fd_set *rfds, fd_set *wfds) { -//if (ic2c->state == PICA_C2C_STATE_ACTIVE) -// { -// -// } - return PICA_OK; + int ret = PICA_OK; + + switch(c2c->state) + { + case PICA_C2C_STATE_NEW: + break; + + case PICA_C2C_STATE_CONNECTING: + break; + + case PICA_C2C_STATE_CONNID: + break; + + case PICA_C2C_STATE_WAITINGTLS: + break; + + case PICA_C2C_STATE_WAITINGREP: + break; + + case PICA_C2C_STATE_ACTIVE: + break; + } + + return ret; } static int process_listener(struct PICA_listener *lst, fd_set *rfds) @@ -2018,6 +2128,9 @@ int PICA_write_c2n(struct PICA_c2n *ci) else if (PICA_C2N_STATE_CONNECTED == ci->state) ret = PICA_write_ssl( ci->ssl_comm, ci->write_buf, &ci->write_pos, &ci->write_sslbytestowrite); + if (ci->disconnect_on_empty_write_buf) + PICA_close_c2n(ci); + return ret; } @@ -2030,6 +2143,9 @@ int PICA_write_c2c(struct PICA_c2c *chn) else ret = PICA_write_ssl( chn->ssl, chn->write_buf, &chn->write_pos, &chn->write_sslbytestowrite); + if (chn->disconnect_on_empty_write_buf) + PICA_close_c2c(chn); + return ret; } diff --git a/PICA_client.h b/PICA_client.h index 421861a..841a7cf 100644 --- a/PICA_client.h +++ b/PICA_client.h @@ -157,11 +157,16 @@ struct PICA_c2n int init_resp_ok; unsigned char node_ver_major, node_ver_minor; + int disconnect_on_empty_write_buf; }; enum PICA_c2c_state { PICA_C2C_STATE_NEW = 0, + PICA_C2C_STATE_CONNECTING, + PICA_C2C_STATE_CONNID, + PICA_C2C_STATE_WAITINGTLS, + PICA_C2C_STATE_WAITINGREP, PICA_C2C_STATE_ACTIVE }; @@ -196,6 +201,8 @@ struct PICA_c2c uint64_t recvfile_size; uint64_t recvfile_pos; FILE *recvfile_stream; +//this flag should be set when connection must be closed after sending last pushed packet + int disconnect_on_empty_write_buf; }; struct PICA_listener -- cgit v1.2.1 From b2ce204c78131113c1a4a24f69a8d9cc4e5fe34c Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 5 May 2016 20:50:05 +0400 Subject: implemented asynchronous processing of c2c connections --- PICA_client.c | 290 ++++++++++++++++++++++++++++++++++++++-------------------- PICA_client.h | 1 + 2 files changed, 193 insertions(+), 98 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 3d199b9..3b63d02 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -266,8 +266,7 @@ static int c2c_stage2_connid(struct PICA_c2c *chnl) } else { - err_ret = PICA_ERRNOMEM; - goto error_ret; + return PICA_ERRNOMEM; } return PICA_OK; @@ -275,22 +274,20 @@ static int c2c_stage2_connid(struct PICA_c2c *chnl) static int c2c_stage3_starttls(struct PICA_c2c *chnl) { + int ret; + chnl->ssl = SSL_new(chnl->acc->ctx); if (!chnl->ssl) { - //puts("SSL_new !- 0");//debug - err_ret = PICA_ERRSSL; - goto error_ret; + return PICA_ERRSSL; } ret = SSL_set_fd(chnl->ssl, chnl->sck_data); if (!ret) { - //puts("SSL_set_fd returned 0");//debug - err_ret = PICA_ERRSSL; - goto error_ret_; + return PICA_ERRSSL; } SSL_set_verify(chnl->ssl, SSL_VERIFY_PEER, verify_callback); @@ -325,8 +322,7 @@ static int c2c_verify_peer_cert(struct PICA_c2c *chnl) if (!chnl->peer_cert) { - err_ret = PICA_ERRNOPEERCERT; - goto error_ret_; + return PICA_ERRNOPEERCERT; } { @@ -334,35 +330,14 @@ static int c2c_verify_peer_cert(struct PICA_c2c *chnl) if (PICA_id_from_X509(chnl->peer_cert, temp_id) == 0) { - err_ret = PICA_ERRNOPEERCERT; - goto error_ret_; + return PICA_ERRNOPEERCERT; } if (memcmp(temp_id, chnl->peer_id, PICA_ID_SIZE) != 0) { - err_ret = PICA_ERRINVPEERCERT; - goto error_ret_; + return PICA_ERRINVPEERCERT; } } - /* - DN_str=X509_NAME_oneline(X509_get_subject_name(chnl->peer_cert), 0, 0); - - if (!DN_str) - { - //puts("no DN_str");//debug - err_ret=PICA_ERRSSL; - goto error_ret_; - } - - if (!get_id_fromsubjstr(DN_str,&tmp_uid) || tmp_uid!=chnl->peer_id) - { - err_ret=PICA_ERRINVPEERCERT; - goto error_ret_; - } - //puts(DN_str);//debug - - OPENSSL_free(DN_str);*/ - { @@ -377,8 +352,7 @@ static int c2c_verify_peer_cert(struct PICA_c2c *chnl) if (callbacks.peer_cert_verify_cb(chnl->peer_id, (const char*)cert_pem, cert_pem_nb) == 0) { BIO_free(mem); - err_ret = PICA_ERRINVPEERCERT; - goto error_ret_; + return PICA_ERRINVPEERCERT; } BIO_free(mem); @@ -425,9 +399,18 @@ static int c2c_start(struct PICA_c2c *chnl) ret = connect(chnl->sck_data, (struct sockaddr*)&addr, sizeof(struct sockaddr_in)); if (ret == 0) - return c2c_stage2_connid(chnl); + { + ret = c2c_stage2_connid(chnl); + + if (ret != PICA_OK) + { + err_ret = ret; + goto error_ret; + } + + return PICA_OK; + } -/////////////////state_ if (ret == SOCKET_ERROR) { #ifndef WIN32 @@ -443,38 +426,8 @@ static int c2c_start(struct PICA_c2c *chnl) } } - -/* --- move to process_c2c - do - { - err_ret = PICA_write_c2c(chnl); - if (PICA_OK != err_ret) - goto error_ret; - } - while( chnl->write_pos > 0); -*/ - -/////////////////state_ -//printf("verify result:%i\n",(int)SSL_get_verify_result(chnl->ssl));//debug - - if (ret != 1) - { - //printf("ret=%i of SSL_connect or accept\n",ret);//debug - //printf("SSL_get_error says:%i\n",SSL_get_error(chnl->ssl,ret));//debug - err_ret = PICA_ERRSSL; - goto error_ret_; - } - - - - chnl->state = PICA_C2C_STATE_ACTIVE; - - IOCTLSETNONBLOCKINGSOCKET(chnl->sck_data, 1); - - return PICA_OK; -error_ret_: error_ret: callbacks.c2c_failed(chnl->peer_id); PICA_close_c2c(chnl); @@ -486,6 +439,9 @@ static unsigned int procmsg_C2CCONNREQ(unsigned char* buf, unsigned int nb, void struct PICA_c2c *cc = (struct PICA_c2n *)p; struct PICA_proto_msg *mp; + if (cc->state != PICA_C2C_STATE_WAITINGC2CPROTOVER) + return 0; + if (buf[2] == PICA_C2CPROTO_VER_HIGH && buf[3] == PICA_C2CPROTO_VER_LOW) { //send ok @@ -498,6 +454,8 @@ static unsigned int procmsg_C2CCONNREQ(unsigned char* buf, unsigned int nb, void mp->tail[1] = 'K'; cc->state = PICA_C2C_STATE_ACTIVE; + + callbacks.c2c_established_cb(cc->peer_id); } else { @@ -518,7 +476,31 @@ static unsigned int procmsg_C2CCONNREQ(unsigned char* buf, unsigned int nb, void static unsigned int procmsg_INITRESP_c2c(unsigned char* buf, unsigned int nb, void* p) { - -- + struct PICA_c2c *cc = (struct PICA_c2c *)p; + + if (cc->state != PICA_C2C_STATE_WAITINGREP) + return 0; + + if (!cc->outgoing) + return 0; + + switch(buf[0]) + { + case PICA_PROTO_INITRESPOK: + cc->state = PICA_C2C_STATE_ACTIVE; + callbacks.c2c_established_cb(cc->peer_id); + break; + + case PICA_PROTO_VERDIFFER: + return 0; // -- ??? + break; + + default: + return 0; + } + + + return 1; } static unsigned int procmsg_INITRESP(unsigned char* buf, unsigned int nb, void* p) @@ -583,8 +565,6 @@ static unsigned int procmsg_CONNREQINC(unsigned char* buf, unsigned int nb, void if (ret != PICA_OK) return 1; - callbacks.c2c_established_cb(_chnl->peer_id);//*nchn=_chnl; - return 1; } else @@ -658,8 +638,6 @@ static unsigned int procmsg_FOUND(unsigned char* buf, unsigned int nb, void* p) if (ret != PICA_OK) return 0; - callbacks.c2c_established_cb(rq->peer_id);//*nchn=_chnl; - return 1; } @@ -1635,6 +1613,24 @@ int PICA_new_c2c(struct PICA_c2n *ci, const unsigned char *peer_id, struct PICA_ return PICA_OK; } +static int check_async_connect_result(int sock, struct sockaddr* a, int addrlen) +{ + int ret = PICA_ERRSOCK; + +#ifndef WIN32 + int optval; + socklen_t optlen = sizeof(optval); + + if (0 == getsockopt(sock, SOL_SOCKET, SO_ERROR, &optval, &optlen) && optval == 0) +#else + if (SOCKET_ERROR == connect(sock, a, addrlen) && + WSAEISCONN == WSAGetLastError()) +#endif + ret = PICA_OK; + + return ret; +} + static int process_c2n(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) { int ret = PICA_OK; @@ -1650,29 +1646,13 @@ static int process_c2n(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) if (FD_ISSET(c2n->sck_comm, wfds)) { - ret = PICA_ERRSOCK; + ret = check_async_connect_result(c2n->sck_comm, (struct sockaddr*)&c2n->srv_addr, sizeof(c2n->srv_addr)); - //check if connect() finished successfully -#ifndef WIN32 - int optval; - socklen_t optlen = sizeof(optval); - - if (0 == getsockopt(c2n->sck_comm, SOL_SOCKET, SO_ERROR, &optval, &optlen)) - { - if (optval == 0) - { - ret = c2n_stage2_sendreq(c2n); - } - } -#else - if (SOCKET_ERROR == connect(c2n->ssl_comm, (struct sockaddr*)&c2n->srv_addr, sizeof(c2n->srv_addr)) && - WSAEISCONN == WSAGetLastError()) + if (ret == PICA_OK) { ret = c2n_stage2_sendreq(c2n); } -#endif } - break; case PICA_C2N_STATE_WAITINGREP: @@ -1750,21 +1730,112 @@ static int process_c2c(struct PICA_c2c *c2c, fd_set *rfds, fd_set *wfds) break; case PICA_C2C_STATE_CONNECTING: + + if (FD_ISSET(c2c->sck_data, wfds)) + { + ret = check_async_connect_result(c2c->sck_data, (struct sockaddr*)&c2c->conn->srv_addr, sizeof(c2c->conn->srv_addr)); + + if (ret == PICA_OK) + { + ret = c2c_stage2_connid(c2c); + } + } break; case PICA_C2C_STATE_CONNID: + + if (FD_ISSET(c2c->sck_data, wfds)) + { + ret = PICA_write_c2c(c2c); + } + + if (c2c->write_pos == 0) + { + ret = c2c_stage3_starttls(c2c); + } + break; case PICA_C2C_STATE_WAITINGTLS: + + if (FD_ISSET(c2c->sck_data, wfds) || FD_ISSET(c2c->sck_data, rfds)) + { + int sslret; + + if (c2c->outgoing) + sslret = SSL_connect(c2c->ssl); + else + sslret = SSL_accept(c2c->ssl); + + if (sslret < 0) + { + sslret = SSL_get_error(c2c->ssl, sslret); + + if (sslret != SSL_ERROR_WANT_READ && sslret != SSL_ERROR_WANT_WRITE) + ret = PICA_ERRSSL; + } + else if(sslret == 0) + { + ret = PICA_ERRSSL; + } + else if (sslret == 1) + { + ret = c2c_verify_peer_cert(c2c); + + if (ret == PICA_OK && c2c->outgoing) + ret = c2c_stage4_sendc2cconnreq(c2c); + + if (ret == PICA_OK && c2c->outgoing == 0) + c2c->state = PICA_C2C_STATE_WAITINGC2CPROTOVER; + } + } break; case PICA_C2C_STATE_WAITINGREP: + case PICA_C2C_STATE_WAITINGC2CPROTOVER: + + if (FD_ISSET(c2c->sck_data, wfds)) + { + ret = PICA_write_c2c(c2c); + } + + if (ret == PICA_OK && FD_ISSET(c2c->sck_data, rfds)) + { + ret = PICA_read_c2c(c2c); + } + break; case PICA_C2C_STATE_ACTIVE: + + if (FD_ISSET(c2c->sck_data, wfds)) + { + if (c2c->write_pos > 0) + { + ret = PICA_write_c2c(c2c); + } + else if (c2c->sendfilestate == PICA_CHANSENDFILESTATE_SENDING) + { + ret = PICA_send_file_fragment(c2c); + } + } + + if (ret == PICA_OK && FD_ISSET(c2c->sck_data, rfds)) + { + ret = PICA_read_c2c(c2c); + } + break; } + if (ret != PICA_OK) + { + if (c2c->state > PICA_C2C_STATE_NEW && c2c->state < PICA_C2C_STATE_ACTIVE) + callbacks.c2c_failed(c2c->peer_id); + else + callbacks.c2c_closed_cb(c2c->peer_id, ret); + } + return ret; } @@ -1827,7 +1898,8 @@ int PICA_event_loop(struct PICA_c2n **connections, struct PICA_listener **listen { fdset_add(&rfds, ic2c->sck_data, &nfds); - if (ic2c->write_pos || ic2c->sendfilestate == PICA_CHANSENDFILESTATE_SENDING) + if (ic2c->write_pos || ic2c->state == PICA_C2C_STATE_CONNECTING || ic2c->state == PICA_C2C_STATE_WAITINGTLS + || ic2c->sendfilestate == PICA_CHANSENDFILESTATE_SENDING) fdset_add(&wfds, ic2c->sck_data, &nfds); } @@ -2138,10 +2210,16 @@ int PICA_write_c2c(struct PICA_c2c *chn) { int ret = PICA_ERRINVARG; - if (PICA_C2C_STATE_ACTIVE != chn->state) - ret = PICA_write_socket( chn->sck_data, chn->write_buf, &chn->write_pos); + if (chn->state != PICA_C2C_STATE_ACTIVE && chn->state != PICA_C2C_STATE_CONNID && chn->state != PICA_C2C_STATE_WAITINGREP) + { + fputs("PICA_write_c2c() was called for incorrect state!\n", stderr); + exit(-1); + } + + if (PICA_C2C_STATE_CONNID == chn->state) + ret = PICA_write_socket(chn->sck_data, chn->write_buf, &chn->write_pos); else - ret = PICA_write_ssl( chn->ssl, chn->write_buf, &chn->write_pos, &chn->write_sslbytestowrite); + ret = PICA_write_ssl(chn->ssl, chn->write_buf, &chn->write_pos, &chn->write_sslbytestowrite); if (chn->disconnect_on_empty_write_buf) PICA_close_c2c(chn); @@ -2225,15 +2303,31 @@ int PICA_read_c2c(struct PICA_c2c *chn) { int ret; - if (chn->state != PICA_C2C_STATE_ACTIVE) - return PICA_OK;// ??? + if (chn->state != PICA_C2C_STATE_WAITINGREP && chn->state != PICA_C2C_STATE_WAITINGC2CPROTOVER && chn->state != PICA_C2C_STATE_ACTIVE) + { + fputs("PICA_read_c2c() was called for incorrect state!\n", stderr); + exit(-1); + } -//ret = SSL_read(chn->ssl , chn->read_buf + chn->read_pos, PICA_CHANREADBUFSIZE - chn->read_pos); ret = PICA_read_ssl(chn->ssl, chn->read_buf, &chn->read_pos, PICA_CHANREADBUFSIZE); if (ret == PICA_OK) { - if(!PICA_processdatastream(chn->read_buf, &(chn->read_pos ), chn, c2c_messages, MSGINFO_MSGSNUM(c2c_messages))) + const struct PICA_msginfo *msgs; + unsigned int nmsgs; + + if (chn->state == PICA_C2C_STATE_ACTIVE) + { + nmsgs = MSGINFO_MSGSNUM(c2c_messages); + msgs = c2c_messages; + } + else + { + nmsgs = MSGINFO_MSGSNUM(c2c_init_messages); + msgs = c2c_init_messages; + } + + if(!PICA_processdatastream(chn->read_buf, &(chn->read_pos ), chn, msgs, nmsgs)) return PICA_ERRSERV; } diff --git a/PICA_client.h b/PICA_client.h index 841a7cf..63ab526 100644 --- a/PICA_client.h +++ b/PICA_client.h @@ -167,6 +167,7 @@ enum PICA_c2c_state PICA_C2C_STATE_CONNID, PICA_C2C_STATE_WAITINGTLS, PICA_C2C_STATE_WAITINGREP, + PICA_C2C_STATE_WAITINGC2CPROTOVER, PICA_C2C_STATE_ACTIVE }; -- cgit v1.2.1 From e319f804ffa3a63a986fc5bb0f9a4241245d5a49 Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 5 May 2016 21:55:50 +0400 Subject: appended _cb suffix to callbacks without one --- PICA_client.c | 16 ++++++++-------- PICA_client.h | 10 +++++----- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 3b63d02..a9f8de1 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -429,7 +429,7 @@ static int c2c_start(struct PICA_c2c *chnl) return PICA_OK; error_ret: - callbacks.c2c_failed(chnl->peer_id); + callbacks.c2c_failed_cb(chnl->peer_id); PICA_close_c2c(chnl); return err_ret; } @@ -903,7 +903,7 @@ static unsigned int procmsg_FILEFRAGMENT(unsigned char* buf, unsigned int nb, vo if (chan->recvfile_pos > chan->recvfile_size) //received more than file_size return 0; - callbacks.file_progress(chan->peer_id, 0, chan->recvfile_pos); + callbacks.file_progress_cb(chan->peer_id, 0, chan->recvfile_pos); if (chan->recvfile_pos == chan->recvfile_size) { @@ -911,7 +911,7 @@ static unsigned int procmsg_FILEFRAGMENT(unsigned char* buf, unsigned int nb, vo fclose(chan->recvfile_stream); chan->recvfile_stream = NULL; - callbacks.file_finished(chan->peer_id, 0); + callbacks.file_finished_cb(chan->peer_id, 0); } return 1; @@ -998,7 +998,7 @@ static unsigned int procmsg_FILECONTROL(unsigned char* buf, unsigned int nb, voi } fprintf(stderr, "procmsg_FILECONTROL calling callback\n"); - callbacks.file_control(chan->peer_id, sender_cmd, receiver_cmd); + callbacks.file_control_cb(chan->peer_id, sender_cmd, receiver_cmd); return 1; } @@ -1831,7 +1831,7 @@ static int process_c2c(struct PICA_c2c *c2c, fd_set *rfds, fd_set *wfds) if (ret != PICA_OK) { if (c2c->state > PICA_C2C_STATE_NEW && c2c->state < PICA_C2C_STATE_ACTIVE) - callbacks.c2c_failed(c2c->peer_id); + callbacks.c2c_failed_cb(c2c->peer_id); else callbacks.c2c_closed_cb(c2c->peer_id, ret); } @@ -1936,7 +1936,7 @@ int PICA_event_loop(struct PICA_c2n **connections, struct PICA_listener **listen if (ret != PICA_OK) { - callbacks.listener_error(*ilst, ret); + callbacks.listener_error_cb(*ilst, ret); PICA_close_listener(*ilst); } @@ -2638,7 +2638,7 @@ int PICA_send_file_fragment(struct PICA_c2c *chn) chn->sendfile_pos += fragment_size; - callbacks.file_progress(chn->peer_id, chn->sendfile_pos, 0); + callbacks.file_progress_cb(chn->peer_id, chn->sendfile_pos, 0); if (chn->sendfile_pos >= chn->sendfile_size) { @@ -2646,7 +2646,7 @@ int PICA_send_file_fragment(struct PICA_c2c *chn) fclose(chn->sendfile_stream); chn->sendfile_stream = NULL; - callbacks.file_finished(chn->peer_id, 1); + callbacks.file_finished_cb(chn->peer_id, 1); } if (chn->sendfile_pos > chn->sendfile_size) diff --git a/PICA_client.h b/PICA_client.h index 63ab526..0f47904 100644 --- a/PICA_client.h +++ b/PICA_client.h @@ -228,7 +228,7 @@ struct PICA_client_callbacks //создание канала с собеседником void (*c2c_established_cb)(const unsigned char *peer_id); //создать канал не удалось - void (*c2c_failed)(const unsigned char *peer_id); + void (*c2c_failed_cb)(const unsigned char *peer_id); //входящий запрос на создание канала от пользователя с номером caller_id //возвращаемое значение: 0 - отклонить запрос, ненулевое значение - принять запрос int (*accept_cb)(const unsigned char *caller_id); @@ -247,11 +247,11 @@ struct PICA_client_callbacks void (*denied_file_cb)(const unsigned char *peer_id); - void (*file_progress)(const unsigned char *peer_id, uint64_t sent, uint64_t received); + void (*file_progress_cb)(const unsigned char *peer_id, uint64_t sent, uint64_t received); - void (*file_control)(const unsigned char *peer_id, unsigned int sender_cmd, unsigned int receiver_cmd); + void (*file_control_cb)(const unsigned char *peer_id, unsigned int sender_cmd, unsigned int receiver_cmd); - void (*file_finished)(const unsigned char *peer_id, int sending); + void (*file_finished_cb)(const unsigned char *peer_id, int sending); void (*c2n_established_cb)(struct PICA_c2n *c2n); @@ -259,7 +259,7 @@ struct PICA_client_callbacks void (*c2n_closed_cb)(struct PICA_c2n *c2n); - void (*listener_error)(struct PICA_listener *lst, int errorcode); + void (*listener_error_cb)(struct PICA_listener *lst, int errorcode); }; -- cgit v1.2.1 From 7f25e841d052fed8ea008a1b6843f51e024a25e5 Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 8 May 2016 22:10:48 +0400 Subject: fixed pointer types --- PICA_client.c | 2 +- PICA_client.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index a9f8de1..27e2755 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -436,7 +436,7 @@ error_ret: static unsigned int procmsg_C2CCONNREQ(unsigned char* buf, unsigned int nb, void* p) { - struct PICA_c2c *cc = (struct PICA_c2n *)p; + struct PICA_c2c *cc = (struct PICA_c2c *)p; struct PICA_proto_msg *mp; if (cc->state != PICA_C2C_STATE_WAITINGC2CPROTOVER) diff --git a/PICA_client.h b/PICA_client.h index 0f47904..4e9dd17 100644 --- a/PICA_client.h +++ b/PICA_client.h @@ -173,7 +173,7 @@ enum PICA_c2c_state struct PICA_c2c { - struct PICA_acc *acc; + const struct PICA_acc *acc; struct PICA_c2n *conn;//соединение с сервером, через которое установлен данный логический канал связи unsigned char peer_id[PICA_ID_SIZE]; SOCKET sck_data; @@ -208,7 +208,7 @@ struct PICA_c2c struct PICA_listener { - struct PICA_acc *acc; + const struct PICA_acc *acc; SOCKET sck_listener; int public_port; -- cgit v1.2.1 From 42d945364721a184ec3379c583aed998ade61aaf Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 19 Jun 2016 17:52:34 +0400 Subject: return error from PICA_new_c2c() when c2n argument is not in connected state --- PICA_client.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PICA_client.c b/PICA_client.c index 27e2755..5dc7fb0 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -1595,6 +1595,9 @@ int PICA_new_c2c(struct PICA_c2n *ci, const unsigned char *peer_id, struct PICA_ if (!(ci && chn)) return PICA_ERRINVARG; + if (ci->state != PICA_C2N_STATE_CONNECTED) + return PICA_ERRINVARG; + if (!c2n_alloc_c2c(ci, chn, peer_id, PICA_c2c_OUTGOING)) return PICA_ERRNOMEM; -- cgit v1.2.1 From 9401b1a5fcf6079a00fbd852979ec07891da17fb Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 19 Jun 2016 19:57:41 +0400 Subject: bugfix - add c2c socket to write fd_set if state is connecting or higher --- PICA_client.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 5dc7fb0..7e7dce5 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -1595,8 +1595,8 @@ int PICA_new_c2c(struct PICA_c2n *ci, const unsigned char *peer_id, struct PICA_ if (!(ci && chn)) return PICA_ERRINVARG; - if (ci->state != PICA_C2N_STATE_CONNECTED) - return PICA_ERRINVARG; + if (ci->state != PICA_C2N_STATE_CONNECTED) + return PICA_ERRINVARG; if (!c2n_alloc_c2c(ci, chn, peer_id, PICA_c2c_OUTGOING)) return PICA_ERRNOMEM; @@ -1897,7 +1897,7 @@ int PICA_event_loop(struct PICA_c2n **connections, struct PICA_listener **listen while(ic2c) { - if (ic2c->state == PICA_C2C_STATE_ACTIVE) + if (ic2c->state >= PICA_C2C_STATE_CONNECTING) { fdset_add(&rfds, ic2c->sck_data, &nfds); -- cgit v1.2.1 From d6ac2d840a6f0a18ee41065db9926b585445c19c Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 19 Jun 2016 19:59:12 +0400 Subject: updated test client, now it supports two-way communication --- tests/test_client.c | 336 +++++++++++++++++++++++++--------------------------- 1 file changed, 160 insertions(+), 176 deletions(-) mode change 100755 => 100644 tests/test_client.c diff --git a/tests/test_client.c b/tests/test_client.c old mode 100755 new mode 100644 index 5480eee..5cbd24d --- a/tests/test_client.c +++ b/tests/test_client.c @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include "../PICA_client.h" @@ -10,39 +12,47 @@ struct PICA_acc *acc; struct PICA_c2n *c; struct PICA_c2c *chn; -int _outgoing_chnl=0; +int _outgoing_chnl = 0; -unsigned char buf[64*1024]; +int connected_to_node = 0; +int c2c_active = 0; +int c2c_in_progress = 0; + +unsigned char buf[64 * 1024]; int accept_cb(const unsigned char *id) { -printf("accept_cb: %s\n",PICA_id_to_base64(id, NULL)); -return 1; + printf("accept_cb: %s\n", PICA_id_to_base64(id, NULL)); + return 1; } //получение сообщения. -void newmsg_cb(const unsigned char *peer_id, const char* msgbuf,unsigned int nb,int type) +void newmsg_cb(const unsigned char *peer_id, const char* msgbuf, unsigned int nb, int type) { -memcpy(buf,msgbuf,nb); -buf[nb]=0; -printf(" %s: ",PICA_id_to_base64(peer_id, NULL)); -puts(buf); + memcpy(buf, msgbuf, nb); + buf[nb] = 0; + printf(" %s: ", PICA_id_to_base64(peer_id, NULL)); + puts(buf); } //получение подтверждения о доставке сообщения void msgok_cb(const unsigned char *peer_id) { -puts("[V]"); + puts("[V]"); } //создание канала с собеседником void c2c_established_cb(const unsigned char *peer_id) { -puts("c2c_established_cb"); + c2c_active = 1; + c2c_in_progress = 0; + puts("c2c_established_cb"); + chn = c->chan_list_head;//hack, its better to pass new c2c pointer as callback arg } void c2c_failed_cb(const unsigned char *peer_id) { -printf("Failed to create c2c to %s\n",PICA_id_to_base64(peer_id, NULL)); -chn=0; + c2c_in_progress = 0; + printf("Failed to create c2c to %s\n", PICA_id_to_base64(peer_id, NULL)); + chn = 0; } //входящий запрос на создание канала от пользователя с номером caller_id @@ -50,265 +60,239 @@ chn=0; //запрошенный пользователь не найден, в оффлайне или отказался от общения void notfound_cb(const unsigned char *callee_id) { -puts("notfound_cb"); + puts("notfound_cb"); } void c2c_closed_cb(const unsigned char *peer_id, int reason) { -printf("c2c_closed_cb( peer_id = %s, reason = %i)\n", PICA_id_to_base64(peer_id, NULL), reason); + c2c_active = 0; + c2c_in_progress = 0; + printf("c2c_closed_cb( peer_id = %s, reason = %i)\n", PICA_id_to_base64(peer_id, NULL), reason); } void nodelist_cb(int type, void *addr_bin, const char *addr_str, unsigned int port) { -switch(type) - { - case 0xA0: + switch(type) + { + case 0xA0: printf("node (IP %s port %u)\n", addr_str, port); break; - - case 0xA1: + + case 0xA1: printf("node (IPv6 %s port %u)", addr_str, port); break; - - case 0xA2: + + case 0xA2: printf("node (hostname %s port %u)\n", addr_str, port); break; - - default: + + default: puts("unknown node address type"); return; - } + } } int peer_cert_verify_cb(const unsigned char *peer_id, const char *cert_pem, unsigned int nb) { - printf("peer's certificate (%s): \n%.*s\n", PICA_id_to_base64(peer_id, NULL), nb,cert_pem); - return 1; + printf("peer's certificate (%s): \n%.*s\n", PICA_id_to_base64(peer_id, NULL), nb, cert_pem); + return 1; } int accept_file_cb(const unsigned char *peer_id, uint64_t file_size, const char *filename, unsigned int filename_size) { - printf("accept_file_cb: peer_id %s\n", PICA_id_to_base64(peer_id, NULL)); - return 0; + printf("accept_file_cb: peer_id %s\n", PICA_id_to_base64(peer_id, NULL)); + return 0; } void accepted_file_cb(const unsigned char *peer_id) { - printf("accepted_file_cb: peer_id %s \n", PICA_id_to_base64(peer_id, NULL)); + printf("accepted_file_cb: peer_id %s \n", PICA_id_to_base64(peer_id, NULL)); } void denied_file_cb(const unsigned char *peer_id) { - printf("denied_file_cb: peer_id %s \n", PICA_id_to_base64(peer_id, NULL)); + printf("denied_file_cb: peer_id %s \n", PICA_id_to_base64(peer_id, NULL)); } void file_progress(const unsigned char *peer_id, uint64_t sent, uint64_t received) { - printf("file_progress: peer_id %s\n", PICA_id_to_base64(peer_id, NULL)); + printf("file_progress: peer_id %s\n", PICA_id_to_base64(peer_id, NULL)); } void file_control(const unsigned char *peer_id, unsigned int sender_cmd, unsigned int receiver_cmd) { - printf("file_control: peer_id %s sender_cmd %u receiver_cmd %u \n", PICA_id_to_base64(peer_id, NULL), sender_cmd, receiver_cmd); + printf("file_control: peer_id %s sender_cmd %u receiver_cmd %u \n", PICA_id_to_base64(peer_id, NULL), sender_cmd, receiver_cmd); } void file_finished(const unsigned char *peer_id, int sending) { - printf("file_finished: peer_id %s\n", PICA_id_to_base64(peer_id, NULL)); + printf("file_finished: peer_id %s\n", PICA_id_to_base64(peer_id, NULL)); } void c2n_established_cb(struct PICA_c2n *c2n) { - printf("c2n_established_cb: %p\n peer_id %s\n", c2n, PICA_id_to_base64(c2n->acc->id, NULL)); + connected_to_node = 1; + printf("c2n_established_cb: %p\n my_id %s\n", c2n, PICA_id_to_base64(c2n->acc->id, NULL)); } void c2n_failed_cb(struct PICA_c2n *c2n) { - printf("c2n_failed_cb: %p\n", c2n); + printf("c2n_failed_cb: %p\n", c2n); } void c2n_closed_cb(struct PICA_c2n *c2n) { - printf("c2n_closed_cb: %p\n", c2n); + printf("c2n_closed_cb: %p\n", c2n); } void listener_error(struct PICA_listener *lst, int errorcode) { - printf("listener_error: %p error code %i\n", lst, errorcode); + printf("listener_error: %p error code %i\n", lst, errorcode); } -struct PICA_client_callbacks cbs = { - newmsg_cb, - msgok_cb, - c2c_established_cb, - c2c_failed_cb, - accept_cb, - notfound_cb, - c2c_closed_cb, - nodelist_cb, - peer_cert_verify_cb, - accept_file_cb, - accepted_file_cb, - denied_file_cb, - file_progress, - file_control, - file_finished, - c2n_established_cb, - c2n_failed_cb, - c2n_closed_cb, - listener_error +struct PICA_client_callbacks cbs = +{ + newmsg_cb, + msgok_cb, + c2c_established_cb, + c2c_failed_cb, + accept_cb, + notfound_cb, + c2c_closed_cb, + nodelist_cb, + peer_cert_verify_cb, + accept_file_cb, + accepted_file_cb, + denied_file_cb, + file_progress, + file_control, + file_finished, + c2n_established_cb, + c2n_failed_cb, + c2n_closed_cb, + listener_error }; -int main(int argc,char** argv) +int main(int argc, char** argv) { -int ret; -unsigned char peer_id[PICA_ID_SIZE]; -struct PICA_c2n* c2ns[] = {NULL, NULL}; + int ret; + unsigned char peer_id[PICA_ID_SIZE]; + struct PICA_c2n* c2ns[] = {NULL, NULL}; -if (argc<4) + fd_set stdinfds; + struct timeval tv; + + if (argc < 4) { - puts("usage: test_client address port cert_filename [peer id]"); - return 0; + puts("usage: test_client address port cert_filename [peer id]\ncert_filename should point to file that contains client certificate, private key and Diffie-Hellman parameters in PEM format"); + return 0; } -puts(SSLeay_version(SSLEAY_VERSION)); -printf("Calling PICA_init...\n"); + puts(SSLeay_version(SSLEAY_VERSION)); + printf("Calling PICA_init...\n"); -PICA_client_init(&cbs); + PICA_client_init(&cbs); -// printf("setting address...\n"); -// -// memset(&a,0,sizeof(a)); -// -// a.sin_family = AF_INET; -// a.sin_addr.s_addr = inet_addr (argv[1]);//("127.0.0.1"); -// a.sin_port = htons(51914); + printf("opening account..."); + ret = PICA_open_acc(argv[3], argv[3], argv[3], NULL, &acc); -printf("opening account..."); -ret = PICA_open_acc(argv[3], argv[3],argv[3], NULL, &acc); - -if (ret != PICA_OK) -{ - printf("failed to open account, ret = %i\n", ret); - return 1; -} + if (ret != PICA_OK) + { + printf("failed to open account, ret = %i\n", ret); + return 1; + } -printf("making connection...\n"); + printf("making connection...\n"); //PICA_new_c2n(const char *nodeaddr, unsigned int port, const char *CA_file, const char *cert_file, const char *pkey_file, const char* password, struct PICA_c2n **ci) -ret=PICA_new_c2n(acc, argv[1], atoi(argv[2]), /*"trusted_CA.pem"*/ &c); - -ERR_print_errors_fp(stdout); - -if (ret==PICA_OK) -printf("PICA_OK started c2n connection to node...\n"); -else -{ -printf("PICA_new_c2n: ret=%i\n",ret); -return 1; -} + ret = PICA_new_c2n(acc, argv[1], atoi(argv[2]), /*"trusted_CA.pem"*/ &c); -c2ns[0] = c; + ERR_print_errors_fp(stdout); -if (argc==5) - { - if (PICA_id_from_base64(argv[4], peer_id) == NULL) + if (ret == PICA_OK) + printf("PICA_OK started c2n connection to node...\n"); + else { - puts("invalid peer_id"); - return 1; - } - - printf("Creating c2c to %s...\n",PICA_id_to_base64(peer_id, NULL)); - - ret=PICA_new_c2c(c,peer_id,NULL,&chn); - //sleep(17);//timeout test - if (ret!=PICA_OK) - { - printf("error: ret=%i\n",ret); + printf("PICA_new_c2n: ret=%i\n", ret); return 1; - } - } - while(PICA_event_loop(c2ns, NULL, 1500) == PICA_OK); -/* -do + c2ns[0] = c; + + + while(PICA_event_loop(c2ns, NULL, 500) == PICA_OK) { - if (chn && chn->state==PICA_CHANSTATE_ACTIVE) + //puts("event loop..."); + if (argc == 5 && connected_to_node == 1 && c2c_active == 0 && c2c_in_progress == 0) { - unsigned int msglen; - gets(buf); - msglen=strlen(buf); - - ret=PICA_send_msg(chn,buf,msglen); - - if (ret!=PICA_OK) - printf("PICA_send_msg ret=%i\n",ret); - } - } -while(PICA_read(c,100000) == PICA_OK && PICA_write(c) == PICA_OK);*/ + if (PICA_id_from_base64(argv[4], peer_id) == NULL) + { + puts("invalid peer_id"); + return 1; + } -/* -puts("Enter peer_id to talk with or . for waiting incoming sessions:"); -gets(buf); -if (buf[0]=='.') - { - unsigned int br; - ret=PICA_read_conn(c,accept_cb,&chn); + printf("Creating c2c to %s...\n", PICA_id_to_base64(peer_id, NULL)); - if (ret==PICA_NEWCHAN) + ret = PICA_new_c2c(c, peer_id, NULL, &chn); + //sleep(17);//timeout test + if (ret != PICA_OK) { - puts("PICA_NEWCHAN!"); + printf("error: ret=%i\n", ret); + return 1; } - else - printf("read_conn error: ret=%i\n",ret); - - ret=PICA_read_msg(chn,buf,&br); - switch(ret) + + printf("chn = %p\n", chn); + c2c_in_progress = 1; + + } + + if (connected_to_node == 1 && c2c_active == 1) + { + FD_ZERO(&stdinfds); + FD_SET(STDIN_FILENO, &stdinfds); + + tv.tv_sec = 0; + tv.tv_usec = 500000; + + ret = select(STDIN_FILENO + 1, &stdinfds, NULL, NULL, &tv); + + if (ret == -1) { - case PICA_MSGUTF8: - printf("%u (%u bytes): ",c->id,br); - puts(buf); - break; - case PICA_MSGOK: - puts("[v]"); - break; - default: - printf("PICA_read_msg ret=%i\n",ret); + perror("select() on stdin failed"); + return 1; } - } -else - { - peer_id=atoi(buf); - printf("Creating c2c to %u...\n",peer_id); - - ret=PICA_new_c2c(c,peer_id,&chn,1); - if (ret==PICA_OK) - { - unsigned int msglen; - puts("c2c established..."); - gets(buf); - msglen=strlen(buf); - - ret=PICA_send_msg(chn,buf,msglen); - if (ret!=PICA_OK) - printf("PICA_send_msg ret=%i\n",ret); + if (ret > 0 && FD_ISSET(STDIN_FILENO, &stdinfds)) + { + ret = read(STDIN_FILENO, buf, 256); + + if (ret <= 0) + { + perror("read from stdin"); + return 1; + } + + ret = PICA_send_msg(chn, buf, ret); + + if (ret != PICA_OK) + printf("failed to send message, error = %i\n", ret); + } } - else - printf("error: ret=%i\n",ret); + + } -*/ -sleep(10); -if (chn) + + sleep(10); + + if (chn) { - puts("--------"); - PICA_close_c2c(chn); + puts("--------"); + PICA_close_c2c(chn); } -PICA_close_c2n(c); + PICA_close_c2n(c); -return 0; + return 0; } -- cgit v1.2.1 From 4c9c3beee4bc540d592d7be1c332bb68827f97f0 Mon Sep 17 00:00:00 2001 From: Anton Date: Fri, 24 Jun 2016 22:29:04 +0400 Subject: updated protocol spec --- doc/proto.txt | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/doc/proto.txt b/doc/proto.txt index e8a99ad..53c13c5 100755 --- a/doc/proto.txt +++ b/doc/proto.txt @@ -47,7 +47,7 @@ UH - user hash - SHA224 хэш от сертификата пользовате 0x08 0x08 (UH вызывающего пользователя) +++[запрос списка узлов] - клиент -0x09 0x09 (2 случайных байта) +0x09 0x09 (2 псевдослучайных байта) +++[список узлов] - сервер 0x0A 0x0A -- см формат 0xA4 @@ -67,27 +67,37 @@ UH - user hash - SHA224 хэш от сертификата пользовате 0xCC 0xCC Ver_major Ver_minor - версия протокола клиента варианты ответа - 0x01,0x02 -+++[анонс адреса клиента] ++++[список прямых адресов клиента] +0x0B 0x0B -- см формат A4 0xA0, 0xA1, 0xA1 - аналогично сообщениям n2n -Если клиент настроен для приёма входящих прямых соединений между клиентами (минуя ноду), он может послать анонс своего -адреса. Получив анонс, другой клиент может создать соединение с этим адресом и закрыть соединение через ноду +Если клиент настроен для приёма входящих прямых соединений между клиентами (минуя ноду), он может послать список своих адресов. +Первыми в списке должны идти адреса локальной сети (если они есть) из подсетей 192.168.0.0/16, 172.16.0.0/12, 10.0.0.0/8, +чтобы клиенты, находящиеся в одной локальной сети могли соединиться напрямую. Далее следуют публичные адреса интернета. +Если клиент находится за NAT и пробрасывает открытый порт на свой локальный адрес, в адресе должен быть указан внешний порт. + Получив анонс, другой клиент может создать соединение с этим адресом и закрыть соединение через ноду + ++++[попытки прямого соединения провалились] +0x0C 0x0C (2 псевдослучайных байта) +отправляется инициатором, если он получил от вызываемого клиента список прямых адресов и все попытки подключения к полученным адресам оказались неуспешны. +После получения этого сообщения вызываемый клиент начинает попытки подключения к прямым адресам инициатора, если от инициатора был получен список прямых +адресов и прямые подключения разрешены настройками вызываемого +++[сообщение - текст в кодировке UTF8] 0x30 0x30 (длина сообщения в байтах- 2 байта в формате little-endian) сообщение в кодировке UTF8 +++[отчет о доставке предыдущего сообщения] -0x40 0x40 (2 случайных байта) +0x40 0x40 (2 псевдослучайных байта) +++ [запрос на отправку файла] 0x50 0x50 (длина сообщения - 2 байта, 9..263) (размер файла - 8 байт) имя файла в UTF-8, 1 - 255 байт +++ [подтверждение принятия файла] -0x51 0x51 (2 случайных байта) +0x51 0x51 (2 псевдослучайных байта) после получения этого сообщения отправитель начинает отправку файла +++ [отказ от приёма файла] -0x52 0x52 (2 случайных байта) +0x52 0x52 (2 псевдослучайных байта) +++ [фрагмент файла] 0x53 0x53 (длина фрагмента - 2 байта, 0 - 65532) фрагмент файла @@ -100,10 +110,10 @@ UH - user hash - SHA224 хэш от сертификата пользовате Пинг +++[пинг-запрос] - может быть отправлен любой стороной, как по управляющему соединению, так и по межклиентскому -0x68 0x68 (2 случайных байта) +0x68 0x68 (2 псевдослучайных байта) +++[пинг-ответ] -0x69 0x69 (2 случайных байта) +0x69 0x69 (2 псевдослучайных байта) @@ -137,7 +147,7 @@ UH - user hash - SHA224 хэш от сертификата пользовате Размер всего пакета не превышает 64кб +++[запрос списка узлов] @@@ -0x90 0x90 (2 случайных байта) +0x90 0x90 (2 псевдослучайных байта) +++[поиск клиента] - отправляется всем узлам. Узел-получатель отвечает на это сообщение, только если искомый UH найден среди локальных клиентов либо в кэше -- cgit v1.2.1 From 398a4e5cc4431430537dc3039f920cdf6bb4b305 Mon Sep 17 00:00:00 2001 From: Anton Date: Fri, 24 Jun 2016 22:37:56 +0400 Subject: use pseudorandom bytes in short fixed-length protocol messages instead of random in order to not drain entropy pool --- PICA_client.c | 12 ++++++------ PICA_node.c | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 7e7dce5..fa52e63 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -720,7 +720,7 @@ static unsigned int procmsg_MSGUTF8(unsigned char* buf, unsigned int nb, void* p if (mp) { - RAND_bytes( mp->tail, 2); + RAND_pseudo_bytes( mp->tail, 2); } else return 0; @@ -745,7 +745,7 @@ unsigned int procmsg_PINGREQ(unsigned char* buf, unsigned int nb, void* p) if (mp) { - RAND_bytes(mp->tail, 2); + RAND_pseudo_bytes(mp->tail, 2); } else return 0; @@ -766,7 +766,7 @@ int PICA_deny_file(struct PICA_c2c *chan) if (mp) { - RAND_bytes(mp->tail, 2); + RAND_pseudo_bytes(mp->tail, 2); } else return PICA_ERRNOMEM; @@ -792,7 +792,7 @@ int PICA_accept_file(struct PICA_c2c *chan, char *filename, unsigned int filenam if (mp) { - RAND_bytes(mp->tail, 2); + RAND_pseudo_bytes(mp->tail, 2); } else return PICA_ERRNOMEM; @@ -1371,7 +1371,7 @@ static int c2n_stage4_nodelistrequest(struct PICA_c2n *c2n) if (mp) { - RAND_bytes(mp->tail, 2); + RAND_pseudo_bytes(mp->tail, 2); } else return PICA_ERRNOMEM; @@ -1558,7 +1558,7 @@ mp = c2n_writebuf_push( cid, PICA_PROTO_CLNODELISTREQ, PICA_PROTO_CLNODELISTREQ_ if (mp) { - RAND_bytes(mp->tail, 2); + RAND_pseudo_bytes(mp->tail, 2); } } */ diff --git a/PICA_node.c b/PICA_node.c index 6b63b71..1d04f4c 100644 --- a/PICA_node.c +++ b/PICA_node.c @@ -353,7 +353,7 @@ unsigned int procmsg_NODECONNREQ(unsigned char* buf, unsigned int size, void* pt return 0; } - return 1; + return ; } @@ -522,7 +522,7 @@ unsigned int procmsg_PINGREQ_client(unsigned char* buf, unsigned int size, void* if ((mp = client_wbuf_push(c, PICA_PROTO_PINGREP, PICA_PROTO_PINGREP_SIZE))) { - RAND_bytes(mp->tail, 2); + RAND_pseudo_bytes(mp->tail, 2); } else return 0; @@ -551,7 +551,7 @@ unsigned int procmsg_PINGREQ_node(unsigned char* buf, unsigned int size, void* p if ((mp = nodelink_wbuf_push(n, PICA_PROTO_PINGREP, PICA_PROTO_PINGREP_SIZE))) { - RAND_bytes(mp->tail, 2); + RAND_pseudo_bytes(mp->tail, 2); } else return 0; @@ -597,7 +597,7 @@ unsigned int procmsg_NODERESP(unsigned char* buf, unsigned int size, void* ptr) mp = nodelink_wbuf_push(n, PICA_PROTO_NODELISTREQ, PICA_PROTO_NODELISTREQ_SIZE); if (mp) { - RAND_bytes(mp->tail, 2); + RAND_pseudo_bytes(mp->tail, 2); } else return 0; @@ -2002,7 +2002,7 @@ void process_timeouts_c2n() if ((mp = client_wbuf_push(i_ptr, PICA_PROTO_PINGREQ, PICA_PROTO_PINGREQ_SIZE))) { PICA_debug3("sending PINGREQ to %p", i_ptr); - RAND_bytes(mp->tail, 2); + RAND_pseudo_bytes(mp->tail, 2); i_ptr->tmst = time(0); i_ptr->disconnect_ticking = 1; @@ -2061,7 +2061,7 @@ void process_timeouts_n2n() if ((mp = nodelink_wbuf_push(i_ptr, PICA_PROTO_PINGREQ, PICA_PROTO_PINGREQ_SIZE))) { PICA_debug3("sending PINGREQ to node %p", i_ptr); - RAND_bytes(mp->tail, 2); + RAND_pseudo_bytes(mp->tail, 2); i_ptr->tmst = time(0); i_ptr->disconnect_ticking = 1; -- cgit v1.2.1 From a0a2d2915706113c09149afbfc4d7c4659514f7f Mon Sep 17 00:00:00 2001 From: Anton Date: Fri, 24 Jun 2016 22:51:52 +0400 Subject: added proto definitions --- PICA_proto.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PICA_proto.h b/PICA_proto.h index be162c3..c6d53db 100644 --- a/PICA_proto.h +++ b/PICA_proto.h @@ -31,9 +31,11 @@ #define PICA_PROTO_C2CCONNREQ 0xCC +#define PICA_PROTO_C2CDIRECT_ADDRLIST 0x0B #define PICA_PROTO_C2CDIRECT_IPV4 0xA0 #define PICA_PROTO_C2CDIRECT_IPV6 0xA1 #define PICA_PROTO_C2CDIRECT_DNS 0xA2 +#define PICA_PROTO_C2CDIRECT_FAILED 0x0C #define PICA_PROTO_MSGUTF8 0x30 #define PICA_PROTO_MSGOK 0x40 @@ -88,6 +90,7 @@ #define PICA_PROTO_C2CCONNREQ_SIZE 4 #define PICA_PROTO_C2CDIRECT_IPV4_SIZE 8 #define PICA_PROTO_C2CDIRECT_IPV6_SIZE 20 +#define PICA_PROTO_C2CDIRECT_FAILED_SIZE 4 #define PICA_PROTO_MSGOK_SIZE 4 -- cgit v1.2.1 From d8567c4ff9d78283773a19a84f02dcc3df775a61 Mon Sep 17 00:00:00 2001 From: Anton Date: Fri, 24 Jun 2016 22:56:08 +0400 Subject: new direct c2c related types and struct fields --- PICA_client.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/PICA_client.h b/PICA_client.h index 4e9dd17..661ae6d 100644 --- a/PICA_client.h +++ b/PICA_client.h @@ -171,6 +171,21 @@ enum PICA_c2c_state PICA_C2C_STATE_ACTIVE }; +enum PICA_directc2c_config +{ + PICA_DIRECTC2C_CFG_DISABLED, + PICA_DIRECTC2C_CFG_CONNECTONLY, + PICA_DIRECTC2C_CFG_ALLOWINCOMING +}; + +enum PICA_directc2c_state +{ + PICA_DIRECTC2C_STATE_NEW, + PICA_DIRECTC2C_STATE_WAITINGINCOMING, + PICA_DIRECTC2C_STATE_CONNECTING, + PICA_DIRECTC2C_STATE_ACTIVE +}; + struct PICA_c2c { const struct PICA_acc *acc; @@ -178,6 +193,8 @@ struct PICA_c2c unsigned char peer_id[PICA_ID_SIZE]; SOCKET sck_data; SSL *ssl; + SOCKET direct_sck; + SSL *direct_ssl; int outgoing;//1 если создание канала инициировано локальным клиентом, 0 - если собеседником X509 *peer_cert; //unsigned char msgbuf[PICA_CHNMSGBUFLEN]; @@ -192,6 +209,7 @@ struct PICA_c2c struct PICA_c2c *next; struct PICA_c2c *prev; enum PICA_c2c_state state; + enum PICA_directc2c_state directc2c_state; time_t timestamp; int sendfilestate; uint64_t sendfile_size; -- cgit v1.2.1 From 7474744a007d615093091c74e9ba72f56e39a205 Mon Sep 17 00:00:00 2001 From: Anton Date: Sat, 25 Jun 2016 23:31:22 +0400 Subject: fixed signal name --- pica-client/filetransfercontroller.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pica-client/filetransfercontroller.cpp b/pica-client/filetransfercontroller.cpp index 9f07a38..87c1c3f 100644 --- a/pica-client/filetransfercontroller.cpp +++ b/pica-client/filetransfercontroller.cpp @@ -19,7 +19,7 @@ FileTransferController::FileTransferController(QObject *parent) : connect(skynet, SIGNAL(OutgoingFileRequestDenied(QByteArray)), this, SLOT(file_denied_by_peer(QByteArray))); - connect(skynet, SIGNAL(ChannelClosed(QByteArray)), this, SLOT(file_peer_disconnected(QByteArray))); + connect(skynet, SIGNAL(c2cClosed(QByteArray)), this, SLOT(file_peer_disconnected(QByteArray))); } void FileTransferController::file_peer_disconnected(QByteArray peer_id) -- cgit v1.2.1 From c4304c26ce0ff043779e861fde9ec39f207f7600 Mon Sep 17 00:00:00 2001 From: Anton Date: Sat, 25 Jun 2016 23:35:49 +0400 Subject: added callbacks --- pica-client/skynet.cpp | 26 +++++++++++++++++++++++++- pica-client/skynet.h | 8 ++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/pica-client/skynet.cpp b/pica-client/skynet.cpp index 55a4120..a3bf44d 100644 --- a/pica-client/skynet.cpp +++ b/pica-client/skynet.cpp @@ -31,7 +31,11 @@ PICA_client_callbacks cbs = { denied_file_cb, file_progress, file_control, - file_finished + file_finished, + c2n_established_cb, + c2n_failed_cb, + c2n_closed_cb, + listener_error_cb }; PICA_client_init(&cbs); @@ -793,3 +797,23 @@ void SkyNet::file_finished(const unsigned char *peer_id, int sending) else skynet->emit_IncomingFileFinished(QByteArray((const char *)peer_id, PICA_ID_SIZE)); } + +void SkyNet::c2n_established_cb(struct PICA_c2n *c2n) +{ + +} + +void SkyNet::c2n_failed_cb(struct PICA_c2n *c2n) +{ + +} + +void SkyNet::c2n_closed_cb(struct PICA_c2n *c2n) +{ + +} + +void SkyNet::listener_error_cb(struct PICA_listener *lst, int errorcode) +{ + +} diff --git a/pica-client/skynet.h b/pica-client/skynet.h index 0b2c84b..b9e1298 100644 --- a/pica-client/skynet.h +++ b/pica-client/skynet.h @@ -131,6 +131,14 @@ private: static void file_finished(const unsigned char *peer_id, int sending); + static void c2n_established_cb(struct PICA_c2n *c2n); + + static void c2n_failed_cb(struct PICA_c2n *c2n); + + static void c2n_closed_cb(struct PICA_c2n *c2n); + + static void listener_error_cb(struct PICA_listener *lst, int errorcode); + private slots: void nodethread_finished(); void nodethread_connected(QString addr, quint16 port, NodeThread *thread); -- cgit v1.2.1 From c78395ea13aead21e7041f42699fcbf3753f1832 Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 11 Aug 2016 22:28:55 +0400 Subject: added error code argument to c2n callbacks --- PICA_client.c | 4 ++-- PICA_client.h | 4 ++-- tests/test_client.c | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index fa52e63..82d9a81 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -1959,9 +1959,9 @@ int PICA_event_loop(struct PICA_c2n **connections, struct PICA_listener **listen if (ret != PICA_OK) { if ((*ic2n)->state == PICA_C2N_STATE_CONNECTED) - callbacks.c2n_closed_cb(*ic2n); + callbacks.c2n_closed_cb(*ic2n, ret); else - callbacks.c2n_failed_cb(*ic2n); + callbacks.c2n_failed_cb(*ic2n, ret); PICA_close_c2n(*ic2n); } diff --git a/PICA_client.h b/PICA_client.h index 661ae6d..0fd1025 100644 --- a/PICA_client.h +++ b/PICA_client.h @@ -273,9 +273,9 @@ struct PICA_client_callbacks void (*c2n_established_cb)(struct PICA_c2n *c2n); - void (*c2n_failed_cb)(struct PICA_c2n *c2n); + void (*c2n_failed_cb)(struct PICA_c2n *c2n, int error); - void (*c2n_closed_cb)(struct PICA_c2n *c2n); + void (*c2n_closed_cb)(struct PICA_c2n *c2n, int error); void (*listener_error_cb)(struct PICA_listener *lst, int errorcode); }; diff --git a/tests/test_client.c b/tests/test_client.c index 5cbd24d..7a16732 100644 --- a/tests/test_client.c +++ b/tests/test_client.c @@ -135,14 +135,14 @@ void c2n_established_cb(struct PICA_c2n *c2n) printf("c2n_established_cb: %p\n my_id %s\n", c2n, PICA_id_to_base64(c2n->acc->id, NULL)); } -void c2n_failed_cb(struct PICA_c2n *c2n) +void c2n_failed_cb(struct PICA_c2n *c2n, int error) { - printf("c2n_failed_cb: %p\n", c2n); + printf("c2n_failed_cb: %p error_code %i\n", c2n, error); } -void c2n_closed_cb(struct PICA_c2n *c2n) +void c2n_closed_cb(struct PICA_c2n *c2n, int error) { - printf("c2n_closed_cb: %p\n", c2n); + printf("c2n_closed_cb: %p error_code %i\n", c2n, error); } void listener_error(struct PICA_listener *lst, int errorcode) -- cgit v1.2.1 From dc932321943129297cd9b32184134b86fb72aa37 Mon Sep 17 00:00:00 2001 From: Anton Date: Sat, 13 Aug 2016 19:39:27 +0400 Subject: show only critical messages, other messages are available on clicking "show notifications" button --- pica-client/mainwindow.cpp | 6 ++++-- pica-client/mainwindow.h | 2 +- pica-client/msguirouter.cpp | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/pica-client/mainwindow.cpp b/pica-client/mainwindow.cpp index c440e20..2081dbc 100644 --- a/pica-client/mainwindow.cpp +++ b/pica-client/mainwindow.cpp @@ -138,11 +138,13 @@ void MainWindow::showhide_click() hide_notifications(); } -void MainWindow::AddNotification(QString &text) +void MainWindow::AddNotification(QString &text, bool is_critical) { notifications->addItem(text); notifications->item(notifications->count() -1) ->setForeground(QBrush(QColor(230, 10, 10, 196))); - show_notifications(); + + if (is_critical) + show_notifications(); } diff --git a/pica-client/mainwindow.h b/pica-client/mainwindow.h index ba73c9a..4f5ee0d 100644 --- a/pica-client/mainwindow.h +++ b/pica-client/mainwindow.h @@ -23,7 +23,7 @@ public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); - void AddNotification(QString &text); + void AddNotification(QString &text, bool is_critical); protected: private: diff --git a/pica-client/msguirouter.cpp b/pica-client/msguirouter.cpp index 3264490..84bbf56 100644 --- a/pica-client/msguirouter.cpp +++ b/pica-client/msguirouter.cpp @@ -23,7 +23,7 @@ MsgUIRouter::MsgUIRouter(QObject *parent) : connect(skynet, SIGNAL(UnableToDeliver(QByteArray,QString)), this, SLOT(delivery_failed(QByteArray,QString))); connect(skynet, SIGNAL(Delivered(QByteArray)), this, SLOT(delivered(QByteArray))); connect(skynet, SIGNAL(CertificateForged(QByteArray,QString,QString)), this, SLOT(scary_cert_message(QByteArray,QString,QString))); - connect(skynet, SIGNAL(ErrMsgFromNode(QString)), this, SLOT(notification(QString))); + connect(skynet, SIGNAL(StatusMsg(QString, bool)), this, SLOT(notification(QString, bool))); connect(systray, SIGNAL(doubleclicked()), this, SLOT(trayicon_dclick())); } @@ -166,8 +166,8 @@ void MsgUIRouter::scary_cert_message(QByteArray peer_id, QString received_cert, fcd.exec(); } -void MsgUIRouter::notification(QString text) +void MsgUIRouter::notification(QString text, bool is_critical) { if (mainwindow) - mainwindow->AddNotification(text); + mainwindow->AddNotification(text, is_critical); } -- cgit v1.2.1 From b7039a6f5a1cf84b40b16a12b5b97a34c27c9604 Mon Sep 17 00:00:00 2001 From: Anton Date: Sat, 13 Aug 2016 22:08:45 +0400 Subject: fixed notification() calls --- pica-client/filetransfercontroller.cpp | 6 +++--- pica-client/msguirouter.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pica-client/filetransfercontroller.cpp b/pica-client/filetransfercontroller.cpp index 87c1c3f..44dba15 100644 --- a/pica-client/filetransfercontroller.cpp +++ b/pica-client/filetransfercontroller.cpp @@ -217,7 +217,7 @@ void FileTransferController::send_file(QByteArray peer_id) if (ftdialogs_out.contains(peer_id)) { - msguirouter->notification(tr("There is already file transfer in progress. Wait until it is finished.")); + msguirouter->notification(tr("There is already file transfer in progress. Wait until it is finished."), true); return; } @@ -230,13 +230,13 @@ void FileTransferController::send_file(QByteArray peer_id) if (!fi.exists()) { - msguirouter->notification(tr("File \"%1\" does not exist.").arg(filepath)); + msguirouter->notification(tr("File \"%1\" does not exist.").arg(filepath), true); return; } if (fi.size() == 0) { - msguirouter->notification(tr("Cannot send empty file.")); + msguirouter->notification(tr("Cannot send empty file."), true); } skynet->SendFile(peer_id, filepath); diff --git a/pica-client/msguirouter.h b/pica-client/msguirouter.h index 9fb404c..aefef2c 100644 --- a/pica-client/msguirouter.h +++ b/pica-client/msguirouter.h @@ -27,7 +27,7 @@ public slots: void delivered(QByteArray to); void scary_cert_message(QByteArray peer_id, QString received_cert, QString stored_cert); - void notification(QString text); + void notification(QString text, bool is_critical); void trayicon_dclick(); private: -- cgit v1.2.1 From 3ba25d63fd5b22bde755bd1a7d0f3f2a43900cd0 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 15 Aug 2016 23:11:46 +0400 Subject: removed NodeThread class files --- Makefile.am | 2 -- pica-client/pica-client.pro | 2 -- 2 files changed, 4 deletions(-) diff --git a/Makefile.am b/Makefile.am index 5ec82f5..2b1dbff 100644 --- a/Makefile.am +++ b/Makefile.am @@ -71,8 +71,6 @@ pica-client/msguirouter.cpp \ pica-client/msguirouter.h \ pica-client/nodes.cpp \ pica-client/nodes.h \ -pica-client/nodethread.cpp \ -pica-client/nodethread.h \ pica-client/openssltool.cpp \ pica-client/openssltool.h \ pica-client/picaactioncenter.cpp \ diff --git a/pica-client/pica-client.pro b/pica-client/pica-client.pro index 70c1222..421b02b 100644 --- a/pica-client/pica-client.pro +++ b/pica-client/pica-client.pro @@ -22,7 +22,6 @@ SOURCES += main.cpp\ accountswindow.cpp \ accounts.cpp \ dialogs/addaccountdialog.cpp \ - nodethread.cpp \ askpassword.cpp \ msguirouter.cpp \ picasystray.cpp \ @@ -51,7 +50,6 @@ HEADERS += mainwindow.h \ accountswindow.h \ accounts.h \ dialogs/addaccountdialog.h \ - nodethread.h \ askpassword.h \ msguirouter.h \ picasystray.h \ -- cgit v1.2.1 From 61aa2b0243e3ba7a086b697a3bf94c2b0830955f Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 15 Aug 2016 23:12:06 +0400 Subject: removed unused variables --- PICA_client.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 82d9a81..c2eb54b 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -172,7 +172,6 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) char buf[256]; X509 *err_cert; int err, depth; - SSL *ssl; err_cert = X509_STORE_CTX_get_current_cert(ctx); err = X509_STORE_CTX_get_error(ctx); @@ -208,7 +207,7 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) static int c2n_alloc_c2c(struct PICA_c2n *ci, struct PICA_c2c **chn, const unsigned char *peer_id, int is_outgoing) { - struct PICA_c2c *chnl, *ipt; + struct PICA_c2c *chnl; chnl = *chn = (struct PICA_c2c*)calloc(sizeof(struct PICA_c2c), 1); @@ -380,9 +379,7 @@ static int c2c_stage4_sendc2cconnreq(struct PICA_c2c *chnl) static int c2c_start(struct PICA_c2c *chnl) { - char* DN_str; int ret, err_ret; - unsigned int tmp_uid; chnl->sck_data = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); -- cgit v1.2.1 From fc15c12ff293dfebd6dd7a89d3c982e1c63eebe5 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 15 Aug 2016 23:13:25 +0400 Subject: implemented asynchronous processing of all c2n and c2c connections in main thread --- pica-client/skynet.cpp | 318 +++++++++++++++++++++++++++++++++---------------- pica-client/skynet.h | 29 +++-- 2 files changed, 232 insertions(+), 115 deletions(-) diff --git a/pica-client/skynet.cpp b/pica-client/skynet.cpp index a3bf44d..399b39e 100644 --- a/pica-client/skynet.cpp +++ b/pica-client/skynet.cpp @@ -40,78 +40,134 @@ PICA_client_callbacks cbs = { PICA_client_init(&cbs); -this->nodelink = NULL; +this->active_nodelink = NULL; this->acc = NULL; connect(this, SIGNAL(PeerCertificateReceived(QByteArray,QString,bool*)), this, SLOT(verify_peer_cert(QByteArray,QString,bool*)),Qt::DirectConnection); +event_loop_timer_id = startTimer(0); + } -void SkyNet::nodethread_finished() +void SkyNet::nodelink_activated(PICA_c2n *c2n) { -//удалить здесь завершившийся поток - for (int i=0;iisFinished()) - { - delete threads.takeAt(i); - break; - } - } + for (int i = 0; i < connecting_nodes.size(); i++) + { + if (connecting_nodes[i].first == c2n) + { + node_status_changed(connecting_nodes[i].second, true); + connecting_nodes.removeAt(i); + break; + } + } - if (threads.count() == 0) - { - self_aware = false; - emit LostSelfAwareness(); - } -} + if (self_aware) + { + PICA_close_c2n(c2n); + } + else + { + self_aware = true; + active_nodelink = c2n; -void SkyNet::nodethread_connected(QString addr, quint16 port, NodeThread *thread) -{ - if (self_aware) - { - emit BecameSelfAware(); + emit BecameSelfAware(); + // + //restore old peer connections, if any + QList c2c_peer_ids; - //restore old peer connections, if any - QList c2c_peer_ids; + //load undelivered messages from history + if (msgqueues.isEmpty()) + { + History h(config_dbname, Accounts::GetCurrentAccount().id); - //load undelivered messages from history - if (msgqueues.isEmpty()) - { - History h(config_dbname, Accounts::GetCurrentAccount().id); + msgqueues = h.GetUndeliveredMessages(); + } - msgqueues = h.GetUndeliveredMessages(); - } + //load file transfers to be completed + // sndfilequeues = ... - //load file transfers to be completed - // sndfilequeues = ... + QMap > queues = msgqueues; - QMap > queues = msgqueues; + queues.unite(sndfilequeues); - queues.unite(sndfilequeues); + c2c_peer_ids = queues.uniqueKeys(); - c2c_peer_ids = queues.uniqueKeys(); + for (int i = 0; i < c2c_peer_ids.size(); i++) + { + int ret; + struct PICA_c2c *chan = NULL; - for (int i = 0; i < c2c_peer_ids.size(); i++) - { - int ret; - write_mutex.lock(); - struct PICA_c2c *chan = NULL; + ret = PICA_new_c2c(active_nodelink, (const unsigned char*)c2c_peer_ids[i].constData(), NULL, &chan); - ret = PICA_new_c2c(nodelink, (const unsigned char*)c2c_peer_ids[i].constData(), NULL, &chan); + qDebug()<<"restoring c2c to "<timerId() == event_loop_timer_id) + { + if (connecting_nodes.size() > 0 || self_aware) + { + int ret; + QVector nodelinks; + + nodelinks.reserve(connecting_nodes.size() + 1); + + for (int i = 0; i < connecting_nodes.size(); i++) + nodelinks.append(connecting_nodes[i].first); + + if (self_aware) + nodelinks.append(active_nodelink); + + nodelinks.append(NULL); + + ret = PICA_event_loop(nodelinks.data(), NULL, 1); + + if (ret != PICA_OK) + emit StatusMsg("event loop error!", true);//show some error message + } + + return; + } + + if (self_aware) { - if (write_mutex.tryLock(10)) - { - QMap > queues = msgqueues; - queues.unite(sndfilequeues); + QMap > queues = msgqueues; + queues.unite(sndfilequeues); - QList c2c_peer_ids = queues.uniqueKeys(); + QList c2c_peer_ids = queues.uniqueKeys(); - c2c_peer_ids = filter_existing_chans(c2c_peer_ids); + c2c_peer_ids = filter_existing_chans(c2c_peer_ids); - for (int i = 0; i < c2c_peer_ids.size(); i++) - { - int ret; + for (int i = 0; i < c2c_peer_ids.size(); i++) + { + int ret; - struct PICA_c2c *chan = NULL; + struct PICA_c2c *chan = NULL; - ret = PICA_new_c2c(nodelink, (const unsigned char*)c2c_peer_ids[i].constData(), NULL, &chan); + ret = PICA_new_c2c(active_nodelink, (const unsigned char*)c2c_peer_ids[i].constData(), NULL, &chan); - qDebug()<<"restoring c2c to "< nodelist; skynet_account = accrec; - nodelist = nodes.GetNodes(); + + QList noderecords = nodes.GetNodes(); if (!acc) { @@ -243,12 +323,37 @@ void SkyNet::Join(Accounts::AccountRecord &accrec) return; } - if (nodelist.count()==0) + if (noderecords.count()==0) { - status = QObject::tr("No known Pica Pica nodes"); + emit StatusMsg(QString(tr("No known Pica Pica nodes")), true); return; } + if (!connecting_nodes.empty()) + { + for (int i = 0; i < connecting_nodes.size(); i++) + PICA_close_c2n(connecting_nodes[i].first); + + connecting_nodes.clear(); + } + + for (int i = 0; i < noderecords.size();i++) + { + int ret; + struct PICA_c2n *c2n = NULL; + + ret = PICA_new_c2n(acc, noderecords[i].address.toUtf8().constData(), noderecords[i].port, &c2n); + + if (ret == PICA_OK) + { + connecting_nodes.append(QPair(c2n, noderecords[i])); + } + else + { + node_status_changed(noderecords[i], false); + } + } +/* for (int i=0;iCloseThread(); + if (self_aware && active_nodelink) + { + PICA_close_c2n(active_nodelink); + active_nodelink = NULL; + } self_aware = false; - killTimer(timer_id); + killTimer(retry_timer_id); + + msgqueues.clear(); + + for (int i = 0; i < connecting_nodes.size(); i++) + PICA_close_c2n(connecting_nodes[i].first); + + connecting_nodes.clear(); + + emit LostSelfAwareness(); } bool SkyNet::isSelfAware() @@ -280,7 +397,7 @@ void SkyNet::SendFile(QByteArray to, QString filepath) int ret = PICA_OK; struct PICA_c2c *iptr; -write_mutex.lock();//<< + if ( (iptr = find_active_chan(to)) ) { @@ -291,7 +408,7 @@ if ( (iptr = find_active_chan(to)) ) //show error somewhere somehow } - write_mutex.unlock();//>> + return; } @@ -303,14 +420,14 @@ if ( (iptr = find_active_chan(to)) ) { struct PICA_c2c *chan = NULL; - ret = PICA_new_c2c(nodelink, (const unsigned char*)to.constData(), NULL, &chan); + ret = PICA_new_c2c(active_nodelink, (const unsigned char*)to.constData(), NULL, &chan); QList l; l.append(filepath); sndfilequeues[to] = l; } -write_mutex.unlock();//>> + if (ret!= PICA_OK) { @@ -323,7 +440,7 @@ void SkyNet::AcceptFile(QByteArray from, QString filepath) int ret = PICA_OK; struct PICA_c2c *iptr; -write_mutex.lock();//<< + if ( (iptr = find_active_chan(from)) ) { ret = PICA_accept_file(iptr, filepath.toUtf8().data(), filepath.toUtf8().size()); @@ -334,7 +451,7 @@ if ( (iptr = find_active_chan(from)) ) //show error somewhere somehow } } -write_mutex.unlock();//>> + } void SkyNet::DenyFile(QByteArray from) @@ -342,7 +459,7 @@ void SkyNet::DenyFile(QByteArray from) int ret = PICA_OK; struct PICA_c2c *iptr; -write_mutex.lock();//<< + if ( (iptr = find_active_chan(from)) ) { ret = PICA_deny_file(iptr); @@ -353,7 +470,7 @@ if ( (iptr = find_active_chan(from)) ) //show error somewhere somehow } } -write_mutex.unlock();//>> + } void SkyNet::PauseFile(QByteArray peer_id, bool pause_sending) @@ -361,7 +478,7 @@ void SkyNet::PauseFile(QByteArray peer_id, bool pause_sending) int ret = PICA_OK; struct PICA_c2c *iptr; -write_mutex.lock();//<< + if ( (iptr = find_active_chan(peer_id)) ) { qDebug() << "calling PICA_pause_file(" << iptr << "," << pause_sending << ")\n"; @@ -372,7 +489,7 @@ if ( (iptr = find_active_chan(peer_id)) ) qDebug() << "PICA_pause_file() returned " << ret << "\n"; } } -write_mutex.unlock();//>> + } void SkyNet::ResumeFile(QByteArray peer_id, bool resume_sending) @@ -380,7 +497,7 @@ void SkyNet::ResumeFile(QByteArray peer_id, bool resume_sending) int ret = PICA_OK; struct PICA_c2c *iptr; -write_mutex.lock();//<< + if ( (iptr = find_active_chan(peer_id)) ) { ret = PICA_resume_file(iptr, (int)resume_sending ); @@ -390,7 +507,7 @@ if ( (iptr = find_active_chan(peer_id)) ) //show error somewhere somehow } } -write_mutex.unlock();//>> + } void SkyNet::CancelFile(QByteArray peer_id, bool cancel_sending) @@ -398,7 +515,7 @@ void SkyNet::CancelFile(QByteArray peer_id, bool cancel_sending) int ret = PICA_OK; struct PICA_c2c *iptr; -write_mutex.lock();//<< + if ( (iptr = find_active_chan(peer_id)) ) { ret = PICA_cancel_file(iptr, (int)cancel_sending ); @@ -408,7 +525,7 @@ if ( (iptr = find_active_chan(peer_id)) ) //show error somewhere somehow } } -write_mutex.unlock();//>> + } void SkyNet::SendMessage(QByteArray to, QString msg) @@ -416,7 +533,7 @@ void SkyNet::SendMessage(QByteArray to, QString msg) int ret = PICA_OK; struct PICA_c2c *iptr; -write_mutex.lock();//<< + if ( (iptr = find_active_chan(to)) ) { @@ -427,7 +544,7 @@ if ( (iptr = find_active_chan(to)) ) if (ret != PICA_OK) emit UnableToDeliver(to, msg); - write_mutex.unlock();//>> + return; } @@ -439,7 +556,7 @@ if ( (iptr = find_active_chan(to)) ) { struct PICA_c2c *chan = NULL; - ret = PICA_new_c2c(nodelink, (const unsigned char*)to.constData(), NULL, &chan); + ret = PICA_new_c2c(active_nodelink, (const unsigned char*)to.constData(), NULL, &chan); QList l; l.append(msg); @@ -447,7 +564,7 @@ if ( (iptr = find_active_chan(to)) ) } -write_mutex.unlock();//>> + if (ret != PICA_OK) emit UnableToDeliver(to, msg); @@ -506,10 +623,10 @@ void SkyNet::flush_queues(QByteArray to) struct PICA_c2c * SkyNet::find_active_chan(QByteArray peer_id) { -if (!nodelink) +if (!active_nodelink) return NULL; -struct PICA_c2c *iptr = nodelink->chan_list_head; +struct PICA_c2c *iptr = active_nodelink->chan_list_head; while(iptr) { @@ -526,10 +643,10 @@ QList SkyNet::filter_existing_chans(QList peer_ids) { QList ret = peer_ids; - if (!nodelink) + if (!active_nodelink) return ret; - struct PICA_c2c *iptr = nodelink->chan_list_head; + struct PICA_c2c *iptr = active_nodelink->chan_list_head; while(iptr) { @@ -640,9 +757,6 @@ void SkyNet::emit_c2cClosed(QByteArray peer_id) //callbacks -//all callbacks are executed in separate thread, created in Nodethread instance, REMEMBER THAT !!! -// write_mutex is locked - void SkyNet::newmsg_cb(const unsigned char *peer_id, const char *msgbuf, unsigned int nb, int type) { QString msg = QString::fromUtf8(msgbuf, nb); @@ -800,17 +914,17 @@ void SkyNet::file_finished(const unsigned char *peer_id, int sending) void SkyNet::c2n_established_cb(struct PICA_c2n *c2n) { - + skynet->nodelink_activated(c2n); } -void SkyNet::c2n_failed_cb(struct PICA_c2n *c2n) +void SkyNet::c2n_failed_cb(struct PICA_c2n *c2n, int error) { - + skynet->nodelink_failed(c2n, error); } -void SkyNet::c2n_closed_cb(struct PICA_c2n *c2n) +void SkyNet::c2n_closed_cb(struct PICA_c2n *c2n, int error) { - + skynet->nodelink_closed(c2n, error); } void SkyNet::listener_error_cb(struct PICA_listener *lst, int errorcode) diff --git a/pica-client/skynet.h b/pica-client/skynet.h index b9e1298..3e03b87 100644 --- a/pica-client/skynet.h +++ b/pica-client/skynet.h @@ -2,12 +2,13 @@ #define SKYNET_H #include "nodes.h" -#include "nodethread.h" #include "../PICA_client.h" #include "../PICA_proto.h" #include "accounts.h" #include #include +#include +#include class SkyNet : public QObject @@ -17,7 +18,6 @@ public: SkyNet(); void Join(Accounts::AccountRecord &accrec); bool isSelfAware(); - QString& Status(); void Exit(); void SendMessage(QByteArray to, QString msg); @@ -38,7 +38,7 @@ signals: void LostSelfAwareness(); void PeerCertificateReceived(QByteArray peer_id, QString cert_pem, bool *verified); void CertificateForged(QByteArray peer_id, QString received_cert, QString stored_cert); - void ErrMsgFromNode(QString msg); + void StatusMsg(QString msg, bool is_critical); void ContactsUpdated(); void IncomingFileRequestReceived(QByteArray peer_id, quint64 file_size, QString filename); void OutgoingFileRequestAccepted(QByteArray peer_id); @@ -58,17 +58,18 @@ signals: void c2cClosed(QByteArray peer_id); private: - Nodes nodes; - QList threads; + Nodes nodes; + QList > connecting_nodes; bool self_aware; QString status; - struct PICA_c2n *nodelink; + struct PICA_c2n *active_nodelink; struct PICA_acc *acc; Accounts::AccountRecord skynet_account; - QMutex write_mutex; + QMap > msgqueues; QMap > sndfilequeues; - int timer_id; + int retry_timer_id; + int event_loop_timer_id; void timerEvent(QTimerEvent * e); @@ -133,16 +134,18 @@ private: static void c2n_established_cb(struct PICA_c2n *c2n); - static void c2n_failed_cb(struct PICA_c2n *c2n); + static void c2n_failed_cb(struct PICA_c2n *c2n, int error); - static void c2n_closed_cb(struct PICA_c2n *c2n); + static void c2n_closed_cb(struct PICA_c2n *c2n, int error); static void listener_error_cb(struct PICA_listener *lst, int errorcode); private slots: - void nodethread_finished(); - void nodethread_connected(QString addr, quint16 port, NodeThread *thread); - void node_status_changed(QString addr,quint16 port,bool alive); + void nodelink_activated(PICA_c2n *c2n); + void nodelink_closed(PICA_c2n *c2n, int error); + void nodelink_failed(PICA_c2n *c2n, int error); + + void node_status_changed(Nodes::NodeRecord nr,bool alive); void verify_peer_cert(QByteArray peer_id, QString cert_pem, bool *verified); }; -- cgit v1.2.1 From bd74b5f2aef6e43a8060cfa1dd214f6797718008 Mon Sep 17 00:00:00 2001 From: Anton Date: Tue, 16 Aug 2016 22:04:50 +0400 Subject: removed moc_nodethread.cpp from Makefile.am --- Makefile.am | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 2b1dbff..6182aa7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -117,7 +117,6 @@ moc_contactlistwidget.cpp \ moc_forgedcertdialog.cpp \ moc_mainwindow.cpp \ moc_msguirouter.cpp \ -moc_nodethread.cpp \ moc_picaactioncenter.cpp \ moc_picasystray.cpp \ moc_registeraccountdialog.cpp \ -- cgit v1.2.1 From d2991d30b0062bfd2ad3ae272ccac8acf7a4997d Mon Sep 17 00:00:00 2001 From: Anton Date: Tue, 30 Aug 2016 21:55:10 +0400 Subject: added sqlite table settings and updated schema version --- pica-client/main.cpp | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/pica-client/main.cpp b/pica-client/main.cpp index 7df81ce..fcfa3c1 100644 --- a/pica-client/main.cpp +++ b/pica-client/main.cpp @@ -135,7 +135,17 @@ static bool create_database() if (query.lastError().isValid()) goto showerror; - query.exec("insert into schema_version values (2, strftime('%s','now'));"); //current schema version. update when needed + query.exec("create table settings \ + ( \ + name varchar(255) not null, \ + value varchar(255) not null \ + );" + ); + + if (query.lastError().isValid()) + goto showerror; + + query.exec("insert into schema_version values (3, strftime('%s','now'));"); //current schema version. update when needed if (query.lastError().isValid()) showerror: @@ -363,6 +373,21 @@ static bool update_database() schema_ver = 2; } + if (schema_ver == 2) + { + query.exec("create table settings \ + ( \ + name varchar(255) not null, \ + value varchar(255) not null \ + );" + ); + + if (query.lastError().isValid()) + goto showerror; + + schema_ver = 3; + } + if (query.lastError().isValid()) showerror: { -- cgit v1.2.1 From 15b2d1edd9a0d9f258f6ac38eeb9d2a5aaec21c0 Mon Sep 17 00:00:00 2001 From: Anton Date: Tue, 30 Aug 2016 22:19:01 +0400 Subject: fixed schema update --- pica-client/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/pica-client/main.cpp b/pica-client/main.cpp index fcfa3c1..018374b 100644 --- a/pica-client/main.cpp +++ b/pica-client/main.cpp @@ -385,6 +385,7 @@ static bool update_database() if (query.lastError().isValid()) goto showerror; + query.exec("insert into schema_version values (3, strftime('%s','now'));"); schema_ver = 3; } -- cgit v1.2.1 From aea328fdd6663587cfb249e55394ac96010d07ba Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 1 Sep 2016 02:11:19 +0400 Subject: new dialog SettingsDialog; widgets for direct c2c connections settings --- pica-client/dialogs/settingsdialog.cpp | 47 ++++++++++++++++++++++++++++++++++ pica-client/dialogs/settingsdialog.h | 36 ++++++++++++++++++++++++++ pica-client/pica-client.pro | 6 +++-- 3 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 pica-client/dialogs/settingsdialog.cpp create mode 100644 pica-client/dialogs/settingsdialog.h diff --git a/pica-client/dialogs/settingsdialog.cpp b/pica-client/dialogs/settingsdialog.cpp new file mode 100644 index 0000000..3b1cab7 --- /dev/null +++ b/pica-client/dialogs/settingsdialog.cpp @@ -0,0 +1,47 @@ +#include "settingsdialog.h" +#include +#include +#include + +SettingsDialog::SettingsDialog(QWidget *parent) : + QDialog(parent) +{ + QVBoxLayout *settingsLayout = new QVBoxLayout(); + + QGroupBox *groupBox = new QGroupBox(tr("Direct Connections"), this); + QVBoxLayout *directc2cLayout = new QVBoxLayout(); + + rbDisableDirectConns = new QRadioButton(tr("Disable direct connections"), this); + rbEnableOutgoingConns = new QRadioButton(tr("Enable only outgoing direct connections"), this); + rbEnableIncomingConns = new QRadioButton(tr("Enable incoming direct connections"), this); + + rbEnableIncomingConns->setChecked(true); + + QLabel *lbAddr = new QLabel(tr("Public address for incoming connections"), this); + addr = new QLineEdit(tr("0.0.0.0"), this); + publicPort = new QSpinBox(this); + localPort = new QSpinBox(this); + + publicPort->setRange(1, 65535); + localPort->setRange(1, 65535); + + publicPort->setValue(2298); + localPort->setValue(2298); + + + + directc2cLayout->addWidget(rbDisableDirectConns); + directc2cLayout->addWidget(rbEnableOutgoingConns); + directc2cLayout->addWidget(rbEnableIncomingConns); + directc2cLayout->addWidget(lbAddr); + directc2cLayout->addWidget(addr); + directc2cLayout->addWidget(publicPort); + directc2cLayout->addWidget(localPort); + directc2cLayout->addStretch(1); + + groupBox->setLayout(directc2cLayout); + + settingsLayout->addWidget(groupBox); + + setLayout(settingsLayout); +} diff --git a/pica-client/dialogs/settingsdialog.h b/pica-client/dialogs/settingsdialog.h new file mode 100644 index 0000000..883ff89 --- /dev/null +++ b/pica-client/dialogs/settingsdialog.h @@ -0,0 +1,36 @@ +#ifndef SETTINGSDIALOG_H +#define SETTINGSDIALOG_H + +#include +#include +#include +#include +#include + +class SettingsDialog : public QDialog +{ + Q_OBJECT +public: + explicit SettingsDialog(QWidget *parent = 0); + +signals: + +public slots: +private slots: + +private: + QRadioButton *rbDisableDirectConns; + QRadioButton *rbEnableOutgoingConns; + QRadioButton *rbEnableIncomingConns; + + QLineEdit *addr; + QSpinBox *publicPort; + QSpinBox *localPort; + + QPushButton *btOk; + QPushButton *btCancel; + + +}; + +#endif // SETTINGSDIALOG_H diff --git a/pica-client/pica-client.pro b/pica-client/pica-client.pro index 421b02b..74f484a 100644 --- a/pica-client/pica-client.pro +++ b/pica-client/pica-client.pro @@ -36,7 +36,8 @@ SOURCES += main.cpp\ dialogs/showpicaiddialog.cpp \ dialogs/filetransferdialog.cpp \ filetransfercontroller.cpp \ - sound.cpp + sound.cpp \ + dialogs/settingsdialog.cpp HEADERS += mainwindow.h \ chatwindow.h \ @@ -66,7 +67,8 @@ HEADERS += mainwindow.h \ dialogs/showpicaiddialog.h \ dialogs/filetransferdialog.h \ filetransfercontroller.h \ - sound.h + sound.h \ + dialogs/settingsdialog.h DEFINES = PICA_MULTITHREADED -- cgit v1.2.1 From eb9d793ca218f61169997f2efcd838c831b614ac Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 4 Sep 2016 00:55:58 +0400 Subject: fixed settings table creation query, make values unique --- pica-client/main.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pica-client/main.cpp b/pica-client/main.cpp index 018374b..99a19f2 100644 --- a/pica-client/main.cpp +++ b/pica-client/main.cpp @@ -138,7 +138,8 @@ static bool create_database() query.exec("create table settings \ ( \ name varchar(255) not null, \ - value varchar(255) not null \ + value varchar(255) not null, \ + constraint pk primary key (name) on conflict replace \ );" ); @@ -378,7 +379,8 @@ static bool update_database() query.exec("create table settings \ ( \ name varchar(255) not null, \ - value varchar(255) not null \ + value varchar(255) not null, \ + constraint pk primary key (name) on conflict replace \ );" ); -- cgit v1.2.1 From 316f68fc0f86be551052ef79d3da9b32b031e675 Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 4 Sep 2016 00:56:35 +0400 Subject: added Settings class --- pica-client/pica-client.pro | 6 ++++-- pica-client/settings.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++++ pica-client/settings.h | 23 ++++++++++++++++++++ 3 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 pica-client/settings.cpp create mode 100644 pica-client/settings.h diff --git a/pica-client/pica-client.pro b/pica-client/pica-client.pro index 74f484a..ef9f9fd 100644 --- a/pica-client/pica-client.pro +++ b/pica-client/pica-client.pro @@ -37,7 +37,8 @@ SOURCES += main.cpp\ dialogs/filetransferdialog.cpp \ filetransfercontroller.cpp \ sound.cpp \ - dialogs/settingsdialog.cpp + dialogs/settingsdialog.cpp \ + settings.cpp HEADERS += mainwindow.h \ chatwindow.h \ @@ -68,7 +69,8 @@ HEADERS += mainwindow.h \ dialogs/filetransferdialog.h \ filetransfercontroller.h \ sound.h \ - dialogs/settingsdialog.h + dialogs/settingsdialog.h \ + settings.h DEFINES = PICA_MULTITHREADED diff --git a/pica-client/settings.cpp b/pica-client/settings.cpp new file mode 100644 index 0000000..160e402 --- /dev/null +++ b/pica-client/settings.cpp @@ -0,0 +1,51 @@ +#include "settings.h" + +Settings::Settings(QString storage) +{ + dbconn=QSqlDatabase::addDatabase("QSQLITE"); + dbconn.setDatabaseName(storage); + + if (!dbconn.open()) + { + lasterr=dbconn.lastError(); + return; + } + +} + +QString Settings::GetLastError() +{ + return lasterr.text(); +} + +QVariant Settings::loadValue(QString name, QVariant defval) +{ + QSqlQuery query; + + query.prepare("select value from settings where name = :name"); + query.bindValue(":name", name); + query.exec(); + + lasterr = query.lastError(); + + query.next(); + + if (!query.isValid()) + { + return defval; + } + + return query.value(0); +} + +void Settings::storeValue(QString name, QString val) +{ + QSqlQuery query; + + query.prepare("insert into settings (name, value) values (:name, :val)"); + query.bindValue(":addr", name); + query.bindValue(":val", val); + query.exec(); + + lasterr = query.lastError(); +} diff --git a/pica-client/settings.h b/pica-client/settings.h new file mode 100644 index 0000000..d7d5b5f --- /dev/null +++ b/pica-client/settings.h @@ -0,0 +1,23 @@ +#ifndef SETTINGS_H +#define SETTINGS_H + +#include +#include +#include + +class Settings +{ +public: + Settings(QString storage); + + QVariant loadValue(QString name, QVariant defval); + void storeValue(QString name, QString val); + + QString GetLastError(); + +private: + QSqlDatabase dbconn; + QSqlError lasterr; +}; + +#endif // SETTINGS_H -- cgit v1.2.1 From 1d886eedd6e7cf0b7018a8f9f2a767d6869dad94 Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 4 Sep 2016 00:57:01 +0400 Subject: added Settings and SettingsDialog files to Makefile.am --- Makefile.am | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile.am b/Makefile.am index 6182aa7..9c48bc3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -88,6 +88,8 @@ pica-client/filetransfercontroller.cpp \ pica-client/filetransfercontroller.h \ pica-client/sound.cpp \ pica-client/sound.h \ +pica-client/settings.cpp \ +pica-client/settings.h \ \ pica-client/dialogs/addaccountdialog.cpp \ pica-client/dialogs/addaccountdialog.h \ @@ -101,6 +103,8 @@ pica-client/dialogs/showpicaiddialog.cpp \ pica-client/dialogs/showpicaiddialog.h \ pica-client/dialogs/filetransferdialog.cpp \ pica-client/dialogs/filetransferdialog.h \ +pica-client/dialogs/settingsdialog.cpp \ +pica-client/dialogs/settingsdialog.h \ PICA_client.c \ PICA_client.h \ PICA_msgproc.c \ -- cgit v1.2.1 From de58e6a8392dda40aa15413053a520e2a1f1a3e3 Mon Sep 17 00:00:00 2001 From: Anton Date: Tue, 6 Sep 2016 00:01:06 +0400 Subject: added moc_settingsdialog to Makefile.am --- Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.am b/Makefile.am index 9c48bc3..bb19dac 100644 --- a/Makefile.am +++ b/Makefile.am @@ -126,6 +126,7 @@ moc_picasystray.cpp \ moc_registeraccountdialog.cpp \ moc_filetransferdialog.cpp \ moc_skynet.cpp \ +moc_settingsdialog.cpp \ moc_viewcertdialog.cpp \ moc_showpicaiddialog.cpp \ moc_dhparam.cpp \ -- cgit v1.2.1 From 80ef4a04b567b94e664cdb3e2354cbd204da57bc Mon Sep 17 00:00:00 2001 From: Anton Date: Tue, 6 Sep 2016 01:18:20 +0400 Subject: SettingsDialog implementation --- pica-client/dialogs/settingsdialog.cpp | 87 ++++++++++++++++++++++++++++++++++ pica-client/dialogs/settingsdialog.h | 6 +++ 2 files changed, 93 insertions(+) diff --git a/pica-client/dialogs/settingsdialog.cpp b/pica-client/dialogs/settingsdialog.cpp index 3b1cab7..da6b55f 100644 --- a/pica-client/dialogs/settingsdialog.cpp +++ b/pica-client/dialogs/settingsdialog.cpp @@ -1,7 +1,12 @@ #include "settingsdialog.h" +#include "settings.h" +#include "globals.h" + #include #include +#include #include +#include SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent) @@ -43,5 +48,87 @@ SettingsDialog::SettingsDialog(QWidget *parent) : settingsLayout->addWidget(groupBox); + QHBoxLayout *buttonsLayout = new QHBoxLayout; + + btOk = new QPushButton(tr("&OK"), this); + btCancel = new QPushButton(tr("Cancel"), this); + + buttonsLayout->addStretch(1); + buttonsLayout->addWidget(btOk); + buttonsLayout->addWidget(btCancel); + + settingsLayout->addLayout(buttonsLayout); + setLayout(settingsLayout); + + connect(btOk, SIGNAL(clicked()), this, SLOT(OK())); + connect(btCancel, SIGNAL(clicked()), this, SLOT(Cancel())); + + loadSettings(); +} + +void SettingsDialog::OK() +{ + storeSettings(); + done(1); +} + +void SettingsDialog::Cancel() +{ + done(0); +} + +void SettingsDialog::loadSettings() +{ + Settings st(config_dbname); + + //Direct c2c connections + int c2c_state; + + c2c_state = st.loadValue("direct_c2c.state", 1).toInt(); + + switch (c2c_state) + { + case 0: + rbDisableDirectConns->setChecked(true); + break; + + case 1: + rbEnableOutgoingConns->setChecked(true); + break; + + case 2: + rbEnableIncomingConns->setChecked(true); + break; + + default: + break; + } + + addr->setText(st.loadValue("direct_c2c.public_addr", "0.0.0.0").toString()); + + publicPort->setValue(st.loadValue("direct_c2c.public_port", 2298).toInt()); + localPort->setValue(st.loadValue("direct_c2c.local_port", 2298).toInt()); + +} + +void SettingsDialog::storeSettings() +{ + Settings st(config_dbname); + + //Direct c2c connections + int c2c_state; + + if (rbDisableDirectConns->isChecked()) + c2c_state = 0; + else if (rbEnableOutgoingConns->isChecked()) + c2c_state = 1; + else if (rbEnableIncomingConns->isChecked()) + c2c_state = 2; + + st.storeValue("direct_c2c.state", QString::number(c2c_state)); + + st.storeValue("direct_c2c.public_addr", addr->text()); + st.storeValue("direct_c2c.public_port", QString::number(publicPort->value())); + st.storeValue("direct_c2c.local_port", QString::number(localPort->value())); } diff --git a/pica-client/dialogs/settingsdialog.h b/pica-client/dialogs/settingsdialog.h index 883ff89..06a2cf8 100644 --- a/pica-client/dialogs/settingsdialog.h +++ b/pica-client/dialogs/settingsdialog.h @@ -30,6 +30,12 @@ private: QPushButton *btOk; QPushButton *btCancel; + void loadSettings(); + void storeSettings(); + +private slots: + void OK(); + void Cancel(); }; -- cgit v1.2.1 From aa169097397a8a168ca9309b3602932865a65be4 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 12 Sep 2016 22:57:15 +0400 Subject: added directc2c_config field to PICA_c2c struct --- PICA_client.h | 1 + 1 file changed, 1 insertion(+) diff --git a/PICA_client.h b/PICA_client.h index 0fd1025..5c88040 100644 --- a/PICA_client.h +++ b/PICA_client.h @@ -210,6 +210,7 @@ struct PICA_c2c struct PICA_c2c *prev; enum PICA_c2c_state state; enum PICA_directc2c_state directc2c_state; + enum PICA_directc2c_config directc2c_config; time_t timestamp; int sendfilestate; uint64_t sendfile_size; -- cgit v1.2.1 From 57075f0806f1fcdeef1b5dad8ac4cf61ec7da6e7 Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 15 Sep 2016 19:50:24 +0400 Subject: show settings dialog on first start --- pica-client/main.cpp | 11 +++++++++++ pica-client/settings.cpp | 18 ++++++++++++++++++ pica-client/settings.h | 1 + 3 files changed, 30 insertions(+) diff --git a/pica-client/main.cpp b/pica-client/main.cpp index 99a19f2..1441b5c 100644 --- a/pica-client/main.cpp +++ b/pica-client/main.cpp @@ -14,6 +14,8 @@ #include #include "../PICA_client.h" #include "dhparam.h" +#include "settings.h" +#include "dialogs/settingsdialog.h" //globals QString config_dir; @@ -493,6 +495,15 @@ int main(int argc, char *argv[]) picapica_ico_fly = QIcon("share\\picapica-icon-fly.png"); #endif + Settings st(config_dbname); + + if (st.isEmpty()) //show settings dialog on first start + { + SettingsDialog sd; + + sd.exec(); + } + PicaActionCenter ac; action_center = ∾ diff --git a/pica-client/settings.cpp b/pica-client/settings.cpp index 160e402..4b5485d 100644 --- a/pica-client/settings.cpp +++ b/pica-client/settings.cpp @@ -18,6 +18,24 @@ QString Settings::GetLastError() return lasterr.text(); } +bool Settings::isEmpty() +{ + QSqlQuery query; + + query.exec("select count(*) from settings"); + + lasterr = query.lastError(); + + query.next(); + + if (query.isValid() && query.value(0).toInt() == 0) + { + return true; + } + + return false; +} + QVariant Settings::loadValue(QString name, QVariant defval) { QSqlQuery query; diff --git a/pica-client/settings.h b/pica-client/settings.h index d7d5b5f..9476ab5 100644 --- a/pica-client/settings.h +++ b/pica-client/settings.h @@ -12,6 +12,7 @@ public: QVariant loadValue(QString name, QVariant defval); void storeValue(QString name, QString val); + bool isEmpty(); QString GetLastError(); -- cgit v1.2.1 From 674385ad22cc49084721c6d18052e83e5ad63cc7 Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 15 Sep 2016 20:01:58 +0400 Subject: calling settings dialog from the menu --- pica-client/mainwindow.cpp | 3 +++ pica-client/mainwindow.h | 1 + pica-client/picaactioncenter.cpp | 10 ++++++++++ pica-client/picaactioncenter.h | 3 +++ 4 files changed, 17 insertions(+) diff --git a/pica-client/mainwindow.cpp b/pica-client/mainwindow.cpp index 2081dbc..8f4702f 100644 --- a/pica-client/mainwindow.cpp +++ b/pica-client/mainwindow.cpp @@ -111,6 +111,9 @@ void MainWindow::createMenus() nodesMenu=menuBar()->addMenu(tr("&Nodes")); + settingsMenu = menuBar()->addMenu(tr("&Settings")); + settingsMenu->addAction(action_center->SettingsAct()); + helpMenu=menuBar()->addMenu(tr("&Help")); helpMenu->addAction(action_center->AboutAct()); diff --git a/pica-client/mainwindow.h b/pica-client/mainwindow.h index 4f5ee0d..b61f31a 100644 --- a/pica-client/mainwindow.h +++ b/pica-client/mainwindow.h @@ -39,6 +39,7 @@ private: QMenu *helpMenu; QMenu *nodesMenu; QMenu *accountMenu; + QMenu *settingsMenu; bool status_change_disable_flag; void SetStatus(bool connected); diff --git a/pica-client/picaactioncenter.cpp b/pica-client/picaactioncenter.cpp index 7fe5400..1aa09ec 100644 --- a/pica-client/picaactioncenter.cpp +++ b/pica-client/picaactioncenter.cpp @@ -7,6 +7,7 @@ #include "accounts.h" #include "dialogs/showpicaiddialog.h" #include "sound.h" +#include "dialogs/settingsdialog.h" #include @@ -27,6 +28,9 @@ PicaActionCenter::PicaActionCenter(QObject *parent) : muteSoundsAct = new QAction(tr("&Mute Sounds"), this); muteSoundsAct->setCheckable(true); connect(muteSoundsAct, SIGNAL(triggered(bool)), this, SLOT(muteSounds(bool))); + + settingsAct = new QAction(tr("&Configure Messenger..."), this); + connect(settingsAct, SIGNAL(triggered(bool)), this, SLOT(showsettings())); } void PicaActionCenter::about() @@ -55,6 +59,12 @@ void PicaActionCenter::exit() QApplication::instance()->quit(); } +void PicaActionCenter::showsettings() +{ + SettingsDialog sd; + sd.exec(); +} + void PicaActionCenter::showmyid() { ShowPicaIdDialog d(Accounts::GetCurrentAccount().name, Accounts::GetCurrentAccount().id, tr("My Current Account")); diff --git a/pica-client/picaactioncenter.h b/pica-client/picaactioncenter.h index 6361d01..7fa98c4 100644 --- a/pica-client/picaactioncenter.h +++ b/pica-client/picaactioncenter.h @@ -14,12 +14,14 @@ public: QAction *ExitAct() {return exitAct;}; QAction *ShowMyIDAct() {return showmyidAct;}; QAction *MuteSoundsAct() {return muteSoundsAct;}; + QAction *SettingsAct() {return settingsAct; }; private: QAction *aboutAct; QAction *exitAct; QAction *showmyidAct; QAction *muteSoundsAct; + QAction *settingsAct; signals: @@ -29,6 +31,7 @@ private slots: void exit(); void showmyid(); void muteSounds(bool yes); + void showsettings(); }; #endif // PICAACTIONCENTER_H -- cgit v1.2.1 From 777de7af7c4b4908fbae325f9ff0a37bd9eb6c7a Mon Sep 17 00:00:00 2001 From: Anton Date: Fri, 16 Sep 2016 22:06:37 +0400 Subject: caption for settings dialog --- pica-client/dialogs/settingsdialog.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pica-client/dialogs/settingsdialog.cpp b/pica-client/dialogs/settingsdialog.cpp index da6b55f..24b82a7 100644 --- a/pica-client/dialogs/settingsdialog.cpp +++ b/pica-client/dialogs/settingsdialog.cpp @@ -65,6 +65,8 @@ SettingsDialog::SettingsDialog(QWidget *parent) : connect(btCancel, SIGNAL(clicked()), this, SLOT(Cancel())); loadSettings(); + + setWindowTitle(tr("Pica Pica Messenger Settings")); } void SettingsDialog::OK() -- cgit v1.2.1 From 41cd6ae48332c1ea8465e3a33db10e38103d1694 Mon Sep 17 00:00:00 2001 From: Anton Date: Sat, 17 Sep 2016 15:23:53 +0400 Subject: initialize direct_c2c fields of c2c struct --- PICA_client.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/PICA_client.c b/PICA_client.c index c2eb54b..e6617ee 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -239,6 +239,8 @@ static int c2n_alloc_c2c(struct PICA_c2n *ci, struct PICA_c2c **chn, const unsig } chnl->state = PICA_C2C_STATE_NEW; + chnl->directc2c_config = PICA_DIRECTC2C_CFG_DISABLED; + chnl->directc2c_state = PICA_DIRECTC2C_STATE_NEW; return 1; } -- cgit v1.2.1 From 54831caf1163259aabbec6cec8edf4529b668ef7 Mon Sep 17 00:00:00 2001 From: Anton Date: Sat, 17 Sep 2016 15:24:43 +0400 Subject: added path to included headers --- pica-client/dialogs/settingsdialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pica-client/dialogs/settingsdialog.cpp b/pica-client/dialogs/settingsdialog.cpp index 24b82a7..000e922 100644 --- a/pica-client/dialogs/settingsdialog.cpp +++ b/pica-client/dialogs/settingsdialog.cpp @@ -1,6 +1,6 @@ #include "settingsdialog.h" -#include "settings.h" -#include "globals.h" +#include "../settings.h" +#include "../globals.h" #include #include -- cgit v1.2.1 From 9c7821f93b393ac65118fdc5911cbd666c5c3941 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 19 Sep 2016 18:04:42 +0400 Subject: labels for settings dialog --- pica-client/dialogs/settingsdialog.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pica-client/dialogs/settingsdialog.cpp b/pica-client/dialogs/settingsdialog.cpp index 000e922..c9a60a1 100644 --- a/pica-client/dialogs/settingsdialog.cpp +++ b/pica-client/dialogs/settingsdialog.cpp @@ -17,14 +17,16 @@ SettingsDialog::SettingsDialog(QWidget *parent) : QVBoxLayout *directc2cLayout = new QVBoxLayout(); rbDisableDirectConns = new QRadioButton(tr("Disable direct connections"), this); - rbEnableOutgoingConns = new QRadioButton(tr("Enable only outgoing direct connections"), this); + rbEnableOutgoingConns = new QRadioButton(tr("Connect to the remote peer directly if possible"), this); rbEnableIncomingConns = new QRadioButton(tr("Enable incoming direct connections"), this); rbEnableIncomingConns->setChecked(true); QLabel *lbAddr = new QLabel(tr("Public address for incoming connections"), this); addr = new QLineEdit(tr("0.0.0.0"), this); + QLabel *lbPubPort = new QLabel(tr("External TCP port for incoming connections"), this); publicPort = new QSpinBox(this); + QLabel *lbLocPort = new QLabel(tr("Local TCP port for incoming connections"), this); localPort = new QSpinBox(this); publicPort->setRange(1, 65535); @@ -40,7 +42,9 @@ SettingsDialog::SettingsDialog(QWidget *parent) : directc2cLayout->addWidget(rbEnableIncomingConns); directc2cLayout->addWidget(lbAddr); directc2cLayout->addWidget(addr); + directc2cLayout->addWidget(lbPubPort); directc2cLayout->addWidget(publicPort); + directc2cLayout->addWidget(lbLocPort); directc2cLayout->addWidget(localPort); directc2cLayout->addStretch(1); -- cgit v1.2.1 From 15938ff034c73958159d5a8789b62b4644efc1f3 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 19 Sep 2016 18:11:54 +0400 Subject: disable incoming connection related widgets when incoming connections are disabled --- pica-client/dialogs/settingsdialog.cpp | 8 ++++++++ pica-client/dialogs/settingsdialog.h | 1 + 2 files changed, 9 insertions(+) diff --git a/pica-client/dialogs/settingsdialog.cpp b/pica-client/dialogs/settingsdialog.cpp index c9a60a1..ca29f66 100644 --- a/pica-client/dialogs/settingsdialog.cpp +++ b/pica-client/dialogs/settingsdialog.cpp @@ -21,6 +21,7 @@ SettingsDialog::SettingsDialog(QWidget *parent) : rbEnableIncomingConns = new QRadioButton(tr("Enable incoming direct connections"), this); rbEnableIncomingConns->setChecked(true); + connect(rbEnableIncomingConns, SIGNAL(toggled(bool)), this, SLOT(toggleIncomingConnections(bool))); QLabel *lbAddr = new QLabel(tr("Public address for incoming connections"), this); addr = new QLineEdit(tr("0.0.0.0"), this); @@ -73,6 +74,13 @@ SettingsDialog::SettingsDialog(QWidget *parent) : setWindowTitle(tr("Pica Pica Messenger Settings")); } +void SettingsDialog::toggleIncomingConnections(bool checked) +{ + addr->setEnabled(checked); + publicPort->setEnabled(checked); + localPort->setEnabled(checked); +} + void SettingsDialog::OK() { storeSettings(); diff --git a/pica-client/dialogs/settingsdialog.h b/pica-client/dialogs/settingsdialog.h index 06a2cf8..8c14ca1 100644 --- a/pica-client/dialogs/settingsdialog.h +++ b/pica-client/dialogs/settingsdialog.h @@ -36,6 +36,7 @@ private: private slots: void OK(); void Cancel(); + void toggleIncomingConnections(bool checked); }; -- cgit v1.2.1 From 5b9226164a3237f90823eff57c65f4fcd33f02be Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 22 Sep 2016 22:57:30 +0400 Subject: added declaration of the new function PICA_configure_directc2c() --- PICA_client.c | 6 ++++++ PICA_client.h | 2 ++ 2 files changed, 8 insertions(+) diff --git a/PICA_client.c b/PICA_client.c index e6617ee..28d329d 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -1120,6 +1120,12 @@ static int check_pkey_passphrase(const char *pkey_file, return PICA_OK; } + +int PICA_configure_directc2c(struct PICA_c2n *ci, PICA_directc2c_config mode, const char *public_addr, int public_port) +{ + implement me +} + // Opens socket to listen for incoming direct c2c connections bypassing nodes // // acc - pointer to opened account diff --git a/PICA_client.h b/PICA_client.h index 5c88040..3fa917f 100644 --- a/PICA_client.h +++ b/PICA_client.h @@ -308,6 +308,8 @@ int PICA_new_c2c(struct PICA_c2n *ci, const unsigned char *peer_id, struct PICA_ int PICA_new_listener(const struct PICA_acc *acc, const char *public_addr, int public_port, int local_port, struct PICA_listener **l); +int PICA_configure_directc2c(struct PICA_c2n *ci, PICA_directc2c_config mode, const char *public_addr, int public_port); + // << Date: Fri, 23 Sep 2016 03:26:50 +0400 Subject: moved direct c2c initialization into PICA_new_c2n() by adding new arguments, removed PICA_configure_directc2c() --- PICA_client.c | 96 ++++++++++++++++++++++++++------------------------ PICA_client.h | 33 +++++++---------- pica-client/skynet.cpp | 3 +- 3 files changed, 63 insertions(+), 69 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 28d329d..07dbab2 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -186,7 +186,7 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) if (!preverify_ok) { printf("verify error:num=%d:%s:depth=%d:%s\n", err, - X509_verify_cert_error_string(err), depth, buf); + X509_verify_cert_error_string(err), depth, buf); } @@ -239,8 +239,7 @@ static int c2n_alloc_c2c(struct PICA_c2n *ci, struct PICA_c2c **chn, const unsig } chnl->state = PICA_C2C_STATE_NEW; - chnl->directc2c_config = PICA_DIRECTC2C_CFG_DISABLED; - chnl->directc2c_state = PICA_DIRECTC2C_STATE_NEW; + chnl->directc2c_state = PICA_DIRECTC2C_STATE_NEW; return 1; } @@ -657,10 +656,10 @@ static unsigned int procmsg_CLNODELIST(unsigned char* buf, unsigned int nb, void case PICA_PROTO_NEWNODE_IPV4: callbacks.nodelist_cb( - PICA_PROTO_NEWNODE_IPV4, - buf + pos + 1, - inet_ntop(AF_INET, buf + pos + 1, ipaddr_string, INET6_ADDRSTRLEN), - ntohs(*(uint16_t*)(buf + pos + 5)) + PICA_PROTO_NEWNODE_IPV4, + buf + pos + 1, + inet_ntop(AF_INET, buf + pos + 1, ipaddr_string, INET6_ADDRSTRLEN), + ntohs(*(uint16_t*)(buf + pos + 5)) ); pos += PICA_PROTO_NODELIST_ITEM_IPV4_SIZE; @@ -669,10 +668,10 @@ static unsigned int procmsg_CLNODELIST(unsigned char* buf, unsigned int nb, void case PICA_PROTO_NEWNODE_IPV6: callbacks.nodelist_cb( - PICA_PROTO_NEWNODE_IPV6, - buf + pos + 1, - inet_ntop(AF_INET6, buf + pos + 1, ipaddr_string, INET6_ADDRSTRLEN), - ntohs(*(uint16_t*)(buf + pos + 17)) + PICA_PROTO_NEWNODE_IPV6, + buf + pos + 1, + inet_ntop(AF_INET6, buf + pos + 1, ipaddr_string, INET6_ADDRSTRLEN), + ntohs(*(uint16_t*)(buf + pos + 17)) ); pos += PICA_PROTO_NODELIST_ITEM_IPV6_SIZE; @@ -686,10 +685,10 @@ static unsigned int procmsg_CLNODELIST(unsigned char* buf, unsigned int nb, void buf[pos + 2 + buf[pos + 1]] = '\0'; // and replace it with string terminating zero callbacks.nodelist_cb( - PICA_PROTO_NEWNODE_DNS, - buf + pos + 2, - buf + pos + 2, - port + PICA_PROTO_NEWNODE_DNS, + buf + pos + 2, + buf + pos + 2, + port ); buf[pos + 2 + buf[pos + 1]] = temp_zeroswap; @@ -877,7 +876,7 @@ static unsigned int procmsg_FILEFRAGMENT(unsigned char* buf, unsigned int nb, vo *Allow incoming FILEFRAGMENTs while paused */ if (chan->recvfilestate != PICA_CHANRECVFILESTATE_RECEIVING - && chan->recvfilestate != PICA_CHANRECVFILESTATE_PAUSED) + && chan->recvfilestate != PICA_CHANRECVFILESTATE_PAUSED) return 0; if (nb - 4 != *(uint16_t*)(buf + 2)) @@ -927,7 +926,7 @@ static unsigned int procmsg_FILECONTROL(unsigned char* buf, unsigned int nb, voi fprintf(stderr, "procmsg_FILECONTROL sender_cmd = %i receiver_cmd = %i\n", sender_cmd, receiver_cmd);//debug if ((chan->sendfilestate == PICA_CHANSENDFILESTATE_IDLE || chan->sendfilestate == PICA_CHANSENDFILESTATE_SENTREQ) - && receiver_cmd != PICA_PROTO_FILECONTROL_VOID) + && receiver_cmd != PICA_PROTO_FILECONTROL_VOID) return 0; if (chan->recvfilestate == PICA_CHANRECVFILESTATE_IDLE && sender_cmd != PICA_PROTO_FILECONTROL_VOID) @@ -1088,8 +1087,8 @@ int PICA_client_init(struct PICA_client_callbacks *clcbs) } static int check_pkey_passphrase(const char *pkey_file, - int (*password_cb)(char *buf, int size, int rwflag, void *userdata), - void *userdata) + int (*password_cb)(char *buf, int size, int rwflag, void *userdata), + void *userdata) { RSA *rsa; FILE *f; @@ -1121,10 +1120,6 @@ static int check_pkey_passphrase(const char *pkey_file, } -int PICA_configure_directc2c(struct PICA_c2n *ci, PICA_directc2c_config mode, const char *public_addr, int public_port) -{ - implement me -} // Opens socket to listen for incoming direct c2c connections bypassing nodes // @@ -1214,10 +1209,10 @@ error_ret_1: //(1) } int PICA_open_acc(const char *cert_file, - const char *pkey_file, - const char *dh_param_file, - int (*password_cb)(char *buf, int size, int rwflag, void *userdata), - struct PICA_acc **acc) + const char *pkey_file, + const char *dh_param_file, + int (*password_cb)(char *buf, int size, int rwflag, void *userdata), + struct PICA_acc **acc) { int ret, ret_err; DH *dh = NULL; @@ -1404,9 +1399,9 @@ static int c2n_stage4_nodelistrequest(struct PICA_c2n *c2n) //PICA_OK - успешное завершение функции //.... -int PICA_new_c2n(const struct PICA_acc *acc, const char *nodeaddr, - unsigned int port, - struct PICA_c2n **ci) +int PICA_new_c2n(const struct PICA_acc *acc, const char *nodeaddr, unsigned int port, + enum PICA_directc2c_config direct_c2c_mode, struct PICA_listener *l, + struct PICA_c2n **ci) { int ret, ret_err; struct PICA_c2n *cid; @@ -1423,6 +1418,13 @@ int PICA_new_c2n(const struct PICA_acc *acc, const char *nodeaddr, cid->acc = acc; + cid->directc2c_config = direct_c2c_mode; + + if (direct_c2c_mode == PICA_DIRECTC2C_CFG_ALLOWINCOMING) + { + cid->directc2c_listener = l; + } + cid->read_buf = calloc(PICA_CONNREADBUFSIZE, 1);//(2) if (!cid->read_buf) { @@ -1528,14 +1530,14 @@ int PICA_new_c2n(const struct PICA_acc *acc, const char *nodeaddr, if (cid->init_resp_ok != 1) { if (cid->init_resp_ok == -1) - { - if (cid->node_ver_major > PICA_PROTO_VER_HIGH || - (cid->node_ver_major == PICA_PROTO_VER_HIGH && cid->node_ver_minor > PICA_PROTO_VER_LOW)) - ret_err = PICA_ERRPROTONEW; - else - ret_err = PICA_ERRPROTOOLD; - } - goto error_ret_4; + { + if (cid->node_ver_major > PICA_PROTO_VER_HIGH || + (cid->node_ver_major == PICA_PROTO_VER_HIGH && cid->node_ver_minor > PICA_PROTO_VER_LOW)) + ret_err = PICA_ERRPROTONEW; + else + ret_err = PICA_ERRPROTOOLD; + } + goto error_ret_4; } //printf("6\n");//debug @@ -1552,8 +1554,8 @@ if (ret!=1) //printf("SSL_accept ret=%i\n SSL_get_error=%i\n",ret,SSL_get_error(cid->ssl_comm,ret));//debug //ERR_CHECK ret_err=PICA_ERRSSL; - goto error_ret_4; - }*/ /* + goto error_ret_4; + }*/ /* cid->state = PICA_C2N_STATE_CONNECTED;//<<node_ver_major > PICA_PROTO_VER_HIGH || - (c2n->node_ver_major == PICA_PROTO_VER_HIGH && c2n->node_ver_minor > PICA_PROTO_VER_LOW)) + (c2n->node_ver_major == PICA_PROTO_VER_HIGH && c2n->node_ver_minor > PICA_PROTO_VER_LOW)) ret = PICA_ERRPROTONEW; else ret = PICA_ERRPROTOOLD; @@ -1895,7 +1897,7 @@ int PICA_event_loop(struct PICA_c2n **connections, struct PICA_listener **listen fdset_add(&rfds, (*ic2n)->sck_comm, &nfds); if ((*ic2n)->write_pos || (*ic2n)->state == PICA_C2N_STATE_CONNECTING - || (*ic2n)->state == PICA_C2N_STATE_WAITINGTLS) + || (*ic2n)->state == PICA_C2N_STATE_WAITINGTLS) fdset_add(&wfds, (*ic2n)->sck_comm, &nfds); ic2c = (*ic2n)->chan_list_head; @@ -2569,7 +2571,7 @@ int PICA_cancel_file(struct PICA_c2c *chan, int sending) if (sending) { if (chan->sendfilestate != PICA_CHANSENDFILESTATE_SENDING - && chan->sendfilestate != PICA_CHANSENDFILESTATE_PAUSED) + && chan->sendfilestate != PICA_CHANSENDFILESTATE_PAUSED) return PICA_ERRINVARG; fclose(chan->sendfile_stream); @@ -2581,7 +2583,7 @@ int PICA_cancel_file(struct PICA_c2c *chan, int sending) else { if (chan->recvfilestate != PICA_CHANRECVFILESTATE_RECEIVING - && chan->recvfilestate != PICA_CHANRECVFILESTATE_PAUSED) + && chan->recvfilestate != PICA_CHANRECVFILESTATE_PAUSED) return PICA_ERRINVARG; fclose(chan->recvfile_stream); @@ -2774,9 +2776,9 @@ const char *PICA_inet_ntop(int af, const void *src, char *dst, size_t size) case AF_INET6: sprintf(dst, "%x%02x:%x%02x:%x%02x:%x%02x:%x%02x:%x%02x:%x%02x:%x%02x", chsrc[0], chsrc[1], chsrc[2], chsrc[3], - chsrc[4], chsrc[5], chsrc[6], chsrc[7], - chsrc[8], chsrc[9], chsrc[10], chsrc[11], - chsrc[12], chsrc[13], chsrc[14], chsrc[15]); + chsrc[4], chsrc[5], chsrc[6], chsrc[7], + chsrc[8], chsrc[9], chsrc[10], chsrc[11], + chsrc[12], chsrc[13], chsrc[14], chsrc[15]); break; default: diff --git a/PICA_client.h b/PICA_client.h index 3fa917f..dd1f358 100644 --- a/PICA_client.h +++ b/PICA_client.h @@ -132,6 +132,13 @@ enum PICA_c2n_state PICA_C2N_STATE_CONNECTED }; +enum PICA_directc2c_config +{ + PICA_DIRECTC2C_CFG_DISABLED, + PICA_DIRECTC2C_CFG_CONNECTONLY, + PICA_DIRECTC2C_CFG_ALLOWINCOMING +}; + struct PICA_c2n { struct PICA_acc *acc; @@ -144,6 +151,8 @@ struct PICA_c2n enum PICA_c2n_state state; + enum PICA_directc2c_config directc2c_config; + struct PICA_listener *directc2c_listener; unsigned char *read_buf; unsigned char *write_buf; @@ -171,13 +180,6 @@ enum PICA_c2c_state PICA_C2C_STATE_ACTIVE }; -enum PICA_directc2c_config -{ - PICA_DIRECTC2C_CFG_DISABLED, - PICA_DIRECTC2C_CFG_CONNECTONLY, - PICA_DIRECTC2C_CFG_ALLOWINCOMING -}; - enum PICA_directc2c_state { PICA_DIRECTC2C_STATE_NEW, @@ -210,7 +212,6 @@ struct PICA_c2c struct PICA_c2c *prev; enum PICA_c2c_state state; enum PICA_directc2c_state directc2c_state; - enum PICA_directc2c_config directc2c_config; time_t timestamp; int sendfilestate; uint64_t sendfile_size; @@ -293,24 +294,14 @@ int PICA_get_id_from_cert_file(const char *cert_file, unsigned char *id); int PICA_get_id_from_cert_string(const char *cert_pem, unsigned char *id); int PICA_client_init(struct PICA_client_callbacks *clcbs); -int PICA_new_c2n -(const struct PICA_acc *acc, - const char *nodeaddr, - unsigned int port, - /* const char *CA_file, - const char *cert_file, - const char *pkey_file, - const char *dh_param_file, - int (*password_cb)(char *buf, int size, int rwflag, void *userdata), //move callback to PICA_client_callbacks? */ - struct PICA_c2n **ci); +int PICA_new_c2n(const struct PICA_acc *acc, const char *nodeaddr, unsigned int port, + enum PICA_directc2c_config direct_c2c_mode, struct PICA_listener *l, + struct PICA_c2n **ci); int PICA_new_c2c(struct PICA_c2n *ci, const unsigned char *peer_id, struct PICA_listener *l, struct PICA_c2c **chn); int PICA_new_listener(const struct PICA_acc *acc, const char *public_addr, int public_port, int local_port, struct PICA_listener **l); -int PICA_configure_directc2c(struct PICA_c2n *ci, PICA_directc2c_config mode, const char *public_addr, int public_port); - - // << Date: Fri, 23 Sep 2016 18:20:22 +0400 Subject: renamed to PICA_DIRECTC2C_STATE_INACTIVE --- PICA_client.c | 2 +- PICA_client.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 07dbab2..679c8d2 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -239,7 +239,7 @@ static int c2n_alloc_c2c(struct PICA_c2n *ci, struct PICA_c2c **chn, const unsig } chnl->state = PICA_C2C_STATE_NEW; - chnl->directc2c_state = PICA_DIRECTC2C_STATE_NEW; + chnl->directc2c_state = PICA_DIRECTC2C_STATE_INACTIVE; return 1; } diff --git a/PICA_client.h b/PICA_client.h index dd1f358..2fad713 100644 --- a/PICA_client.h +++ b/PICA_client.h @@ -182,7 +182,7 @@ enum PICA_c2c_state enum PICA_directc2c_state { - PICA_DIRECTC2C_STATE_NEW, + PICA_DIRECTC2C_STATE_INACTIVE, PICA_DIRECTC2C_STATE_WAITINGINCOMING, PICA_DIRECTC2C_STATE_CONNECTING, PICA_DIRECTC2C_STATE_ACTIVE -- cgit v1.2.1 From 637eb86df1027d0e47bd7a801f7f9c5324bb6b01 Mon Sep 17 00:00:00 2001 From: Anton Date: Fri, 23 Sep 2016 19:01:43 +0400 Subject: added timeout handling to process_c2c(); removed unused obsolete functions --- PICA_client.c | 137 +++------------------------------------------------------- PICA_client.h | 4 +- 2 files changed, 7 insertions(+), 134 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 679c8d2..54047e6 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -1838,6 +1838,11 @@ static int process_c2c(struct PICA_c2c *c2c, fd_set *rfds, fd_set *wfds) break; } + if (c2c->state != PICA_C2C_STATE_ACTIVE && (time(0) - c2c->timestamp) > PICA_C2C_ACTIVATE_TIMEOUT) + { + ret = PICA_ERRTIMEDOUT; + } + if (ret != PICA_OK) { if (c2c->state > PICA_C2C_STATE_NEW && c2c->state < PICA_C2C_STATE_ACTIVE) @@ -2001,138 +2006,6 @@ int PICA_event_loop(struct PICA_c2n **connections, struct PICA_listener **listen return PICA_OK; } -int PICA_read(struct PICA_c2n *ci, int timeout) -{ - fd_set fds; - struct timeval tv = {0, 1000}; - struct PICA_c2c *ipt, *kill_ptr = 0; - int ret, nfds; - -//puts("PICA_read<<");//debug - - tv.tv_usec = timeout; - - FD_ZERO(&fds); - - nfds = ci->sck_comm; - FD_SET(ci->sck_comm, &fds); - - ipt = ci->chan_list_head; - - while(ipt) - { - if (ipt->state == PICA_C2C_STATE_ACTIVE) - { - FD_SET(ipt->sck_data, &fds); - - if (ipt->sck_data > nfds) - nfds = ipt->sck_data; - } - - if (ipt->state != PICA_C2C_STATE_ACTIVE && (time(0) - ipt->timestamp) > PICA_CHAN_ACTIVATE_TIMEOUT) - { - kill_ptr = ipt; - } - - ipt = ipt->next; - - if (kill_ptr) - { - PICA_close_c2c(kill_ptr); - kill_ptr = 0; - } - } - -//#warning "make sockets non-blocking!!!!" - - ret = select(nfds + 1, &fds, 0, 0, &tv); - - if (ret > 0) - { - - if (FD_ISSET(ci->sck_comm, &fds)) - { - ret = PICA_read_c2n(ci); - if (ret != PICA_OK) - return ret; - } - - ipt = ci->chan_list_head; - while(ipt) - { - if (ipt->state == PICA_C2C_STATE_ACTIVE && FD_ISSET(ipt->sck_data, &fds)) - { - if (PICA_OK != (ret = PICA_read_c2c(ipt)) ) - { - puts("PICA_read_c2c() failed");//debug - callbacks.c2c_closed_cb(ipt->peer_id, ret); - kill_ptr = ipt; - } - - } - - ipt = ipt->next; - - if (kill_ptr) - { - PICA_close_c2c(kill_ptr); - kill_ptr = 0; - } - } - - } -//puts("PICA_read>>");//debug - - return PICA_OK; -} - -int PICA_write(struct PICA_c2n *ci) -{ - struct PICA_c2c *ipt, *kill_ptr = 0; - int ret = PICA_OK; - -//puts("PICA_write>>");//debug - - if (ci->write_pos) - ret = PICA_write_c2n(ci); - - if (PICA_OK != ret) - return ret; - - ipt = ci->chan_list_head; - - while(ipt) - { - if (ipt->write_pos) - { - if (PICA_OK != (ret = PICA_write_c2c(ipt))) - { - fprintf(stderr, "PICA_write_c2c() failed, ret = %i\n", ret); //debug - callbacks.c2c_closed_cb(ipt->peer_id, ret); - kill_ptr = ipt; - } - } - else if (ipt->sendfilestate == PICA_CHANSENDFILESTATE_SENDING) - { - if (PICA_OK != (ret = PICA_send_file_fragment(ipt))) - { - callbacks.c2c_closed_cb(ipt->peer_id, ret); - kill_ptr = ipt; - } - } - ipt = ipt->next; - - if (kill_ptr) - { - PICA_close_c2c(kill_ptr); - kill_ptr = 0; - } - } - -//puts("PICA_write<<");//debug - return PICA_OK; -} - int PICA_write_socket(SOCKET s, unsigned char *buf, unsigned int *ppos) { int ret; diff --git a/PICA_client.h b/PICA_client.h index 2fad713..cefa9c3 100644 --- a/PICA_client.h +++ b/PICA_client.h @@ -89,6 +89,7 @@ typedef unsigned __int64 uint64_t; #define PICA_ERRINVPKEYPASSPHRASE -22 #define PICA_ERRINVPKEYFILE -23 +#define PICA_ERRTIMEDOUT -24 //#define PICA_CHNMSGBUFLEN 104 @@ -108,7 +109,7 @@ typedef unsigned __int64 uint64_t; #define PICA_CHANRECVFILESTATE_PAUSED 25 #define PICA_CHANRECVFILESTATE_WAITACCEPT 26 -#define PICA_CHAN_ACTIVATE_TIMEOUT 30 +#define PICA_C2C_ACTIVATE_TIMEOUT 30 #define PICA_c2c_INCOMING 0 @@ -320,7 +321,6 @@ int PICA_write(struct PICA_c2n *ci); int PICA_event_loop(struct PICA_c2n **connections, struct PICA_listener **listeners, int timeout); int PICA_send_msg(struct PICA_c2c *chn, char *buf, unsigned int len); -int PICA_read_msg(struct PICA_c2c *chn, char *buf, unsigned int *n); //filename - ASCII or UTF-8 encoded string int PICA_send_file(struct PICA_c2c *chn, const char *filepath); -- cgit v1.2.1 From 1341e2afca0dd1de1f2d28f51f445d09ec6ddc07 Mon Sep 17 00:00:00 2001 From: Anton Date: Fri, 23 Sep 2016 19:06:00 +0400 Subject: renamed macros, use PICA_C2C_INCOMING instead of 0 magic number --- PICA_client.c | 4 ++-- PICA_client.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 54047e6..d50c034 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -545,7 +545,7 @@ static unsigned int procmsg_CONNREQINC(unsigned char* buf, unsigned int nb, void else return 0; - ret = c2n_alloc_c2c( ci, &_chnl, peer_id, 0); + ret = c2n_alloc_c2c( ci, &_chnl, peer_id, PICA_C2C_INCOMING); if (!ret) return 0; //ERR_CHECK - кончилась память @@ -1605,7 +1605,7 @@ int PICA_new_c2c(struct PICA_c2n *ci, const unsigned char *peer_id, struct PICA_ if (ci->state != PICA_C2N_STATE_CONNECTED) return PICA_ERRINVARG; - if (!c2n_alloc_c2c(ci, chn, peer_id, PICA_c2c_OUTGOING)) + if (!c2n_alloc_c2c(ci, chn, peer_id, PICA_C2C_OUTGOING)) return PICA_ERRNOMEM; chnl = *chn; diff --git a/PICA_client.h b/PICA_client.h index cefa9c3..e645365 100644 --- a/PICA_client.h +++ b/PICA_client.h @@ -112,8 +112,8 @@ typedef unsigned __int64 uint64_t; #define PICA_C2C_ACTIVATE_TIMEOUT 30 -#define PICA_c2c_INCOMING 0 -#define PICA_c2c_OUTGOING 1 +#define PICA_C2C_INCOMING 0 +#define PICA_C2C_OUTGOING 1 struct PICA_c2n; struct PICA_c2c; -- cgit v1.2.1 From 7a394a9baf4863ab2c5b8f60eefb98688ee96a7c Mon Sep 17 00:00:00 2001 From: Anton Date: Fri, 23 Sep 2016 19:14:10 +0400 Subject: function declarations --- PICA_client.c | 12 +++++++++--- PICA_client.h | 5 ----- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index d50c034..1f026a7 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -52,6 +52,15 @@ static unsigned int procmsg_C2CCONNREQ(unsigned char* buf, unsigned int nb, void 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 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); +static int PICA_write_socket(SOCKET s, unsigned char *buf, unsigned int *ppos); +static int PICA_read_c2n(struct PICA_c2n *ci); +static int PICA_read_c2c(struct PICA_c2c *chn); +static int PICA_read_ssl(SSL *ssl, unsigned char *buf, unsigned int *ppos, unsigned int size); +static int PICA_read_socket(SOCKET s, unsigned char *buf, unsigned int *ppos, unsigned int size); + #define MSGINFO_MSGSNUM(arr) (sizeof(arr)/sizeof(struct PICA_msginfo)) const struct PICA_msginfo c2n_messages[] = { @@ -2071,9 +2080,6 @@ int PICA_write_ssl(SSL *ssl, unsigned char *buf, unsigned int *ppos, unsigned in return PICA_OK; } -//int PICA_read_socket() -//int PICA_read_ssl() - int PICA_write_c2n(struct PICA_c2n *ci) { int ret = PICA_ERRINVARG; diff --git a/PICA_client.h b/PICA_client.h index e645365..ad13740 100644 --- a/PICA_client.h +++ b/PICA_client.h @@ -311,11 +311,6 @@ int PICA_open_acc(const char *cert_file, struct PICA_acc **acc); // << Date: Sun, 25 Sep 2016 00:59:40 +0400 Subject: direct c2c packet handlers --- PICA_client.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 1f026a7..63ed3eb 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -47,7 +47,10 @@ static unsigned int procmsg_DENIEDFILE(unsigned char*, unsigned int, void*); static unsigned int procmsg_FILEFRAGMENT(unsigned char*, unsigned int, void*); static unsigned int procmsg_FILECONTROL(unsigned char*, unsigned int, void*); static unsigned int procmsg_INITRESP_c2c(unsigned char*, unsigned int, void*); -static unsigned int procmsg_C2CCONNREQ(unsigned char* buf, unsigned int nb, void* p); +static unsigned int procmsg_C2CCONNREQ(unsigned char*, unsigned int, void*); +static unsigned int procmsg_PICA_PROTO_C2CDIRECT_ADDRLIST(unsigned char*, unsigned int, void*); +static unsigned int procmsg_PICA_PROTO_C2CDIRECT_FAILED(unsigned char*, unsigned int, void*); + 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); @@ -79,7 +82,9 @@ const struct PICA_msginfo c2c_messages[] = {PICA_PROTO_ACCEPTEDFILE, PICA_MSG_FIXED_SIZE, PICA_PROTO_ACCEPTEDFILE_SIZE, procmsg_ACCEPTEDFILE}, {PICA_PROTO_DENIEDFILE, PICA_MSG_FIXED_SIZE, PICA_PROTO_DENIEDFILE_SIZE, procmsg_DENIEDFILE}, {PICA_PROTO_FILEFRAGMENT, PICA_MSG_VAR_SIZE, PICA_MSG_VARSIZE_INT16, procmsg_FILEFRAGMENT}, - {PICA_PROTO_FILECONTROL, PICA_MSG_FIXED_SIZE, PICA_PROTO_FILECONTROL_SIZE, procmsg_FILECONTROL} + {PICA_PROTO_FILECONTROL, PICA_MSG_FIXED_SIZE, PICA_PROTO_FILECONTROL_SIZE, procmsg_FILECONTROL}, + {PICA_PROTO_C2CDIRECT_ADDRLIST, PICA_MSG_VAR_SIZE, PICA_MSG_VARSIZE_INT16, procmsg_PICA_PROTO_C2CDIRECT_ADDRLIST}, + {PICA_PROTO_C2CDIRECT_FAILED, PICA_MSG_FIXED_SIZE, PICA_PROTO_C2CDIRECT_FAILED_SIZE, procmsg_PICA_PROTO_C2CDIRECT_FAILED} }; struct PICA_msginfo c2n_init_messages[] = @@ -510,6 +515,16 @@ static unsigned int procmsg_INITRESP_c2c(unsigned char* buf, unsigned int nb, vo return 1; } +static unsigned int procmsg_PICA_PROTO_C2CDIRECT_ADDRLIST(unsigned char* buf, unsigned int nb, void* p) +{ + -- +} + +static unsigned int procmsg_PICA_PROTO_C2CDIRECT_FAILED(unsigned char* buf, unsigned int nb, void* p) +{ + -- +} + static unsigned int procmsg_INITRESP(unsigned char* buf, unsigned int nb, void* p) { struct PICA_c2n *ci = (struct PICA_c2n *)p; @@ -1865,6 +1880,19 @@ static int process_c2c(struct PICA_c2c *c2c, fd_set *rfds, fd_set *wfds) static int process_listener(struct PICA_listener *lst, fd_set *rfds) { + if (FD_ISSET(lst->sck_listener, rfds)) + { + SOCKET s; + struct sockaddr_in addr; + int addrsize = sizeof(struct sockaddr_in); + + s = accept(lst->sck_listener, (struct sockaddr*)&addr, &addrsize); + + if (s >= 0) + { + + } + } return PICA_OK; } -- cgit v1.2.1 From fbe88d4debb49d03a3a97e450ca2a69bf91b058b Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 25 Sep 2016 01:14:51 +0400 Subject: linked listener processing to c2n struct --- PICA_client.c | 38 +++++++++++++------------------------- PICA_client.h | 2 +- pica-client/skynet.cpp | 2 +- 3 files changed, 15 insertions(+), 27 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 63ed3eb..b1ff144 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -1904,13 +1904,12 @@ static void fdset_add(fd_set *fds, int fd, int *max) *max = fd; } -int PICA_event_loop(struct PICA_c2n **connections, struct PICA_listener **listeners, int timeout) +int PICA_event_loop(struct PICA_c2n **connections, int timeout) { fd_set rfds, wfds; struct timeval tv; int ret, nfds = 0; struct PICA_c2n **ic2n; - struct PICA_listener **ilst; //puts("PICA_event_loop");//debug @@ -1920,14 +1919,6 @@ int PICA_event_loop(struct PICA_c2n **connections, struct PICA_listener **listen FD_ZERO(&rfds); FD_ZERO(&wfds); - ilst = listeners; - - while(ilst && *ilst) - { - fdset_add(&rfds, (*ilst)->sck_listener, &nfds); - ilst++; - } - ic2n = connections; while(ic2n && *ic2n) @@ -1942,6 +1933,8 @@ int PICA_event_loop(struct PICA_c2n **connections, struct PICA_listener **listen || (*ic2n)->state == PICA_C2N_STATE_WAITINGTLS) fdset_add(&wfds, (*ic2n)->sck_comm, &nfds); + fdset_add(&rfds, (*ic2n)->directc2c_listener->sck_listener, &nfds); + ic2c = (*ic2n)->chan_list_head; while(ic2c) @@ -1980,21 +1973,6 @@ int PICA_event_loop(struct PICA_c2n **connections, struct PICA_listener **listen //processing listeners, c2n and c2c connections - ilst = listeners; - - while(ilst && *ilst) - { - ret = process_listener(*ilst, &rfds); - - if (ret != PICA_OK) - { - callbacks.listener_error_cb(*ilst, ret); - PICA_close_listener(*ilst); - } - - ilst++; - } - ic2n = connections; while(ic2n && *ic2n) @@ -2018,6 +1996,16 @@ int PICA_event_loop(struct PICA_c2n **connections, struct PICA_listener **listen { struct PICA_c2c *kill_ptr = 0; + //processing listener associated with current c2n + ret = process_listener((*ic2n)->directc2c_listener, &rfds); + + if (ret != PICA_OK) + { + callbacks.listener_error_cb((*ic2n)->directc2c_listener, ret); + PICA_close_listener((*ic2n)->directc2c_listener); + } + + ic2c = (*ic2n)->chan_list_head; //processing c2c connections associated with current c2n diff --git a/PICA_client.h b/PICA_client.h index ad13740..30f9cf9 100644 --- a/PICA_client.h +++ b/PICA_client.h @@ -313,7 +313,7 @@ int PICA_open_acc(const char *cert_file, //connections, listeners - NULL-terminated arrays of pointers to appropriate structures // timeout - timeout in milliseconds -int PICA_event_loop(struct PICA_c2n **connections, struct PICA_listener **listeners, int timeout); +int PICA_event_loop(struct PICA_c2n **connections, int timeout); int PICA_send_msg(struct PICA_c2c *chn, char *buf, unsigned int len); diff --git a/pica-client/skynet.cpp b/pica-client/skynet.cpp index acb0fef..7388634 100644 --- a/pica-client/skynet.cpp +++ b/pica-client/skynet.cpp @@ -246,7 +246,7 @@ void SkyNet::timerEvent(QTimerEvent *e) nodelinks.append(NULL); - ret = PICA_event_loop(nodelinks.data(), NULL, 1); + ret = PICA_event_loop(nodelinks.data(), 1); if (ret != PICA_OK) emit StatusMsg("event loop error!", true);//show some error message -- cgit v1.2.1 From 9008d31c8c4401051e50d26f1743501688ffc9bc Mon Sep 17 00:00:00 2001 From: Anton Date: Wed, 28 Sep 2016 02:30:50 +0400 Subject: listener connection struct and code accepting listener connections --- PICA_client.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- PICA_client.h | 9 +++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/PICA_client.c b/PICA_client.c index b1ff144..ce7f66e 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -1196,6 +1196,8 @@ int PICA_new_listener(const struct PICA_acc *acc, const char *public_addr, int p flag = 1; setsockopt(lst->sck_listener, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)); + IOCTLSETNONBLOCKINGSOCKET(lst->sck_listener, 1); + memset(&s, 0, sizeof(s)); s.sin_family = AF_INET; s.sin_addr.s_addr = INADDR_ANY; @@ -1878,6 +1880,46 @@ static int process_c2c(struct PICA_c2c *c2c, fd_set *rfds, fd_set *wfds) return ret; } +static void listener_add_connection(struct PICA_listener *lst, SOCKET *s) +{ + struct PICA_listener_conn *nc; + int ret; + + nc = calloc(1, sizeof(struct PICA_listener_conn)); + + nc->sck = s; + nc->ssl = SSL_new(lst->acc->ctx); + + SSL_set_fd(nc->ssl, nc->sck); + ret = SSL_accept(nc->ssl); + + if (ret == 0) + { + free(nc); + return; + } + + if (ret < 0) + { + ret = SSL_get_error(nc->ssl, ret); + + if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE) + { + free(nc); + return; + } + } + + nc->next = lst->accepted_connections; + + lst->accepted_connections = nc; +} + +static int process_listener_conn() +{ + -- +} + static int process_listener(struct PICA_listener *lst, fd_set *rfds) { if (FD_ISSET(lst->sck_listener, rfds)) @@ -1890,9 +1932,10 @@ static int process_listener(struct PICA_listener *lst, fd_set *rfds) if (s >= 0) { - + listener_add_connection(lst, s); } } + return PICA_OK; } diff --git a/PICA_client.h b/PICA_client.h index 30f9cf9..764b9dd 100644 --- a/PICA_client.h +++ b/PICA_client.h @@ -227,6 +227,14 @@ struct PICA_c2c int disconnect_on_empty_write_buf; }; +struct PICA_listener_conn +{ + SOCKET sck; + SSL *ssl; + X509 *peer_cert; + struct PICA_listener_conn *next; +}; + struct PICA_listener { const struct PICA_acc *acc; @@ -238,6 +246,7 @@ struct PICA_listener in_addr_t public_addr_ipv4; const char *public_addr_dns; + struct PICA_listener_conn *accepted_connections; }; struct PICA_client_callbacks -- cgit v1.2.1 From 9164d6c7266f2ea66459d1971128ca6071e6a4a2 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 17 Oct 2016 19:22:45 +0400 Subject: processing connections accepted by listener, work in progress --- PICA_client.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index ce7f66e..4f218c3 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -1915,13 +1915,45 @@ static void listener_add_connection(struct PICA_listener *lst, SOCKET *s) lst->accepted_connections = nc; } -static int process_listener_conn() +static int process_listener_conn(struct PICA_listener_conn *conn, fd_set *rfds, fd_set *wfds) { - -- + if (conn->peer_cert == NULL) + { + if (FD_ISSET(conn->sck, rfds) || FD_ISSET(conn->sck, wfds)) + { + int ret; + ret = SSL_accept(conn->ssl); + + if (ret == 1) + { + conn->peer_cert = SSL_get_peer_certificate(conn->ssl); + + if (!conn->peer_cert) + return PICA_ERRSSL; + + return PICA_OK; + } + + if (ret == 0) + return PICA_ERRSSL; + + if (ret < 0) + { + ret = SSL_get_error(conn->ssl, ret); + + if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE) + return PICA_ERRSSL; + } + } + } + + return PICA_OK; } -static int process_listener(struct PICA_listener *lst, fd_set *rfds) +static int process_listener(struct PICA_listener *lst, fd_set *rfds, fd_set *wfds) { + struct PICA_listener_conn *conn; + if (FD_ISSET(lst->sck_listener, rfds)) { SOCKET s; @@ -1936,6 +1968,17 @@ static int process_listener(struct PICA_listener *lst, fd_set *rfds) } } + conn = lst->accepted_connections; + + while(conn) + { + if (process_listener_conn(conn, rfds, wfds) != PICA_OK) + { + --- close listener conn + } + conn = conn->next; + } + return PICA_OK; } @@ -2040,7 +2083,7 @@ int PICA_event_loop(struct PICA_c2n **connections, int timeout) struct PICA_c2c *kill_ptr = 0; //processing listener associated with current c2n - ret = process_listener((*ic2n)->directc2c_listener, &rfds); + ret = process_listener((*ic2n)->directc2c_listener, &rfds, &wfds); if (ret != PICA_OK) { @@ -2700,6 +2743,8 @@ void PICA_close_listener(struct PICA_listener *l) CLOSE(l->sck_listener); free(l->public_addr_dns); free(l); + + -- close accepted connections } #ifdef WIN32 -- cgit v1.2.1 From abbfa4ccdcfc8633e5b30064f66af40b6b17cbd6 Mon Sep 17 00:00:00 2001 From: Anton Date: Fri, 21 Oct 2016 16:35:50 +0400 Subject: implemented closing listener connections --- PICA_client.c | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 4f218c3..85469c9 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -1972,11 +1972,18 @@ static int process_listener(struct PICA_listener *lst, fd_set *rfds, fd_set *wfd while(conn) { + struct PICA_listener_conn *kill_ptr = NULL; + if (process_listener_conn(conn, rfds, wfds) != PICA_OK) { - --- close listener conn + kill_ptr = conn; } conn = conn->next; + + if (kill_ptr) + { + listener_close_conn(kill_ptr); + } } return PICA_OK; @@ -2738,13 +2745,29 @@ void PICA_close_acc(struct PICA_acc *a) free(a); } +void listener_close_conn(struct PICA_listener_conn *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) { CLOSE(l->sck_listener); free(l->public_addr_dns); - free(l); - -- close accepted connections + while(l->accepted_connections) + { + struct PICA_listener_conn *c = l->accepted_connections; + l->accepted_connections = c->next; + listener_close_conn(c); + } + + free(l); } #ifdef WIN32 -- cgit v1.2.1 From 4e4ec4e69c201565e3c1e87a520650ab490924c0 Mon Sep 17 00:00:00 2001 From: Anton Date: Wed, 26 Oct 2016 19:57:36 +0400 Subject: add listener connections' sockets to fd_set-s in event loop --- PICA_client.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/PICA_client.c b/PICA_client.c index 85469c9..9374f35 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -2017,6 +2017,7 @@ int PICA_event_loop(struct PICA_c2n **connections, int timeout) while(ic2n && *ic2n) { struct PICA_c2c *ic2c; + struct PICA_listener_conn *ilstcon; //printf("event_loop: adding c2n %p\n", *ic2n);//debug @@ -2028,6 +2029,15 @@ int PICA_event_loop(struct PICA_c2n **connections, int timeout) fdset_add(&rfds, (*ic2n)->directc2c_listener->sck_listener, &nfds); + ilstcon = (*ic2n)->directc2c_listener->accepted_connections; + + while (ilstcon) + { + fdset_add(&rfds, ilstcon->sck, &nfds); + fdset_add(&wfds, ilstcon->sck, &nfds); + ilstcon = ilstcon->next; + } + ic2c = (*ic2n)->chan_list_head; while(ic2c) -- cgit v1.2.1 From 78967c09eb9e911572b23a4160ce4b06f83da95e Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 24 Nov 2016 21:17:17 +0400 Subject: implemented sending direct c2c address list (single address only yet, to be improved) --- PICA_client.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/PICA_client.c b/PICA_client.c index 9374f35..416e469 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -32,6 +32,7 @@ static int PICA_send_file_fragment(struct PICA_c2c *chn); static int PICA_sendfile_open_read(struct PICA_c2c *chn, const char *filename_utf8, uint64_t *file_size); static int PICA_recvfile_open_write(struct PICA_c2c *chn, const char *filename_utf8, unsigned int filenamesize); static int PICA_send_filecontrol(struct PICA_c2c *chan, int senderctl, int receiverctl); +static int PICA_send_directc2caddrlist(struct PICA_c2c *chn); static unsigned int procmsg_INITRESP(unsigned char*, unsigned int, void*); static unsigned int procmsg_CONNREQINC(unsigned char*, unsigned int, void*); @@ -468,6 +469,9 @@ static unsigned int procmsg_C2CCONNREQ(unsigned char* buf, unsigned int nb, void cc->state = PICA_C2C_STATE_ACTIVE; callbacks.c2c_established_cb(cc->peer_id); + + if (cc->conn->directc2c_config == PICA_DIRECTC2C_CFG_ALLOWINCOMING) + PICA_send_directc2caddrlist(cc); } else { @@ -501,6 +505,10 @@ static unsigned int procmsg_INITRESP_c2c(unsigned char* buf, unsigned int nb, vo case PICA_PROTO_INITRESPOK: cc->state = PICA_C2C_STATE_ACTIVE; callbacks.c2c_established_cb(cc->peer_id); + + if (cc->conn->directc2c_config == PICA_DIRECTC2C_CFG_ALLOWINCOMING) + PICA_send_directc2caddrlist(cc); + break; case PICA_PROTO_VERDIFFER: @@ -2436,6 +2444,27 @@ struct PICA_proto_msg* c2c_writebuf_push(struct PICA_c2c *chn, unsigned int msgi return mp; } +int PICA_send_directc2caddrlist(struct PICA_c2c *chn) +{ + if (chn->conn->directc2c_config == PICA_DIRECTC2C_CFG_ALLOWINCOMING && chn->conn->directc2c_listener) + { + struct PICA_proto_msg *mp; + //TODO send all possible interface addresses, not one + unsigned int len = PICA_PROTO_C2CDIRECT_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); + } + } + + return PICA_OK; +} + int PICA_send_msg(struct PICA_c2c *chn, char *buf, unsigned int len) { struct PICA_proto_msg *mp; -- cgit v1.2.1 From eac0690e821f90793a5d55263ecd71a5ad34adcd Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 24 Nov 2016 21:53:22 +0400 Subject: check if listener is not NULL before processing --- PICA_client.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 416e469..3567a91 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -2035,15 +2035,18 @@ int PICA_event_loop(struct PICA_c2n **connections, int timeout) || (*ic2n)->state == PICA_C2N_STATE_WAITINGTLS) fdset_add(&wfds, (*ic2n)->sck_comm, &nfds); - fdset_add(&rfds, (*ic2n)->directc2c_listener->sck_listener, &nfds); + if ((*ic2n)->directc2c_listener) + { + fdset_add(&rfds, (*ic2n)->directc2c_listener->sck_listener, &nfds); - ilstcon = (*ic2n)->directc2c_listener->accepted_connections; + ilstcon = (*ic2n)->directc2c_listener->accepted_connections; - while (ilstcon) - { - fdset_add(&rfds, ilstcon->sck, &nfds); - fdset_add(&wfds, ilstcon->sck, &nfds); - ilstcon = ilstcon->next; + while (ilstcon) + { + fdset_add(&rfds, ilstcon->sck, &nfds); + fdset_add(&wfds, ilstcon->sck, &nfds); + ilstcon = ilstcon->next; + } } ic2c = (*ic2n)->chan_list_head; @@ -2108,12 +2111,15 @@ int PICA_event_loop(struct PICA_c2n **connections, int timeout) struct PICA_c2c *kill_ptr = 0; //processing listener associated with current c2n - ret = process_listener((*ic2n)->directc2c_listener, &rfds, &wfds); - - if (ret != PICA_OK) + if ((*ic2n)->directc2c_listener) { - callbacks.listener_error_cb((*ic2n)->directc2c_listener, ret); - PICA_close_listener((*ic2n)->directc2c_listener); + ret = process_listener((*ic2n)->directc2c_listener, &rfds, &wfds); + + if (ret != PICA_OK) + { + callbacks.listener_error_cb((*ic2n)->directc2c_listener, ret); + PICA_close_listener((*ic2n)->directc2c_listener); + } } -- cgit v1.2.1 From 3a069e4c0b317793936d7d5cdd1aa67376c3cf82 Mon Sep 17 00:00:00 2001 From: Anton Date: Fri, 25 Nov 2016 22:22:08 +0400 Subject: tab widget in settings dialog --- pica-client/dialogs/settingsdialog.cpp | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/pica-client/dialogs/settingsdialog.cpp b/pica-client/dialogs/settingsdialog.cpp index ca29f66..7300d75 100644 --- a/pica-client/dialogs/settingsdialog.cpp +++ b/pica-client/dialogs/settingsdialog.cpp @@ -7,13 +7,21 @@ #include #include #include +#include +#include +#include +#include SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent) { QVBoxLayout *settingsLayout = new QVBoxLayout(); - QGroupBox *groupBox = new QGroupBox(tr("Direct Connections"), this); + QTabWidget *tabW = new QTabWidget(this); + QWidget* directc2ctab = new QWidget(0); + QWidget* soundstab = new QWidget(0); + + //QGroupBox *groupBox = new QGroupBox(tr("Direct Connections"), directc2ctab); QVBoxLayout *directc2cLayout = new QVBoxLayout(); rbDisableDirectConns = new QRadioButton(tr("Disable direct connections"), this); @@ -36,6 +44,12 @@ SettingsDialog::SettingsDialog(QWidget *parent) : publicPort->setValue(2298); localPort->setValue(2298); + QListWidget *lwAddrs = new QListWidget(this); + QList hostIfAddrs = QNetworkInterface::allAddresses(); + QHostAddress ifAddr; + + foreach (ifAddr, hostIfAddrs) + lwAddrs->addItem(ifAddr.toString()); directc2cLayout->addWidget(rbDisableDirectConns); @@ -47,11 +61,16 @@ SettingsDialog::SettingsDialog(QWidget *parent) : directc2cLayout->addWidget(publicPort); directc2cLayout->addWidget(lbLocPort); directc2cLayout->addWidget(localPort); + directc2cLayout->addWidget(lwAddrs); directc2cLayout->addStretch(1); - groupBox->setLayout(directc2cLayout); + //groupBox->setLayout(directc2cLayout); + directc2ctab->setLayout(directc2cLayout); - settingsLayout->addWidget(groupBox); + //settingsLayout->addWidget(groupBox); + tabW->addTab(directc2ctab, tr("Direct Connections")); + tabW->addTab(soundstab, tr("Sounds")); + settingsLayout->addWidget(tabW); QHBoxLayout *buttonsLayout = new QHBoxLayout; -- cgit v1.2.1 From 3dbb6dab7b05aa37369ce2d5d3e593e63a158250 Mon Sep 17 00:00:00 2001 From: Anton Date: Sat, 26 Nov 2016 02:59:19 +0400 Subject: renamed PICA_listener_conn to PICA_c2c_direct, use same struct for incoming and outgoing direct connections --- PICA_client.c | 16 ++++++++-------- PICA_client.h | 21 ++++++++++----------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 3567a91..57f9877 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -1890,10 +1890,10 @@ static int process_c2c(struct PICA_c2c *c2c, fd_set *rfds, fd_set *wfds) static void listener_add_connection(struct PICA_listener *lst, SOCKET *s) { - struct PICA_listener_conn *nc; + struct PICA_c2c_direct *nc; int ret; - nc = calloc(1, sizeof(struct PICA_listener_conn)); + nc = calloc(1, sizeof(struct PICA_c2c_direct)); nc->sck = s; nc->ssl = SSL_new(lst->acc->ctx); @@ -1923,7 +1923,7 @@ static void listener_add_connection(struct PICA_listener *lst, SOCKET *s) lst->accepted_connections = nc; } -static int process_listener_conn(struct PICA_listener_conn *conn, fd_set *rfds, fd_set *wfds) +static int process_listener_conn(struct PICA_c2c_direct *conn, fd_set *rfds, fd_set *wfds) { if (conn->peer_cert == NULL) { @@ -1960,7 +1960,7 @@ static int process_listener_conn(struct PICA_listener_conn *conn, fd_set *rfds, static int process_listener(struct PICA_listener *lst, fd_set *rfds, fd_set *wfds) { - struct PICA_listener_conn *conn; + struct PICA_c2c_direct *conn; if (FD_ISSET(lst->sck_listener, rfds)) { @@ -1980,7 +1980,7 @@ static int process_listener(struct PICA_listener *lst, fd_set *rfds, fd_set *wfd while(conn) { - struct PICA_listener_conn *kill_ptr = NULL; + struct PICA_c2c_direct *kill_ptr = NULL; if (process_listener_conn(conn, rfds, wfds) != PICA_OK) { @@ -2025,7 +2025,7 @@ int PICA_event_loop(struct PICA_c2n **connections, int timeout) while(ic2n && *ic2n) { struct PICA_c2c *ic2c; - struct PICA_listener_conn *ilstcon; + struct PICA_c2c_direct *ilstcon; //printf("event_loop: adding c2n %p\n", *ic2n);//debug @@ -2790,7 +2790,7 @@ void PICA_close_acc(struct PICA_acc *a) free(a); } -void listener_close_conn(struct PICA_listener_conn *c) +void listener_close_conn(struct PICA_c2c_direct *c) { SSL_free(c->ssl); SHUTDOWN(c->sck); @@ -2807,7 +2807,7 @@ void PICA_close_listener(struct PICA_listener *l) while(l->accepted_connections) { - struct PICA_listener_conn *c = l->accepted_connections; + struct PICA_c2c_direct *c = l->accepted_connections; l->accepted_connections = c->next; listener_close_conn(c); } diff --git a/PICA_client.h b/PICA_client.h index 764b9dd..c63d106 100644 --- a/PICA_client.h +++ b/PICA_client.h @@ -189,6 +189,14 @@ enum PICA_directc2c_state PICA_DIRECTC2C_STATE_ACTIVE }; +struct PICA_c2c_direct +{ + SOCKET sck; + SSL *ssl; + X509 *peer_cert; + struct PICA_c2c_direct *next; +}; + struct PICA_c2c { const struct PICA_acc *acc; @@ -196,8 +204,7 @@ struct PICA_c2c unsigned char peer_id[PICA_ID_SIZE]; SOCKET sck_data; SSL *ssl; - SOCKET direct_sck; - SSL *direct_ssl; + struct PICA_c2c_direct *direct; int outgoing;//1 если создание канала инициировано локальным клиентом, 0 - если собеседником X509 *peer_cert; //unsigned char msgbuf[PICA_CHNMSGBUFLEN]; @@ -227,14 +234,6 @@ struct PICA_c2c int disconnect_on_empty_write_buf; }; -struct PICA_listener_conn -{ - SOCKET sck; - SSL *ssl; - X509 *peer_cert; - struct PICA_listener_conn *next; -}; - struct PICA_listener { const struct PICA_acc *acc; @@ -246,7 +245,7 @@ struct PICA_listener in_addr_t public_addr_ipv4; const char *public_addr_dns; - struct PICA_listener_conn *accepted_connections; + struct PICA_c2c_direct *accepted_connections; }; struct PICA_client_callbacks -- cgit v1.2.1 From 29474a9aa7375cef44788b4a2dad8ab137d75748 Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 27 Nov 2016 04:27:26 +0400 Subject: added PICA_c2c members to hold direct c2c address list for outgoing direct connection and position in that list, stored as a zero-terminated copy of received PICA_PROTO_C2CDIRECT_ADDRLIST payload --- PICA_client.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/PICA_client.h b/PICA_client.h index c63d106..2dbd1bf 100644 --- a/PICA_client.h +++ b/PICA_client.h @@ -204,7 +204,11 @@ struct PICA_c2c unsigned char peer_id[PICA_ID_SIZE]; SOCKET sck_data; SSL *ssl; + struct PICA_c2c_direct *direct; + uint8_t *directc2c_addrlist; + uint8_t *directc2c_addrpos; + int outgoing;//1 если создание канала инициировано локальным клиентом, 0 - если собеседником X509 *peer_cert; //unsigned char msgbuf[PICA_CHNMSGBUFLEN]; -- cgit v1.2.1 From 158d5b71b968d17c7b50d77302ee73466cb099fe Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 4 Dec 2016 22:46:43 +0400 Subject: implementing outgoing direct c2c connections and direct c2c-related packets exchange, work in progress --- PICA_client.c | 153 ++++++++++++++++++++++++++++++++++++++++++---------------- PICA_client.h | 11 ++++- PICA_proto.h | 4 +- 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 -- cgit v1.2.1 From 3464c67eb77400d3fa04684ea8d4afe185eab462 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 5 Dec 2016 00:47:25 +0400 Subject: enum for direct c2c connection instance state --- PICA_client.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/PICA_client.h b/PICA_client.h index afe51de..247b949 100644 --- a/PICA_client.h +++ b/PICA_client.h @@ -191,6 +191,15 @@ enum PICA_directc2c_state PICA_DIRECTC2C_STATE_ACTIVE }; +enum PICA_directc2c_connection_state +{ + PICA_DIRECTC2C_CONNSTATE_NEW = 0, + PICA_DIRECTC2C_CONNSTATE_CONNECTING, + PICA_DIRECTC2C_CONNSTATE_WAITINGTLS, + PICA_DIRECTC2C_CONNSTATE_ACTIVE, + PICA_DIRECTC2C_CONNSTATE_FAILED +}; + struct PICA_c2c_direct { int is_outgoing; @@ -203,6 +212,8 @@ struct PICA_c2c_direct struct sockaddr_in addr; + enum PICA_directc2c_connection_state state; + struct PICA_c2c_direct *next; }; -- cgit v1.2.1 From 8b79ad64f29e845badf95f5f3b625a09505d3f02 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 5 Dec 2016 15:52:12 +0400 Subject: renamed C2CDIRECT to DIRECTC2C everywhere --- PICA_client.c | 46 +++++++++++++++++++++++----------------------- PICA_client.h | 8 ++++---- PICA_proto.h | 16 ++++++++-------- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index a54e31f..3a67827 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -49,8 +49,8 @@ static unsigned int procmsg_FILEFRAGMENT(unsigned char*, unsigned int, void*); static unsigned int procmsg_FILECONTROL(unsigned char*, unsigned int, void*); static unsigned int procmsg_INITRESP_c2c(unsigned char*, unsigned int, void*); static unsigned int procmsg_C2CCONNREQ(unsigned char*, unsigned int, void*); -static unsigned int procmsg_PICA_PROTO_C2CDIRECT_ADDRLIST(unsigned char*, unsigned int, void*); -static unsigned int procmsg_PICA_PROTO_C2CDIRECT_FAILED(unsigned char*, unsigned int, void*); +static unsigned int procmsg_PICA_PROTO_DIRECTC2C_ADDRLIST(unsigned char*, unsigned int, void*); +static unsigned int procmsg_PICA_PROTO_DIRECTC2C_FAILED(unsigned char*, unsigned int, void*); static struct PICA_proto_msg* c2n_writebuf_push(struct PICA_c2n *ci, unsigned int msgid, unsigned int size); @@ -87,8 +87,8 @@ const struct PICA_msginfo c2c_messages[] = {PICA_PROTO_DENIEDFILE, PICA_MSG_FIXED_SIZE, PICA_PROTO_DENIEDFILE_SIZE, procmsg_DENIEDFILE}, {PICA_PROTO_FILEFRAGMENT, PICA_MSG_VAR_SIZE, PICA_MSG_VARSIZE_INT16, procmsg_FILEFRAGMENT}, {PICA_PROTO_FILECONTROL, PICA_MSG_FIXED_SIZE, PICA_PROTO_FILECONTROL_SIZE, procmsg_FILECONTROL}, - {PICA_PROTO_C2CDIRECT_ADDRLIST, PICA_MSG_VAR_SIZE, PICA_MSG_VARSIZE_INT16, procmsg_PICA_PROTO_C2CDIRECT_ADDRLIST}, - {PICA_PROTO_C2CDIRECT_FAILED, PICA_MSG_FIXED_SIZE, PICA_PROTO_C2CDIRECT_FAILED_SIZE, procmsg_PICA_PROTO_C2CDIRECT_FAILED} + {PICA_PROTO_DIRECTC2C_ADDRLIST, PICA_MSG_VAR_SIZE, PICA_MSG_VARSIZE_INT16, procmsg_PICA_PROTO_DIRECTC2C_ADDRLIST}, + {PICA_PROTO_DIRECTC2C_FAILED, PICA_MSG_FIXED_SIZE, PICA_PROTO_DIRECTC2C_FAILED_SIZE, procmsg_PICA_PROTO_DIRECTC2C_FAILED} }; struct PICA_msginfo c2n_init_messages[] = @@ -515,7 +515,7 @@ 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) +static int directc2c_connect_next(struct PICA_directc2c *dc2c, struct PICA_c2c *c2c) { int ret; @@ -527,7 +527,7 @@ static int c2c_direct_connect_next(struct PICA_c2c_direct *dc2c, struct PICA_c2c switch(*dc2c->addrpos) { - case PICA_PROTO_C2CDIRECT_IPV4: + case PICA_PROTO_DIRECTC2C_IPV4: dc2c->sck = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); memset(&dc2c->addr, 0, sizeof(dc2c->addr)); @@ -540,10 +540,10 @@ static int c2c_direct_connect_next(struct PICA_c2c_direct *dc2c, struct PICA_c2c if (ret) ... - dc2c->addrpos += PICA_PROTO_C2CDIRECT_ADDRLIST_ITEM_IPV4_SIZE; + dc2c->addrpos += PICA_PROTO_DIRECTC2C_ADDRLIST_ITEM_IPV4_SIZE; break; - case PICA_PROTO_C2CDIRECT_IPV6: + case PICA_PROTO_DIRECTC2C_IPV6: break; } @@ -551,7 +551,7 @@ static int c2c_direct_connect_next(struct PICA_c2c_direct *dc2c, struct PICA_c2c } -static unsigned int procmsg_PICA_PROTO_C2CDIRECT_ADDRLIST(unsigned char* buf, unsigned int nb, void* p) +static unsigned int procmsg_PICA_PROTO_DIRECTC2C_ADDRLIST(unsigned char* buf, unsigned int nb, void* p) { struct PICA_c2c *cc = (struct PICA_c2c *)p; @@ -561,7 +561,7 @@ static unsigned int procmsg_PICA_PROTO_C2CDIRECT_ADDRLIST(unsigned char* buf, un return 1; cc->directc2c_state = PICA_DIRECTC2C_STATE_CONNECTING; - cc->direct = calloc(1, sizeof(struct PICA_c2c_direct)); + cc->direct = calloc(1, sizeof(struct PICA_directc2c)); if (!cc->direct) return 1; @@ -578,14 +578,14 @@ static unsigned int procmsg_PICA_PROTO_C2CDIRECT_ADDRLIST(unsigned char* buf, un cc->direct->addrpos = 0; - ret = c2c_direct_connect_next(cc->direct, cc); + ret = directc2c_connect_next(cc->direct, cc); ... } return 1; } -static unsigned int procmsg_PICA_PROTO_C2CDIRECT_FAILED(unsigned char* buf, unsigned int nb, void* p) +static unsigned int procmsg_PICA_PROTO_DIRECTC2C_FAILED(unsigned char* buf, unsigned int nb, void* p) { -- } @@ -1953,10 +1953,10 @@ static int process_c2c(struct PICA_c2c *c2c, fd_set *rfds, fd_set *wfds) static void listener_add_connection(struct PICA_listener *lst, SOCKET *s) { - struct PICA_c2c_direct *nc; + struct PICA_directc2c *nc; int ret; - nc = calloc(1, sizeof(struct PICA_c2c_direct)); + nc = calloc(1, sizeof(struct PICA_directc2c)); nc->is_outgoing = PICA_DIRECTC2C_INCOMING; nc->sck = s; @@ -1987,7 +1987,7 @@ static void listener_add_connection(struct PICA_listener *lst, SOCKET *s) lst->accepted_connections = nc; } -static int process_listener_conn(struct PICA_c2c_direct *conn, fd_set *rfds, fd_set *wfds) +static int process_listener_conn(struct PICA_directc2c *conn, fd_set *rfds, fd_set *wfds) { if (conn->peer_cert == NULL) { @@ -2024,7 +2024,7 @@ static int process_listener_conn(struct PICA_c2c_direct *conn, fd_set *rfds, fd_ static int process_listener(struct PICA_listener *lst, fd_set *rfds, fd_set *wfds) { - struct PICA_c2c_direct *conn; + struct PICA_directc2c *conn; if (FD_ISSET(lst->sck_listener, rfds)) { @@ -2044,7 +2044,7 @@ static int process_listener(struct PICA_listener *lst, fd_set *rfds, fd_set *wfd while(conn) { - struct PICA_c2c_direct *kill_ptr = NULL; + struct PICA_directc2c *kill_ptr = NULL; if (process_listener_conn(conn, rfds, wfds) != PICA_OK) { @@ -2089,7 +2089,7 @@ int PICA_event_loop(struct PICA_c2n **connections, int timeout) while(ic2n && *ic2n) { struct PICA_c2c *ic2c; - struct PICA_c2c_direct *ilstcon; + struct PICA_directc2c *ilstcon; //printf("event_loop: adding c2n %p\n", *ic2n);//debug @@ -2520,12 +2520,12 @@ 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_ADDRLIST_ITEM_IPV4_SIZE; + unsigned int len = PICA_PROTO_DIRECTC2C_ADDRLIST_ITEM_IPV4_SIZE; - if ((mp = c2c_writebuf_push(chn, PICA_PROTO_C2CDIRECT_ADDRLIST, len + 4))) + if ((mp = c2c_writebuf_push(chn, PICA_PROTO_DIRECTC2C_ADDRLIST, len + 4))) { *((uint16_t*)mp->tail) = len; - *((uint8_t*)mp->tail + 2) = PICA_PROTO_C2CDIRECT_IPV4; + *((uint8_t*)mp->tail + 2) = PICA_PROTO_DIRECTC2C_IPV4; *((uint32_t*)mp->tail + 3) = chn->conn->directc2c_listener->public_addr_ipv4; *((uint16_t*)mp->tail + 7) = htons(chn->conn->directc2c_listener->public_port); } @@ -2760,7 +2760,7 @@ int PICA_send_file_fragment(struct PICA_c2c *chn) return PICA_OK; } -void PICA_close_directc2c(struct PICA_c2c_direct *d) +void PICA_close_directc2c(struct PICA_directc2c *d) { if (d->peer_cert) X509_free(d->peer_cert); @@ -2878,7 +2878,7 @@ void PICA_close_listener(struct PICA_listener *l) while(l->accepted_connections) { - struct PICA_c2c_direct *c = l->accepted_connections; + struct PICA_directc2c *c = l->accepted_connections; l->accepted_connections = c->next; PICA_close_directc2c(c); } diff --git a/PICA_client.h b/PICA_client.h index 247b949..b5e27e3 100644 --- a/PICA_client.h +++ b/PICA_client.h @@ -200,7 +200,7 @@ enum PICA_directc2c_connection_state PICA_DIRECTC2C_CONNSTATE_FAILED }; -struct PICA_c2c_direct +struct PICA_directc2c { int is_outgoing; SOCKET sck; @@ -214,7 +214,7 @@ struct PICA_c2c_direct enum PICA_directc2c_connection_state state; - struct PICA_c2c_direct *next; + struct PICA_directc2c *next; }; struct PICA_c2c @@ -225,7 +225,7 @@ struct PICA_c2c SOCKET sck_data; SSL *ssl; - struct PICA_c2c_direct *direct; + struct PICA_directc2c *direct; int outgoing;//1 если создание канала инициировано локальным клиентом, 0 - если собеседником X509 *peer_cert; @@ -267,7 +267,7 @@ struct PICA_listener in_addr_t public_addr_ipv4; const char *public_addr_dns; - struct PICA_c2c_direct *accepted_connections; + struct PICA_directc2c *accepted_connections; }; struct PICA_client_callbacks diff --git a/PICA_proto.h b/PICA_proto.h index 4d8b506..09cee25 100644 --- a/PICA_proto.h +++ b/PICA_proto.h @@ -31,11 +31,11 @@ #define PICA_PROTO_C2CCONNREQ 0xCC -#define PICA_PROTO_C2CDIRECT_ADDRLIST 0x0B -#define PICA_PROTO_C2CDIRECT_IPV4 0xA0 -#define PICA_PROTO_C2CDIRECT_IPV6 0xA1 -#define PICA_PROTO_C2CDIRECT_DNS 0xA2 -#define PICA_PROTO_C2CDIRECT_FAILED 0x0C +#define PICA_PROTO_DIRECTC2C_ADDRLIST 0x0B +#define PICA_PROTO_DIRECTC2C_IPV4 0xA0 +#define PICA_PROTO_DIRECTC2C_IPV6 0xA1 +#define PICA_PROTO_DIRECTC2C_DNS 0xA2 +#define PICA_PROTO_DIRECTC2C_FAILED 0x0C #define PICA_PROTO_MSGUTF8 0x30 #define PICA_PROTO_MSGOK 0x40 @@ -88,9 +88,9 @@ #define PICA_PROTO_CONNID_SIZE 58 #define PICA_PROTO_C2CCONNREQ_SIZE 4 -#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_DIRECTC2C_ADDRLIST_ITEM_IPV4_SIZE 7 +#define PICA_PROTO_DIRECTC2C_ADDRLIST_ITEM_IPV6_SIZE 19 +#define PICA_PROTO_DIRECTC2C_FAILED_SIZE 4 #define PICA_PROTO_MSGOK_SIZE 4 -- cgit v1.2.1 From 660205d022eb3b9a48b613035ad4fcd0663c98ff Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 5 Dec 2016 19:42:33 +0400 Subject: implemented starting direct c2c connection --- PICA_client.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 3a67827..aa0ad95 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -523,7 +523,7 @@ static int directc2c_connect_next(struct PICA_directc2c *dc2c, struct PICA_c2c * dc2c->addrpos += 2; if (dc2c->addrpos >= *(uint16_t*)dc2c->addrlist) - return PICA_OK; + return PICA_ERRNOTFOUND; switch(*dc2c->addrpos) { @@ -535,10 +535,14 @@ static int directc2c_connect_next(struct PICA_directc2c *dc2c, struct PICA_c2c * dc2c->addr.sin_addr.s_addr = *((in_addr_t*)(dc2c->addrpos + 1)); dc2c->addr.sin_port = *((uint16_t*)(dc2c->addrpos + 5)); + dc2c->state = PICA_DIRECTC2C_CONNSTATE_CONNECTING; + ret = connect(dc2c->sck, (struct sockaddr*)&dc2c->addr, sizeof(dc2c->addr)); - if (ret) - ... + ret = process_first_async_connect_result(ret); + + if (ret != PICA_OK) + dc2c->state = PICA_DIRECTC2C_CONNSTATE_FAILED; dc2c->addrpos += PICA_PROTO_DIRECTC2C_ADDRLIST_ITEM_IPV4_SIZE; break; @@ -548,12 +552,13 @@ static int directc2c_connect_next(struct PICA_directc2c *dc2c, struct PICA_c2c * } - + return PICA_OK; } static unsigned int procmsg_PICA_PROTO_DIRECTC2C_ADDRLIST(unsigned char* buf, unsigned int nb, void* p) { struct PICA_c2c *cc = (struct PICA_c2c *)p; + int ret; if (cc->conn->directc2c_config != PICA_DIRECTC2C_CFG_DISABLED) { @@ -567,6 +572,7 @@ static unsigned int procmsg_PICA_PROTO_DIRECTC2C_ADDRLIST(unsigned char* buf, un return 1; cc->direct->is_outgoing = PICA_DIRECTC2C_OUTGOING; + cc->direct->state = PICA_DIRECTC2C_CONNSTATE_NEW; cc->direct->sck = -1; cc->direct->addrlist = malloc(nb - 2 + 1); @@ -579,7 +585,11 @@ static unsigned int procmsg_PICA_PROTO_DIRECTC2C_ADDRLIST(unsigned char* buf, un ret = directc2c_connect_next(cc->direct, cc); - ... + + if (ret == PICA_ERRNOTFOUND) + { + cc->directc2c_state = PICA_DIRECTC2C_STATE_INACTIVE; + } } return 1; -- cgit v1.2.1 From eb132677fd65a57582cb920caed15dd9fa310888 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 5 Dec 2016 19:46:59 +0400 Subject: new direct c2c state that is set when outgoing connections to all direct addresses provided by peer have failed --- PICA_client.c | 2 +- PICA_client.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index aa0ad95..af6718e 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -588,7 +588,7 @@ static unsigned int procmsg_PICA_PROTO_DIRECTC2C_ADDRLIST(unsigned char* buf, un if (ret == PICA_ERRNOTFOUND) { - cc->directc2c_state = PICA_DIRECTC2C_STATE_INACTIVE; + cc->directc2c_state = PICA_DIRECTC2C_STATE_FAILEDTOCONNECT; } } diff --git a/PICA_client.h b/PICA_client.h index b5e27e3..f672505 100644 --- a/PICA_client.h +++ b/PICA_client.h @@ -186,8 +186,9 @@ enum PICA_c2c_state enum PICA_directc2c_state { PICA_DIRECTC2C_STATE_INACTIVE, - PICA_DIRECTC2C_STATE_WAITINGINCOMING, PICA_DIRECTC2C_STATE_CONNECTING, + PICA_DIRECTC2C_STATE_FAILEDTOCONNECT, + PICA_DIRECTC2C_STATE_WAITINGINCOMING, PICA_DIRECTC2C_STATE_ACTIVE }; -- cgit v1.2.1 From 13fee28314bbe2c6e2e59dd6451838ed1a944d6f Mon Sep 17 00:00:00 2001 From: Anton Date: Sat, 24 Dec 2016 02:52:15 +0400 Subject: setting and handling PICA_DIRECTC2C_STATE_WAITINGINCOMING state --- PICA_client.c | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index af6718e..6c86a35 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -562,10 +562,18 @@ static unsigned int procmsg_PICA_PROTO_DIRECTC2C_ADDRLIST(unsigned char* buf, un if (cc->conn->directc2c_config != PICA_DIRECTC2C_CFG_DISABLED) { - if (cc->directc2c_state != PICA_DIRECTC2C_STATE_INACTIVE) - return 1; + //if (cc->directc2c_state != PICA_DIRECTC2C_STATE_INACTIVE) + // return 1; + + //if (cc->outgoing == PICA_C2C_OUTGOING) + // cc->directc2c_state = PICA_DIRECTC2C_STATE_CONNECTING; + //else if (cc->outgoing == PICA_C2C_INCOMING) + // cc->directc2c_state = PICA_DIRECTC2C_STATE_WAITINGINCOMING; + //else + // return 0; + if (cc->directc2c_state != PICA_DIRECTC2C_STATE_WAITINGINCOMING) + cc->directc2c_state = PICA_DIRECTC2C_STATE_CONNECTING; - cc->directc2c_state = PICA_DIRECTC2C_STATE_CONNECTING; cc->direct = calloc(1, sizeof(struct PICA_directc2c)); if (!cc->direct) @@ -583,6 +591,8 @@ static unsigned int procmsg_PICA_PROTO_DIRECTC2C_ADDRLIST(unsigned char* buf, un cc->direct->addrlist[nb - 2] = 0; cc->direct->addrpos = 0; + if (cc->directc2c_state == PICA_DIRECTC2C_STATE_WAITINGINCOMING) + return 1;//connect later, if no incoming connection is accepted and DIRECTC2C_FAILED is received ret = directc2c_connect_next(cc->direct, cc); @@ -597,7 +607,23 @@ static unsigned int procmsg_PICA_PROTO_DIRECTC2C_ADDRLIST(unsigned char* buf, un static unsigned int procmsg_PICA_PROTO_DIRECTC2C_FAILED(unsigned char* buf, unsigned int nb, void* p) { - -- + struct PICA_c2c *cc = (struct PICA_c2c *)p; + int ret; + + if (cc->directc2c_state != PICA_DIRECTC2C_STATE_WAITINGINCOMING) + return 0; + + if (cc->conn->directc2c_config == PICA_DIRECTC2C_CFG_DISABLED) + return 0; + + ret = directc2c_connect_next(cc->direct, cc); + + if (ret == PICA_ERRNOTFOUND) + { + cc->directc2c_state = PICA_DIRECTC2C_STATE_FAILEDTOCONNECT; + } + + return 1; } static unsigned int procmsg_INITRESP(unsigned char* buf, unsigned int nb, void* p) @@ -2538,6 +2564,9 @@ int PICA_send_directc2caddrlist(struct PICA_c2c *chn) *((uint8_t*)mp->tail + 2) = PICA_PROTO_DIRECTC2C_IPV4; *((uint32_t*)mp->tail + 3) = chn->conn->directc2c_listener->public_addr_ipv4; *((uint16_t*)mp->tail + 7) = htons(chn->conn->directc2c_listener->public_port); + + if (chn->outgoing == PICA_C2C_INCOMING) + chn->directc2c_state = PICA_DIRECTC2C_STATE_WAITINGINCOMING; } } @@ -2778,9 +2807,9 @@ void PICA_close_directc2c(struct PICA_directc2c *d) if (d->addrlist) free(d->addrlist); - SSL_free(c->ssl); - SHUTDOWN(c->sck); - CLOSE(c->sck); + SSL_free(d->ssl); + SHUTDOWN(d->sck); + CLOSE(d->sck); free(d); } -- cgit v1.2.1 From a991eb82decec01d25ac39805ee60e4fea196ef7 Mon Sep 17 00:00:00 2001 From: Anton Date: Sat, 24 Dec 2016 22:56:45 +0400 Subject: implementing process_directc2c(), work in progress --- PICA_client.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/PICA_client.c b/PICA_client.c index 6c86a35..fe82195 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -1987,6 +1987,45 @@ static int process_c2c(struct PICA_c2c *c2c, fd_set *rfds, fd_set *wfds) return ret; } +static struct PICA_c2c * find_matching_c2c(struct PICA_c2n *c2n, struct PICA_directc2c *d) +{ + -- +} + +static void process_directc2c(struct PICA_c2n *c2n) +{ + //process accepted connections + if (c2n->directc2c_listener) + { + PICA_directc2c *d; + PICA_c2c *c2c; + + d = c2n->directc2c_listener->accepted_connections; + + while(d) + { + if (d->state == PICA_DIRECTC2C_STATE_ACTIVE) + { + if ((c2c = find_matching_c2c(c2n, d))) + { + if (c2c->direct) + PICA_close_directc2c(c2c->direct); + + c2c->direct = d; + ... + } + else + { + -- + } + } + d = d->next; + } + } + //process outgoing connections + -- +} + static void listener_add_connection(struct PICA_listener *lst, SOCKET *s) { struct PICA_directc2c *nc; @@ -1997,6 +2036,7 @@ static void listener_add_connection(struct PICA_listener *lst, SOCKET *s) nc->is_outgoing = PICA_DIRECTC2C_INCOMING; nc->sck = s; nc->ssl = SSL_new(lst->acc->ctx); + nc->state = PICA_DIRECTC2C_CONNSTATE_NEW; SSL_set_fd(nc->ssl, nc->sck); ret = SSL_accept(nc->ssl); @@ -2018,6 +2058,8 @@ static void listener_add_connection(struct PICA_listener *lst, SOCKET *s) } } + nc->state = PICA_DIRECTC2C_CONNSTATE_WAITINGTLS; + nc->next = lst->accepted_connections; lst->accepted_connections = nc; @@ -2039,6 +2081,7 @@ static int process_listener_conn(struct PICA_directc2c *conn, fd_set *rfds, fd_s if (!conn->peer_cert) return PICA_ERRSSL; + conn->state = PICA_DIRECTC2C_CONNSTATE_ACTIVE; return PICA_OK; } @@ -2241,6 +2284,12 @@ int PICA_event_loop(struct PICA_c2n **connections, int timeout) kill_ptr = 0; } } + + //processing direct c2c connections associated with current c2n + if ((*ic2n)->directc2c_config != PICA_DIRECTC2C_CFG_DISABLED) + { + process_directc2c(*ic2n); + } } ic2n++; } -- cgit v1.2.1 From a4762905029bd8710ced13fcee80763bafba6ff3 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 26 Dec 2016 18:41:55 +0400 Subject: implemented find_matching_c2c() --- PICA_client.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index fe82195..709e817 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -1989,7 +1989,27 @@ static int process_c2c(struct PICA_c2c *c2c, fd_set *rfds, fd_set *wfds) static struct PICA_c2c * find_matching_c2c(struct PICA_c2n *c2n, struct PICA_directc2c *d) { - -- + struct PICA_c2c *c2c; + unsigned char idbuf[PICA_ID_SIZE]; + + if (!PICA_id_from_X509(d->peer_cert, idbuf)) + return NULL; + + c2c = c2n->chan_list_head; + + while(c2c) + { + if (c2c->directc2c_state == PICA_DIRECTC2C_STATE_WAITINGINCOMING) + { + if (memcmp(idbuf, c2c->peer_id, PICA_ID_SIZE) == 0) + { + return c2c; + } + } + c2c = c2c->next; + } + + return NULL; } static void process_directc2c(struct PICA_c2n *c2n) @@ -1997,8 +2017,8 @@ static void process_directc2c(struct PICA_c2n *c2n) //process accepted connections if (c2n->directc2c_listener) { - PICA_directc2c *d; - PICA_c2c *c2c; + struct PICA_directc2c *d; + struct PICA_c2c *c2c; d = c2n->directc2c_listener->accepted_connections; -- cgit v1.2.1 From f13e465ecbc0ea245a3945e562d8a74f5a1f3493 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 26 Dec 2016 20:21:20 +0400 Subject: set verification callback for incoming directc2c TLS connection --- PICA_client.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/PICA_client.c b/PICA_client.c index 709e817..73984df 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -2059,6 +2059,10 @@ static void listener_add_connection(struct PICA_listener *lst, SOCKET *s) nc->state = PICA_DIRECTC2C_CONNSTATE_NEW; SSL_set_fd(nc->ssl, nc->sck); + + SSL_set_verify(nc->ssl, SSL_VERIFY_PEER, verify_callback); + SSL_set_verify_depth(nc->ssl, 1); + ret = SSL_accept(nc->ssl); if (ret == 0) -- cgit v1.2.1 From 0b7e1040293e24a20460a3cf5707b99aef2c969c Mon Sep 17 00:00:00 2001 From: Anton Date: Tue, 27 Dec 2016 22:12:21 +0400 Subject: added new proto message definition - PICA_PROTO_DIRECTC2C_SWITCH --- PICA_proto.h | 2 ++ doc/proto.txt | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/PICA_proto.h b/PICA_proto.h index 09cee25..32c817a 100644 --- a/PICA_proto.h +++ b/PICA_proto.h @@ -36,6 +36,7 @@ #define PICA_PROTO_DIRECTC2C_IPV6 0xA1 #define PICA_PROTO_DIRECTC2C_DNS 0xA2 #define PICA_PROTO_DIRECTC2C_FAILED 0x0C +#define PICA_PROTO_DIRECTC2C_SWITCH 0x0D #define PICA_PROTO_MSGUTF8 0x30 #define PICA_PROTO_MSGOK 0x40 @@ -91,6 +92,7 @@ #define PICA_PROTO_DIRECTC2C_ADDRLIST_ITEM_IPV4_SIZE 7 #define PICA_PROTO_DIRECTC2C_ADDRLIST_ITEM_IPV6_SIZE 19 #define PICA_PROTO_DIRECTC2C_FAILED_SIZE 4 +#define PICA_PROTO_DIRECTC2C_SWITCH_SIZE 4 #define PICA_PROTO_MSGOK_SIZE 4 diff --git a/doc/proto.txt b/doc/proto.txt index 53c13c5..b45e2d9 100755 --- a/doc/proto.txt +++ b/doc/proto.txt @@ -82,6 +82,11 @@ UH - user hash - SHA224 хэш от сертификата пользовате После получения этого сообщения вызываемый клиент начинает попытки подключения к прямым адресам инициатора, если от инициатора был получен список прямых адресов и прямые подключения разрешены настройками вызываемого ++++[переключение на прямое соединение] +0x0D 0x0D (2 псевдослучайных байта) +отправляется после успешного TLS хэндшейка на прямом соединении каждой из сторон по соединению через ноду, после отправки этого сообщения все следующие сообщения +отправляются по прямому соединению, получатель сообщения соответственно ожидает следующие соединения уже по прямому соединению. + +++[сообщение - текст в кодировке UTF8] 0x30 0x30 (длина сообщения в байтах- 2 байта в формате little-endian) сообщение в кодировке UTF8 -- cgit v1.2.1 From 8c43c0fda7bbc41316021668084f47bedb66c26c Mon Sep 17 00:00:00 2001 From: Anton Date: Wed, 28 Dec 2016 21:56:26 +0400 Subject: declared functions for sending DIRECTC2C_FAILED and DIRECTC2C_SWITCH messages, also for processing received DIRECTC2C_SWITCH --- PICA_client.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 73984df..179778a 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -33,6 +33,8 @@ static int PICA_sendfile_open_read(struct PICA_c2c *chn, const char *filename_ut static int PICA_recvfile_open_write(struct PICA_c2c *chn, const char *filename_utf8, unsigned int filenamesize); static int PICA_send_filecontrol(struct PICA_c2c *chan, int senderctl, int receiverctl); static int PICA_send_directc2caddrlist(struct PICA_c2c *chn); +static int PICA_send_directc2cfailed(struct PICA_c2c *chn); +static int PICA_send_directc2c_switch(struct PICA_c2c *chn); static unsigned int procmsg_INITRESP(unsigned char*, unsigned int, void*); static unsigned int procmsg_CONNREQINC(unsigned char*, unsigned int, void*); @@ -51,6 +53,7 @@ static unsigned int procmsg_INITRESP_c2c(unsigned char*, unsigned int, void*); static unsigned int procmsg_C2CCONNREQ(unsigned char*, unsigned int, void*); static unsigned int procmsg_PICA_PROTO_DIRECTC2C_ADDRLIST(unsigned char*, unsigned int, void*); static unsigned int procmsg_PICA_PROTO_DIRECTC2C_FAILED(unsigned char*, unsigned int, void*); +static unsigned int procmsg_PICA_PROTO_DIRECTC2C_SWITCH(unsigned char*, unsigned int, void*); static struct PICA_proto_msg* c2n_writebuf_push(struct PICA_c2n *ci, unsigned int msgid, unsigned int size); @@ -88,7 +91,8 @@ const struct PICA_msginfo c2c_messages[] = {PICA_PROTO_FILEFRAGMENT, PICA_MSG_VAR_SIZE, PICA_MSG_VARSIZE_INT16, procmsg_FILEFRAGMENT}, {PICA_PROTO_FILECONTROL, PICA_MSG_FIXED_SIZE, PICA_PROTO_FILECONTROL_SIZE, procmsg_FILECONTROL}, {PICA_PROTO_DIRECTC2C_ADDRLIST, PICA_MSG_VAR_SIZE, PICA_MSG_VARSIZE_INT16, procmsg_PICA_PROTO_DIRECTC2C_ADDRLIST}, - {PICA_PROTO_DIRECTC2C_FAILED, PICA_MSG_FIXED_SIZE, PICA_PROTO_DIRECTC2C_FAILED_SIZE, procmsg_PICA_PROTO_DIRECTC2C_FAILED} + {PICA_PROTO_DIRECTC2C_FAILED, PICA_MSG_FIXED_SIZE, PICA_PROTO_DIRECTC2C_FAILED_SIZE, procmsg_PICA_PROTO_DIRECTC2C_FAILED}, + {PICA_PROTO_DIRECTC2C_SWITCH, PICA_MSG_FIXED_SIZE, PICA_PROTO_DIRECTC2C_SWITCH_SIZE, procmsg_PICA_PROTO_DIRECTC2C_SWITCH} }; struct PICA_msginfo c2n_init_messages[] = @@ -2024,7 +2028,7 @@ static void process_directc2c(struct PICA_c2n *c2n) while(d) { - if (d->state == PICA_DIRECTC2C_STATE_ACTIVE) + if (d->state == PICA_DIRECTC2C_CONNSTATE_ACTIVE) { if ((c2c = find_matching_c2c(c2n, d))) { @@ -2036,6 +2040,7 @@ static void process_directc2c(struct PICA_c2n *c2n) } else { + //close and remove from listener's list -- } } @@ -2646,6 +2651,16 @@ int PICA_send_directc2caddrlist(struct PICA_c2c *chn) return PICA_OK; } +static int PICA_send_directc2cfailed(struct PICA_c2c *chn) +{ + -- +} + +static int PICA_send_directc2c_switch(struct PICA_c2c *chn) +{ + -- +} + int PICA_send_msg(struct PICA_c2c *chn, char *buf, unsigned int len) { struct PICA_proto_msg *mp; -- cgit v1.2.1 From ebda46444033ac87dccc1fae725a101c8fef38e4 Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 29 Dec 2016 21:11:08 +0400 Subject: implemented PICA_send_directc2cfailed() and PICA_send_directc2c_switch() --- PICA_client.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 179778a..ef4e2dc 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -2653,12 +2653,30 @@ int PICA_send_directc2caddrlist(struct PICA_c2c *chn) static int PICA_send_directc2cfailed(struct PICA_c2c *chn) { - -- + struct PICA_proto_msg *mp; + + if ((mp = c2c_writebuf_push(chn, PICA_PROTO_DIRECTC2C_FAILED, PICA_PROTO_DIRECTC2C_FAILED_SIZE))) + { + RAND_pseudo_bytes(mp->tail, 2); + } + else + return PICA_ERRNOMEM; + + return PICA_OK; } static int PICA_send_directc2c_switch(struct PICA_c2c *chn) { - -- + struct PICA_proto_msg *mp; + + if ((mp = c2c_writebuf_push(chn, PICA_PROTO_DIRECTC2C_SWITCH, PICA_PROTO_DIRECTC2C_SWITCH_SIZE))) + { + RAND_pseudo_bytes(mp->tail, 2); + } + else + return PICA_ERRNOMEM; + + return PICA_OK; } int PICA_send_msg(struct PICA_c2c *chn, char *buf, unsigned int len) -- cgit v1.2.1 From ec015653e2b9396390ef4e273d3273931d908ebc Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 9 Jan 2017 21:42:00 +0400 Subject: processing directc2c, work in progress --- PICA_client.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 145 insertions(+), 7 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index ef4e2dc..0a59af8 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -627,9 +627,16 @@ static unsigned int procmsg_PICA_PROTO_DIRECTC2C_FAILED(unsigned char* buf, unsi cc->directc2c_state = PICA_DIRECTC2C_STATE_FAILEDTOCONNECT; } + cc->directc2c_state = PICA_DIRECTC2C_STATE_CONNECTING; + return 1; } +unsigned int procmsg_PICA_PROTO_DIRECTC2C_SWITCH(unsigned char*, unsigned int, void*) +{ + --- +} + static unsigned int procmsg_INITRESP(unsigned char* buf, unsigned int nb, void* p) { struct PICA_c2n *ci = (struct PICA_c2n *)p; @@ -1514,6 +1521,34 @@ static int c2n_stage4_nodelistrequest(struct PICA_c2n *c2n) return PICA_OK; } +static int directc2c_stage2_starttls(struct PICA_directc2c *d, struct PICA_c2c *c2c) +{ + int ret; + + d->ssl = SSL_new(c2c->acc->ctx); + + SSL_set_fd(d->ssl, d->sck); + SSL_set_verify(d->ssl, SSL_VERIFY_PEER, verify_callback); + SSL_set_verify_depth(d->ssl, 1); + + ret = SSL_connect(d->ssl); + + if (ret == 0) + return PICA_ERRSSL; + + if (ret < 0) + { + ret = SSL_get_error(d->ssl, ret); + + if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE) + return PICA_ERRSSL; + } + + d->state = PICA_DIRECTC2C_CONNSTATE_WAITINGTLS; + + return PICA_OK; +} + /*адрес сервера, сертификат клиента и закрытый ключ*/ //Осуществляет подключение к серверу по указанному адресу. @@ -2016,15 +2051,19 @@ static struct PICA_c2c * find_matching_c2c(struct PICA_c2n *c2n, struct PICA_dir return NULL; } -static void process_directc2c(struct PICA_c2n *c2n) +static void process_directc2c(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) { + struct PICA_directc2c *d; + struct PICA_c2c *c2c; + int ret; + //process accepted connections if (c2n->directc2c_listener) { - struct PICA_directc2c *d; - struct PICA_c2c *c2c; + struct PICA_directc2c **pdprev; d = c2n->directc2c_listener->accepted_connections; + pdprev = &c2n->directc2c_listener->accepted_connections; while(d) { @@ -2036,19 +2075,104 @@ static void process_directc2c(struct PICA_c2n *c2n) PICA_close_directc2c(c2c->direct); c2c->direct = d; - ... + + ret = PICA_send_directc2c_switch(c2c);---//??? who should send first? + + if (ret != PICA_OK) + { + PICA_close_directc2c(d); + c2c->directc2c_state = PICA_DIRECTC2C_STATE_INACTIVE; + } + else + { + c2c->directc2c_state = PICA_DIRECTC2C_STATE_ACTIVE; + } + + //remove from listener's list + *pdprev = d->next; + d->next = 0; } else { //close and remove from listener's list - -- + *pdprev = d->next; + PICA_close_directc2c(d); } } + pdprev = &d->next; d = d->next; + -- killptr? } } //process outgoing connections - -- + c2c = c2n->chan_list_head; + while(c2c) + { + if (c2c->directc2c_state == PICA_DIRECTC2C_STATE_FAILEDTOCONNECT) + { + if (c2c->outgoing == PICA_C2C_OUTGOING && c2c->conn->directc2c_config == PICA_DIRECTC2C_CFG_ALLOWINCOMING) + { + ret = PICA_send_directc2cfailed(c2c); + + if (ret == PICA_OK) + c2c->directc2c_state = PICA_DIRECTC2C_STATE_WAITINGINCOMING; + else + c2c->directc2c_state = PICA_DIRECTC2C_STATE_INACTIVE; + } + else + c2c->directc2c_state = PICA_DIRECTC2C_STATE_INACTIVE; + } + + if (c2c->directc2c_state == PICA_DIRECTC2C_STATE_CONNECTING) + { + d = c2c->direct; + ret = PICA_OK; + + switch(d->state) + { + case PICA_DIRECTC2C_CONNSTATE_CONNECTING: + + if (FD_ISSET(d->sck, wfds)) + { + ret = check_async_connect_result(d->sck, (struct sockaddr*)&d->addr, sizeof(d->addr)); + + if (ret == PICA_OK) + { + ret = directc2c_stage2_starttls(d, c2c); + } + else + { + ret = directc2c_connect_next(d, c2c); + + if (ret == PICA_ERRNOTFOUND) + c2c->directc2c_state = PICA_DIRECTC2C_STATE_FAILEDTOCONNECT; + } + } + break; + + case PICA_DIRECTC2C_CONNSTATE_WAITINGTLS: + break; + + case PICA_DIRECTC2C_CONNSTATE_FAILED: + break; + + case PICA_DIRECTC2C_CONNSTATE_ACTIVE: + break; + -- + } + + if (ret != PICA_OK) + { + PICA_close_directc2c(d); + c2c->direct = 0; + + if (c2c->directc2c_state != PICA_DIRECTC2C_STATE_FAILEDTOCONNECT) + c2c->directc2c_state = PICA_DIRECTC2C_STATE_INACTIVE;//fallback to c2c through node? + } + + } + c2c = c2c->next; + } } static void listener_add_connection(struct PICA_listener *lst, SOCKET *s) @@ -2133,6 +2257,7 @@ static int process_listener_conn(struct PICA_directc2c *conn, fd_set *rfds, fd_s static int process_listener(struct PICA_listener *lst, fd_set *rfds, fd_set *wfds) { struct PICA_directc2c *conn; + struct PICA_directc2c **pprevconn; if (FD_ISSET(lst->sck_listener, rfds)) { @@ -2149,6 +2274,7 @@ static int process_listener(struct PICA_listener *lst, fd_set *rfds, fd_set *wfd } conn = lst->accepted_connections; + pprevconn = &lst->accepted_connections; while(conn) { @@ -2158,10 +2284,13 @@ static int process_listener(struct PICA_listener *lst, fd_set *rfds, fd_set *wfd { kill_ptr = conn; } + + pprevconn = &conn->next; conn = conn->next; if (kill_ptr) { + *pprevconn = kill_ptr->next; PICA_close_directc2c(kill_ptr); } } @@ -2234,6 +2363,13 @@ int PICA_event_loop(struct PICA_c2n **connections, int timeout) fdset_add(&wfds, ic2c->sck_data, &nfds); } + if (ic2c->state == PICA_C2C_STATE_ACTIVE && ic2c->directc2c_state == PICA_DIRECTC2C_STATE_CONNECTING + && ic2c->direct && ic2c->direct->state >= PICA_DIRECTC2C_CONNSTATE_CONNECTING)// CHECK CONDITIONS! + { + fdset_add(&rfds, ic2c->direct->sck, &nfds); + fdset_add(&wfds, ic2c->direct->sck, &nfds); + } + ic2c = ic2c->next; } @@ -2317,7 +2453,7 @@ int PICA_event_loop(struct PICA_c2n **connections, int timeout) //processing direct c2c connections associated with current c2n if ((*ic2n)->directc2c_config != PICA_DIRECTC2C_CFG_DISABLED) { - process_directc2c(*ic2n); + process_directc2c(*ic2n, &rfds, &wfds); } } ic2n++; @@ -2917,6 +3053,8 @@ void PICA_close_directc2c(struct PICA_directc2c *d) SHUTDOWN(d->sck); CLOSE(d->sck); + d->next = NULL; + free(d); } -- cgit v1.2.1 From 37c34005d93dc10348123f79b2d3110c288a324b Mon Sep 17 00:00:00 2001 From: Anton Date: Tue, 10 Jan 2017 19:48:59 +0400 Subject: implementing directc2c processing, work in progress --- PICA_client.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/PICA_client.c b/PICA_client.c index 0a59af8..239260d 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -61,6 +61,7 @@ static struct PICA_proto_msg* c2c_writebuf_push(struct PICA_c2c *chn, unsigned i 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 process_async_ssl_errors(SSL *ssl, int ret); static int PICA_write_c2n(struct PICA_c2n *ci); static int PICA_write_c2c(struct PICA_c2c *chn); @@ -1777,6 +1778,24 @@ int PICA_new_c2c(struct PICA_c2n *ci, const unsigned char *peer_id, struct PICA_ return PICA_OK; } +static int process_async_ssl_errors(SSL *ssl, int ret) +{ + if (ret < 0) + switch(SSL_get_error(ssl, ret)) + { + case SSL_ERROR_WANT_WRITE: + case SSL_ERROR_WANT_READ: + break; + default: + return PICA_ERRSSL; + }; + + if (ret == 0) + return PICA_ERRDISCONNECT; + + return PICA_OK; +} + static int process_first_async_connect_result(int connect_ret) { if (connect_ret == SOCKET_ERROR) @@ -2051,6 +2070,28 @@ static struct PICA_c2c * find_matching_c2c(struct PICA_c2n *c2n, struct PICA_dir return NULL; } +static int directc2c_verify_peer_cert(struct PICA_directc2c *d, struct PICA_c2c *c2c) +{ + unsigned char idbuf[PICA_ID_SIZE]; + + d->peer_cert = SSL_get_peer_certificate(d->ssl); + + if (!d->peer_cert) + return PICA_ERRNOPEERCERT; + + if (PICA_id_from_X509(d->peer_cert, idbuf) == 0) + { + return PICA_ERRNOPEERCERT; + } + + if (memcmp(idbuf, c2c->peer_id, PICA_ID_SIZE) != 0) + { + return PICA_ERRINVPEERCERT; + } + + return PICA_OK; +} + static void process_directc2c(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) { struct PICA_directc2c *d; @@ -2151,6 +2192,25 @@ static void process_directc2c(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) break; case PICA_DIRECTC2C_CONNSTATE_WAITINGTLS: + if (FD_ISSET(d->sck, wfds) || FD_ISSET(d->sck, rfds)) + { + ret = SSL_connect(d->ssl); + + ret = process_async_ssl_errors(d->ssl, ret); + + if (ret != PICA_OK) + break; + + ret = directc2c_verify_peer_cert(d, c2c); + + if (ret != PICA_OK) + break; + + d->state = PICA_DIRECTC2C_STATE_ACTIVE; + + ---//? send switch message + + } break; case PICA_DIRECTC2C_CONNSTATE_FAILED: @@ -2269,6 +2329,7 @@ static int process_listener(struct PICA_listener *lst, fd_set *rfds, fd_set *wfd if (s >= 0) { + IOCTLSETNONBLOCKINGSOCKET(s, 1); listener_add_connection(lst, s); } } -- cgit v1.2.1 From 4ef4db981bf4a417b8adf8a55817bf0c2a8ec8f9 Mon Sep 17 00:00:00 2001 From: Anton Date: Wed, 14 Jun 2017 22:22:10 +0400 Subject: fix in proto doc --- doc/proto.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/proto.txt b/doc/proto.txt index b45e2d9..49cb4a0 100755 --- a/doc/proto.txt +++ b/doc/proto.txt @@ -85,7 +85,7 @@ UH - user hash - SHA224 хэш от сертификата пользовате +++[переключение на прямое соединение] 0x0D 0x0D (2 псевдослучайных байта) отправляется после успешного TLS хэндшейка на прямом соединении каждой из сторон по соединению через ноду, после отправки этого сообщения все следующие сообщения -отправляются по прямому соединению, получатель сообщения соответственно ожидает следующие соединения уже по прямому соединению. +отправляются по прямому соединению, получатель сообщения соответственно ожидает следующие сообщения уже по прямому соединению. +++[сообщение - текст в кодировке UTF8] 0x30 0x30 (длина сообщения в байтах- 2 байта в формате little-endian) сообщение в кодировке UTF8 -- cgit v1.2.1 From 214557159edbeaad3bf8b2c637836455724a74d3 Mon Sep 17 00:00:00 2001 From: Anton Date: Wed, 14 Jun 2017 22:23:21 +0400 Subject: add QtNetwork module, used for enumerating network interfaces --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 9bb2de2..38c6460 100644 --- a/configure.ac +++ b/configure.ac @@ -67,7 +67,7 @@ AS_IF([test "x$SQLITE3" != xyes], [ AC_MSG_ERROR(["sqlite3 program not found"]) #pica-client tests AS_IF([test "x$PICA_CLIENT_ENABLED" = "xyes"],[ #AC_PROG_CXX -PKG_CHECK_MODULES([QT_DEPENDENCIES], [QtCore QtGui QtSql]) +PKG_CHECK_MODULES([QT_DEPENDENCIES], [QtCore QtGui QtSql QtNetwork]) AC_SUBST([QT_DEPENDENCIES_CFLAGS]) AC_SUBST([QT_DEPENDENCIES_LIBS]) AC_CHECK_PROGS([UIC], [uic uic-qt4 uic4], [notfound]) -- cgit v1.2.1 From 02a5141837de5a9370786e208e3e2181380d03a1 Mon Sep 17 00:00:00 2001 From: Anton Date: Sat, 17 Jun 2017 20:47:51 +0400 Subject: directc2c, work in progress --- PICA_client.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++------------- PICA_client.h | 4 +++ 2 files changed, 75 insertions(+), 20 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 239260d..d7928c8 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -633,9 +633,20 @@ static unsigned int procmsg_PICA_PROTO_DIRECTC2C_FAILED(unsigned char* buf, unsi return 1; } -unsigned int procmsg_PICA_PROTO_DIRECTC2C_SWITCH(unsigned char*, unsigned int, void*) +unsigned int procmsg_PICA_PROTO_DIRECTC2C_SWITCH(unsigned char* buf, unsigned int nb, void* p) { - --- + struct PICA_c2c *cc = (struct PICA_c2c *)p; + int ret; + + if (cc->conn->directc2c_config == PICA_DIRECTC2C_CFG_DISABLED) + return 0; + + if (cc->directc2c_state != PICA_DIRECTC2C_STATE_WAITINGINCOMING && cc->directc2c_state != PICA_DIRECTC2C_STATE_CONNECTING) + return 0; + + cc->switched_to_directc2c_read = 1; + + return 1; } static unsigned int procmsg_INITRESP(unsigned char* buf, unsigned int nb, void* p) @@ -2098,6 +2109,8 @@ static void process_directc2c(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) struct PICA_c2c *c2c; int ret; + fputs("process_directc2c()\n", stderr);//debug + //process accepted connections if (c2n->directc2c_listener) { @@ -2117,7 +2130,7 @@ static void process_directc2c(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) c2c->direct = d; - ret = PICA_send_directc2c_switch(c2c);---//??? who should send first? + ret = PICA_send_directc2c_switch(c2c);//??? who should send first? if (ret != PICA_OK) { @@ -2142,7 +2155,7 @@ static void process_directc2c(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) } pdprev = &d->next; d = d->next; - -- killptr? + //-- killptr? } } //process outgoing connections @@ -2183,10 +2196,7 @@ static void process_directc2c(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) } else { - ret = directc2c_connect_next(d, c2c); - - if (ret == PICA_ERRNOTFOUND) - c2c->directc2c_state = PICA_DIRECTC2C_STATE_FAILEDTOCONNECT; + d->state = PICA_DIRECTC2C_CONNSTATE_FAILED; } } break; @@ -2196,29 +2206,42 @@ static void process_directc2c(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) { ret = SSL_connect(d->ssl); - ret = process_async_ssl_errors(d->ssl, ret); + if (ret != 1) + { + ret = process_async_ssl_errors(d->ssl, ret); + + if (ret != PICA_OK) + d->state = PICA_DIRECTC2C_CONNSTATE_FAILED; - if (ret != PICA_OK) break; + } ret = directc2c_verify_peer_cert(d, c2c); if (ret != PICA_OK) break; - d->state = PICA_DIRECTC2C_STATE_ACTIVE; + ret = PICA_send_directc2c_switch(c2c); - ---//? send switch message + if (ret != PICA_OK) + break; + + d->state = PICA_DIRECTC2C_CONNSTATE_ACTIVE; } break; case PICA_DIRECTC2C_CONNSTATE_FAILED: + ret = directc2c_connect_next(d, c2c); + + if (ret == PICA_ERRNOTFOUND) + c2c->directc2c_state = PICA_DIRECTC2C_STATE_FAILEDTOCONNECT; break; case PICA_DIRECTC2C_CONNSTATE_ACTIVE: + c2c->directc2c_state = PICA_DIRECTC2C_STATE_ACTIVE; break; - -- + } if (ret != PICA_OK) @@ -2608,17 +2631,39 @@ int PICA_write_c2c(struct PICA_c2c *chn) int ret = PICA_ERRINVARG; if (chn->state != PICA_C2C_STATE_ACTIVE && chn->state != PICA_C2C_STATE_CONNID && chn->state != PICA_C2C_STATE_WAITINGREP) - { - fputs("PICA_write_c2c() was called for incorrect state!\n", stderr); - exit(-1); - } + { + fputs("PICA_write_c2c() was called for incorrect state!\n", stderr); + exit(-1); + } if (PICA_C2C_STATE_CONNID == chn->state) ret = PICA_write_socket(chn->sck_data, chn->write_buf, &chn->write_pos); else - ret = PICA_write_ssl(chn->ssl, chn->write_buf, &chn->write_pos, &chn->write_sslbytestowrite); + { + SSL *ssl_to_write = chn->ssl; + + if (chn->switched_to_directc2c_write) + ssl_to_write = chn->direct->ssl; + + if (chn->directc2c_write_barrier_pos) + { + if (chn->directc2c_write_before_barrier_pos == 0) + chn->directc2c_write_before_barrier_pos = chn->directc2c_write_barrier_pos; - if (chn->disconnect_on_empty_write_buf) + ret = PICA_write_ssl(chn->ssl, chn->write_buf, &chn->directc2c_write_before_barrier_pos, &chn->write_sslbytestowrite); + + if (ret == PICA_OK && chn->directc2c_write_before_barrier_pos == 0) + { + chn->switched_to_directc2c_write = 1; + memmove(chn->write_buf, chn->write_buf + chn->directc2c_write_barrier_pos, chn->write_pos - chn->directc2c_write_barrier_pos); + chn->directc2c_write_barrier_pos = 0; + } + } + else + ret = PICA_write_ssl(ssl_to_write, chn->write_buf, &chn->write_pos, &chn->write_sslbytestowrite); + } + + if (chn->disconnect_on_empty_write_buf && chn->write_pos == 0) PICA_close_c2c(chn); return ret; @@ -2699,6 +2744,7 @@ int PICA_read_ssl(SSL *ssl, unsigned char *buf, unsigned int *ppos, unsigned int int PICA_read_c2c(struct PICA_c2c *chn) { int ret; + SSL *ssl_to_read = chn->ssl; if (chn->state != PICA_C2C_STATE_WAITINGREP && chn->state != PICA_C2C_STATE_WAITINGC2CPROTOVER && chn->state != PICA_C2C_STATE_ACTIVE) { @@ -2706,7 +2752,10 @@ int PICA_read_c2c(struct PICA_c2c *chn) exit(-1); } - ret = PICA_read_ssl(chn->ssl, chn->read_buf, &chn->read_pos, PICA_CHANREADBUFSIZE); + if (chn->switched_to_directc2c_read) + ssl_to_read = chn->direct->ssl; + + ret = PICA_read_ssl(ssl_to_read, chn->read_buf, &chn->read_pos, PICA_CHANREADBUFSIZE); if (ret == PICA_OK) { @@ -2873,6 +2922,8 @@ static int PICA_send_directc2c_switch(struct PICA_c2c *chn) else return PICA_ERRNOMEM; + chn->directc2c_write_barrier_pos = chn->write_pos; + return PICA_OK; } diff --git a/PICA_client.h b/PICA_client.h index f672505..e2a2626 100644 --- a/PICA_client.h +++ b/PICA_client.h @@ -255,6 +255,10 @@ struct PICA_c2c FILE *recvfile_stream; //this flag should be set when connection must be closed after sending last pushed packet int disconnect_on_empty_write_buf; + int switched_to_directc2c_write; + int switched_to_directc2c_read; + unsigned int directc2c_write_barrier_pos; + unsigned int directc2c_write_before_barrier_pos; }; struct PICA_listener -- cgit v1.2.1 From 242abc09a94cf0cb8b33d7d5b9affb70a4b8e86e Mon Sep 17 00:00:00 2001 From: Anton Date: Sat, 17 Jun 2017 20:48:13 +0400 Subject: updated test client --- tests/test_client.c | 80 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 65 insertions(+), 15 deletions(-) diff --git a/tests/test_client.c b/tests/test_client.c index 7a16732..0b4db7c 100644 --- a/tests/test_client.c +++ b/tests/test_client.c @@ -11,6 +11,9 @@ struct sockaddr_in a; struct PICA_acc *acc; struct PICA_c2n *c; struct PICA_c2c *chn; +enum PICA_directc2c_config directc2c_cfg = PICA_DIRECTC2C_CFG_DISABLED; +struct PICA_listener *l = NULL; + int _outgoing_chnl = 0; @@ -138,11 +141,13 @@ void c2n_established_cb(struct PICA_c2n *c2n) void c2n_failed_cb(struct PICA_c2n *c2n, int error) { printf("c2n_failed_cb: %p error_code %i\n", c2n, error); + c = NULL; } void c2n_closed_cb(struct PICA_c2n *c2n, int error) { printf("c2n_closed_cb: %p error_code %i\n", c2n, error); + c = NULL; } void listener_error(struct PICA_listener *lst, int errorcode) @@ -175,37 +180,85 @@ struct PICA_client_callbacks cbs = int main(int argc, char** argv) { - int ret; + int ret, opt; unsigned char peer_id[PICA_ID_SIZE]; struct PICA_c2n* c2ns[] = {NULL, NULL}; fd_set stdinfds; struct timeval tv; - if (argc < 4) + const char *nodeaddr = NULL, *nodeport = NULL, + *certfile = NULL, *peerid = NULL, + *localdirectaddr = NULL, *extport = NULL, + *locport = NULL; + + while ((opt = getopt(argc, argv, "a:p:c:i:d:e:l:")) != -1) + { + switch(opt) + { + case 'a': + nodeaddr = optarg; + break; + + case 'p': + nodeport = optarg; + break; + + case 'c': + certfile = optarg; + break; + + case 'i': + peerid = optarg; + break; + + case 'd': + localdirectaddr = optarg; + break; + + case 'e': + extport = optarg; + break; + + case 'l': + locport = optarg; + break; + + default: + fprintf(stderr, "invalid arg %s\n", optarg); + return -1; + } + } + + if (argc < 4 || !nodeaddr || !nodeport || !certfile) { - puts("usage: test_client address port cert_filename [peer id]\ncert_filename should point to file that contains client certificate, private key and Diffie-Hellman parameters in PEM format"); + puts("usage: test_client -a node address -p node port -c cert_filename [-i peer id]\n\ + -d local address for direct incoming c2c connections\n\ + -e external port for incoming direct connections\n\ + -l internal port to listen for incoming direct connections\n\ +cert_filename should point to file that contains client certificate, private key and Diffie-Hellman parameters in PEM format"); return 0; } + puts(SSLeay_version(SSLEAY_VERSION)); printf("Calling PICA_init...\n"); PICA_client_init(&cbs); printf("opening account..."); - ret = PICA_open_acc(argv[3], argv[3], argv[3], NULL, &acc); + ret = PICA_open_acc(certfile, certfile, certfile, NULL, &acc); if (ret != PICA_OK) { - printf("failed to open account, ret = %i\n", ret); + fprintf(stderr, "failed to open account, ret = %i\n", ret); return 1; } printf("making connection...\n"); //PICA_new_c2n(const char *nodeaddr, unsigned int port, const char *CA_file, const char *cert_file, const char *pkey_file, const char* password, struct PICA_c2n **ci) - ret = PICA_new_c2n(acc, argv[1], atoi(argv[2]), /*"trusted_CA.pem"*/ &c); + ret = PICA_new_c2n(acc, nodeaddr, atoi(nodeport), directc2c_cfg, l, &c); ERR_print_errors_fp(stdout); @@ -220,12 +273,12 @@ int main(int argc, char** argv) c2ns[0] = c; - while(PICA_event_loop(c2ns, NULL, 500) == PICA_OK) + while(PICA_event_loop(c2ns, 500) == PICA_OK) { //puts("event loop..."); - if (argc == 5 && connected_to_node == 1 && c2c_active == 0 && c2c_in_progress == 0) + if (peerid && connected_to_node == 1 && c2c_active == 0 && c2c_in_progress == 0) { - if (PICA_id_from_base64(argv[4], peer_id) == NULL) + if (PICA_id_from_base64(peerid, peer_id) == NULL) { puts("invalid peer_id"); return 1; @@ -233,7 +286,7 @@ int main(int argc, char** argv) printf("Creating c2c to %s...\n", PICA_id_to_base64(peer_id, NULL)); - ret = PICA_new_c2c(c, peer_id, NULL, &chn); + ret = PICA_new_c2c(c, peer_id, l, &chn); //sleep(17);//timeout test if (ret != PICA_OK) { @@ -284,15 +337,12 @@ int main(int argc, char** argv) - sleep(10); if (chn) - { - puts("--------"); PICA_close_c2c(chn); - } - PICA_close_c2n(c); + if (c) + PICA_close_c2n(c); return 0; } -- cgit v1.2.1 From ecf7ff07d284b06a43d7f14f8320b13434627463 Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 18 Jun 2017 21:51:09 +0400 Subject: directc2c support in test_client --- tests/test_client.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/tests/test_client.c b/tests/test_client.c index 0b4db7c..7103914 100644 --- a/tests/test_client.c +++ b/tests/test_client.c @@ -153,6 +153,7 @@ void c2n_closed_cb(struct PICA_c2n *c2n, int error) void listener_error(struct PICA_listener *lst, int errorcode) { printf("listener_error: %p error code %i\n", lst, errorcode); + l = NULL; } struct PICA_client_callbacks cbs = @@ -192,7 +193,7 @@ int main(int argc, char** argv) *localdirectaddr = NULL, *extport = NULL, *locport = NULL; - while ((opt = getopt(argc, argv, "a:p:c:i:d:e:l:")) != -1) + while ((opt = getopt(argc, argv, "a:p:c:i:d:e:l:t")) != -1) { switch(opt) { @@ -224,6 +225,10 @@ int main(int argc, char** argv) locport = optarg; break; + case 't': + directc2c_cfg = PICA_DIRECTC2C_CFG_CONNECTONLY; + break; + default: fprintf(stderr, "invalid arg %s\n", optarg); return -1; @@ -236,11 +241,13 @@ int main(int argc, char** argv) -d local address for direct incoming c2c connections\n\ -e external port for incoming direct connections\n\ -l internal port to listen for incoming direct connections\n\ + -t enable connect-only mode for direct c2c connections\n\ cert_filename should point to file that contains client certificate, private key and Diffie-Hellman parameters in PEM format"); return 0; } + puts(SSLeay_version(SSLEAY_VERSION)); printf("Calling PICA_init...\n"); @@ -255,6 +262,29 @@ cert_filename should point to file that contains client certificate, private key return 1; } + if (localdirectaddr) + { + int intp = 2300, extp = 2300; + + directc2c_cfg = PICA_DIRECTC2C_CFG_ALLOWINCOMING; + + if (extport) + extp = atoi(extport); + if (locport) + intp = atoi(locport); + + printf("new listener on %s port %i external announced port %i\n", localdirectaddr, intp, extp); + + ret = PICA_new_listener(acc, localdirectaddr, extp, intp, &l); + + if (ret != PICA_OK) + { + fprintf(stderr, "failed to create listener, error code: %i\n", ret); + l = NULL; + } + + } + printf("making connection...\n"); //PICA_new_c2n(const char *nodeaddr, unsigned int port, const char *CA_file, const char *cert_file, const char *pkey_file, const char* password, struct PICA_c2n **ci) @@ -344,5 +374,8 @@ cert_filename should point to file that contains client certificate, private key if (c) PICA_close_c2n(c); + if(l) + PICA_close_listener(l); + return 0; } -- cgit v1.2.1 From e2703cff50b32db08a1746c68a5b25db41e5baa8 Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 18 Jun 2017 23:10:08 +0400 Subject: fixing directc2c bugs, work in progress... get rid of c2c/c2n _init_messages arrays; fixed resource release in PICA_new_listener; fixed pointer manipulations in PICA_send_directc2caddrlist --- PICA_client.c | 80 ++++++++++++++++++++++++++++++++--------------------------- PICA_client.h | 2 +- 2 files changed, 44 insertions(+), 38 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index d7928c8..91558d3 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -79,7 +79,9 @@ const struct PICA_msginfo c2n_messages[] = {PICA_PROTO_NOTFOUND, PICA_MSG_FIXED_SIZE, PICA_PROTO_NOTFOUND_SIZE, procmsg_NOTFOUND}, {PICA_PROTO_FOUND, PICA_MSG_FIXED_SIZE, PICA_PROTO_FOUND_SIZE, procmsg_FOUND}, {PICA_PROTO_CLNODELIST, PICA_MSG_VAR_SIZE, PICA_MSG_VARSIZE_INT16, procmsg_CLNODELIST}, - {PICA_PROTO_PINGREQ, PICA_MSG_FIXED_SIZE, PICA_PROTO_PINGREQ_SIZE, procmsg_PINGREQ} + {PICA_PROTO_PINGREQ, PICA_MSG_FIXED_SIZE, PICA_PROTO_PINGREQ_SIZE, procmsg_PINGREQ}, + {PICA_PROTO_INITRESPOK, PICA_MSG_FIXED_SIZE, PICA_PROTO_INITRESPOK_SIZE, procmsg_INITRESP}, + {PICA_PROTO_VERDIFFER, PICA_MSG_FIXED_SIZE, PICA_PROTO_VERDIFFER_SIZE, procmsg_INITRESP} };//---!!! PING!!! const struct PICA_msginfo c2c_messages[] = @@ -93,20 +95,15 @@ const struct PICA_msginfo c2c_messages[] = {PICA_PROTO_FILECONTROL, PICA_MSG_FIXED_SIZE, PICA_PROTO_FILECONTROL_SIZE, procmsg_FILECONTROL}, {PICA_PROTO_DIRECTC2C_ADDRLIST, PICA_MSG_VAR_SIZE, PICA_MSG_VARSIZE_INT16, procmsg_PICA_PROTO_DIRECTC2C_ADDRLIST}, {PICA_PROTO_DIRECTC2C_FAILED, PICA_MSG_FIXED_SIZE, PICA_PROTO_DIRECTC2C_FAILED_SIZE, procmsg_PICA_PROTO_DIRECTC2C_FAILED}, - {PICA_PROTO_DIRECTC2C_SWITCH, PICA_MSG_FIXED_SIZE, PICA_PROTO_DIRECTC2C_SWITCH_SIZE, procmsg_PICA_PROTO_DIRECTC2C_SWITCH} -}; - -struct PICA_msginfo c2n_init_messages[] = -{ - {PICA_PROTO_INITRESPOK, PICA_MSG_FIXED_SIZE, PICA_PROTO_INITRESPOK_SIZE, procmsg_INITRESP}, - {PICA_PROTO_VERDIFFER, PICA_MSG_FIXED_SIZE, PICA_PROTO_VERDIFFER_SIZE, procmsg_INITRESP} + {PICA_PROTO_DIRECTC2C_SWITCH, PICA_MSG_FIXED_SIZE, PICA_PROTO_DIRECTC2C_SWITCH_SIZE, procmsg_PICA_PROTO_DIRECTC2C_SWITCH}, + {PICA_PROTO_C2CCONNREQ, PICA_MSG_FIXED_SIZE, PICA_PROTO_C2CCONNREQ_SIZE, procmsg_C2CCONNREQ}, + {PICA_PROTO_INITRESPOK, PICA_MSG_FIXED_SIZE, PICA_PROTO_INITRESPOK_SIZE, procmsg_INITRESP_c2c}, + {PICA_PROTO_VERDIFFER, PICA_MSG_FIXED_SIZE, PICA_PROTO_VERDIFFER_SIZE, procmsg_INITRESP_c2c} }; struct PICA_msginfo c2c_init_messages[] = { - {PICA_PROTO_C2CCONNREQ, PICA_MSG_FIXED_SIZE, PICA_PROTO_C2CCONNREQ_SIZE, procmsg_C2CCONNREQ}, - {PICA_PROTO_INITRESPOK, PICA_MSG_FIXED_SIZE, PICA_PROTO_INITRESPOK_SIZE, procmsg_INITRESP_c2c}, - {PICA_PROTO_VERDIFFER, PICA_MSG_FIXED_SIZE, PICA_PROTO_VERDIFFER_SIZE, procmsg_INITRESP_c2c} + }; // static int pem_passwd_cb(char *buf, int size, int rwflag, void *userdata) @@ -530,15 +527,17 @@ static int directc2c_connect_next(struct PICA_directc2c *dc2c, struct PICA_c2c * if (dc2c->addrpos >= *(uint16_t*)dc2c->addrlist) return PICA_ERRNOTFOUND; - switch(*dc2c->addrpos) + switch(dc2c->addrlist[dc2c->addrpos]) { case PICA_PROTO_DIRECTC2C_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)); + dc2c->addr.sin_addr.s_addr = *((in_addr_t*)(dc2c->addrlist + dc2c->addrpos + 1)); + dc2c->addr.sin_port = *((uint16_t*)(dc2c->addrlist + dc2c->addrpos + 5)); + + printf("received direct IPv4 addr %s port %i\n", inet_ntoa(dc2c->addr.sin_addr), ntohs(dc2c->addr.sin_port)); dc2c->state = PICA_DIRECTC2C_CONNSTATE_CONNECTING; @@ -565,6 +564,8 @@ static unsigned int procmsg_PICA_PROTO_DIRECTC2C_ADDRLIST(unsigned char* buf, un struct PICA_c2c *cc = (struct PICA_c2c *)p; int ret; + fprintf(stderr, "procmsg_PICA_PROTO_DIRECTC2C_ADDRLIST()\n"); + if (cc->conn->directc2c_config != PICA_DIRECTC2C_CFG_DISABLED) { //if (cc->directc2c_state != PICA_DIRECTC2C_STATE_INACTIVE) @@ -653,6 +654,9 @@ static unsigned int procmsg_INITRESP(unsigned char* buf, unsigned int nb, void* { struct PICA_c2n *ci = (struct PICA_c2n *)p; + if (ci->state != PICA_C2N_STATE_WAITINGREP) + return 0; + switch(buf[0]) { case PICA_PROTO_INITRESPOK: @@ -859,6 +863,9 @@ static unsigned int procmsg_MSGUTF8(unsigned char* buf, unsigned int nb, void* p struct PICA_c2c *chan = (struct PICA_c2c *)p; struct PICA_proto_msg *mp; + if (chan->state != PICA_C2C_STATE_ACTIVE) + return 0; + callbacks.newmsg_cb(chan->peer_id, buf + 4, nb - 4, buf[0]); //send PICA_PROTO_MSGOK @@ -1301,7 +1308,10 @@ int PICA_new_listener(const struct PICA_acc *acc, const char *public_addr, int p lst->public_addr_dns = strdup(public_addr); if (!lst->public_addr_dns) - return PICA_ERRNOMEM; + { + ret_err = PICA_ERRNOMEM; + goto error_ret_0; + } lst->public_addr_ipv4 = inet_addr(public_addr); @@ -1352,6 +1362,9 @@ error_ret_2: //(2) error_ret_1: //(1) free(lst->public_addr_dns); + +error_ret_0: //(0) + free(lst); *l = 0; @@ -2109,8 +2122,6 @@ static void process_directc2c(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) struct PICA_c2c *c2c; int ret; - fputs("process_directc2c()\n", stderr);//debug - //process accepted connections if (c2n->directc2c_listener) { @@ -2121,6 +2132,7 @@ static void process_directc2c(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) while(d) { + fprintf(stderr, "processing accepted direct connection\n"); if (d->state == PICA_DIRECTC2C_CONNSTATE_ACTIVE) { if ((c2c = find_matching_c2c(c2n, d))) @@ -2352,6 +2364,7 @@ static int process_listener(struct PICA_listener *lst, fd_set *rfds, fd_set *wfd if (s >= 0) { + fprintf(stderr, "accepted direct connection on socket %i\n", s); IOCTLSETNONBLOCKINGSOCKET(s, 1); listener_add_connection(lst, s); } @@ -2362,13 +2375,16 @@ static int process_listener(struct PICA_listener *lst, fd_set *rfds, fd_set *wfd while(conn) { + int ret; struct PICA_directc2c *kill_ptr = NULL; - if (process_listener_conn(conn, rfds, wfds) != PICA_OK) + if ((ret = process_listener_conn(conn, rfds, wfds)) != PICA_OK) { kill_ptr = conn; } + fprintf(stderr, "process_listener_conn() returned %i\n", ret); + pprevconn = &conn->next; conn = conn->next; @@ -2762,16 +2778,8 @@ int PICA_read_c2c(struct PICA_c2c *chn) const struct PICA_msginfo *msgs; unsigned int nmsgs; - if (chn->state == PICA_C2C_STATE_ACTIVE) - { - nmsgs = MSGINFO_MSGSNUM(c2c_messages); - msgs = c2c_messages; - } - else - { - nmsgs = MSGINFO_MSGSNUM(c2c_init_messages); - msgs = c2c_init_messages; - } + nmsgs = MSGINFO_MSGSNUM(c2c_messages); + msgs = c2c_messages; if(!PICA_processdatastream(chn->read_buf, &(chn->read_pos ), chn, msgs, nmsgs)) return PICA_ERRSERV; @@ -2796,13 +2804,8 @@ int PICA_read_c2n(struct PICA_c2n *ci) if (ret == PICA_OK) { - if (PICA_C2N_STATE_WAITINGREP == ci->state) - if(!PICA_processdatastream( ci->read_buf, &(ci->read_pos), ci, c2n_init_messages, MSGINFO_MSGSNUM(c2n_init_messages))) - return PICA_ERRSERV; - - if (PICA_C2N_STATE_CONNECTED == ci->state) - if(!PICA_processdatastream( ci->read_buf, &(ci->read_pos), ci, c2n_messages, MSGINFO_MSGSNUM(c2n_messages))) - return PICA_ERRSERV; + if(!PICA_processdatastream( ci->read_buf, &(ci->read_pos), ci, c2n_messages, MSGINFO_MSGSNUM(c2n_messages))) + return PICA_ERRSERV; } return ret; @@ -2876,6 +2879,7 @@ struct PICA_proto_msg* c2c_writebuf_push(struct PICA_c2c *chn, unsigned int msgi int PICA_send_directc2caddrlist(struct PICA_c2c *chn) { + fprintf(stderr, "PICA_send_directc2caddrlist()\n"); if (chn->conn->directc2c_config == PICA_DIRECTC2C_CFG_ALLOWINCOMING && chn->conn->directc2c_listener) { struct PICA_proto_msg *mp; @@ -2886,8 +2890,8 @@ int PICA_send_directc2caddrlist(struct PICA_c2c *chn) { *((uint16_t*)mp->tail) = len; *((uint8_t*)mp->tail + 2) = PICA_PROTO_DIRECTC2C_IPV4; - *((uint32_t*)mp->tail + 3) = chn->conn->directc2c_listener->public_addr_ipv4; - *((uint16_t*)mp->tail + 7) = 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); if (chn->outgoing == PICA_C2C_INCOMING) chn->directc2c_state = PICA_DIRECTC2C_STATE_WAITINGINCOMING; @@ -2899,6 +2903,7 @@ int PICA_send_directc2caddrlist(struct PICA_c2c *chn) static int PICA_send_directc2cfailed(struct PICA_c2c *chn) { + fprintf(stderr, "PICA_send_directc2cfailed()\n"); struct PICA_proto_msg *mp; if ((mp = c2c_writebuf_push(chn, PICA_PROTO_DIRECTC2C_FAILED, PICA_PROTO_DIRECTC2C_FAILED_SIZE))) @@ -2913,6 +2918,7 @@ static int PICA_send_directc2cfailed(struct PICA_c2c *chn) static int PICA_send_directc2c_switch(struct PICA_c2c *chn) { + fputs("PICA_send_directc2c_switch()\n", stderr);//debug struct PICA_proto_msg *mp; if ((mp = c2c_writebuf_push(chn, PICA_PROTO_DIRECTC2C_SWITCH, PICA_PROTO_DIRECTC2C_SWITCH_SIZE))) diff --git a/PICA_client.h b/PICA_client.h index e2a2626..4f99a91 100644 --- a/PICA_client.h +++ b/PICA_client.h @@ -209,7 +209,7 @@ struct PICA_directc2c X509 *peer_cert; uint8_t *addrlist; - uint8_t *addrpos; + int addrpos; struct sockaddr_in addr; -- cgit v1.2.1 From e18087e95337faa292507ba0027b84e944df8150 Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 25 Jun 2017 20:24:33 +0400 Subject: fixed bugs in directc2c processing --- PICA_client.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 91558d3..456b7d3 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -531,6 +531,7 @@ static int directc2c_connect_next(struct PICA_directc2c *dc2c, struct PICA_c2c * { case PICA_PROTO_DIRECTC2C_IPV4: dc2c->sck = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + IOCTLSETNONBLOCKINGSOCKET(dc2c->sck, 1); memset(&dc2c->addr, 0, sizeof(dc2c->addr)); dc2c->addr.sin_family = AF_INET; @@ -642,7 +643,7 @@ unsigned int procmsg_PICA_PROTO_DIRECTC2C_SWITCH(unsigned char* buf, unsigned in if (cc->conn->directc2c_config == PICA_DIRECTC2C_CFG_DISABLED) return 0; - if (cc->directc2c_state != PICA_DIRECTC2C_STATE_WAITINGINCOMING && cc->directc2c_state != PICA_DIRECTC2C_STATE_CONNECTING) + if (cc->directc2c_state != PICA_DIRECTC2C_STATE_ACTIVE && cc->directc2c_state != PICA_DIRECTC2C_STATE_CONNECTING) return 0; cc->switched_to_directc2c_read = 1; @@ -1804,6 +1805,9 @@ int PICA_new_c2c(struct PICA_c2n *ci, const unsigned char *peer_id, struct PICA_ static int process_async_ssl_errors(SSL *ssl, int ret) { + if (ret == 0) + return PICA_ERRDISCONNECT; + if (ret < 0) switch(SSL_get_error(ssl, ret)) { @@ -1814,9 +1818,6 @@ static int process_async_ssl_errors(SSL *ssl, int ret) return PICA_ERRSSL; }; - if (ret == 0) - return PICA_ERRDISCONNECT; - return PICA_OK; } @@ -2033,7 +2034,8 @@ static int process_c2c(struct PICA_c2c *c2c, fd_set *rfds, fd_set *wfds) case PICA_C2C_STATE_ACTIVE: - if (FD_ISSET(c2c->sck_data, wfds)) + if (FD_ISSET(c2c->sck_data, wfds) + || c2c->directc2c_state == PICA_DIRECTC2C_STATE_ACTIVE && FD_ISSET(c2c->direct->sck, wfds)) { if (c2c->write_pos > 0) { @@ -2045,7 +2047,8 @@ static int process_c2c(struct PICA_c2c *c2c, fd_set *rfds, fd_set *wfds) } } - if (ret == PICA_OK && FD_ISSET(c2c->sck_data, rfds)) + if (ret == PICA_OK && (FD_ISSET(c2c->sck_data, rfds) + || c2c->directc2c_state == PICA_DIRECTC2C_STATE_ACTIVE && FD_ISSET(c2c->direct->sck, rfds))) { ret = PICA_read_c2c(c2c); } @@ -2090,7 +2093,6 @@ static struct PICA_c2c * find_matching_c2c(struct PICA_c2n *c2n, struct PICA_dir } c2c = c2c->next; } - return NULL; } @@ -2237,7 +2239,7 @@ static void process_directc2c(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) if (ret != PICA_OK) break; - + fprintf(stderr, "outgoing directc2c is PICA_DIRECTC2C_CONNSTATE_ACTIVE\n"); d->state = PICA_DIRECTC2C_CONNSTATE_ACTIVE; } @@ -2463,7 +2465,7 @@ int PICA_event_loop(struct PICA_c2n **connections, int timeout) fdset_add(&wfds, ic2c->sck_data, &nfds); } - if (ic2c->state == PICA_C2C_STATE_ACTIVE && ic2c->directc2c_state == PICA_DIRECTC2C_STATE_CONNECTING + if (ic2c->state == PICA_C2C_STATE_ACTIVE && (ic2c->directc2c_state == PICA_DIRECTC2C_STATE_CONNECTING || ic2c->directc2c_state == PICA_DIRECTC2C_STATE_ACTIVE) && ic2c->direct && ic2c->direct->state >= PICA_DIRECTC2C_CONNSTATE_CONNECTING)// CHECK CONDITIONS! { fdset_add(&rfds, ic2c->direct->sck, &nfds); @@ -2672,6 +2674,7 @@ int PICA_write_c2c(struct PICA_c2c *chn) { chn->switched_to_directc2c_write = 1; memmove(chn->write_buf, chn->write_buf + chn->directc2c_write_barrier_pos, chn->write_pos - chn->directc2c_write_barrier_pos); + chn->write_pos -= chn->directc2c_write_barrier_pos; chn->directc2c_write_barrier_pos = 0; } } -- cgit v1.2.1 From 705fb54609386b65e4b8b973082fb37408db553c Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 25 Jun 2017 22:13:41 +0400 Subject: new macro PICA_TRACEFUNC to print func name; fixed releasing resources for failed direct connections --- PICA_client.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 13 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 456b7d3..0488737 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -7,6 +7,12 @@ #define PICA_DEBUG // debug +#ifdef PICA_DEBUG +#define PICA_TRACEFUNC fprintf(stderr, "%s()\n", __PRETTY_FUNCTION__); +#else +#define PICA_TRACEFUNC +#endif + //static SSL_CTX* ctx; //unsigned char __hellomsg[4]={0xCA,0xCA,PICA_PROTO_VER_HIGH,PICA_PROTO_VER_LOW}; @@ -519,8 +525,16 @@ static unsigned int procmsg_INITRESP_c2c(unsigned char* buf, unsigned int nb, vo static int directc2c_connect_next(struct PICA_directc2c *dc2c, struct PICA_c2c *c2c) { + PICA_TRACEFUNC int ret; + if (dc2c->ssl) + SSL_free(dc2c->ssl); + dc2c->ssl = NULL; + if (dc2c->sck >= 0) + CLOSE(dc2c->sck); + dc2c->sck = -1; + if (dc2c->addrpos == 0) dc2c->addrpos += 2; @@ -562,11 +576,10 @@ static int directc2c_connect_next(struct PICA_directc2c *dc2c, struct PICA_c2c * static unsigned int procmsg_PICA_PROTO_DIRECTC2C_ADDRLIST(unsigned char* buf, unsigned int nb, void* p) { + PICA_TRACEFUNC struct PICA_c2c *cc = (struct PICA_c2c *)p; int ret; - fprintf(stderr, "procmsg_PICA_PROTO_DIRECTC2C_ADDRLIST()\n"); - if (cc->conn->directc2c_config != PICA_DIRECTC2C_CFG_DISABLED) { //if (cc->directc2c_state != PICA_DIRECTC2C_STATE_INACTIVE) @@ -614,6 +627,7 @@ static unsigned int procmsg_PICA_PROTO_DIRECTC2C_ADDRLIST(unsigned char* buf, un static unsigned int procmsg_PICA_PROTO_DIRECTC2C_FAILED(unsigned char* buf, unsigned int nb, void* p) { + PICA_TRACEFUNC struct PICA_c2c *cc = (struct PICA_c2c *)p; int ret; @@ -637,6 +651,7 @@ static unsigned int procmsg_PICA_PROTO_DIRECTC2C_FAILED(unsigned char* buf, unsi unsigned int procmsg_PICA_PROTO_DIRECTC2C_SWITCH(unsigned char* buf, unsigned int nb, void* p) { + PICA_TRACEFUNC struct PICA_c2c *cc = (struct PICA_c2c *)p; int ret; @@ -794,6 +809,7 @@ static unsigned int procmsg_FOUND(unsigned char* buf, unsigned int nb, void* p) static unsigned int procmsg_CLNODELIST(unsigned char* buf, unsigned int nb, void* p) { + PICA_TRACEFUNC unsigned int pos = 4; char ipaddr_string[INET6_ADDRSTRLEN]; char temp_zeroswap; @@ -892,6 +908,7 @@ static unsigned int procmsg_MSGOK(unsigned char* buf, unsigned int nb, void* p) unsigned int procmsg_PINGREQ(unsigned char* buf, unsigned int nb, void* p) { + PICA_TRACEFUNC struct PICA_c2n *ci = (struct PICA_c2n *)p; struct PICA_proto_msg *mp; @@ -1481,6 +1498,7 @@ error_ret_1: //(1) static int c2n_stage2_sendreq(struct PICA_c2n *c2n) { + PICA_TRACEFUNC struct PICA_proto_msg *mp; puts("c2n_stage2_sendreq");//debug @@ -1502,6 +1520,7 @@ static int c2n_stage2_sendreq(struct PICA_c2n *c2n) static int c2n_stage3_starttls(struct PICA_c2n *c2n) { + PICA_TRACEFUNC int ret; ret = SSL_set_fd(c2n->ssl_comm, c2n->sck_comm); @@ -1529,6 +1548,7 @@ static int c2n_stage3_starttls(struct PICA_c2n *c2n) static int c2n_stage4_nodelistrequest(struct PICA_c2n *c2n) { + PICA_TRACEFUNC struct PICA_proto_msg *mp; mp = c2n_writebuf_push(c2n, PICA_PROTO_CLNODELISTREQ, PICA_PROTO_CLNODELISTREQ_SIZE); @@ -1549,6 +1569,7 @@ static int c2n_stage4_nodelistrequest(struct PICA_c2n *c2n) static int directc2c_stage2_starttls(struct PICA_directc2c *d, struct PICA_c2c *c2c) { + PICA_TRACEFUNC int ret; d->ssl = SSL_new(c2c->acc->ctx); @@ -1595,6 +1616,7 @@ int PICA_new_c2n(const struct PICA_acc *acc, const char *nodeaddr, unsigned int enum PICA_directc2c_config direct_c2c_mode, struct PICA_listener *l, struct PICA_c2n **ci) { + PICA_TRACEFUNC int ret, ret_err; struct PICA_c2n *cid; struct sockaddr_in a; @@ -1776,6 +1798,7 @@ error_ret_1: //(1) // в данный момент. int PICA_new_c2c(struct PICA_c2n *ci, const unsigned char *peer_id, struct PICA_listener *l, struct PICA_c2c **chn) { + PICA_TRACEFUNC struct PICA_proto_msg *mp; struct PICA_c2c *chnl; @@ -1805,6 +1828,7 @@ int PICA_new_c2c(struct PICA_c2n *ci, const unsigned char *peer_id, struct PICA_ static int process_async_ssl_errors(SSL *ssl, int ret) { + PICA_TRACEFUNC if (ret == 0) return PICA_ERRDISCONNECT; @@ -1823,6 +1847,7 @@ static int process_async_ssl_errors(SSL *ssl, int ret) static int process_first_async_connect_result(int connect_ret) { + PICA_TRACEFUNC if (connect_ret == SOCKET_ERROR) { #ifndef WIN32 @@ -1841,6 +1866,7 @@ static int process_first_async_connect_result(int connect_ret) static int check_async_connect_result(int sock, struct sockaddr* a, int addrlen) { + PICA_TRACEFUNC int ret = PICA_ERRSOCK; #ifndef WIN32 @@ -2074,6 +2100,7 @@ static int process_c2c(struct PICA_c2c *c2c, fd_set *rfds, fd_set *wfds) static struct PICA_c2c * find_matching_c2c(struct PICA_c2n *c2n, struct PICA_directc2c *d) { + PICA_TRACEFUNC struct PICA_c2c *c2c; unsigned char idbuf[PICA_ID_SIZE]; @@ -2098,6 +2125,7 @@ static struct PICA_c2c * find_matching_c2c(struct PICA_c2n *c2n, struct PICA_dir static int directc2c_verify_peer_cert(struct PICA_directc2c *d, struct PICA_c2c *c2c) { + PICA_TRACEFUNC unsigned char idbuf[PICA_ID_SIZE]; d->peer_cert = SSL_get_peer_certificate(d->ssl); @@ -2225,7 +2253,9 @@ static void process_directc2c(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) ret = process_async_ssl_errors(d->ssl, ret); if (ret != PICA_OK) + { d->state = PICA_DIRECTC2C_CONNSTATE_FAILED; + } break; } @@ -2233,12 +2263,19 @@ static void process_directc2c(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) ret = directc2c_verify_peer_cert(d, c2c); if (ret != PICA_OK) + { + d->state = PICA_DIRECTC2C_CONNSTATE_FAILED; break; + } ret = PICA_send_directc2c_switch(c2c); if (ret != PICA_OK) + { + d->state = PICA_DIRECTC2C_CONNSTATE_FAILED; break; + } + fprintf(stderr, "outgoing directc2c is PICA_DIRECTC2C_CONNSTATE_ACTIVE\n"); d->state = PICA_DIRECTC2C_CONNSTATE_ACTIVE; @@ -2249,7 +2286,11 @@ static void process_directc2c(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) ret = directc2c_connect_next(d, c2c); if (ret == PICA_ERRNOTFOUND) + { + PICA_close_directc2c(d); + c2c->direct = 0; c2c->directc2c_state = PICA_DIRECTC2C_STATE_FAILEDTOCONNECT; + } break; case PICA_DIRECTC2C_CONNSTATE_ACTIVE: @@ -2258,14 +2299,14 @@ static void process_directc2c(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) } - if (ret != PICA_OK) - { - PICA_close_directc2c(d); - c2c->direct = 0; +// if (ret != PICA_OK) +// { +// PICA_close_directc2c(d); +// c2c->direct = 0; - if (c2c->directc2c_state != PICA_DIRECTC2C_STATE_FAILEDTOCONNECT) - c2c->directc2c_state = PICA_DIRECTC2C_STATE_INACTIVE;//fallback to c2c through node? - } +// if (c2c->directc2c_state != PICA_DIRECTC2C_STATE_FAILEDTOCONNECT) +// c2c->directc2c_state = PICA_DIRECTC2C_STATE_INACTIVE;//fallback to c2c through node? +// } } c2c = c2c->next; @@ -2274,6 +2315,7 @@ static void process_directc2c(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) static void listener_add_connection(struct PICA_listener *lst, SOCKET *s) { + PICA_TRACEFUNC struct PICA_directc2c *nc; int ret; @@ -2882,7 +2924,7 @@ struct PICA_proto_msg* c2c_writebuf_push(struct PICA_c2c *chn, unsigned int msgi int PICA_send_directc2caddrlist(struct PICA_c2c *chn) { - fprintf(stderr, "PICA_send_directc2caddrlist()\n"); + PICA_TRACEFUNC if (chn->conn->directc2c_config == PICA_DIRECTC2C_CFG_ALLOWINCOMING && chn->conn->directc2c_listener) { struct PICA_proto_msg *mp; @@ -2906,7 +2948,7 @@ int PICA_send_directc2caddrlist(struct PICA_c2c *chn) static int PICA_send_directc2cfailed(struct PICA_c2c *chn) { - fprintf(stderr, "PICA_send_directc2cfailed()\n"); + PICA_TRACEFUNC struct PICA_proto_msg *mp; if ((mp = c2c_writebuf_push(chn, PICA_PROTO_DIRECTC2C_FAILED, PICA_PROTO_DIRECTC2C_FAILED_SIZE))) @@ -2921,7 +2963,7 @@ static int PICA_send_directc2cfailed(struct PICA_c2c *chn) static int PICA_send_directc2c_switch(struct PICA_c2c *chn) { - fputs("PICA_send_directc2c_switch()\n", stderr);//debug + PICA_TRACEFUNC struct PICA_proto_msg *mp; if ((mp = c2c_writebuf_push(chn, PICA_PROTO_DIRECTC2C_SWITCH, PICA_PROTO_DIRECTC2C_SWITCH_SIZE))) @@ -3164,6 +3206,7 @@ int PICA_send_file_fragment(struct PICA_c2c *chn) } void PICA_close_directc2c(struct PICA_directc2c *d) { + PICA_TRACEFUNC if (d->peer_cert) X509_free(d->peer_cert); @@ -3183,7 +3226,7 @@ void PICA_close_c2c(struct PICA_c2c *chn) { struct PICA_c2c *ipt; - fprintf(stderr, "PICA_close_c2c(%p)\n", chn);//debug + PICA_TRACEFUNC ipt = chn->conn->chan_list_head; //puts("PICA_close_c2c_chkp0");//debug @@ -3249,6 +3292,7 @@ void PICA_close_c2c(struct PICA_c2c *chn) void PICA_close_c2n(struct PICA_c2n *cid) { + PICA_TRACEFUNC struct PICA_c2c *ipt; while((ipt = cid->chan_list_head)) -- cgit v1.2.1 From 41117d6c03271b971e48c5d5989168f826dfddcd Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 26 Jun 2017 18:42:09 +0400 Subject: fixed directc2c logic for cases when receiver side does not wait for incoming direct connection --- PICA_client.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index 0488737..d9f26df 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -582,16 +582,10 @@ static unsigned int procmsg_PICA_PROTO_DIRECTC2C_ADDRLIST(unsigned char* buf, un if (cc->conn->directc2c_config != PICA_DIRECTC2C_CFG_DISABLED) { - //if (cc->directc2c_state != PICA_DIRECTC2C_STATE_INACTIVE) - // return 1; - - //if (cc->outgoing == PICA_C2C_OUTGOING) - // cc->directc2c_state = PICA_DIRECTC2C_STATE_CONNECTING; - //else if (cc->outgoing == PICA_C2C_INCOMING) - // cc->directc2c_state = PICA_DIRECTC2C_STATE_WAITINGINCOMING; - //else - // return 0; - if (cc->directc2c_state != PICA_DIRECTC2C_STATE_WAITINGINCOMING) + if (cc->directc2c_state != PICA_DIRECTC2C_STATE_INACTIVE && cc->directc2c_state != PICA_DIRECTC2C_STATE_WAITINGINCOMING) + return 0; + + if (cc->outgoing == PICA_C2C_OUTGOING || cc->conn->directc2c_config == PICA_DIRECTC2C_CFG_CONNECTONLY) cc->directc2c_state = PICA_DIRECTC2C_STATE_CONNECTING; cc->direct = calloc(1, sizeof(struct PICA_directc2c)); @@ -611,7 +605,7 @@ static unsigned int procmsg_PICA_PROTO_DIRECTC2C_ADDRLIST(unsigned char* buf, un cc->direct->addrlist[nb - 2] = 0; cc->direct->addrpos = 0; - if (cc->directc2c_state == PICA_DIRECTC2C_STATE_WAITINGINCOMING) + if (cc->outgoing == PICA_C2C_INCOMING && cc->conn->directc2c_config == PICA_DIRECTC2C_CFG_ALLOWINCOMING) return 1;//connect later, if no incoming connection is accepted and DIRECTC2C_FAILED is received ret = directc2c_connect_next(cc->direct, cc); @@ -637,6 +631,9 @@ static unsigned int procmsg_PICA_PROTO_DIRECTC2C_FAILED(unsigned char* buf, unsi if (cc->conn->directc2c_config == PICA_DIRECTC2C_CFG_DISABLED) return 0; + if (cc->outgoing != PICA_C2C_INCOMING) + return 0; + ret = directc2c_connect_next(cc->direct, cc); if (ret == PICA_ERRNOTFOUND) @@ -2938,8 +2935,7 @@ int PICA_send_directc2caddrlist(struct PICA_c2c *chn) *((uint32_t*)(mp->tail + 3)) = chn->conn->directc2c_listener->public_addr_ipv4; *((uint16_t*)(mp->tail + 7)) = htons(chn->conn->directc2c_listener->public_port); - if (chn->outgoing == PICA_C2C_INCOMING) - chn->directc2c_state = PICA_DIRECTC2C_STATE_WAITINGINCOMING; + chn->directc2c_state = PICA_DIRECTC2C_STATE_WAITINGINCOMING; } } -- cgit v1.2.1 From bd355c598bcfef7897e7af3418ef1fa438beedc3 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 26 Jun 2017 19:11:21 +0400 Subject: fixed segfault in test_client --- tests/test_client.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/test_client.c b/tests/test_client.c index 7103914..8434611 100644 --- a/tests/test_client.c +++ b/tests/test_client.c @@ -303,7 +303,7 @@ cert_filename should point to file that contains client certificate, private key c2ns[0] = c; - while(PICA_event_loop(c2ns, 500) == PICA_OK) + while(PICA_event_loop(c2ns, 500) == PICA_OK && c != NULL) { //puts("event loop..."); if (peerid && connected_to_node == 1 && c2c_active == 0 && c2c_in_progress == 0) @@ -367,10 +367,6 @@ cert_filename should point to file that contains client certificate, private key - - if (chn) - PICA_close_c2c(chn); - if (c) PICA_close_c2n(c); -- cgit v1.2.1 From 9b2132d83ab2ea8fa60cdb7ebfebf10f7c62c470 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 26 Jun 2017 19:11:47 +0400 Subject: fixed memory leak in PICA_get_id_from_cert_file() --- PICA_client.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/PICA_client.c b/PICA_client.c index d9f26df..d488a16 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -155,6 +155,7 @@ int PICA_get_id_from_cert_file(const char *cert_file, unsigned char *id) { X509 *x; FILE *f; + int ret; f = fopen(cert_file, "r"); @@ -172,7 +173,10 @@ int PICA_get_id_from_cert_file(const char *cert_file, unsigned char *id) return 0; } - return PICA_id_from_X509(x, id); + ret = PICA_id_from_X509(x, id); + X509_free(x); + + return ret; } int PICA_get_id_from_cert_string(const char *cert_pem, unsigned char *id) -- cgit v1.2.1 From 0b7e4355d56973ec801ef86371d837dd50b1012e Mon Sep 17 00:00:00 2001 From: Anton Date: Wed, 12 Jul 2017 13:16:08 +0400 Subject: implemented echo mode in test client --- tests/test_client.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/tests/test_client.c b/tests/test_client.c index 8434611..0995d51 100644 --- a/tests/test_client.c +++ b/tests/test_client.c @@ -21,6 +21,8 @@ int connected_to_node = 0; int c2c_active = 0; int c2c_in_progress = 0; +int echo_mode = 0; + unsigned char buf[64 * 1024]; int accept_cb(const unsigned char *id) @@ -32,6 +34,19 @@ int accept_cb(const unsigned char *id) //получение сообщения. void newmsg_cb(const unsigned char *peer_id, const char* msgbuf, unsigned int nb, int type) { + + if (echo_mode) + { + int ret; + + ret = PICA_send_msg(chn, msgbuf, nb); + + if (ret != PICA_OK) + printf("failed to send message, error = %i\n", ret); + + return; + } + memcpy(buf, msgbuf, nb); buf[nb] = 0; printf(" %s: ", PICA_id_to_base64(peer_id, NULL)); @@ -193,7 +208,7 @@ int main(int argc, char** argv) *localdirectaddr = NULL, *extport = NULL, *locport = NULL; - while ((opt = getopt(argc, argv, "a:p:c:i:d:e:l:t")) != -1) + while ((opt = getopt(argc, argv, "a:p:c:i:d:e:l:tm")) != -1) { switch(opt) { @@ -229,6 +244,10 @@ int main(int argc, char** argv) directc2c_cfg = PICA_DIRECTC2C_CFG_CONNECTONLY; break; + case 'm': + echo_mode = 1; + break; + default: fprintf(stderr, "invalid arg %s\n", optarg); return -1; @@ -329,7 +348,7 @@ cert_filename should point to file that contains client certificate, private key } - if (connected_to_node == 1 && c2c_active == 1) + if (connected_to_node == 1 && c2c_active == 1 && !echo_mode) { FD_ZERO(&stdinfds); FD_SET(STDIN_FILENO, &stdinfds); -- cgit v1.2.1 From f15e2db611dbb96e3294a5a778ac77022ece7e81 Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 20 Jul 2017 01:21:50 +0400 Subject: implemented random message mode in test_client --- tests/test_client.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/tests/test_client.c b/tests/test_client.c index 0995d51..5f5e44b 100644 --- a/tests/test_client.c +++ b/tests/test_client.c @@ -5,7 +5,7 @@ #include #include "../PICA_client.h" - +#include "../PICA_proto.h" struct sockaddr_in a; struct PICA_acc *acc; @@ -22,6 +22,8 @@ int c2c_active = 0; int c2c_in_progress = 0; int echo_mode = 0; +int random_message_mode = 0; +int delivery_acks_count = 0; unsigned char buf[64 * 1024]; @@ -55,6 +57,7 @@ void newmsg_cb(const unsigned char *peer_id, const char* msgbuf, unsigned int nb //получение подтверждения о доставке сообщения void msgok_cb(const unsigned char *peer_id) { + delivery_acks_count++; puts("[V]"); } //создание канала с собеседником @@ -208,7 +211,7 @@ int main(int argc, char** argv) *localdirectaddr = NULL, *extport = NULL, *locport = NULL; - while ((opt = getopt(argc, argv, "a:p:c:i:d:e:l:tm")) != -1) + while ((opt = getopt(argc, argv, "a:p:c:i:d:e:l:tmr")) != -1) { switch(opt) { @@ -248,12 +251,22 @@ int main(int argc, char** argv) echo_mode = 1; break; + case 'r': + random_message_mode = 1; + break; + default: fprintf(stderr, "invalid arg %s\n", optarg); return -1; } } + if (echo_mode && random_message_mode) + { + puts("echo mode and random test messages mode are mutually exclusive, please select only one of them"); + return -1; + } + if (argc < 4 || !nodeaddr || !nodeport || !certfile) { puts("usage: test_client -a node address -p node port -c cert_filename [-i peer id]\n\ @@ -261,6 +274,8 @@ int main(int argc, char** argv) -e external port for incoming direct connections\n\ -l internal port to listen for incoming direct connections\n\ -t enable connect-only mode for direct c2c connections\n\ + -m start in echo mode, received messages are sent back, input from stdin is not accepted\n\ + -r send random test messages and exit, expects other side to be run in echo mode\n\ cert_filename should point to file that contains client certificate, private key and Diffie-Hellman parameters in PEM format"); return 0; } @@ -348,7 +363,51 @@ cert_filename should point to file that contains client certificate, private key } - if (connected_to_node == 1 && c2c_active == 1 && !echo_mode) + if (random_message_mode && connected_to_node == 1 && c2c_active == 1) + { + static int test_stage = 0; + + switch(test_stage) + { + //send zero-length message + case 0: + ret = PICA_send_msg(chn, NULL, 0); + test_stage++; + break; + + //send max length message + case 1: + memset(buf, 'X', PICA_PROTO_C2CMSG_MAXDATASIZE); + ret = PICA_send_msg(chn, buf, PICA_PROTO_C2CMSG_MAXDATASIZE); + test_stage++; + break; + + //send random length message + case 2: + RAND_pseudo_bytes((unsigned char*)&ret, sizeof ret); + if (ret < 0) + ret = 0 - ret; + ret %= PICA_PROTO_C2CMSG_MAXDATASIZE; + memset(buf, 'x', ret); + ret = PICA_send_msg(chn, buf, ret); + test_stage++; + break; + + default: + puts("waiting for test messages to be delivered"); + } + + if (ret != PICA_OK) + { + printf("failed to send message, error = %i\n", ret); + return 1; + } + + if (delivery_acks_count == 3) + break;//exit main loop on success + } + + if (connected_to_node == 1 && c2c_active == 1 && !echo_mode && !random_message_mode) { FD_ZERO(&stdinfds); FD_SET(STDIN_FILENO, &stdinfds); -- cgit v1.2.1 From 1ba81a25b54881d0519963df31ef85f45ea30a87 Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 20 Jul 2017 19:30:18 +0400 Subject: fixed removing PICA_directc2c from listener's accepted connections list --- PICA_client.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/PICA_client.c b/PICA_client.c index d488a16..ad4c3eb 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -2430,7 +2430,9 @@ static int process_listener(struct PICA_listener *lst, fd_set *rfds, fd_set *wfd fprintf(stderr, "process_listener_conn() returned %i\n", ret); - pprevconn = &conn->next; + if (!kill_ptr) + pprevconn = &conn->next; + conn = conn->next; if (kill_ptr) @@ -2438,6 +2440,7 @@ static int process_listener(struct PICA_listener *lst, fd_set *rfds, fd_set *wfd *pprevconn = kill_ptr->next; PICA_close_directc2c(kill_ptr); } + } return PICA_OK; -- cgit v1.2.1 From c0713b9a9ffca4516b44127cc335332a9405eb27 Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 27 Jul 2017 02:17:14 +0400 Subject: test_client: compare sent & received messages in random message mode --- tests/test_client.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/test_client.c b/tests/test_client.c index 5f5e44b..691dd6d 100644 --- a/tests/test_client.c +++ b/tests/test_client.c @@ -49,6 +49,17 @@ void newmsg_cb(const unsigned char *peer_id, const char* msgbuf, unsigned int nb return; } + if (random_message_mode) + { + //compare received & sent messages, fail if they do not match exactly + if (memcmp(msgbuf, buf, nb) != 0) + { + printf("sent and returned messages are not equal!\n"); + return 1; + } + + } + memcpy(buf, msgbuf, nb); buf[nb] = 0; printf(" %s: ", PICA_id_to_base64(peer_id, NULL)); -- cgit v1.2.1 From 1ec1d72b5dc98b93c86b4a09950a3e975efe8487 Mon Sep 17 00:00:00 2001 From: Anton Date: Mon, 4 Sep 2017 22:31:11 +0400 Subject: test_client: wait for reply before sending next message in random message mode --- tests/test_client.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/test_client.c b/tests/test_client.c index 691dd6d..d78441e 100644 --- a/tests/test_client.c +++ b/tests/test_client.c @@ -24,6 +24,7 @@ int c2c_in_progress = 0; int echo_mode = 0; int random_message_mode = 0; int delivery_acks_count = 0; +int rmm_wait_for_reply = 0; unsigned char buf[64 * 1024]; @@ -55,9 +56,10 @@ void newmsg_cb(const unsigned char *peer_id, const char* msgbuf, unsigned int nb if (memcmp(msgbuf, buf, nb) != 0) { printf("sent and returned messages are not equal!\n"); - return 1; + exit(1); } + rmm_wait_for_reply = 0; } memcpy(buf, msgbuf, nb); @@ -374,7 +376,7 @@ cert_filename should point to file that contains client certificate, private key } - if (random_message_mode && connected_to_node == 1 && c2c_active == 1) + if (random_message_mode && connected_to_node == 1 && c2c_active == 1 && rmm_wait_for_reply == 0) { static int test_stage = 0; @@ -384,6 +386,7 @@ cert_filename should point to file that contains client certificate, private key case 0: ret = PICA_send_msg(chn, NULL, 0); test_stage++; + rmm_wait_for_reply = 1; break; //send max length message @@ -391,6 +394,7 @@ cert_filename should point to file that contains client certificate, private key memset(buf, 'X', PICA_PROTO_C2CMSG_MAXDATASIZE); ret = PICA_send_msg(chn, buf, PICA_PROTO_C2CMSG_MAXDATASIZE); test_stage++; + rmm_wait_for_reply = 1; break; //send random length message @@ -402,6 +406,7 @@ cert_filename should point to file that contains client certificate, private key memset(buf, 'x', ret); ret = PICA_send_msg(chn, buf, ret); test_stage++; + rmm_wait_for_reply = 1; break; default: -- cgit v1.2.1 From fdb06bfda394614a18fa714f3209eba2b844925c Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 12 Nov 2017 01:13:02 +0400 Subject: test_client: implemented sending & receiving files --- tests/test_client.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/tests/test_client.c b/tests/test_client.c index d78441e..c469c74 100644 --- a/tests/test_client.c +++ b/tests/test_client.c @@ -134,8 +134,22 @@ int peer_cert_verify_cb(const unsigned char *peer_id, const char *cert_pem, unsi int accept_file_cb(const unsigned char *peer_id, uint64_t file_size, const char *filename, unsigned int filename_size) { - printf("accept_file_cb: peer_id %s\n", PICA_id_to_base64(peer_id, NULL)); - return 0; + int ret; + char namebuf[256]; + + printf("accept_file_cb: peer_id %s filename: %.*s\n", PICA_id_to_base64(peer_id, NULL), filename_size, filename); + + sprintf(namebuf, "/tmp/received_%.*s", filename_size, filename); + + ret = PICA_accept_file(chn, namebuf, strlen(namebuf)); + + if (ret != PICA_OK) + { + printf("faild to accept file, errror %i\n", ret); + return 0; + } + + return 2; } void accepted_file_cb(const unsigned char *peer_id) @@ -222,9 +236,10 @@ int main(int argc, char** argv) const char *nodeaddr = NULL, *nodeport = NULL, *certfile = NULL, *peerid = NULL, *localdirectaddr = NULL, *extport = NULL, + *filetosend = NULL, *locport = NULL; - while ((opt = getopt(argc, argv, "a:p:c:i:d:e:l:tmr")) != -1) + while ((opt = getopt(argc, argv, "a:p:c:i:d:e:l:f:tmr")) != -1) { switch(opt) { @@ -252,6 +267,10 @@ int main(int argc, char** argv) extport = optarg; break; + case 'f': + filetosend = optarg; + break; + case 'l': locport = optarg; break; @@ -456,6 +475,17 @@ cert_filename should point to file that contains client certificate, private key } } + if (connected_to_node == 1 && c2c_active == 1 && filetosend) + { + printf("sending file %s to peer...\n", filetosend); + ret = PICA_send_file(chn, filetosend); + + if (ret != PICA_OK) + printf("failed to send file %s, error = %i\n", filetosend, ret); + + filetosend = NULL; + } + } -- cgit v1.2.1 From d9566575bf5b09bbb4b6efc7026d1ee7df0965a4 Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 12 Nov 2017 17:20:55 +0400 Subject: bugfix, prevent removing entry from client_tree by duplicate connection --- PICA_node.c | 1 + 1 file changed, 1 insertion(+) diff --git a/PICA_node.c b/PICA_node.c index 1d04f4c..a6c5878 100644 --- a/PICA_node.c +++ b/PICA_node.c @@ -2479,6 +2479,7 @@ void process_c2n_write() if (client_tree_search(i_ptr->id)) { PICA_info("Disconnecting client %p because other user with same ID = %u is already connected", i_ptr, i_ptr->id); + memset(i_ptr->id, 0, PICA_ID_SIZE);//reset id to all zeros to prevent removing existing ID from previous connection from client_tree ret = 0;//id already exists in tree } else -- cgit v1.2.1 From 8359fb8c77d6cf68b8475fc6c3e6daeba1c5866a Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 12 Nov 2017 18:17:55 +0400 Subject: reject all-zeroes ID --- PICA_node.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/PICA_node.c b/PICA_node.c index a6c5878..79268a6 100644 --- a/PICA_node.c +++ b/PICA_node.c @@ -2470,13 +2470,20 @@ void process_c2n_write() PICA_error("Unable to get client id from certificate"); kill_ptr = i_ptr; } - //PICA_debug2("user id=%u",i_ptr->id); -#warning "see comments below" - //сделать проверку названия сети!!!!---------------------------<<<<<<<<<<<<<<<<<<<<<< X509_free(client_cert); - //прицепить структуру к дереву - if (client_tree_search(i_ptr->id)) + + //reject all-zeroes ID + { + static const char zeroID[PICA_ID_SIZE] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + if (memcmp(zeroID, i_ptr->id, PICA_ID_SIZE) == 0) + { + PICA_error("Rejecting all-zero Pica ID"); + kill_ptr = i_ptr; + } + } + + if (!kill_ptr && client_tree_search(i_ptr->id)) { PICA_info("Disconnecting client %p because other user with same ID = %u is already connected", i_ptr, i_ptr->id); memset(i_ptr->id, 0, PICA_ID_SIZE);//reset id to all zeros to prevent removing existing ID from previous connection from client_tree -- cgit v1.2.1 From 45a61ccd3f676341901c594a9e7e778a85e1e1c7 Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 12 Nov 2017 18:30:57 +0400 Subject: removed excess memcmp() calls --- PICA_node.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/PICA_node.c b/PICA_node.c index 79268a6..b7360e4 100644 --- a/PICA_node.c +++ b/PICA_node.c @@ -1482,10 +1482,14 @@ int client_tree_add(struct client *ci) do { - if (memcmp(i->id, ci->id, PICA_ID_SIZE) == 0) + int cmp; + + cmp = memcmp(ci->id, i->id, PICA_ID_SIZE); + + if (cmp == 0) return 0; - if (memcmp(ci->id, i->id, PICA_ID_SIZE) < 0) // ci->id < i->id + if (cmp < 0) // ci->id < i->id { if (i->left) i = i->left; @@ -1525,10 +1529,12 @@ struct client* client_tree_search(const unsigned char *id) while(i_ptr) { - if (memcmp(i_ptr->id, id, PICA_ID_SIZE) == 0) + int cmp = memcmp(id, i_ptr->id, PICA_ID_SIZE); + + if (cmp == 0) return i_ptr; - if (memcmp(id, i_ptr->id, PICA_ID_SIZE) < 0) //id < i_ptr->id + if (cmp < 0) //id < i_ptr->id i_ptr = i_ptr->left; else i_ptr = i_ptr->right; -- cgit v1.2.1 From ced679b1e7896b0df7215d842d2122d8c8f40edf Mon Sep 17 00:00:00 2001 From: Anton Date: Sun, 12 Nov 2017 22:06:30 +0400 Subject: added flag want_write, fixed conditions for adding sockets to write FD set for select() in order to prevent CPU wasting loops --- PICA_client.c | 40 +++++++++++++++++++++++++++++++++------- PICA_client.h | 3 +++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/PICA_client.c b/PICA_client.c index ad4c3eb..60ea14e 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -1954,6 +1954,9 @@ static int process_c2n(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) if (sslret != SSL_ERROR_WANT_READ && sslret != SSL_ERROR_WANT_WRITE) ret = PICA_ERRSSL; + + if (sslret == SSL_ERROR_WANT_WRITE) + c2n->want_write = 1; } } @@ -2026,6 +2029,8 @@ static int process_c2c(struct PICA_c2c *c2c, fd_set *rfds, fd_set *wfds) if (sslret != SSL_ERROR_WANT_READ && sslret != SSL_ERROR_WANT_WRITE) ret = PICA_ERRSSL; + if (sslret == SSL_ERROR_WANT_WRITE) + c2c->want_write = 1; } else if(sslret == 0) { @@ -2251,6 +2256,9 @@ static void process_directc2c(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds) if (ret != 1) { + if (SSL_get_error(d->ssl, ret)== SSL_ERROR_WANT_WRITE) + d->want_write = 1; + ret = process_async_ssl_errors(d->ssl, ret); if (ret != PICA_OK) @@ -2385,6 +2393,9 @@ static int process_listener_conn(struct PICA_directc2c *conn, fd_set *rfds, fd_s { ret = SSL_get_error(conn->ssl, ret); + if (ret == SSL_ERROR_WANT_WRITE) + conn->want_write = 1; + if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE) return PICA_ERRSSL; } @@ -2428,7 +2439,7 @@ static int process_listener(struct PICA_listener *lst, fd_set *rfds, fd_set *wfd kill_ptr = conn; } - fprintf(stderr, "process_listener_conn() returned %i\n", ret); + //fprintf(stderr, "process_listener_conn() returned %i\n", ret); if (!kill_ptr) pprevconn = &conn->next; @@ -2481,8 +2492,11 @@ int PICA_event_loop(struct PICA_c2n **connections, int timeout) fdset_add(&rfds, (*ic2n)->sck_comm, &nfds); if ((*ic2n)->write_pos || (*ic2n)->state == PICA_C2N_STATE_CONNECTING - || (*ic2n)->state == PICA_C2N_STATE_WAITINGTLS) + || (*ic2n)->want_write/*(*ic2n)->state == PICA_C2N_STATE_WAITINGTLS*/) + { + (*ic2n)->want_write = 0; fdset_add(&wfds, (*ic2n)->sck_comm, &nfds); + } if ((*ic2n)->directc2c_listener) { @@ -2493,7 +2507,11 @@ int PICA_event_loop(struct PICA_c2n **connections, int timeout) while (ilstcon) { fdset_add(&rfds, ilstcon->sck, &nfds); - fdset_add(&wfds, ilstcon->sck, &nfds); + + if (ilstcon->want_write) + fdset_add(&wfds, ilstcon->sck, &nfds); + ilstcon->want_write = 0; + ilstcon = ilstcon->next; } } @@ -2506,16 +2524,24 @@ int PICA_event_loop(struct PICA_c2n **connections, int timeout) { fdset_add(&rfds, ic2c->sck_data, &nfds); - if (ic2c->write_pos || ic2c->state == PICA_C2C_STATE_CONNECTING || ic2c->state == PICA_C2C_STATE_WAITINGTLS - || ic2c->sendfilestate == PICA_CHANSENDFILESTATE_SENDING) + if ((ic2c->write_pos || ic2c->state == PICA_C2C_STATE_CONNECTING || (ic2c->state == PICA_C2C_STATE_WAITINGTLS && ic2c->want_write) + || ic2c->sendfilestate == PICA_CHANSENDFILESTATE_SENDING) && ic2c->directc2c_state != PICA_DIRECTC2C_STATE_ACTIVE) + { + ic2c->want_write = 0; fdset_add(&wfds, ic2c->sck_data, &nfds); + } } if (ic2c->state == PICA_C2C_STATE_ACTIVE && (ic2c->directc2c_state == PICA_DIRECTC2C_STATE_CONNECTING || ic2c->directc2c_state == PICA_DIRECTC2C_STATE_ACTIVE) - && ic2c->direct && ic2c->direct->state >= PICA_DIRECTC2C_CONNSTATE_CONNECTING)// CHECK CONDITIONS! + && ic2c->direct && ic2c->direct->state >= PICA_DIRECTC2C_CONNSTATE_CONNECTING) { fdset_add(&rfds, ic2c->direct->sck, &nfds); - fdset_add(&wfds, ic2c->direct->sck, &nfds); + + if (ic2c->write_pos || ic2c->direct->state == PICA_DIRECTC2C_CONNSTATE_CONNECTING || ic2c->direct->want_write || ic2c->sendfilestate == PICA_CHANSENDFILESTATE_SENDING) + { + ic2c->direct->want_write = 0; + fdset_add(&wfds, ic2c->direct->sck, &nfds); + } } ic2c = ic2c->next; diff --git a/PICA_client.h b/PICA_client.h index 4f99a91..b56e034 100644 --- a/PICA_client.h +++ b/PICA_client.h @@ -170,6 +170,7 @@ struct PICA_c2n int init_resp_ok; unsigned char node_ver_major, node_ver_minor; int disconnect_on_empty_write_buf; + int want_write; }; enum PICA_c2c_state @@ -207,6 +208,7 @@ struct PICA_directc2c SOCKET sck; SSL *ssl; X509 *peer_cert; + int want_write; uint8_t *addrlist; int addrpos; @@ -257,6 +259,7 @@ struct PICA_c2c int disconnect_on_empty_write_buf; int switched_to_directc2c_write; int switched_to_directc2c_read; + int want_write; unsigned int directc2c_write_barrier_pos; unsigned int directc2c_write_before_barrier_pos; }; -- cgit v1.2.1 From c2f8b64da40dd73f75230f18816578a2cc8c1b9a Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 30 Nov 2017 22:57:25 +0400 Subject: pica-client: display client protocol version --- PICA_proto.h | 1 + pica-client/picaactioncenter.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/PICA_proto.h b/PICA_proto.h index 32c817a..46ca178 100644 --- a/PICA_proto.h +++ b/PICA_proto.h @@ -10,6 +10,7 @@ #define PICA_C2CPROTO_VER_HIGH 0 #define PICA_C2CPROTO_VER_LOW 1 +#define PICA_PROTO_CLIENT_VER_STRING PICA_STRINGIFY2(PICA_C2CPROTO_VER_HIGH, PICA_C2CPROTO_VER_LOW) #define PICA_PROTO_VER_STRING PICA_STRINGIFY2(PICA_PROTO_VER_HIGH, PICA_PROTO_VER_LOW) #define PICA_STRINGIFY2(H, L) PICA_STRINGIFY(H, L) #define PICA_STRINGIFY(H, L) #H#L diff --git a/pica-client/picaactioncenter.cpp b/pica-client/picaactioncenter.cpp index 1aa09ec..b6b228a 100644 --- a/pica-client/picaactioncenter.cpp +++ b/pica-client/picaactioncenter.cpp @@ -46,7 +46,8 @@ void PicaActionCenter::about() mbx.setTextFormat(Qt::RichText); mbx.setText(tr("Pica Pica Messenger "VERSION_STRING"
(c) 2012 - 2014 Anton Sviridenko

\ http://picapica.im

Contributors:
Daniil Ustinov - bugfixes
EXL - bugfixes

\ -protocol version " PICA_PROTO_VER_STRING)); +protocol version " PICA_PROTO_VER_STRING "
" + "client protocol version " PICA_PROTO_CLIENT_VER_STRING)); mbx.exec(); } -- cgit v1.2.1 From 8bb59811285b17d9b81baac60bb214efe434fb03 Mon Sep 17 00:00:00 2001 From: Anton Date: Fri, 1 Dec 2017 04:14:09 +0400 Subject: pica-client: combobox for incoming direct connections address in settings dialog --- pica-client/dialogs/settingsdialog.cpp | 13 +++++++------ pica-client/dialogs/settingsdialog.h | 3 ++- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/pica-client/dialogs/settingsdialog.cpp b/pica-client/dialogs/settingsdialog.cpp index 7300d75..852cc95 100644 --- a/pica-client/dialogs/settingsdialog.cpp +++ b/pica-client/dialogs/settingsdialog.cpp @@ -32,24 +32,26 @@ SettingsDialog::SettingsDialog(QWidget *parent) : connect(rbEnableIncomingConns, SIGNAL(toggled(bool)), this, SLOT(toggleIncomingConnections(bool))); QLabel *lbAddr = new QLabel(tr("Public address for incoming connections"), this); - addr = new QLineEdit(tr("0.0.0.0"), this); + addr = new QComboBox(this); QLabel *lbPubPort = new QLabel(tr("External TCP port for incoming connections"), this); publicPort = new QSpinBox(this); QLabel *lbLocPort = new QLabel(tr("Local TCP port for incoming connections"), this); localPort = new QSpinBox(this); + addr->setEditable(true); + publicPort->setRange(1, 65535); localPort->setRange(1, 65535); publicPort->setValue(2298); localPort->setValue(2298); - QListWidget *lwAddrs = new QListWidget(this); QList hostIfAddrs = QNetworkInterface::allAddresses(); QHostAddress ifAddr; foreach (ifAddr, hostIfAddrs) - lwAddrs->addItem(ifAddr.toString()); + if (ifAddr.protocol() == QAbstractSocket::IPv4Protocol) + addr->addItem(ifAddr.toString()); directc2cLayout->addWidget(rbDisableDirectConns); @@ -61,7 +63,6 @@ SettingsDialog::SettingsDialog(QWidget *parent) : directc2cLayout->addWidget(publicPort); directc2cLayout->addWidget(lbLocPort); directc2cLayout->addWidget(localPort); - directc2cLayout->addWidget(lwAddrs); directc2cLayout->addStretch(1); //groupBox->setLayout(directc2cLayout); @@ -138,7 +139,7 @@ void SettingsDialog::loadSettings() break; } - addr->setText(st.loadValue("direct_c2c.public_addr", "0.0.0.0").toString()); + addr->lineEdit()->setText(st.loadValue("direct_c2c.public_addr", "0.0.0.0").toString()); publicPort->setValue(st.loadValue("direct_c2c.public_port", 2298).toInt()); localPort->setValue(st.loadValue("direct_c2c.local_port", 2298).toInt()); @@ -161,7 +162,7 @@ void SettingsDialog::storeSettings() st.storeValue("direct_c2c.state", QString::number(c2c_state)); - st.storeValue("direct_c2c.public_addr", addr->text()); + st.storeValue("direct_c2c.public_addr", addr->lineEdit()->text()); st.storeValue("direct_c2c.public_port", QString::number(publicPort->value())); st.storeValue("direct_c2c.local_port", QString::number(localPort->value())); } diff --git a/pica-client/dialogs/settingsdialog.h b/pica-client/dialogs/settingsdialog.h index 8c14ca1..9b11630 100644 --- a/pica-client/dialogs/settingsdialog.h +++ b/pica-client/dialogs/settingsdialog.h @@ -6,6 +6,7 @@ #include #include #include +#include class SettingsDialog : public QDialog { @@ -23,7 +24,7 @@ private: QRadioButton *rbEnableOutgoingConns; QRadioButton *rbEnableIncomingConns; - QLineEdit *addr; + QComboBox *addr; QSpinBox *publicPort; QSpinBox *localPort; -- cgit v1.2.1 From 9c0a5bf2bbd94539427ece7eb1cb8ea82c6c3dec Mon Sep 17 00:00:00 2001 From: Anton Date: Fri, 1 Dec 2017 18:21:49 +0400 Subject: pica-client: accepting direct connections --- pica-client/skynet.cpp | 25 ++++++++++++++++++++++++- pica-client/skynet.h | 1 + 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/pica-client/skynet.cpp b/pica-client/skynet.cpp index 7388634..a016b48 100644 --- a/pica-client/skynet.cpp +++ b/pica-client/skynet.cpp @@ -10,6 +10,7 @@ #include "history.h" #include "dhparam.h" #include "askpassword.h" +#include "settings.h" SkyNet::SkyNet() : nodes(config_dbname), QObject(0) @@ -42,6 +43,7 @@ PICA_client_init(&cbs); this->active_nodelink = NULL; this->acc = NULL; +this->listener = NULL; connect(this, SIGNAL(PeerCertificateReceived(QByteArray,QString,bool*)), this, SLOT(verify_peer_cert(QByteArray,QString,bool*)),Qt::DirectConnection); @@ -313,6 +315,9 @@ bool SkyNet::open_account() void SkyNet::Join(Accounts::AccountRecord &accrec) { + PICA_directc2c_config directc2c_cfg = PICA_DIRECTC2C_CFG_DISABLED; + Settings st(config_dbname); + skynet_account = accrec; QList noderecords = nodes.GetNodes(); @@ -329,6 +334,24 @@ void SkyNet::Join(Accounts::AccountRecord &accrec) return; } + directc2c_cfg = (PICA_directc2c_config)st.loadValue("direct_c2c.state", 1).toInt(); + + if (!listener && directc2c_cfg == PICA_DIRECTC2C_CFG_ALLOWINCOMING) + { + int pub_port = st.loadValue("direct_c2c.public_port", 2298).toInt(); + int loc_port = st.loadValue("direct_c2c.local_port", 2298).toInt(); + + int ret = PICA_new_listener(acc, + st.loadValue("direct_c2c.public_addr", "0.0.0.0").toString().toAscii().constData(), + pub_port, + loc_port, &listener); + if (ret != PICA_OK) + { + emit StatusMsg(QString(tr("Failed to open port %1 for incoming direct connections")).arg(loc_port), true); + directc2c_cfg = PICA_DIRECTC2C_CFG_CONNECTONLY; + } + } + if (!connecting_nodes.empty()) { for (int i = 0; i < connecting_nodes.size(); i++) @@ -343,7 +366,7 @@ void SkyNet::Join(Accounts::AccountRecord &accrec) struct PICA_c2n *c2n = NULL; ret = PICA_new_c2n(acc, noderecords[i].address.toUtf8().constData(), noderecords[i].port, - PICA_DIRECTC2C_CFG_DISABLED, NULL, &c2n); + directc2c_cfg, listener, &c2n); if (ret == PICA_OK) { diff --git a/pica-client/skynet.h b/pica-client/skynet.h index 3e03b87..5384023 100644 --- a/pica-client/skynet.h +++ b/pica-client/skynet.h @@ -64,6 +64,7 @@ private: QString status; struct PICA_c2n *active_nodelink; struct PICA_acc *acc; + struct PICA_listener *listener; Accounts::AccountRecord skynet_account; QMap > msgqueues; -- cgit v1.2.1