summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am8
-rw-r--r--[-rwxr-xr-x]PICA_client.c3860
-rw-r--r--[-rwxr-xr-x]PICA_client.h308
-rw-r--r--PICA_common.h4
-rw-r--r--PICA_id.c88
-rw-r--r--PICA_id.h2
-rw-r--r--PICA_log.c106
-rw-r--r--PICA_log.h14
-rw-r--r--[-rwxr-xr-x]PICA_msgproc.c92
-rw-r--r--[-rwxr-xr-x]PICA_msgproc.h16
-rw-r--r--[-rwxr-xr-x]PICA_node.c2020
-rw-r--r--[-rwxr-xr-x]PICA_node.h136
-rw-r--r--[-rwxr-xr-x]PICA_nodeaddrlist.c258
-rw-r--r--[-rwxr-xr-x]PICA_nodeaddrlist.h36
-rw-r--r--PICA_nodeconfig.c24
-rw-r--r--PICA_nodeconfig.h16
-rw-r--r--PICA_nodewait.c220
-rw-r--r--PICA_nodewait.h14
-rw-r--r--[-rwxr-xr-x]PICA_proto.h25
-rw-r--r--configure.ac2
-rwxr-xr-xdoc/TASKS.txt16
-rwxr-xr-xdoc/bugtraq.txt21
-rwxr-xr-xdoc/concepts.txt1
-rwxr-xr-xdoc/glossary.txt1
-rwxr-xr-xdoc/proto.txt38
-rw-r--r--pica-client/askpassword.cpp73
-rw-r--r--pica-client/askpassword.h8
-rw-r--r--pica-client/dialogs/settingsdialog.cpp168
-rw-r--r--pica-client/dialogs/settingsdialog.h44
-rw-r--r--pica-client/filetransfercontroller.cpp8
-rw-r--r--pica-client/main.cpp41
-rw-r--r--pica-client/mainwindow.cpp9
-rw-r--r--pica-client/mainwindow.h3
-rw-r--r--pica-client/msguirouter.cpp6
-rw-r--r--pica-client/msguirouter.h2
-rw-r--r--pica-client/nodethread.cpp11
-rw-r--r--pica-client/nodethread.h8
-rw-r--r--pica-client/pica-client.pro10
-rw-r--r--pica-client/picaactioncenter.cpp17
-rw-r--r--pica-client/picaactioncenter.h3
-rw-r--r--pica-client/settings.cpp69
-rw-r--r--pica-client/settings.h24
-rw-r--r--pica-client/skynet.cpp446
-rw-r--r--pica-client/skynet.h47
-rwxr-xr-xtests/test_clientbin35075 -> 0 bytes
-rw-r--r--[-rwxr-xr-x]tests/test_client.c546
46 files changed, 5631 insertions, 3238 deletions
diff --git a/Makefile.am b/Makefile.am
index 5ec82f5..bb19dac 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 \
@@ -90,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 \
@@ -103,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 \
@@ -119,12 +121,12 @@ moc_contactlistwidget.cpp \
moc_forgedcertdialog.cpp \
moc_mainwindow.cpp \
moc_msguirouter.cpp \
-moc_nodethread.cpp \
moc_picaactioncenter.cpp \
moc_picasystray.cpp \
moc_registeraccountdialog.cpp \
moc_filetransferdialog.cpp \
moc_skynet.cpp \
+moc_settingsdialog.cpp \
moc_viewcertdialog.cpp \
moc_showpicaiddialog.cpp \
moc_dhparam.cpp \
diff --git a/PICA_client.c b/PICA_client.c
index 50751d4..60ea14e 100755..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};
@@ -28,52 +34,83 @@ 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 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 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 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 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*);
+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*, 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);
+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 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);
+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[] = {
+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},
{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[] = {
+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},
{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},
+ {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},
+ {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 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[] =
+{
+};
// static int pem_passwd_cb(char *buf, int size, int rwflag, void *userdata)
//{
@@ -116,790 +153,1026 @@ return 1;
int PICA_get_id_from_cert_file(const char *cert_file, unsigned char *id)
{
-X509 *x;
-FILE *f;
+ X509 *x;
+ FILE *f;
+ int ret;
-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;
+ }
+
+ ret = PICA_id_from_X509(x, id);
+ X509_free(x);
-return PICA_id_from_X509(x, id);
+ return ret;
}
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;
-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_conninfo *ci, struct PICA_chaninfo **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_chaninfo *chnl,*ipt;
+ struct PICA_c2c *chnl;
-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
+ 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->timestamp = time(0);
+ chnl->acc = ci->acc;
-chnl->sck_data = -1;//prevent closing stdin when closing non-active connection
+ chnl->timestamp = time(0);
-chnl->read_buf = calloc(PICA_CHANREADBUFSIZE, 1);
+ chnl->sck_data = -1;//prevent closing stdin when closing non-active connection
-if (ci->chan_list_head)
+ chnl->read_buf = calloc(PICA_CHANREADBUFSIZE, 1);
+
+ 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;
+ chnl->state = PICA_C2C_STATE_NEW;
+ chnl->directc2c_state = PICA_DIRECTC2C_STATE_INACTIVE;
+
+ return 1;
}
-static int establish_data_connection(struct PICA_chaninfo *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;
+ struct PICA_proto_msg *mp;
-chnl->sck_data=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ mp = c2c_writebuf_push(chnl, PICA_PROTO_CONNID, PICA_PROTO_CONNID_SIZE);
+ if (mp)
+ {
+ if (chnl->outgoing)
+ {
+ 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->acc->id, PICA_ID_SIZE);//вызываемый
+ }
-{
-struct sockaddr_in addr=chnl->conn->srv_addr;
+ chnl->state = PICA_C2C_STATE_CONNID;
+ }
+ else
+ {
+ return PICA_ERRNOMEM;
+ }
-addr.sin_port = htons(ntohs(addr.sin_port));
+ return PICA_OK;
+}
-ret=connect( chnl->sck_data, (struct sockaddr*)&addr, sizeof(struct sockaddr_in));
+static int c2c_stage3_starttls(struct PICA_c2c *chnl)
+{
+ int ret;
+
+ chnl->ssl = SSL_new(chnl->acc->ctx);
-if (ret==SOCKET_ERROR)
+ if (!chnl->ssl)
{
- err_ret=PICA_ERRSOCK;
- goto error_ret;
+ return PICA_ERRSSL;
}
-}
-mp = c2c_writebuf_push( chnl, PICA_PROTO_CONNID, PICA_PROTO_CONNID_SIZE);
-if (mp)
+ ret = SSL_set_fd(chnl->ssl, chnl->sck_data);
+
+ if (!ret)
{
+ return PICA_ERRSSL;
+ }
+
+ 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)
- {
- memcpy(mp->tail, chnl->conn->id, PICA_ID_SIZE);//вызвывающий
- memcpy(mp->tail + PICA_ID_SIZE, chnl->peer_id, PICA_ID_SIZE);//вызываемый
- }
+ ret = SSL_connect(chnl->ssl);
else
- {
- memcpy(mp->tail, chnl->peer_id, PICA_ID_SIZE);//вызвывающий
- memcpy(mp->tail + PICA_ID_SIZE, chnl->conn->id, PICA_ID_SIZE);//вызываемый
- }
+ ret = SSL_accept(chnl->ssl);
+
+ if (ret == 0)
+ return PICA_ERRSSL;
+
+ if (ret < 0)
+ {
+ ret = SSL_get_error(chnl->ssl, ret);
+
+ if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
+ return PICA_ERRSSL;
}
-else
+
+ 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);
+
+ if (!chnl->peer_cert)
{
- err_ret=PICA_ERRNOMEM;
- goto error_ret;
+ return PICA_ERRNOPEERCERT;
}
-do
{
- err_ret = PICA_write_c2c(chnl);
- if (PICA_OK != err_ret)
- goto error_ret;
+ unsigned char temp_id[PICA_ID_SIZE];
+
+ if (PICA_id_from_X509(chnl->peer_cert, temp_id) == 0)
+ {
+ return PICA_ERRNOPEERCERT;
+ }
+
+ if (memcmp(temp_id, chnl->peer_id, PICA_ID_SIZE) != 0)
+ {
+ return PICA_ERRINVPEERCERT;
+ }
}
-while( chnl->write_pos > 0);
-chnl->ssl=SSL_new(chnl->conn->ctx);
-if (!chnl->ssl)
{
- //puts("SSL_new !- 0");//debug
- err_ret=PICA_ERRSSL;
- goto error_ret;
+ BIO *mem = BIO_new(BIO_s_mem());
+ char *cert_pem;
+ unsigned int cert_pem_nb;
+
+ PEM_write_bio_X509(mem, chnl->peer_cert);
+
+ 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);
+ return PICA_ERRINVPEERCERT;
+ }
+
+ BIO_free(mem);
}
-ret=SSL_set_fd(chnl->ssl, chnl->sck_data);
+ 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)
+{
+ int ret, err_ret;
+
+
+ chnl->sck_data = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+ IOCTLSETNONBLOCKINGSOCKET(chnl->sck_data, 1);
-if (!ret)
{
- //puts("SSL_set_fd returned 0");//debug
- err_ret=PICA_ERRSSL;
- goto error_ret_;
+ 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)
+ {
+ ret = c2c_stage2_connid(chnl);
+
+ if (ret != PICA_OK)
+ {
+ err_ret = ret;
+ goto error_ret;
+ }
+
+ return PICA_OK;
+ }
+
+ if ((err_ret = process_first_async_connect_result(ret)) != PICA_OK)
+ 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
+ return PICA_OK;
+error_ret:
+ callbacks.c2c_failed_cb(chnl->peer_id);
+ PICA_close_c2c(chnl);
+ return err_ret;
+}
-if (chnl->outgoing)
-ret=SSL_connect(chnl->ssl);
-else
-ret=SSL_accept(chnl->ssl);
+static unsigned int procmsg_C2CCONNREQ(unsigned char* buf, unsigned int nb, void* p)
+{
+ struct PICA_c2c *cc = (struct PICA_c2c *)p;
+ struct PICA_proto_msg *mp;
-//printf("verify result:%i\n",(int)SSL_get_verify_result(chnl->ssl));//debug
+ if (cc->state != PICA_C2C_STATE_WAITINGC2CPROTOVER)
+ return 0;
-if (ret!=1)
+ if (buf[2] == PICA_C2CPROTO_VER_HIGH && buf[3] == PICA_C2CPROTO_VER_LOW)
{
- //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_;
- }
+ //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';
-chnl->peer_cert=SSL_get_peer_certificate(chnl->ssl);
+ cc->state = PICA_C2C_STATE_ACTIVE;
-if (!chnl->peer_cert)
+ callbacks.c2c_established_cb(cc->peer_id);
+
+ if (cc->conn->directc2c_config == PICA_DIRECTC2C_CFG_ALLOWINCOMING)
+ PICA_send_directc2caddrlist(cc);
+ }
+ else
{
- err_ret=PICA_ERRNOPEERCERT;
- goto error_ret_;
+ //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;
+}
+
+static unsigned int procmsg_INITRESP_c2c(unsigned char* buf, unsigned int nb, void* p)
{
-unsigned char temp_id[PICA_ID_SIZE];
+ struct PICA_c2c *cc = (struct PICA_c2c *)p;
-if (PICA_id_from_X509(chnl->peer_cert, temp_id) == 0)
- {
- err_ret=PICA_ERRNOPEERCERT;
- goto error_ret_;
- }
+ if (cc->state != PICA_C2C_STATE_WAITINGREP)
+ return 0;
+
+ if (!cc->outgoing)
+ return 0;
-if (memcmp(temp_id, chnl->peer_id, PICA_ID_SIZE) != 0)
+ switch(buf[0])
{
- err_ret=PICA_ERRINVPEERCERT;
- goto error_ret_;
+ 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:
+ return 0; // -- ???
+ break;
+
+ default:
+ return 0;
}
+
+
+ return 1;
}
-/*
-DN_str=X509_NAME_oneline(X509_get_subject_name(chnl->peer_cert), 0, 0);
-if (!DN_str)
+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;
+
+ if (dc2c->addrpos >= *(uint16_t*)dc2c->addrlist)
+ return PICA_ERRNOTFOUND;
+
+ switch(dc2c->addrlist[dc2c->addrpos])
{
- //puts("no DN_str");//debug
- err_ret=PICA_ERRSSL;
- goto error_ret_;
+ 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;
+ 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;
+
+ ret = connect(dc2c->sck, (struct sockaddr*)&dc2c->addr, sizeof(dc2c->addr));
+
+ 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;
+
+ case PICA_PROTO_DIRECTC2C_IPV6:
+ break;
+
}
-if (!get_id_fromsubjstr(DN_str,&tmp_uid) || tmp_uid!=chnl->peer_id)
+ return PICA_OK;
+}
+
+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;
+
+ if (cc->conn->directc2c_config != PICA_DIRECTC2C_CFG_DISABLED)
{
- err_ret=PICA_ERRINVPEERCERT;
- goto error_ret_;
- }
-//puts(DN_str);//debug
+ 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));
+
+ if (!cc->direct)
+ 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);
+
+ 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;
-OPENSSL_free(DN_str);*/
+ 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);
+
+ if (ret == PICA_ERRNOTFOUND)
+ {
+ cc->directc2c_state = PICA_DIRECTC2C_STATE_FAILEDTOCONNECT;
+ }
+ }
+ return 1;
+}
+static unsigned int procmsg_PICA_PROTO_DIRECTC2C_FAILED(unsigned char* buf, unsigned int nb, void* p)
{
-BIO *mem = BIO_new(BIO_s_mem());
-char *cert_pem;
-unsigned int cert_pem_nb;
+ PICA_TRACEFUNC
+ struct PICA_c2c *cc = (struct PICA_c2c *)p;
+ int ret;
-PEM_write_bio_X509(mem, chnl->peer_cert);
+ if (cc->directc2c_state != PICA_DIRECTC2C_STATE_WAITINGINCOMING)
+ return 0;
-cert_pem_nb = (unsigned int)BIO_get_mem_data(mem, &cert_pem);
+ if (cc->conn->directc2c_config == PICA_DIRECTC2C_CFG_DISABLED)
+ return 0;
+
+ if (cc->outgoing != PICA_C2C_INCOMING)
+ return 0;
-if (callbacks.peer_cert_verify_cb(chnl->peer_id, (const char*)cert_pem, cert_pem_nb) == 0)
+ ret = directc2c_connect_next(cc->direct, cc);
+
+ if (ret == PICA_ERRNOTFOUND)
{
- BIO_free(mem);
- err_ret=PICA_ERRINVPEERCERT;
- goto error_ret_;
+ cc->directc2c_state = PICA_DIRECTC2C_STATE_FAILEDTOCONNECT;
}
-BIO_free(mem);
-}
+ cc->directc2c_state = PICA_DIRECTC2C_STATE_CONNECTING;
-chnl->state=PICA_CHANSTATE_ACTIVE;
+ return 1;
+}
+unsigned int procmsg_PICA_PROTO_DIRECTC2C_SWITCH(unsigned char* buf, unsigned int nb, void* p)
{
-unsigned long arg = 1;
+ PICA_TRACEFUNC
+ struct PICA_c2c *cc = (struct PICA_c2c *)p;
+ int ret;
-IOCTLSETNONBLOCKINGSOCKET(chnl->sck_data, &arg);
-}
+ if (cc->conn->directc2c_config == PICA_DIRECTC2C_CFG_DISABLED)
+ return 0;
-return PICA_OK;
+ if (cc->directc2c_state != PICA_DIRECTC2C_STATE_ACTIVE && cc->directc2c_state != PICA_DIRECTC2C_STATE_CONNECTING)
+ return 0;
-error_ret_:
-error_ret:
-callbacks.channel_failed(chnl->peer_id);
-PICA_close_channel(chnl);
-return err_ret;
+ cc->switched_to_directc2c_read = 1;
+
+ return 1;
}
-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_conninfo *ci=(struct PICA_conninfo *)p;
+ struct PICA_c2n *ci = (struct PICA_c2n *)p;
-switch(buf[0])
+ if (ci->state != PICA_C2N_STATE_WAITINGREP)
+ return 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_conninfo *ci=(struct PICA_conninfo *)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_chaninfo *_chnl;
-
+ {
+ 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);
+
+ ret = c2n_alloc_c2c( ci, &_chnl, peer_id, PICA_C2C_INCOMING);
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);
+ ret = c2c_start(_chnl);
- if (ret!=PICA_OK)
+ if (ret != PICA_OK)
return 1;
- callbacks.channel_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_conninfo *ci=(struct PICA_conninfo *)p;
-struct PICA_chaninfo *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_channel(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_conninfo *ci=(struct PICA_conninfo *)p;
-struct PICA_chaninfo *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;
- }
-
-if (!rq)
- return 0;// ERR_CHECK -левое сообщение, такой запрос не посылался
+ ipt = ipt->prev;
+ }
-ret=establish_data_connection(rq);
+ if (!rq)
+ return 0;// ERR_CHECK -левое сообщение, такой запрос не посылался
-if (ret!=PICA_OK)
- return 0;
+ ret = c2c_start(rq);
-callbacks.channel_established_cb(rq->peer_id);//*nchn=_chnl;
+ if (ret != PICA_OK)
+ return 0;
-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;
+ PICA_TRACEFUNC
+ 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),
+ 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),
+ );
+
+ 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,
+ );
+
+ 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;
+ );
+
+ 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_chaninfo *chan = (struct PICA_chaninfo *)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]);
+ 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
-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_pseudo_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_chaninfo *chan = (struct PICA_chaninfo *)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_conninfo *ci=(struct PICA_conninfo *)p;
-struct PICA_proto_msg *mp;
+ PICA_TRACEFUNC
+ 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_pseudo_bytes(mp->tail, 2);
+ }
+ else
+ return 0;
-return 1;
+ return 1;
}
-int PICA_deny_file(struct PICA_chaninfo *chan)
+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_pseudo_bytes(mp->tail, 2);
+ }
+ else
+ return PICA_ERRNOMEM;
-return PICA_OK;
+ 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;
+ 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_pseudo_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_chaninfo *chan = (struct PICA_chaninfo *)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_chaninfo *chan = (struct PICA_chaninfo *)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_chaninfo *chan = (struct PICA_chaninfo *)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_chaninfo *chan = (struct PICA_chaninfo *)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_cb(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_cb(chan->peer_id, 0);
+ }
-return 1;
+ return 1;
}
static unsigned int procmsg_FILECONTROL(unsigned char* buf, unsigned int nb, void* p)
{
-struct PICA_chaninfo *chan = (struct PICA_chaninfo *)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_cb(chan->peer_id, sender_cmd, receiver_cmd);
+
+ return 1;
}
#ifdef PICA_MULTITHREADED
@@ -907,23 +1180,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
@@ -932,48 +1205,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<CRYPTO_num_locks(); i++)
- mt_locks[i] = CreateMutex(NULL,FALSE,NULL);
+ for (i = 0; i < CRYPTO_num_locks(); i++)
+ mt_locks[i] = CreateMutex(NULL, FALSE, NULL);
-CRYPTO_set_locking_callback(locking_cb);
+ CRYPTO_set_locking_callback(locking_cb);
#else
-mt_locks = malloc(CRYPTO_num_locks()*sizeof(pthread_mutex_t));
+ mt_locks = malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
-memset(mt_locks,0,CRYPTO_num_locks()*sizeof(pthread_mutex_t));
+ memset(mt_locks, 0, CRYPTO_num_locks()*sizeof(pthread_mutex_t));
-for (i=0; i<CRYPTO_num_locks(); i++)
- pthread_mutex_init(&mt_locks[i],NULL);
+ for (i = 0; i < CRYPTO_num_locks(); i++)
+ pthread_mutex_init(&mt_locks[i], NULL);
-CRYPTO_set_id_callback(thread_id_cb);
-CRYPTO_set_locking_callback(locking_cb);
+ CRYPTO_set_id_callback(thread_id_cb);
+ CRYPTO_set_locking_callback(locking_cb);
#endif
-}
+ }
#endif
//ctx=SSL_CTX_new(TLSv1_method());
@@ -981,556 +1254,1525 @@ CRYPTO_set_locking_callback(locking_cb);
//;//ERR_CHECK
#ifndef WIN32
-signal(SIGPIPE, SIG_IGN);
+ signal(SIGPIPE, SIG_IGN);
#endif
-return 1;
+ 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_conninfo, который будет проинициализирован при успешном выполнении функции
-//Память, выделенная под структуру, освобождается при вызове 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_conninfo **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;
+}
+
+
+
+// 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;
-struct PICA_conninfo *cid;
-struct sockaddr_in a;
-DH *dh = NULL;
-FILE *dh_file = NULL;
+ int ret, ret_err, flag;
+ struct PICA_listener *lst = NULL;
+ struct sockaddr_in s;
-if (!(nodeaddr && CA_file && cert_file && pkey_file && ci))
- 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);
-cid=*ci=(struct PICA_conninfo*)calloc(sizeof(struct PICA_conninfo),1);//(1)
-if (!cid)
- return PICA_ERRNOMEM;
+ if (!lst)
+ return PICA_ERRNOMEM;
-cid->read_buf = calloc(PICA_CONNREADBUFSIZE, 1);//(2)
-if (!cid->read_buf)
- {
- ret_err = PICA_ERRNOMEM;
- goto error_ret_1;
- }
+ lst->public_addr_dns = strdup(public_addr);
-cid->ctx=SSL_CTX_new(TLSv1_2_method());//(3)
+ if (!lst->public_addr_dns)
+ {
+ ret_err = PICA_ERRNOMEM;
+ goto error_ret_0;
+ }
-if (!cid->ctx)
+ 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_ERRSSL;
- goto error_ret_2;
+ ret_err = PICA_ERRSOCK;
+ goto error_ret_1;
}
-dh_file = fopen(dh_param_file, "r");
+ flag = 1;
+ setsockopt(lst->sck_listener, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));
-if (dh_file)
- {
- dh = PEM_read_DHparams(dh_file, NULL, NULL, NULL);
- fclose(dh_file);
- }
+ IOCTLSETNONBLOCKINGSOCKET(lst->sck_listener, 1);
-if (1 != SSL_CTX_set_tmp_dh(cid->ctx, dh))
-{
- ret_err = PICA_ERRSSL;
- goto error_ret_2;
+ 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);
+
+error_ret_0: //(0)
+
+ free(lst);
+ *l = 0;
+
+ return ret_err;
}
-DH_free (dh);
+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;
+ DH *dh = NULL;
+ FILE *dh_file = NULL;
+ struct PICA_acc *a = NULL;
+
+
+ if (!(cert_file && pkey_file && dh_param_file && acc))
+ return PICA_ERRINVARG;
+
+ a = *acc = (struct PICA_acc*)calloc(sizeof(struct PICA_acc), 1);//(1)
+
+ if (!a)
+ return PICA_ERRNOMEM;
+
+ a->ctx = SSL_CTX_new(TLSv1_2_method());//(2)
+
+ if (!a->ctx)
+ {
+ ret_err = PICA_ERRSSL;
+ goto error_ret_1;
+ }
+
+ dh_file = fopen(dh_param_file, "r");
+
+ 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;
+ }
+
+ 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;
+ 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 (!PICA_get_id_from_cert_file(cert_file, cid->id))
- {
- ret_err=PICA_ERRINVCERT;
- goto error_ret_3;
- }
////<<
-if (password_cb)
- {
- SSL_CTX_set_default_passwd_cb(cid->ctx, password_cb);
- SSL_CTX_set_default_passwd_cb_userdata(cid->ctx,cid->id);
- }
+ 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(cid->ctx,cert_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_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_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)
-{
- ret_err = PICA_ERRSSL;
- goto error_ret_2;
+ if (ret != 1)
+ {
+ ret_err = PICA_ERRSSL;
+ 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;
}
+static int c2n_stage2_sendreq(struct PICA_c2n *c2n)
+{
+ PICA_TRACEFUNC
+ struct PICA_proto_msg *mp;
-cid->ssl_comm=SSL_new(cid->ctx);//(4)
+ puts("c2n_stage2_sendreq");//debug
-if (!cid->ssl_comm)
+ mp = c2n_writebuf_push(c2n, PICA_PROTO_INITREQ, PICA_PROTO_INITREQ_SIZE);
+
+ if (mp)
{
- ret_err=PICA_ERRSSL;
- goto error_ret_3;
+ mp->tail[0] = PICA_PROTO_VER_HIGH;
+ mp->tail[1] = PICA_PROTO_VER_LOW;
}
+ else
+ return PICA_ERRNOMEM;
+ c2n->state = PICA_C2N_STATE_WAITINGREP;
-//resolving name
+ return PICA_OK;
+}
+
+static int c2n_stage3_starttls(struct PICA_c2n *c2n)
{
- struct addrinfo h,*r;
+ PICA_TRACEFUNC
+ int ret;
- memset(&h,0,sizeof(struct addrinfo));
+ ret = SSL_set_fd(c2n->ssl_comm, c2n->sck_comm);
- h.ai_flags=0;
-#ifdef AI_IDN
- h.ai_flags = h.ai_flags | AI_IDN;
-#endif
-#ifdef 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;
+ if (ret != 1)
+ return PICA_ERRSSL;
- if (0!=getaddrinfo(nodeaddr,NULL,&h,&r))
- {
- ret_err=PICA_ERRDNSRESOLVE;
- goto error_ret_4;
- }
+ ret = SSL_accept(c2n->ssl_comm);
- 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);
+ if (ret == 0)
+ return PICA_ERRSSL;
+
+ if (ret < 0)
+ {
+ ret = SSL_get_error(c2n->ssl_comm, ret);
- freeaddrinfo(r);
+ if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
+ return PICA_ERRSSL;
+ }
+
+ c2n->state = PICA_C2N_STATE_WAITINGTLS;
+
+ return PICA_OK;
}
-cid->srv_addr=a;
+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);
-cid->sck_comm=socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//(5)
-if (cid->sck_comm==SOCKET_ERROR)
+ if (mp)
{
- ret_err=PICA_ERRSOCK;
- goto error_ret_4;
+ RAND_pseudo_bytes(mp->tail, 2);
}
+ else
+ return PICA_ERRNOMEM;
+
+ c2n->state = PICA_C2N_STATE_CONNECTED;
+
+ callbacks.c2n_established_cb(c2n);
+
+ return PICA_OK;
+}
+
+static int directc2c_stage2_starttls(struct PICA_directc2c *d, struct PICA_c2c *c2c)
+{
+ PICA_TRACEFUNC
+ int ret;
-cid->state = PICA_CONNSTATE_CONNECTING;
+ d->ssl = SSL_new(c2c->acc->ctx);
-ret=connect(cid->sck_comm,(struct sockaddr*)&a,sizeof(struct sockaddr_in));
+ 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==SOCKET_ERROR)
+ if (ret == 0)
+ return PICA_ERRSSL;
+
+ if (ret < 0)
{
- ret_err=PICA_ERRSOCK;
- goto error_ret_5;
+ 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;
+}
+
+/*адрес сервера, сертификат клиента и закрытый ключ*/
+//Осуществляет подключение к серверу по указанному адресу.
+//Аргументы:
+//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_c2n
+//Возвращаемое значение - код завершения
+//PICA_OK - успешное завершение функции
+//....
+
+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)
{
-struct PICA_proto_msg *mp;
+ PICA_TRACEFUNC
+ int ret, ret_err;
+ struct PICA_c2n *cid;
+ struct sockaddr_in a;
-mp = c2n_writebuf_push( cid, PICA_PROTO_INITREQ, PICA_PROTO_INITREQ_SIZE);
-
-if (mp)
+
+ 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->acc = acc;
+
+ cid->directc2c_config = direct_c2c_mode;
+
+ if (direct_c2c_mode == PICA_DIRECTC2C_CFG_ALLOWINCOMING)
{
- mp->tail[0] = PICA_PROTO_VER_HIGH;
- mp->tail[1] = PICA_PROTO_VER_LOW;
+ cid->directc2c_listener = l;
}
-else
+
+ cid->read_buf = calloc(PICA_CONNREADBUFSIZE, 1);//(2)
+ if (!cid->read_buf)
{
- ret_err = PICA_ERRNOMEM;
- goto error_ret_5;
+ ret_err = PICA_ERRNOMEM;
+ goto error_ret_1;
}
-}
-do
+ cid->ssl_comm = SSL_new(acc->ctx); //(3)
+
+ if (!cid->ssl_comm)
{
- ret = PICA_write_c2n(cid);
- if (ret != PICA_OK)
+ ret_err = PICA_ERRSSL;
+ goto error_ret_2;
+ }
+
+
+//resolving name
+ {
+ struct addrinfo h, *r;
+
+ memset(&h, 0, sizeof(struct addrinfo));
+
+ h.ai_flags = 0;
+#ifdef AI_IDN
+ h.ai_flags = h.ai_flags | AI_IDN;
+#endif
+#ifdef 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;
+
+ if (0 != getaddrinfo(nodeaddr, NULL, &h, &r))
{
- ret_err = ret;
- break;
+ ret_err = PICA_ERRDNSRESOLVE;
+ goto error_ret_4;
}
- ret = PICA_read_c2n(cid);
- if (ret != PICA_OK)
- {
- ret_err = ret;
- break;
- }
- //TODO Timeout
+
+ 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);
}
-while (cid->init_resp_ok == 0);
-if (cid->init_resp_ok != 1)
+ cid->srv_addr = a;
+
+ cid->sck_comm = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //(5)
+ if (cid->sck_comm == SOCKET_ERROR)
{
- 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_5;
+ ret_err = PICA_ERRSOCK;
+ goto error_ret_3;
}
-//printf("6\n");//debug
+ IOCTLSETNONBLOCKINGSOCKET(cid->sck_comm, 1);
+
+ cid->state = PICA_C2N_STATE_CONNECTING;
+
+ 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_err = process_first_async_connect_result(ret)) != PICA_OK)
+ goto error_ret_4;
+
+ /*
+ do
+ {
+ 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
+ }
+ 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
+ */ /*
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_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
//ERR_CHECK
ret_err=PICA_ERRSSL;
- goto error_ret_5;
- }
-cid->state = PICA_CONNSTATE_CONNECTED;//<<<!!!
+ goto error_ret_4;
+ }*/ /*
+cid->state = PICA_C2N_STATE_CONNECTED;//<<<!!!
{
struct PICA_proto_msg *mp;
mp = c2n_writebuf_push( cid, PICA_PROTO_CLNODELISTREQ, PICA_PROTO_CLNODELISTREQ_SIZE);
-
+
if (mp)
{
- RAND_bytes(mp->tail, 2);
- }
-}
-
-{
-unsigned long arg = 1;
-
-IOCTLSETNONBLOCKINGSOCKET(cid->sck_comm, &arg);
+ RAND_pseudo_bytes(mp->tail, 2);
+ }
}
+*/
-return PICA_OK;
-
+ return PICA_OK;
-error_ret_5: //(5)
- SHUTDOWN(cid->sck_comm);
- CLOSE(cid->sck_comm);
error_ret_4: //(4)
- SSL_free(cid->ssl_comm);
+ SHUTDOWN(cid->sck_comm);
+ CLOSE(cid->sck_comm);
error_ret_3: //(3)
- SSL_CTX_free(cid->ctx);
+ 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_create_channel(struct PICA_conninfo *ci,const unsigned char *peer_id,struct PICA_chaninfo **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_chaninfo *chnl;
+ PICA_TRACEFUNC
+ 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_CHANNEL_OUTGOING))
- return PICA_ERRNOMEM;
+ if (ci->state != PICA_C2N_STATE_CONNECTED)
+ return PICA_ERRINVARG;
-chnl=*chn;
+ if (!c2n_alloc_c2c(ci, chn, peer_id, PICA_C2C_OUTGOING))
+ return PICA_ERRNOMEM;
+
+ 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;
}
-int PICA_read(struct PICA_conninfo *ci,int timeout)
+static int process_async_ssl_errors(SSL *ssl, int ret)
{
-fd_set fds;
-struct timeval tv={0,1000};
-struct PICA_chaninfo *ipt, *kill_ptr = 0;
-int ret,nfds;
+ PICA_TRACEFUNC
+ if (ret == 0)
+ return PICA_ERRDISCONNECT;
-//puts("PICA_read<<");//debug
+ if (ret < 0)
+ switch(SSL_get_error(ssl, ret))
+ {
+ case SSL_ERROR_WANT_WRITE:
+ case SSL_ERROR_WANT_READ:
+ break;
+ default:
+ return PICA_ERRSSL;
+ };
-tv.tv_usec=timeout;
+ return PICA_OK;
+}
-FD_ZERO(&fds);
+static int process_first_async_connect_result(int connect_ret)
+{
+ PICA_TRACEFUNC
+ if (connect_ret == SOCKET_ERROR)
+ {
+#ifndef WIN32
+ if (errno == EINPROGRESS || errno == EINTR)
+ return PICA_OK;
+#else
+ if (WSAGetLastError() == WSAEWOULDBLOCK)
+ return PICA_OK;
+#endif
-nfds=ci->sck_comm;
-FD_SET(ci->sck_comm,&fds);
+ return PICA_ERRSOCK;
+ }
+
+ return PICA_OK;
+}
+
+static int check_async_connect_result(int sock, struct sockaddr* a, int addrlen)
+{
+ PICA_TRACEFUNC
+ 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;
-ipt=ci->chan_list_head;
+//puts("process_c2n()");//debug
-while(ipt)
+ switch(c2n->state)
{
- if (ipt->state==PICA_CHANSTATE_ACTIVE)
+ case PICA_C2N_STATE_NEW:
+ break;
+
+ case PICA_C2N_STATE_CONNECTING:
+
+ if (FD_ISSET(c2n->sck_comm, wfds))
{
- FD_SET(ipt->sck_data,&fds);
+ ret = check_async_connect_result(c2n->sck_comm, (struct sockaddr*)&c2n->srv_addr, sizeof(c2n->srv_addr));
- if (ipt->sck_data>nfds)
- nfds=ipt->sck_data;
- }
+ if (ret == PICA_OK)
+ {
+ ret = c2n_stage2_sendreq(c2n);
+ }
+ }
+ break;
- if (ipt->state != PICA_CHANSTATE_ACTIVE && (time(0) - ipt->timestamp) > PICA_CHAN_ACTIVATE_TIMEOUT)
+ case PICA_C2N_STATE_WAITINGREP:
+
+ if (FD_ISSET(c2n->sck_comm, wfds))
{
- kill_ptr = ipt;
+ ret = PICA_write_c2n(c2n);
}
- ipt=ipt->next;
+ if (FD_ISSET(c2n->sck_comm, rfds))
+ {
+ ret = PICA_read_c2n(c2n);
+ }
- if (kill_ptr)
+ if (ret == PICA_OK && c2n->init_resp_ok != 0)
{
- PICA_close_channel(kill_ptr);
- kill_ptr = 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;
+
+ if (sslret == SSL_ERROR_WANT_WRITE)
+ c2n->want_write = 1;
+ }
+ }
+
+ 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;
}
-//#warning "make sockets non-blocking!!!!"
+ return ret;
+}
-ret=select(nfds+1,&fds,0,0,&tv);
+static int process_c2c(struct PICA_c2c *c2c, fd_set *rfds, fd_set *wfds)
+{
+ int ret = PICA_OK;
-if (ret>0)
+ switch(c2c->state)
{
-
- if (FD_ISSET(ci->sck_comm,&fds))
+ case PICA_C2C_STATE_NEW:
+ break;
+
+ case PICA_C2C_STATE_CONNECTING:
+
+ if (FD_ISSET(c2c->sck_data, wfds))
{
- ret=PICA_read_c2n(ci);
- if (ret!=PICA_OK)
- return ret;
+ 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;
- ipt=ci->chan_list_head;
- while(ipt)
+ case PICA_C2C_STATE_CONNID:
+
+ if (FD_ISSET(c2c->sck_data, wfds))
+ {
+ ret = PICA_write_c2c(c2c);
+ }
+
+ if (c2c->write_pos == 0)
{
- if (ipt->state==PICA_CHANSTATE_ACTIVE && FD_ISSET(ipt->sck_data, &fds))
+ 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)
{
- if (PICA_OK != (ret = PICA_read_c2c(ipt)) )
+ sslret = SSL_get_error(c2c->ssl, sslret);
+
+ 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)
+ {
+ ret = PICA_ERRSSL;
+ }
+ else if (sslret == 1)
{
- puts("PICA_read_c2c() failed");//debug
- callbacks.channel_closed_cb(ipt->peer_id, ret);
- kill_ptr = ipt;
+ 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)
+ || c2c->directc2c_state == PICA_DIRECTC2C_STATE_ACTIVE && FD_ISSET(c2c->direct->sck, wfds))
+ {
+ if (c2c->write_pos > 0)
+ {
+ ret = PICA_write_c2c(c2c);
}
-
- ipt=ipt->next;
+ else if (c2c->sendfilestate == PICA_CHANSENDFILESTATE_SENDING)
+ {
+ ret = PICA_send_file_fragment(c2c);
+ }
+ }
- if (kill_ptr)
+ 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);
+ }
+
+ 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)
+ callbacks.c2c_failed_cb(c2c->peer_id);
+ else
+ callbacks.c2c_closed_cb(c2c->peer_id, ret);
+ }
+
+ return ret;
+}
+
+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];
+
+ 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)
{
- PICA_close_channel(kill_ptr);
- kill_ptr = 0;
+ return c2c;
}
}
+ c2c = c2c->next;
+ }
+ return NULL;
+}
+
+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);
+
+ if (!d->peer_cert)
+ return PICA_ERRNOPEERCERT;
+
+ if (PICA_id_from_X509(d->peer_cert, idbuf) == 0)
+ {
+ return PICA_ERRNOPEERCERT;
}
-//puts("PICA_read>>");//debug
-return PICA_OK;
+ if (memcmp(idbuf, c2c->peer_id, PICA_ID_SIZE) != 0)
+ {
+ return PICA_ERRINVPEERCERT;
+ }
+
+ return PICA_OK;
}
-int PICA_write(struct PICA_conninfo *ci)
+static void process_directc2c(struct PICA_c2n *c2n, fd_set *rfds, fd_set *wfds)
{
-struct PICA_chaninfo *ipt, *kill_ptr = 0;
-int ret = PICA_OK;
+ struct PICA_directc2c *d;
+ struct PICA_c2c *c2c;
+ int ret;
-//puts("PICA_write>>");//debug
+ //process accepted connections
+ if (c2n->directc2c_listener)
+ {
+ struct PICA_directc2c **pdprev;
-if (ci->write_pos)
- ret = PICA_write_c2n(ci);
+ d = c2n->directc2c_listener->accepted_connections;
+ pdprev = &c2n->directc2c_listener->accepted_connections;
-if (PICA_OK != ret)
- return ret;
+ while(d)
+ {
+ fprintf(stderr, "processing accepted direct connection\n");
+ if (d->state == PICA_DIRECTC2C_CONNSTATE_ACTIVE)
+ {
+ if ((c2c = find_matching_c2c(c2n, d)))
+ {
+ if (c2c->direct)
+ 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
+ {
+ d->state = PICA_DIRECTC2C_CONNSTATE_FAILED;
+ }
+ }
+ break;
+
+ case PICA_DIRECTC2C_CONNSTATE_WAITINGTLS:
+ if (FD_ISSET(d->sck, wfds) || FD_ISSET(d->sck, rfds))
+ {
+ ret = SSL_connect(d->ssl);
+
+ 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)
+ {
+ d->state = PICA_DIRECTC2C_CONNSTATE_FAILED;
+ }
-ipt=ci->chan_list_head;
+ break;
+ }
-while(ipt)
+ 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;
+
+ }
+ break;
+
+ case PICA_DIRECTC2C_CONNSTATE_FAILED:
+ 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:
+ c2c->directc2c_state = PICA_DIRECTC2C_STATE_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)
+{
+ PICA_TRACEFUNC
+ struct PICA_directc2c *nc;
+ int ret;
+
+ nc = calloc(1, sizeof(struct PICA_directc2c));
+
+ 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);
+
+ 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)
+ {
+ free(nc);
+ return;
+ }
+
+ if (ret < 0)
{
- if (ipt->write_pos)
+ ret = SSL_get_error(nc->ssl, ret);
+
+ if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE)
{
- if (PICA_OK != (ret = PICA_write_c2c(ipt)))
+ free(nc);
+ return;
+ }
+ }
+
+ nc->state = PICA_DIRECTC2C_CONNSTATE_WAITINGTLS;
+
+ nc->next = lst->accepted_connections;
+
+ lst->accepted_connections = nc;
+}
+
+static int process_listener_conn(struct PICA_directc2c *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)
{
- fprintf(stderr,"PICA_write_c2c() failed, ret = %i\n", ret);//debug
- callbacks.channel_closed_cb(ipt->peer_id, ret);
- kill_ptr = ipt;
+ conn->peer_cert = SSL_get_peer_certificate(conn->ssl);
+
+ if (!conn->peer_cert)
+ return PICA_ERRSSL;
+
+ conn->state = PICA_DIRECTC2C_CONNSTATE_ACTIVE;
+ return PICA_OK;
+ }
+
+ if (ret == 0)
+ return PICA_ERRSSL;
+
+ if (ret < 0)
+ {
+ 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;
}
}
- else if (ipt->sendfilestate == PICA_CHANSENDFILESTATE_SENDING)
- {
- if (PICA_OK != (ret = PICA_send_file_fragment(ipt)))
- {
- callbacks.channel_closed_cb(ipt->peer_id, ret);
- kill_ptr = ipt;
- }
- }
- ipt = ipt->next;
-
- if (kill_ptr)
+ }
+
+ return PICA_OK;
+}
+
+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))
+ {
+ SOCKET s;
+ struct sockaddr_in addr;
+ int addrsize = sizeof(struct sockaddr_in);
+
+ s = accept(lst->sck_listener, (struct sockaddr*)&addr, &addrsize);
+
+ if (s >= 0)
{
- PICA_close_channel(kill_ptr);
- kill_ptr = 0;
+ fprintf(stderr, "accepted direct connection on socket %i\n", s);
+ IOCTLSETNONBLOCKINGSOCKET(s, 1);
+ listener_add_connection(lst, s);
}
}
-//puts("PICA_write<<");//debug
-return PICA_OK;
+ conn = lst->accepted_connections;
+ pprevconn = &lst->accepted_connections;
+
+ while(conn)
+ {
+ int ret;
+ struct PICA_directc2c *kill_ptr = NULL;
+
+ if ((ret = process_listener_conn(conn, rfds, wfds)) != PICA_OK)
+ {
+ kill_ptr = conn;
+ }
+
+ //fprintf(stderr, "process_listener_conn() returned %i\n", ret);
+
+ if (!kill_ptr)
+ pprevconn = &conn->next;
+
+ conn = conn->next;
+
+ if (kill_ptr)
+ {
+ *pprevconn = kill_ptr->next;
+ PICA_close_directc2c(kill_ptr);
+ }
+
+ }
+
+ return PICA_OK;
+}
+
+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, int timeout)
+{
+ fd_set rfds, wfds;
+ struct timeval tv;
+ int ret, nfds = 0;
+ struct PICA_c2n **ic2n;
+
+//puts("PICA_event_loop");//debug
+
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+
+ FD_ZERO(&rfds);
+ FD_ZERO(&wfds);
+
+ ic2n = connections;
+
+ while(ic2n && *ic2n)
+ {
+ struct PICA_c2c *ic2c;
+ struct PICA_directc2c *ilstcon;
+
+ //printf("event_loop: adding c2n %p\n", *ic2n);//debug
+
+ fdset_add(&rfds, (*ic2n)->sck_comm, &nfds);
+
+ if ((*ic2n)->write_pos || (*ic2n)->state == PICA_C2N_STATE_CONNECTING
+ || (*ic2n)->want_write/*(*ic2n)->state == PICA_C2N_STATE_WAITINGTLS*/)
+ {
+ (*ic2n)->want_write = 0;
+ fdset_add(&wfds, (*ic2n)->sck_comm, &nfds);
+ }
+
+ if ((*ic2n)->directc2c_listener)
+ {
+ fdset_add(&rfds, (*ic2n)->directc2c_listener->sck_listener, &nfds);
+
+ ilstcon = (*ic2n)->directc2c_listener->accepted_connections;
+
+ while (ilstcon)
+ {
+ fdset_add(&rfds, ilstcon->sck, &nfds);
+
+ if (ilstcon->want_write)
+ fdset_add(&wfds, ilstcon->sck, &nfds);
+ ilstcon->want_write = 0;
+
+ ilstcon = ilstcon->next;
+ }
+ }
+
+ ic2c = (*ic2n)->chan_list_head;
+
+ while(ic2c)
+ {
+ if (ic2c->state >= PICA_C2C_STATE_CONNECTING)
+ {
+ fdset_add(&rfds, ic2c->sck_data, &nfds);
+
+ 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)
+ {
+ fdset_add(&rfds, 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;
+ }
+
+ ic2n++;
+ }
+
+
+ ret = select(nfds + 1, &rfds, &wfds, NULL, &tv);
+
+ 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
+ }
+
+//printf("select() returned %i\n", ret);//debug
+
+//processing listeners, c2n and c2c connections
+
+ ic2n = connections;
+
+ while(ic2n && *ic2n)
+ {
+ struct PICA_c2c *ic2c;
+
+ //processing current c2n
+
+ ret = process_c2n(*ic2n, &rfds, &wfds);
+
+ if (ret != PICA_OK)
+ {
+ if ((*ic2n)->state == PICA_C2N_STATE_CONNECTED)
+ callbacks.c2n_closed_cb(*ic2n, ret);
+ else
+ callbacks.c2n_failed_cb(*ic2n, ret);
+
+ PICA_close_c2n(*ic2n);
+ }
+ else
+ {
+ struct PICA_c2c *kill_ptr = 0;
+
+ //processing listener associated with current c2n
+ if ((*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);
+ }
+ }
+
+
+ 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;
+ }
+ }
+
+ //processing direct c2c connections associated with current c2n
+ if ((*ic2n)->directc2c_config != PICA_DIRECTC2C_CFG_DISABLED)
+ {
+ process_directc2c(*ic2n, &rfds, &wfds);
+ }
+ }
+ ic2n++;
+ }
+
+ 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()
-//int PICA_read_ssl()
-
-int PICA_write_c2n(struct PICA_conninfo *ci)
+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_CONNSTATE_CONNECTING == ci->state)
- ret = PICA_write_socket( ci->sck_comm, ci->write_buf, &ci->write_pos);
-else if (PICA_CONNSTATE_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;
+ return ret;
}
-int PICA_write_c2c(struct PICA_chaninfo *chn)
+int PICA_write_c2c(struct PICA_c2c *chn)
{
-int ret = PICA_ERRINVARG;
+ 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);
+ }
+
+ if (PICA_C2C_STATE_CONNID == chn->state)
+ ret = PICA_write_socket(chn->sck_data, chn->write_buf, &chn->write_pos);
+ else
+ {
+ SSL *ssl_to_write = chn->ssl;
+
+ if (chn->switched_to_directc2c_write)
+ ssl_to_write = chn->direct->ssl;
-if (PICA_CHANSTATE_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 (chn->directc2c_write_barrier_pos)
+ {
+ if (chn->directc2c_write_before_barrier_pos == 0)
+ chn->directc2c_write_before_barrier_pos = chn->directc2c_write_barrier_pos;
+
+ 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->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;
+ 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:
@@ -1540,597 +2782,703 @@ 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_chaninfo *chn)
+int PICA_read_c2c(struct PICA_c2c *chn)
{
-int ret;
+ int ret;
+ SSL *ssl_to_read = chn->ssl;
-if (chn->state != PICA_CHANSTATE_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);
+ }
+
+ if (chn->switched_to_directc2c_read)
+ ssl_to_read = chn->direct->ssl;
-//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(ssl_to_read, 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;
+ const struct PICA_msginfo *msgs;
+ unsigned int nmsgs;
+
+ nmsgs = MSGINFO_MSGSNUM(c2c_messages);
+ msgs = c2c_messages;
+
+ if(!PICA_processdatastream(chn->read_buf, &(chn->read_pos ), chn, msgs, nmsgs))
+ return PICA_ERRSERV;
}
-return ret;
+ return ret;
}
//функция читает и обрабатывает данные, приходящие от сервера по управляющему соединению.
-int PICA_read_c2n(struct PICA_conninfo *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_CONNSTATE_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)
- 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_CONNSTATE_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_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_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;
-
-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_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;
-
-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)
+ {
+ 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;
+ }
+ else
+ return 0;
}
-
-if (chn->write_buflen - chn->write_pos < size)
+
+ 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_directc2caddrlist(struct PICA_c2c *chn)
+{
+ PICA_TRACEFUNC
+ if (chn->conn->directc2c_config == PICA_DIRECTC2C_CFG_ALLOWINCOMING && chn->conn->directc2c_listener)
{
- unsigned char*p;
- p = realloc(chn->write_buf, size + chn->write_pos);
-
- if (p)
+ struct PICA_proto_msg *mp;
+ //TODO send all possible interface addresses, not one
+ unsigned int len = PICA_PROTO_DIRECTC2C_ADDRLIST_ITEM_IPV4_SIZE;
+
+ if ((mp = c2c_writebuf_push(chn, PICA_PROTO_DIRECTC2C_ADDRLIST, len + 4)))
{
- chn->write_buf = p;
- chn->write_buflen = size + chn->write_pos;
+ *((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);
+
+ chn->directc2c_state = PICA_DIRECTC2C_STATE_WAITINGINCOMING;
}
+ }
+
+ return PICA_OK;
+}
+
+static int PICA_send_directc2cfailed(struct PICA_c2c *chn)
+{
+ PICA_TRACEFUNC
+ 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 0;
+ return PICA_ERRNOMEM;
+
+ return PICA_OK;
+}
+
+static int PICA_send_directc2c_switch(struct PICA_c2c *chn)
+{
+ PICA_TRACEFUNC
+ 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);
}
-
-mp = (struct PICA_proto_msg *)(chn->write_buf + chn->write_pos);
-mp->head[0] = mp->head[1] = msgid;
-chn->write_pos += size;
+ else
+ return PICA_ERRNOMEM;
+
+ chn->directc2c_write_barrier_pos = chn->write_pos;
-return mp;
+ return PICA_OK;
}
-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;
+ 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_chaninfo *chn, const char *filepath)
+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_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;
+ 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_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;
+ 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_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;
+ 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_chaninfo *chan, int senderctl, int 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_chaninfo *chn)
+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_cb(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_cb(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_directc2c(struct PICA_directc2c *d)
+{
+ PICA_TRACEFUNC
+ if (d->peer_cert)
+ X509_free(d->peer_cert);
+
+ if (d->addrlist)
+ free(d->addrlist);
+
+ SSL_free(d->ssl);
+ SHUTDOWN(d->sck);
+ CLOSE(d->sck);
-void PICA_close_channel(struct PICA_chaninfo *chn)
+ d->next = NULL;
+
+ free(d);
+}
+
+void PICA_close_c2c(struct PICA_c2c *chn)
{
-struct PICA_chaninfo *ipt;
+ struct PICA_c2c *ipt;
-fprintf(stderr, "PICA_close_channel(%p)\n", chn);//debug
-
-ipt=chn->conn->chan_list_head;
-//puts("PICA_close_channel_chkp0");//debug
-while(ipt)
+ PICA_TRACEFUNC
+
+ ipt = chn->conn->chan_list_head;
+//puts("PICA_close_c2c_chkp0");//debug
+ 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_channel_chkp1");//debug
+//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_channel_chkp2");//debug
+//puts("PICA_close_c2c_chkp2");//debug
-if (chn->ssl)
- SSL_shutdown(chn->ssl);
- //puts("PICA_close_channel_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_channel_chkp4");//debug
-SHUTDOWN(chn->sck_data);
-//puts("PICA_close_channel_chkp5");//debug
-CLOSE(chn->sck_data);
-//puts("PICA_close_channel_chkp6");//debug
-free(chn);
-//puts("PICA_close_channel_chkp7");//debug
+//puts("PICA_close_c2c_chkp4");//debug
+ SHUTDOWN(chn->sck_data);
+//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
}
-void PICA_close_connection(struct PICA_conninfo *cid)
+void PICA_close_c2n(struct PICA_c2n *cid)
{
-struct PICA_chaninfo *ipt;
+ PICA_TRACEFUNC
+ struct PICA_c2c *ipt;
-while((ipt = cid->chan_list_head))
- PICA_close_channel(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_CTX_free(cid->ctx);
-free(cid->read_buf);
+ SSL_free(cid->ssl_comm);
+ SHUTDOWN(cid->sck_comm);
+ CLOSE(cid->sck_comm);
+
+ free(cid->read_buf);
+
+ if (cid->write_buf)
+ free(cid->write_buf);
+
+ free(cid);
+}
+
+void PICA_close_acc(struct PICA_acc *a)
+{
+ SSL_CTX_free(a->ctx);
+ free(a);
+}
+
-if (cid->write_buf)
- free(cid->write_buf);
+void PICA_close_listener(struct PICA_listener *l)
+{
+ CLOSE(l->sck_listener);
+ free(l->public_addr_dns);
-free(cid);
+ while(l->accepted_connections)
+ {
+ struct PICA_directc2c *c = l->accepted_connections;
+ l->accepted_connections = c->next;
+ PICA_close_directc2c(c);
+ }
+
+ 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
-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
-{
-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_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
-{
-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
index db1a52d..b56e034 100755..100644
--- a/PICA_client.h
+++ b/PICA_client.h
@@ -53,7 +53,7 @@ typedef unsigned __int64 uint64_t;
#define OPENSSL_THREAD_DEFINES
#include <openssl/opensslconf.h>
#if defined(OPENSSL_THREADS)
- // thread support enabled
+// thread support enabled
#else
#error "THREAD SUPPORT IS NOT ENABLED IN OPENSSL!"
#endif
@@ -87,6 +87,10 @@ typedef unsigned __int64 uint64_t;
#define PICA_ERRFILEOPEN -20
#define PICA_ERRFILEIO -21
+#define PICA_ERRINVPKEYPASSPHRASE -22
+#define PICA_ERRINVPKEYFILE -23
+#define PICA_ERRTIMEDOUT -24
+
//#define PICA_CHNMSGBUFLEN 104
#define PICA_CHANREADBUFSIZE 65536
@@ -95,10 +99,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_CONNECTED 19
-
#define PICA_CHANSENDFILESTATE_IDLE 0
#define PICA_CHANSENDFILESTATE_SENTREQ 20
#define PICA_CHANSENDFILESTATE_SENDING 22
@@ -109,151 +109,265 @@ 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
+#define PICA_C2C_OUTGOING 1
+#define PICA_DIRECTC2C_INCOMING 0
+#define PICA_DIRECTC2C_OUTGOING 1
+
+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;
+};
-#define PICA_CHANNEL_INCOMING 0
-#define PICA_CHANNEL_OUTGOING 1
+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
+};
-struct PICA_conninfo;
-struct PICA_chaninfo;
+enum PICA_directc2c_config
+{
+ PICA_DIRECTC2C_CFG_DISABLED,
+ PICA_DIRECTC2C_CFG_CONNECTONLY,
+ PICA_DIRECTC2C_CFG_ALLOWINCOMING
+};
-struct PICA_conninfo
+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;
-SOCKET sck_comm;
-SSL* ssl_comm;
+ 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;
+
+
+ enum PICA_c2n_state state;
+ enum PICA_directc2c_config directc2c_config;
+ struct PICA_listener *directc2c_listener;
+
+ 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;
+
+ 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
+{
+ PICA_C2C_STATE_NEW = 0,
+ PICA_C2C_STATE_CONNECTING,
+ PICA_C2C_STATE_CONNID,
+ PICA_C2C_STATE_WAITINGTLS,
+ PICA_C2C_STATE_WAITINGREP,
+ PICA_C2C_STATE_WAITINGC2CPROTOVER,
+ PICA_C2C_STATE_ACTIVE
+};
+enum PICA_directc2c_state
+{
+ PICA_DIRECTC2C_STATE_INACTIVE,
+ PICA_DIRECTC2C_STATE_CONNECTING,
+ PICA_DIRECTC2C_STATE_FAILEDTOCONNECT,
+ PICA_DIRECTC2C_STATE_WAITINGINCOMING,
+ PICA_DIRECTC2C_STATE_ACTIVE
+};
-int state;
+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
+};
-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_directc2c
+{
+ int is_outgoing;
+ SOCKET sck;
+ SSL *ssl;
+ X509 *peer_cert;
+ int want_write;
-struct PICA_chaninfo *chan_list_head;
-struct PICA_chaninfo *chan_list_end;
+ uint8_t *addrlist;
+ int addrpos;
-int init_resp_ok;
-unsigned char node_ver_major, node_ver_minor;
+ struct sockaddr_in addr;
+
+ enum PICA_directc2c_connection_state state;
+
+ struct PICA_directc2c *next;
};
-struct PICA_chaninfo
+struct PICA_c2c
{
-struct PICA_conninfo *conn;//соединение с сервером, через которое установлен данный логический канал связи
-unsigned char peer_id[PICA_ID_SIZE];
-SOCKET sck_data;
-SSL *ssl;
-int outgoing;//1 если создание канала инициировано локальным клиентом, 0 - если собеседником
-X509 *peer_cert;
+ const struct PICA_acc *acc;
+ struct PICA_c2n *conn;//соединение с сервером, через которое установлен данный логический канал связи
+ unsigned char peer_id[PICA_ID_SIZE];
+ SOCKET sck_data;
+ SSL *ssl;
+
+ struct PICA_directc2c *direct;
+
+ 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_chaninfo *next;
-struct PICA_chaninfo *prev;
-int 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;
+ enum PICA_directc2c_state directc2c_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;
+//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;
+ int want_write;
+ unsigned int directc2c_write_barrier_pos;
+ unsigned int directc2c_write_before_barrier_pos;
+};
+
+struct PICA_listener
+{
+ const 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_directc2c *accepted_connections;
};
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 (*channel_established_cb)(const unsigned char *peer_id);
-//создать канал не удалось
-void (*channel_failed)(const unsigned char *peer_id);
+ void (*c2c_established_cb)(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);
+ 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 (*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);
+ 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_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);
+
+ void (*c2n_failed_cb)(struct PICA_c2n *c2n, int error);
+
+ void (*c2n_closed_cb)(struct PICA_c2n *c2n, int error);
+
+ void (*listener_error_cb)(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_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_conninfo **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_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_new_c2c(struct PICA_c2n *ci, const unsigned char *peer_id, struct PICA_listener *l, struct PICA_c2c **chn);
-int PICA_read(struct PICA_conninfo *ci,int timeout);
-int PICA_write(struct PICA_conninfo *ci);
+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_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_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);
+// <<<////
-//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);
-// 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);
+//connections, listeners - NULL-terminated arrays of pointers to appropriate structures
+// timeout - timeout in milliseconds
+int PICA_event_loop(struct PICA_c2n **connections, int timeout);
-void PICA_close_channel(struct PICA_chaninfo *chn);
-void PICA_close_connection(struct PICA_conninfo *cid);
+int PICA_send_msg(struct PICA_c2c *chn, char *buf, unsigned int len);
+//filename - ASCII or UTF-8 encoded string
+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_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_c2c(struct PICA_c2c *chn);
+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
}
#endif
diff --git a/PICA_common.h b/PICA_common.h
index 49d18f1..5c0882a 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
#if defined(WIN32) || defined (__APPLE__)
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 <openssl/bio.h>
#include <string.h>
-
+
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
index 1564af7..00d19c0 100755..100644
--- 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<nmsg;i++)
- if (buf[0]==(unsigned char)msgs[i].msgid)
+ for (i = 0; i < nmsg; i++)
+ if (buf[0] == (unsigned char)msgs[i].msgid)
{
- if (msgs[i].fixedsz==PICA_MSG_FIXED_SIZE)
- return msgs[i].sz;
- else if (msgs[i].fixedsz==PICA_MSG_VAR_SIZE)
+ if (msgs[i].fixedsz == PICA_MSG_FIXED_SIZE)
+ return msgs[i].sz;
+ else if (msgs[i].fixedsz == PICA_MSG_VAR_SIZE)
{
- if (nb>=(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<msgs[i].sz;j++)
- ((char*)&tail_len)[sizeof(int)-1-j]=buf[2+j];
+ for (j = 0; j < msgs[i].sz; j++)
+ ((char*)&tail_len)[sizeof(int) - 1 - j] = buf[2 + j];
#else
- for (j=0;j<msgs[i].sz;j++)
- ((char*)&tail_len)[j]=buf[2+j];
+ for (j = 0; j < msgs[i].sz; j++)
+ ((char*)&tail_len)[j] = buf[2 + j];
#endif
- return 2+msgs[i].sz+tail_len;
+ return 2 + msgs[i].sz + tail_len;
}
- else
- return UINT_MAX;
+ else
+ return UINT_MAX;
}
}
-return 0;
+ return 0;
}
//Определяет тип сообщения размера size, находящегося в буфере buf, вызывает соответствующий обработчик и передает обработчику аргумент arg. Возвращает значение, которое вернула функция-обработчик сообщения. Если тип сообщения неизвестен, возвращает 0
-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)
{
-int i;
+ int i;
-if (buf[0]!=buf[1])
- return 0;
+ if (buf[0] != buf[1])
+ return 0;
-for (i=0;i<nmsg;i++)
- if (buf[0]==(unsigned char)msgs[i].msgid)
- return msgs[i].msgprocfn(buf,size,arg);
+ for (i = 0; i < nmsg; i++)
+ if (buf[0] == (unsigned char)msgs[i].msgid)
+ return msgs[i].msgprocfn(buf, size, arg);
-return 0;
+ return 0;
}
-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)
{
- while(*read_pos)
- {
- unsigned int uret;
- uret=PICA_msggetsize(buf,*read_pos,msgs,nmsg);
+ while(*read_pos)
+ {
+ unsigned int uret;
+ uret = PICA_msggetsize(buf, *read_pos, msgs, nmsg);
- if (!uret)
- return 0;
+ if (!uret)
+ return 0;
- if (uret > *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
index 0bf144e..5c8311c 100755..100644
--- 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
index d4bc5d9..951e8d9 100755..100644
--- a/PICA_node.c
+++ b/PICA_node.c
@@ -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,98 +118,102 @@ 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)
+ 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;
}
-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);
+ 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);
+ 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))
{
@@ -223,61 +227,61 @@ else
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;
}
-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;
}
-{
-struct client *c;
+ {
+ struct client *c;
//проверка IP адреса.
//IP адрес должен совпадать с адресом клиента в управляющем соединении
-if (link->state==PICA_CCLINK_LOCAL_WAITCONNCLE || link->state==PICA_CCLINK_N2NCLE_WAITCONNCLE)
+ 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)
+ 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)
+ 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);
}
@@ -288,9 +292,9 @@ if (link->state==PICA_CCLINK_LOCAL_WAITCONNCLE)
}
}
-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);
@@ -301,40 +305,40 @@ if (link->state==PICA_CCLINK_N2NCLE_WAITCONNCLE)
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);
+ 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);
+ 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))
{
@@ -349,61 +353,61 @@ else
return 0;
}
-return 1;
+ return ;
}
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)
+ if (mp)
memcpy(mp->tail, id, PICA_ID_SIZE);
}
int nodelink_send_searchreq(const unsigned char *id)
{
-if (!nodelink_list_count)
+ if (!nodelink_list_count)
return 0;
-LISTMAP(nodelink,nodelink,mapfunc_sendsearchreq,id);
+ LISTMAP(nodelink, nodelink, mapfunc_sendsearchreq, id);
-return 1;
+ 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))
{
- 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;
}
//отправить o _CONNREQINC
- if ((mp = client_wbuf_push(o,PICA_PROTO_CONNREQINC,PICA_PROTO_CONNREQINC_SIZE)))
+ 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);
+ 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
@@ -413,225 +417,226 @@ if ((o = client_tree_search(callee_id)))
return 1;//сообщение отправить не удалось, но все равно возвращаем 1
}
-if (cclink_list_findwaitsearch(callee_id)/*search request for this id is already in progress*/
+ 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);
+ 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);
}
-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)
+ if (!link)
return 0;
-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)
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)
+ 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;
}
-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)))
+ if ((mp = client_wbuf_push(caller, PICA_PROTO_NOTFOUND, PICA_PROTO_NOTFOUND_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)))
+ 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);
}
}
-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_pseudo_bytes(mp->tail, 2);
}
-else
+ 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_pseudo_bytes(mp->tail, 2);
}
-else
+ 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')
+ 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)
+ 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;
+ *((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
+ else
return 0;
-mp = nodelink_wbuf_push(n, PICA_PROTO_NODELISTREQ, PICA_PROTO_NODELISTREQ_SIZE);
-if (mp)
+ 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
+ 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");
}
else
- {//peer node has older software version
+ {
+ //peer node has older software version
PICA_info("peer node has older protocol version");
}
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])
+ 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)));
+ PICA_debug1("NEWNODE_IPV4: ip %.16s port %hu\n", inet_ntoa(*(struct in_addr*)(buf + 2)), ntohs(*(in_port_t*)(buf + 6)));
{
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);
+ 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
{
@@ -647,38 +652,38 @@ switch (buf[0])
return 0;
}
- sprintf(na.addr,"%.16s",inet_ntoa(*(struct in_addr*)&na_ipv4.addr));
+ 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));
+ nodelink_attach_nodeaddr(n, na_ipv4.magick, &na_ipv4, sizeof(struct PICA_nodeaddr_ipv4));
}
break;
case PICA_PROTO_NEWNODE_IPV6:
- #warning "TO DO"
+#warning "TO DO"
break;
case PICA_PROTO_NEWNODE_DNS:
- #warning "TODO"
+#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;
@@ -688,34 +693,35 @@ switch(buf[0])
break;
}
-nl_buf = (unsigned char*)malloc(65536);
+ nl_buf = (unsigned char*)malloc(65536);
-if (!nl_buf)
+ 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;
-}
+ 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
+ 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 )
+ ((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_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;
}
@@ -723,50 +729,50 @@ while(nlp && nl_size < 65532)//MAP
nlp = nlp->next;
}
-switch(buf[0])
+ switch(buf[0])
{
case PICA_PROTO_CLNODELISTREQ:
- mp = client_wbuf_push( c, PICA_PROTO_CLNODELIST, nl_size+4);
+ 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);
+ 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;
+ listleft -= PICA_PROTO_NODELIST_ITEM_IPV4_SIZE;
break;
}
continue;
@@ -779,17 +785,17 @@ while(listleft)
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));
+ sprintf(na.addr, "%.16s", inet_ntoa(*(struct in_addr*)&na_ipv4.addr));
na.port = ntohs(na_ipv4.port);
//nodewait_start_connection(&na);
@@ -811,7 +817,7 @@ while(listleft)
inet_ntoa(*(struct in_addr*)&na_ipv4.addr), ntohs(na_ipv4.port)
);
}
- listleft-=PICA_PROTO_NODELIST_ITEM_IPV4_SIZE;
+ listleft -= PICA_PROTO_NODELIST_ITEM_IPV4_SIZE;
break;
}
if (!skip_save)
@@ -819,154 +825,154 @@ while(listleft)
}
}
-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);
}
}
-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);
}
}
-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);
}
}
-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);
}
}
-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);
}
}
-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);
}
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)
+ 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)
{
@@ -979,9 +985,9 @@ if (cc && cc->state==PICA_CCLINK_N2NCLE_ACTIVE)
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)
{
@@ -989,65 +995,65 @@ if (cc && cc->state==PICA_CCLINK_N2NCLR_ACTIVE)
return 1;
}
- memcpy(cc->buf_p2p1 + cc->bufpos_p2p1, buf + 4 + 2 * PICA_ID_SIZE,datalen);
+ 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);
}
-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)
+ && c->state == PICA_CCLINK_N2NCLR_WAITSEARCH)
return c;
- c=c->next;
+ 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;
+ c = c->next;
}
-return 0;
+ return 0;
}
void cclink_list_delete(struct cclink *l)
{
-PICA_debug1("cclink_list_delete(%p)", (void*)l);
+ PICA_debug1("cclink_list_delete(%p)", (void*)l);
//удаление из глобального списка
-if (l->prev)
- l->prev->next=l->next;
-else
- cclink_list_head=l->next;
+ 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)
{
@@ -1056,10 +1062,10 @@ if (l->p1)
PICA_debug2("closed socket %i", l->sck_p1);
}
}//caller_id is stored in p1 structure
-else
+ else
free(l->caller_id);//caller_id was allocated by malloc
-if (l->p2)
+ if (l->p2)
{
if (l->sck_p2)
{
@@ -1068,25 +1074,25 @@ if (l->p2)
PICA_debug2("closed socket %i", l->sck_p2);
}
}
-else
+ else
free(l->callee_id);
-if (l->buf_p1p2)
+ if (l->buf_p1p2)
free(l->buf_p1p2);
-if (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;
@@ -1104,11 +1110,11 @@ 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;
@@ -1127,51 +1133,51 @@ 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)
+ 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->state = PICA_CCLINK_LOCAL_WAITREP;
l->caller_id = l->p1->id;
l->callee_id = l->p2->id;
}
@@ -1180,13 +1186,13 @@ if (l)
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->state = PICA_CCLINK_N2NCLR_WAITSEARCH;
l->caller_id = l->p1->id;
l->callee_id = (unsigned char*)malloc(PICA_ID_SIZE);
@@ -1199,22 +1205,22 @@ if (l)
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->state = PICA_CCLINK_N2NCLE_WAITREP;
l->caller_id = (unsigned char*)malloc(PICA_ID_SIZE);
if (l->caller_id == NULL)
@@ -1229,17 +1235,17 @@ if (l)
void cclink_setwaitconn(struct cclink *ccl)
{
-switch (ccl->state)
+ switch (ccl->state)
{
case PICA_CCLINK_LOCAL_WAITREP:
- ccl->state=PICA_CCLINK_LOCAL_WAITCONNCLE;
+ ccl->state = PICA_CCLINK_LOCAL_WAITCONNCLE;
//
break;
case PICA_CCLINK_N2NCLR_WAITREP:
- ccl->state=PICA_CCLINK_N2NCLR_WAITCONNCLR;
+ ccl->state = PICA_CCLINK_N2NCLR_WAITCONNCLR;
break;
case PICA_CCLINK_N2NCLE_WAITREP:
- ccl->state=PICA_CCLINK_N2NCLE_WAITCONNCLE;
+ ccl->state = PICA_CCLINK_N2NCLE_WAITCONNCLE;
break;
default:
;
@@ -1248,9 +1254,9 @@ switch (ccl->state)
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);
@@ -1258,14 +1264,14 @@ if (!ccl->buf_p1p2 || !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;
@@ -1304,81 +1310,81 @@ switch(ccl->state)
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)
+ 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)))
-{
+ 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)
+ if (ret == -1)
PICA_fatal("unable to bind socket - %s", strerror(errno));
-ret = listen(listen_comm_sck,20);
-if (ret == -1)
+ 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)
+ if (ret_comm == -1)
PICA_fatal("unable to set non-blocking mode on socket - %s", strerror(errno));
-}
+ }
//#ifdef NO_RAND_DEV
//PICA_rand_seed();
//#endif
-ctx = SSL_CTX_new(TLSv1_2_method());
+ ctx = SSL_CTX_new(TLSv1_2_method());
-if (!ctx)
+ 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)
+ 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,41 +1420,41 @@ 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 (*pos<MAX_NEWCONNS && !ncs[*pos].sck)
+ time_t min;
+ int min_pos = 0;
+ if (*pos < MAX_NEWCONNS && !ncs[*pos].sck)
{
goto ret;
}
-else
+ else
{
- *pos=0;
- min=ncs->tmst;
- while(ncs[*pos].sck && *pos<MAX_NEWCONNS)
+ *pos = 0;
+ min = ncs->tmst;
+ while(ncs[*pos].sck && *pos < MAX_NEWCONNS)
{
- if (ncs[*pos].tmst<min)
+ if (ncs[*pos].tmst < min)
{
- min=ncs[*pos].tmst;
- min_pos=*pos;
+ min = ncs[*pos].tmst;
+ min_pos = *pos;
}
(*pos)++;
}
- if ( (*pos)==MAX_NEWCONNS)
+ if ( (*pos) == MAX_NEWCONNS)
{
- *pos=min_pos;
+ *pos = min_pos;
SHUTDOWN(ncs[min_pos].sck);
CLOSE(ncs[min_pos].sck);
PICA_debug2("closed socket %i", ncs[min_pos].sck);
@@ -1456,436 +1462,442 @@ else
}
ret:
-ncs[*pos].pos=0;
-ncs[*pos].tmst=time(0);
-return &ncs[(*pos)++];
+ ncs[*pos].pos = 0;
+ ncs[*pos].tmst = time(0);
+ return &ncs[(*pos)++];
}
void newconn_free(struct newconn* nc)
{
-nc->sck=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;
+ i = client_tree_root;
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;
+ i = i->left;
else
{
- i->left=ci;
- ci->up=i;
+ i->left = ci;
+ ci->up = i;
return 1;
}
}
else
{
if (i->right)
- i=i->right;
+ i = i->right;
else
{
- i->right=ci;
- ci->up=i;
+ i->right = ci;
+ ci->up = i;
return 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)
+ 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
- i_ptr=i_ptr->left;
+ if (cmp < 0) //id < i_ptr->id
+ i_ptr = i_ptr->left;
else
- i_ptr=i_ptr->right;
+ 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;
}
-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)
+ if (c->left)
client_tree_print(c->left);
-if (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;
}
-else
+ else
{
- if (ci==ci->up->left)
- p_link=&(ci->up->left);
+ if (ci == ci->up->left)
+ p_link = &(ci->up->left);
else
- p_link=&(ci->up->right);
+ p_link = &(ci->up->right);
}
-if (!ci->left && !ci->right)
+ if (!ci->left && !ci->right)
{
- *p_link=0;
+ *p_link = 0;
return;
}
-if (ci->left && !ci->right)
+ if (ci->left && !ci->right)
{
- ci->left->up=ci->up;
- *p_link=ci->left;
+ 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;
+ ci->right->up = ci->up;
+ *p_link = ci->right;
return;
}
{
struct client *lm;
- lm=ci->right;
- while(lm->left) lm=lm->left;//поиск самого левого узла правого поддерева
+ lm = ci->right;
+ while(lm->left) lm = lm->left; //поиск самого левого узла правого поддерева
- if (lm!=ci->right)
+ if (lm != ci->right)
{
- lm->up->left=lm->right;
- lm->right=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;
}
-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;
}
-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);
}
-cclink_list_delete_by_client(ci);
+ cclink_list_delete_by_client(ci);
-if (ci->r_buf)
+ if (ci->r_buf)
free(ci->r_buf);
-if (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)
+ if (!c->w_buf)
{
- c->w_buf = calloc(1,DEFAULT_BUF_SIZE + (size/DEFAULT_BUF_SIZE)*DEFAULT_BUF_SIZE );
+ 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;
}
- 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);
+ p = realloc(c->w_buf, size + c->w_pos);
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;
}
-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;
}
-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)
+ 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;
}
-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);
+ PICA_debug1("nodelink_list_delete(%p)", (void*)n);
-if (n->r_buf)
+ if (n->r_buf)
free(n->r_buf);
-if (n->w_buf)
+ if (n->w_buf)
free(n->w_buf);
-if (n->node_addr)
+ if (n->node_addr)
free(n->node_addr);
-CLOSE(n->sck);
-PICA_debug2("closed socket %i", n->sck);
+ 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->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);
+ nl->node_addr = malloc(nodeaddr_size);
if (!nl->node_addr)
return 0;//ERR_CHECK
- memcpy(nl->node_addr,nodeaddr,nodeaddr_size);
+ memcpy(nl->node_addr, nodeaddr, nodeaddr_size);
- nl->addr_type=addr_type;
+ 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;
}
-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;
+ struct PICA_proto_msg *mp;
-if (!nl->w_buf)
+ if (!nl->w_buf)
{
- nl->w_buf=calloc(1,DEFAULT_BUF_SIZE );
+ nl->w_buf = calloc(1, DEFAULT_BUF_SIZE );
if (!nl->w_buf)
{
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);
+ p = realloc(nl->w_buf, size + nl->w_pos);
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;
}
-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 && !(
+ 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 &&
@@ -1897,32 +1909,32 @@ while(nl && !(
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;i<MAX_NEWCONNS;i++)
+ for (i = 0; i < MAX_NEWCONNS; i++)
{
if (newconns[i].sck)
{
- if (newconns[i].tmst<t)
+ if (newconns[i].tmst < t)
{
- if (t-newconns[i].tmst>NEWCONN_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,11 +1942,11 @@ for (i=0;i<MAX_NEWCONNS;i++)
void process_timeouts_c2c()
{
-struct cclink *il;
+ struct cclink *il;
-il=cclink_list_head;
+ il = cclink_list_head;
-while(il)
+ while(il)
{
switch(il->state)
{
@@ -1946,30 +1958,30 @@ while(il)
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;
+ 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)
{
@@ -1979,7 +1991,8 @@ while(i_ptr)
kill_ptr = i_ptr;
}
else
- {//2038 year has come, and this code is still working somewhere with 32bit Unix timestamps :)
+ {
+ //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;
}
@@ -1995,7 +2008,7 @@ while(i_ptr)
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;
@@ -2012,22 +2025,22 @@ while(i_ptr)
{
PICA_info("Disconnecting user %u due to noreply timeout", kill_ptr -> id);
client_list_delete(kill_ptr);
- kill_ptr=0;
+ 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)
{
@@ -2037,7 +2050,8 @@ while(i_ptr)
kill_ptr = i_ptr;
}
else
- {//2038 year has come, and this code is still working somewhere with 32bit Unix timestamps :)
+ {
+ //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;
}
@@ -2053,7 +2067,7 @@ while(i_ptr)
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;
@@ -2070,103 +2084,103 @@ while(i_ptr)
{
PICA_info("Disconnecting node %p due to noreply timeout", kill_ptr);
nodelink_list_delete(kill_ptr);
- kill_ptr=0;
+ 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);
}
-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;i<MAX_NEWCONNS;i++)
+ for (i = 0; i < MAX_NEWCONNS; i++)
if (newconns[i].sck)
- set_select_fd(newconns[i].sck,readfds,nfds);
+ set_select_fd(newconns[i].sck, readfds, nfds);
}
-void c2n_set_fds(fd_set *readfds,int *nfds)
+void c2n_set_fds(fd_set *readfds, int *nfds)
{
-struct client *i_ptr;
+ struct client *i_ptr;
-i_ptr=client_list_head;
-while(i_ptr)
+ i_ptr = client_list_head;
+ while(i_ptr)
{
- set_select_fd(i_ptr->sck_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_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_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)
{
- nc = newconn_add(newconns,&newconns_pos);
+ nc = newconn_add(newconns, &newconns_pos);
nc->sck = s;
nc->addr = addr;
@@ -2183,24 +2197,24 @@ if (FD_ISSET(listen_comm_sck,readfds))
void process_newconn_read(fd_set *readfds)
{
-int i,ret;
+ int i, ret;
-for (i=0;i<MAX_NEWCONNS;i++)
- if (newconns[i].sck && FD_ISSET(newconns[i].sck,readfds))
+ for (i = 0; i < MAX_NEWCONNS; i++)
+ if (newconns[i].sck && FD_ISSET(newconns[i].sck, readfds))
{
- ret=recv(newconns[i].sck,newconns[i].buf+newconns[i].pos,NEWCONN_BUFSIZE - newconns[i].pos,0);
+ ret = recv(newconns[i].sck, newconns[i].buf + newconns[i].pos, NEWCONN_BUFSIZE - newconns[i].pos, 0);
- if (ret<=0)
+ if (ret <= 0)
{
//perror("process_newconn_read - recv:");//debug
- newconn_close(newconns+i);
+ newconn_close(newconns + i);
continue;
}
- newconns[i].pos+=ret;
+ newconns[i].pos += ret;
- if(!PICA_processdatastream(newconns[i].buf,&(newconns[i].pos),newconns+i /*arg*/,_msginfo_newconn, MSGINFO_MSGSNUM(_msginfo_newconn) ))
+ if(!PICA_processdatastream(newconns[i].buf, &(newconns[i].pos), newconns + i /*arg*/, _msginfo_newconn, MSGINFO_MSGSNUM(_msginfo_newconn) ))
{
- newconn_close(newconns+i);
+ newconn_close(newconns + i);
}
//FD_CLR(newconns[i].sck,readfds);
}
@@ -2210,38 +2224,38 @@ for (i=0;i<MAX_NEWCONNS;i++)
void process_c2n_read(fd_set *readfds)
{
-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)
{
- if (FD_ISSET(i_ptr->sck_comm,readfds))
+ 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);
+ 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;
+ 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;
+ kill_ptr = i_ptr;
}
- if (ret>0)
+ 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;
+ 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))
@@ -2250,17 +2264,17 @@ while (i_ptr)
}
break;
case PICA_CLSTATE_TLSNEGOTIATION:
- i_ptr->w_pos=1;//????
+ i_ptr->w_pos = 1; //????
//-------------- <<<<<<<<<<<<<<<<<<<<<<<<----------------------------------------
break;
};
- i_ptr=i_ptr->next;
+ i_ptr = i_ptr->next;
if (kill_ptr)
{
client_list_delete(kill_ptr);
- kill_ptr=0;
+ kill_ptr = 0;
}
}
@@ -2268,103 +2282,103 @@ 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;
+ 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;
+ kill_ptr = cc;
}
- cc=cc->next;
+ cc = cc->next;
if (kill_ptr)
{
cclink_list_delete(kill_ptr);
- kill_ptr=0;
+ 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);
+ ret = recv(nl->sck, nl->r_buf + nl->r_pos, nl->buflen_r - nl->r_pos, 0);
- if (ret<=0)
+ if (ret <= 0)
{
if (ret < 0)
PICA_debug3("recv() failed in process_n2n_read(): %s", strerror(errno));
- kill_ptr=nl;
+ kill_ptr = nl;
}
else
{
- nl->r_pos+=ret;
+ nl->r_pos += ret;
- if(!PICA_processdatastream(nl->r_buf,&(nl->r_pos),nl,_msginfo_node, MSGINFO_MSGSNUM(_msginfo_node) ))
- kill_ptr=nl;
+ 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;
+ kill_ptr = nl;
}
}
- nl=nl->next;
+ nl = nl->next;
if (kill_ptr)
{
nodelink_list_delete(kill_ptr);
- kill_ptr=0;
+ 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)
@@ -2374,63 +2388,63 @@ while(i_ptr)
break;
if (!i_ptr->btw_ssl)
- i_ptr->btw_ssl=i_ptr->w_pos;
+ i_ptr->btw_ssl = i_ptr->w_pos;
- ret=SSL_write(i_ptr->ssl_comm,i_ptr->w_buf,i_ptr->btw_ssl);
+ 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);
+ PICA_debug3("process_c2n_write: ret of SSL_write()=%i", ret);
- if (ret==i_ptr->btw_ssl)
+ 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;
+ 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;
case PICA_CLSTATE_SENDINGRESP:
- ret=send(i_ptr->sck_comm,i_ptr->w_buf,i_ptr->w_pos,0);
+ ret = send(i_ptr->sck_comm, i_ptr->w_buf, i_ptr->w_pos, 0);
if (!ret)
- kill_ptr=i_ptr;
+ kill_ptr = i_ptr;
- if (ret==SOCKET_ERROR)
+ 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 (??)
+ memmove(i_ptr->w_buf, i_ptr->w_buf + ret, i_ptr->w_pos - ret); //ring buffer is better (??)
- i_ptr->w_pos-=ret;
+ i_ptr->w_pos -= ret;
if (!i_ptr->w_pos)
- i_ptr->state=PICA_CLSTATE_TLSNEGOTIATION;
+ i_ptr->state = PICA_CLSTATE_TLSNEGOTIATION;
break;
case PICA_CLSTATE_TLSNEGOTIATION:
- i_ptr->w_pos=0;
- ret=SSL_connect(i_ptr->ssl_comm);
+ i_ptr->w_pos = 0;
+ ret = SSL_connect(i_ptr->ssl_comm);
- PICA_debug3("process_c2n_write: SSL_connect()=%i",ret);
+ PICA_debug3("process_c2n_write: SSL_connect()=%i", ret);
if (!ret)
- kill_ptr=i_ptr;
+ kill_ptr = i_ptr;
- if (ret<0)
+ if (ret < 0)
{
int eret;
- eret=SSL_get_error(i_ptr->ssl_comm,ret);
+ eret = SSL_get_error(i_ptr->ssl_comm, ret);
switch(eret)
{
case SSL_ERROR_WANT_WRITE:
- i_ptr->w_pos=1;
+ i_ptr->w_pos = 1;
PICA_debug3("SSL_ERROR_WANT_WRITE");
break;
case SSL_ERROR_WANT_READ:
@@ -2438,21 +2452,21 @@ while(i_ptr)
break;
default:
PICA_debug3("SSL_get_error() = %i", eret);
- kill_ptr=i_ptr;
+ kill_ptr = i_ptr;
}
}
- if (ret==1)
+ if (ret == 1)
//проверить сертификат пользователя
{
X509* client_cert;
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);
+ client_cert = SSL_get_peer_certificate (i_ptr->ssl_comm);
if (!client_cert)
{
//ERR_CHECK //нет сертификата
- kill_ptr=i_ptr;
+ kill_ptr = i_ptr;
}
ret = PICA_id_from_X509(client_cert, i_ptr->id);
@@ -2460,234 +2474,242 @@ while(i_ptr)
if (ret == 0)
{
PICA_error("Unable to get client id from certificate");
- kill_ptr=i_ptr;
+ 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
ret = 0;//id already exists in tree
}
else
{
- ret=client_tree_add(i_ptr);
+ ret = client_tree_add(i_ptr);
client_tree_print(client_tree_root);
}
if (!ret)
{
//ERR_CHECK //не уникальный id
- kill_ptr=i_ptr;
+ kill_ptr = i_ptr;
}
- i_ptr->state=PICA_CLSTATE_CONNECTED;
+ i_ptr->state = PICA_CLSTATE_CONNECTED;
}
break;
}
//---------
- i_ptr=i_ptr->next;
+ i_ptr = i_ptr->next;
if (kill_ptr)
{
client_list_delete(kill_ptr);
- kill_ptr=0;
+ 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->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;
- if(mp=nodelink_wbuf_push(cc->callee_node,PICA_PROTO_N2NMSG,sendlen + 4 + 2 * PICA_ID_SIZE))
+ 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;
+ ret = sendlen;
}
else
- ret=0;
+ ret = 0;
}
else
- ret=send(cc->sck_p2,cc->buf_p1p2,cc->bufpos_p1p2,MSG_NOSIGNAL);
+ 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;
+ 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;
+#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
+ 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->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;
- 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;
+ memcpy(mp->tail + 2 + 2 * PICA_ID_SIZE, cc->buf_p2p1, sendlen);
+ ret = sendlen;
}
else
- ret=0;
+ ret = 0;
}
else
- ret=send(cc->sck_p1,cc->buf_p2p1,cc->bufpos_p2p1,MSG_NOSIGNAL);
+ 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;
+ 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;
+#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
+ ret = errno;
+ if (ret == EAGAIN || ret == ENOBUFS)
+ cc->jam_p2p1 = 1;
else
{
- kill_ptr=cc;
+ kill_ptr = cc;
}
- #endif
+#endif
}
}
- cc=cc->next;
+ cc = cc->next;
if (kill_ptr)
{
cclink_list_delete(kill_ptr);
- kill_ptr=0;
+ 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;
+ 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;
+ nl = nl->next;
if (kill_ptr)
{
nodelink_list_delete(kill_ptr);
- kill_ptr=0;
+ kill_ptr = 0;
}
}
}
void process_nodewait()
{
-struct nodewait *kill_ptr = 0, *nw = nodewait_list;
+ struct nodewait *kill_ptr = 0, *nw = nodewait_list;
-while(nw)
+ while(nw)
{
//PICA_debug3("checking nodewait pointer %p", nw);
switch(nw->state)
@@ -2734,7 +2756,7 @@ while(nw)
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);
+ nlp = nodelink_list_addnew(&nw->nc);
if (nlp)
{
struct PICA_proto_msg *mp;
@@ -2781,34 +2803,34 @@ while(nw)
int node_loop()
{
-fd_set fds;
-struct timeval tv;
-int nfds, ret;
+ fd_set fds;
+ struct timeval tv;
+ int nfds, ret;
-do
+ 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);
+ 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);
+ ret = select(nfds + 1, &fds, 0, 0, &tv);
- if (ret<0)
+ 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);
@@ -2825,13 +2847,13 @@ do
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,30 +2864,30 @@ Options:\n\
void print_version()
{
-puts("Pica Pica Node v"PACKAGE_VERSION" \n(c) 2012 - 2016 Anton Sviridenko\n");
-puts("protocol version "PICA_PROTO_VER_STRING"\n");
+ puts("Pica Pica Node v"PACKAGE_VERSION" \n(c) 2012 - 2017 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)
{
@@ -2895,27 +2917,27 @@ while((opt = getopt(argc, argv, "f:hvV")) != -1)
}
}
-if (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)
+ 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;
@@ -2940,7 +2962,7 @@ while(nap)
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)
+ 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;
@@ -2949,7 +2971,7 @@ while(nap)
}
}
- if (0 == strncmp(nap->addr, inet_ntoa(nl->addr.sin_addr),16) && nap->port == ntohs(nl->addr.sin_port))
+ if (0 == strncmp(nap->addr, inet_ntoa(nl->addr.sin_addr), 16) && nap->port == ntohs(nl->addr.sin_port))
skip = 1;
@@ -2959,50 +2981,50 @@ while(nap)
if (!skip)
nodewait_start_resolve(nap);
- nap=nap->next;
+ 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_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())
+ 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
);
}
-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_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
index e635df2..4d95417 100755..100644
--- 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
index 6e262f9..52e4f29 100755..100644
--- 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
index 7200cc7..b90de8f 100755..100644
--- 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
index cb20db5..46ca178 100755..100644
--- a/PICA_proto.h
+++ b/PICA_proto.h
@@ -5,8 +5,12 @@
#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_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
@@ -26,6 +30,15 @@
#define PICA_PROTO_CONNID 0x20
+#define PICA_PROTO_C2CCONNREQ 0xCC
+
+#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_DIRECTC2C_SWITCH 0x0D
+
#define PICA_PROTO_MSGUTF8 0x30
#define PICA_PROTO_MSGOK 0x40
#define PICA_PROTO_SENDFILEREQUEST 0x50
@@ -76,6 +89,12 @@
#define PICA_PROTO_CONNID_SIZE 58
+#define PICA_PROTO_C2CCONNREQ_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_DIRECTC2C_SWITCH_SIZE 4
+
#define PICA_PROTO_MSGOK_SIZE 4
#define PICA_PROTO_ACCEPTEDFILE_SIZE 4
@@ -109,8 +128,8 @@
struct PICA_proto_msg
{
-unsigned char head[2];
-unsigned char tail[0];
+ unsigned char head[2];
+ unsigned char tail[0];
};
diff --git a/configure.ac b/configure.ac
index b36c71d..4e2599d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -68,7 +68,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-qt4 uic4 uic], [notfound])
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/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/doc/proto.txt b/doc/proto.txt
index 0f05d6a..49cb4a0 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
@@ -63,22 +63,46 @@ UH - user hash - SHA224 хэш от сертификата пользоватеÐ
Протокол обмена сообщениями (между клиентами через сервер(ы) ) |КЛИЕНТ-КЛИЕНТ|
++++[начало c2c соединения] - клиент клиенту
+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 псевдослучайных байта)
+отправляется инициатором, если он получил от вызываемого клиента список прямых адресов и все попытки подключения к полученным адресам оказались неуспешны.
+После получения этого сообщения вызываемый клиент начинает попытки подключения к прямым адресам инициатора, если от инициатора был получен список прямых
+адресов и прямые подключения разрешены настройками вызываемого
+
++++[переключение на прямое соединение]
+0x0D 0x0D (2 псевдослучайных байта)
+отправляется после успешного TLS хэндшейка на прямом соединении каждой из сторон по соединению через ноду, после отправки этого сообщения все следующие сообщения
+отправляются по прямому соединению, получатель сообщения соответственно ожидает следующие сообщения уже по прямому соединению.
+
+++[сообщение - текст в кодировке 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) фрагмент файла
@@ -91,10 +115,10 @@ UH - user hash - SHA224 хэш от сертификата пользоватеÐ
Пинг
+++[пинг-запрос] - может быть отправлен любой стороной, как по управляющему соединению, так и по межклиентскому
-0x68 0x68 (2 случайных байта)
+0x68 0x68 (2 псевдослучайных байта)
+++[пинг-ответ]
-0x69 0x69 (2 случайных байта)
+0x69 0x69 (2 псевдослучайных байта)
@@ -128,7 +152,7 @@ UH - user hash - SHA224 хэш от сертификата пользоватеÐ
Размер всего пакета не превышает 64кб
+++[запрос списка узлов] @@@
-0x90 0x90 (2 случайных байта)
+0x90 0x90 (2 псевдослучайных байта)
+++[поиск клиента] - отправляется всем узлам. Узел-получатель отвечает на это сообщение, только если искомый UH найден среди локальных клиентов либо в кэше
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 <string.h>
#include <QInputDialog>
+#include <QThread>
#include "accounts.h"
QMutex AskPassword::passwd_mutex;
-QMap<QByteArray,QString> 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<QByteArray,QString> 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/dialogs/settingsdialog.cpp b/pica-client/dialogs/settingsdialog.cpp
new file mode 100644
index 0000000..852cc95
--- /dev/null
+++ b/pica-client/dialogs/settingsdialog.cpp
@@ -0,0 +1,168 @@
+#include "settingsdialog.h"
+#include "../settings.h"
+#include "../globals.h"
+
+#include <QGroupBox>
+#include <QVBoxLayout>
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QVariant>
+#include <QListWidget>
+#include <QNetworkInterface>
+#include <QHostAddress>
+#include <QTabWidget>
+
+SettingsDialog::SettingsDialog(QWidget *parent) :
+ QDialog(parent)
+{
+ QVBoxLayout *settingsLayout = new QVBoxLayout();
+
+ 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);
+ 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);
+ connect(rbEnableIncomingConns, SIGNAL(toggled(bool)), this, SLOT(toggleIncomingConnections(bool)));
+
+ QLabel *lbAddr = new QLabel(tr("Public address for incoming connections"), 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);
+
+ QList<QHostAddress> hostIfAddrs = QNetworkInterface::allAddresses();
+ QHostAddress ifAddr;
+
+ foreach (ifAddr, hostIfAddrs)
+ if (ifAddr.protocol() == QAbstractSocket::IPv4Protocol)
+ addr->addItem(ifAddr.toString());
+
+
+ directc2cLayout->addWidget(rbDisableDirectConns);
+ directc2cLayout->addWidget(rbEnableOutgoingConns);
+ directc2cLayout->addWidget(rbEnableIncomingConns);
+ directc2cLayout->addWidget(lbAddr);
+ directc2cLayout->addWidget(addr);
+ directc2cLayout->addWidget(lbPubPort);
+ directc2cLayout->addWidget(publicPort);
+ directc2cLayout->addWidget(lbLocPort);
+ directc2cLayout->addWidget(localPort);
+ directc2cLayout->addStretch(1);
+
+ //groupBox->setLayout(directc2cLayout);
+ directc2ctab->setLayout(directc2cLayout);
+
+ //settingsLayout->addWidget(groupBox);
+ tabW->addTab(directc2ctab, tr("Direct Connections"));
+ tabW->addTab(soundstab, tr("Sounds"));
+ settingsLayout->addWidget(tabW);
+
+ 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();
+
+ setWindowTitle(tr("Pica Pica Messenger Settings"));
+}
+
+void SettingsDialog::toggleIncomingConnections(bool checked)
+{
+ addr->setEnabled(checked);
+ publicPort->setEnabled(checked);
+ localPort->setEnabled(checked);
+}
+
+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->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());
+
+}
+
+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->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
new file mode 100644
index 0000000..9b11630
--- /dev/null
+++ b/pica-client/dialogs/settingsdialog.h
@@ -0,0 +1,44 @@
+#ifndef SETTINGSDIALOG_H
+#define SETTINGSDIALOG_H
+
+#include <QDialog>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QSpinBox>
+#include <QRadioButton>
+#include <QComboBox>
+
+class SettingsDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ explicit SettingsDialog(QWidget *parent = 0);
+
+signals:
+
+public slots:
+private slots:
+
+private:
+ QRadioButton *rbDisableDirectConns;
+ QRadioButton *rbEnableOutgoingConns;
+ QRadioButton *rbEnableIncomingConns;
+
+ QComboBox *addr;
+ QSpinBox *publicPort;
+ QSpinBox *localPort;
+
+ QPushButton *btOk;
+ QPushButton *btCancel;
+
+ void loadSettings();
+ void storeSettings();
+
+private slots:
+ void OK();
+ void Cancel();
+ void toggleIncomingConnections(bool checked);
+
+};
+
+#endif // SETTINGSDIALOG_H
diff --git a/pica-client/filetransfercontroller.cpp b/pica-client/filetransfercontroller.cpp
index 9f07a38..44dba15 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)
@@ -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/main.cpp b/pica-client/main.cpp
index 7df81ce..1441b5c 100644
--- a/pica-client/main.cpp
+++ b/pica-client/main.cpp
@@ -14,6 +14,8 @@
#include <QIcon>
#include "../PICA_client.h"
#include "dhparam.h"
+#include "settings.h"
+#include "dialogs/settingsdialog.h"
//globals
QString config_dir;
@@ -135,7 +137,18 @@ 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, \
+ constraint pk primary key (name) on conflict replace \
+ );"
+ );
+
+ 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 +376,23 @@ 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, \
+ constraint pk primary key (name) on conflict replace \
+ );"
+ );
+
+ if (query.lastError().isValid())
+ goto showerror;
+
+ query.exec("insert into schema_version values (3, strftime('%s','now'));");
+ schema_ver = 3;
+ }
+
if (query.lastError().isValid())
showerror:
{
@@ -465,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 = &ac;
diff --git a/pica-client/mainwindow.cpp b/pica-client/mainwindow.cpp
index c440e20..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());
@@ -138,11 +141,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..b61f31a 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:
@@ -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/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);
}
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:
diff --git a/pica-client/nodethread.cpp b/pica-client/nodethread.cpp
index 393c156..ee6504f 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, 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_c2n(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_c2n(user_account, node_addr.address.toUtf8().constData(), node_addr.port, &ci);
switch(ret)
{
@@ -41,7 +42,7 @@ void NodeThread::run()
finished_mutex.lock();
if (*finished_flag)
{
- PICA_close_connection(ci);
+ PICA_close_c2n(ci);
exit = 1;
}
else
@@ -105,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/pica-client/nodethread.h b/pica-client/nodethread.h
index 79de4d0..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_conninfo **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();
@@ -22,9 +22,9 @@ private:
bool *finished_flag;
Nodes::NodeRecord node_addr;
- struct PICA_conninfo *ci;
- Accounts::AccountRecord user_account;
- struct PICA_conninfo **connection;
+ struct PICA_c2n *ci;
+ struct PICA_acc *user_account;
+ struct PICA_c2n **connection;
int exit;
diff --git a/pica-client/pica-client.pro b/pica-client/pica-client.pro
index 70c1222..ef9f9fd 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 \
@@ -37,7 +36,9 @@ SOURCES += main.cpp\
dialogs/showpicaiddialog.cpp \
dialogs/filetransferdialog.cpp \
filetransfercontroller.cpp \
- sound.cpp
+ sound.cpp \
+ dialogs/settingsdialog.cpp \
+ settings.cpp
HEADERS += mainwindow.h \
chatwindow.h \
@@ -51,7 +52,6 @@ HEADERS += mainwindow.h \
accountswindow.h \
accounts.h \
dialogs/addaccountdialog.h \
- nodethread.h \
askpassword.h \
msguirouter.h \
picasystray.h \
@@ -68,7 +68,9 @@ HEADERS += mainwindow.h \
dialogs/showpicaiddialog.h \
dialogs/filetransferdialog.h \
filetransfercontroller.h \
- sound.h
+ sound.h \
+ dialogs/settingsdialog.h \
+ settings.h
DEFINES = PICA_MULTITHREADED
diff --git a/pica-client/picaactioncenter.cpp b/pica-client/picaactioncenter.cpp
index bbd19ab..9303ca6 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 <QMessageBox>
@@ -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()
@@ -40,9 +44,10 @@ void PicaActionCenter::about()
mbx.setWindowIcon(picapica_ico_sit);
mbx.setIconPixmap(picapica_ico_sit.pixmap(32));
mbx.setTextFormat(Qt::RichText);
- mbx.setText(tr("<b>Pica Pica Messenger "VERSION_STRING"<br>(c) 2012 - 2016 Anton Sviridenko</b><br>\
-<a href=https://picapica.im>https://picapica.im</a><br><br>Contributors:<br>Daniil Ustinov - bugfixes<br>EXL - bugfixes<br><br>\
-protocol version " PICA_PROTO_VER_STRING));
+ mbx.setText(tr("<b>Pica Pica Messenger "VERSION_STRING"<br>(c) 2012 - 2017 Anton Sviridenko</b><br>\
+<a href=http://picapica.im>http://picapica.im</a><br><br>Contributors:<br>Daniil Ustinov - bugfixes<br>EXL - bugfixes<br><br>\
+protocol version " PICA_PROTO_VER_STRING "<br>"
+ "client protocol version " PICA_PROTO_CLIENT_VER_STRING));
mbx.exec();
}
@@ -55,6 +60,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
diff --git a/pica-client/settings.cpp b/pica-client/settings.cpp
new file mode 100644
index 0000000..4b5485d
--- /dev/null
+++ b/pica-client/settings.cpp
@@ -0,0 +1,69 @@
+#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();
+}
+
+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;
+
+ 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..9476ab5
--- /dev/null
+++ b/pica-client/settings.h
@@ -0,0 +1,24 @@
+#ifndef SETTINGS_H
+#define SETTINGS_H
+
+#include <QtSql>
+#include <QSqlDatabase>
+#include <QVariant>
+
+class Settings
+{
+public:
+ Settings(QString storage);
+
+ QVariant loadValue(QString name, QVariant defval);
+ void storeValue(QString name, QString val);
+ bool isEmpty();
+
+ QString GetLastError();
+
+private:
+ QSqlDatabase dbconn;
+ QSqlError lasterr;
+};
+
+#endif // SETTINGS_H
diff --git a/pica-client/skynet.cpp b/pica-client/skynet.cpp
index 63da308..a016b48 100644
--- a/pica-client/skynet.cpp
+++ b/pica-client/skynet.cpp
@@ -8,21 +8,23 @@
//#include "dialogs/forgedcertdialog.h"
#include <QDebug>
#include "history.h"
+#include "dhparam.h"
+#include "askpassword.h"
+#include "settings.h"
SkyNet::SkyNet()
: nodes(config_dbname), QObject(0)
{
self_aware = false;
- reconnect_enabled = false;
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,
@@ -30,81 +32,144 @@ 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);
-nodelink = NULL;
+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);
-timer_id = startTimer(10000);
+event_loop_timer_id = startTimer(0);
+
}
-void SkyNet::nodethread_finished()
+void SkyNet::nodelink_activated(PICA_c2n *c2n)
{
-//удалить здесь завершившийся поток
- for (int i=0;i<threads.count();i++)
- {
- if (threads[i]->isFinished())
- {
- 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<QByteArray> c2c_peer_ids;
- //restore old peer connections, if any
- QList<QByteArray> 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<QByteArray, QList<QString> > queues = msgqueues;
- QMap<QByteArray, QList<QString> > 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_chaninfo *chan = NULL;
+ ret = PICA_new_c2c(active_nodelink, (const unsigned char*)c2c_peer_ids[i].constData(), NULL, &chan);
- ret = PICA_create_channel(nodelink, (const unsigned char*)c2c_peer_ids[i].constData(), &chan);
+ qDebug()<<"restoring c2c to "<<c2c_peer_ids[i]<<" ret ="<<ret<<"\n";
+ }
- qDebug()<<"restoring channel to "<<c2c_peer_ids[i]<<" ret ="<<ret<<"\n";
- write_mutex.unlock();
- }
+ //start timer
+ retry_timer_id = startTimer(10000);
+ //
+ }
- }
+
+}
+
+void SkyNet::nodelink_closed(PICA_c2n *c2n, int error)
+{
+ if (self_aware && c2n == active_nodelink)
+ {
+ active_nodelink = NULL;
+ emit LostSelfAwareness();
+ }
+ else
+ {
+ for (int i = 0; i < connecting_nodes.size(); i++)
+ {
+ if (connecting_nodes[i].first == c2n)
+ {
+ connecting_nodes.removeAt(i);
+ break;
+ }
+ }
+ }
+}
+
+void SkyNet::nodelink_failed(PICA_c2n *c2n, int error)
+{
+ for (int i = 0; i < connecting_nodes.size(); i++)
+ {
+ if (connecting_nodes[i].first == c2n)
+ {
+ switch(error)
+ {
+ case PICA_ERRPROTONEW:
+
+ emit StatusMsg(QString("Node %1:%2 has newer protocol version. Please check if update for pica-client is available")
+ .arg(connecting_nodes[i].second.address)
+ .arg(connecting_nodes[i].second.port),
+ true);
+ break;
+
+ case PICA_ERRPROTOOLD:
+
+ emit StatusMsg(QString("Node %1:%2 has older protocol. Disconnected.")
+ .arg(connecting_nodes[i].second.address)
+ .arg(connecting_nodes[i].second.port),
+ false);
+ break;
+ }
+
+ node_status_changed(connecting_nodes[i].second, false);
+ connecting_nodes.removeAt(i);
+ break;
+ }
+ }
+ if (connecting_nodes.empty())
+ emit LostSelfAwareness();
}
-void SkyNet::node_status_changed(QString addr, quint16 port, bool alive)
+
+
+void SkyNet::node_status_changed(Nodes::NodeRecord nr, bool alive)
{
- Nodes::NodeRecord nr = {addr, port};
nodes.UpdateStatus(nr, alive);
}
@@ -166,70 +231,184 @@ void SkyNet::verify_peer_cert(QByteArray peer_id, QString cert_pem, bool *verifi
void SkyNet::timerEvent(QTimerEvent *e)
{
+ if (e->timerId() == event_loop_timer_id)
+ {
+ if (connecting_nodes.size() > 0 || self_aware)
+ {
+ int ret;
+ QVector<struct PICA_c2n *> 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(), 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<QByteArray, QList<QString> > queues = msgqueues;
- queues.unite(sndfilequeues);
+ QMap<QByteArray, QList<QString> > queues = msgqueues;
+ queues.unite(sndfilequeues);
- QList<QByteArray> c2c_peer_ids = queues.uniqueKeys();
+ QList<QByteArray> 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_chaninfo *chan = NULL;
+ struct PICA_c2c *chan = NULL;
- ret = PICA_create_channel(nodelink, (const unsigned char*)c2c_peer_ids[i].constData(), &chan);
+ ret = PICA_new_c2c(active_nodelink, (const unsigned char*)c2c_peer_ids[i].constData(), NULL, &chan);
- qDebug()<<"restoring channel to "<<c2c_peer_ids[i]<<" ret ="<<ret<<" in timer event\n";
+ qDebug()<<"restoring c2c to "<<c2c_peer_ids[i]<<" ret ="<<ret<<" in timer event\n";
+
+ }
- }
- write_mutex.unlock();
- }
}
-else if (threads.count() == 0 && reconnect_enabled)
+else
{
+ killTimer(e->timerId());
Accounts::AccountRecord acc = this->CurrentAccount();
Join(acc);
}
}
+bool SkyNet::open_account()
+{
+ 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 false;
+
+ return true;
+}
+
void SkyNet::Join(Accounts::AccountRecord &accrec)
{
- QList<Nodes::NodeRecord> nodelist;
+ PICA_directc2c_config directc2c_cfg = PICA_DIRECTC2C_CFG_DISABLED;
+ Settings st(config_dbname);
+
skynet_account = accrec;
- nodelist = nodes.GetNodes();
- reconnect_enabled = true;
- if (nodelist.count()==0)
+ QList<Nodes::NodeRecord> noderecords = nodes.GetNodes();
+
+ if (!acc)
+ {
+ if (!open_account())
+ return;
+ }
+
+ if (noderecords.count()==0)
{
- status = QObject::tr("No known Pica Pica nodes");
+ emit StatusMsg(QString(tr("No known Pica Pica nodes")), true);
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++)
+ 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,
+ directc2c_cfg, listener, &c2n);
+
+ if (ret == PICA_OK)
+ {
+ connecting_nodes.append(QPair<struct PICA_c2n *, Nodes::NodeRecord>(c2n, noderecords[i]));
+ }
+ else
+ {
+ node_status_changed(noderecords[i], false);
+ }
+ }
+/*
for (int i=0;i<nodelist.count() && !self_aware;i++)
{//TODO FIXME сделать запуск потоков порциями, а не все сразу
- threads.append(new NodeThread(nodelist[i],&self_aware,skynet_account,&nodelink, &write_mutex));
+ threads.append(new NodeThread(nodelist[i],&self_aware, acc,&nodelink, &write_mutex));
connect(threads.last(), SIGNAL(finished()),this,SLOT(nodethread_finished()));
connect(threads.last(), SIGNAL(NodeStatusChanged(QString,quint16,bool)), this, SLOT(node_status_changed(QString,quint16,bool)));
connect(threads.last(), SIGNAL(ConnectedToNode(QString,quint16,NodeThread*)), this, SLOT(nodethread_connected(QString,quint16,NodeThread*)));
connect(threads.last(), SIGNAL(ErrorMsg(QString)), this, SIGNAL(ErrMsgFromNode(QString)));
- }
+ }*/
}
void SkyNet::Exit()
{
- for (int i = 0; i< threads.count(); i++)
- threads[i]->CloseThread();
+ if (self_aware && active_nodelink)
+ {
+ PICA_close_c2n(active_nodelink);
+ active_nodelink = NULL;
+ }
self_aware = false;
- reconnect_enabled = false;
- emit LostSelfAwareness();
+
+ 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()
@@ -240,9 +419,9 @@ 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();//<<
if ( (iptr = find_active_chan(to)) )
{
@@ -253,7 +432,7 @@ if ( (iptr = find_active_chan(to)) )
//show error somewhere somehow
}
- write_mutex.unlock();//>>
+
return;
}
@@ -263,16 +442,16 @@ 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);
+ ret = PICA_new_c2c(active_nodelink, (const unsigned char*)to.constData(), NULL, &chan);
QList<QString> l;
l.append(filepath);
sndfilequeues[to] = l;
}
-write_mutex.unlock();//>>
+
if (ret!= PICA_OK)
{
@@ -283,9 +462,9 @@ 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)) )
{
ret = PICA_accept_file(iptr, filepath.toUtf8().data(), filepath.toUtf8().size());
@@ -296,15 +475,15 @@ if ( (iptr = find_active_chan(from)) )
//show error somewhere somehow
}
}
-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)) )
{
ret = PICA_deny_file(iptr);
@@ -315,15 +494,15 @@ if ( (iptr = find_active_chan(from)) )
//show error somewhere somehow
}
}
-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)) )
{
qDebug() << "calling PICA_pause_file(" << iptr << "," << pause_sending << ")\n";
@@ -334,15 +513,15 @@ 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)
{
int ret = PICA_OK;
-struct PICA_chaninfo *iptr;
+struct PICA_c2c *iptr;
+
-write_mutex.lock();//<<
if ( (iptr = find_active_chan(peer_id)) )
{
ret = PICA_resume_file(iptr, (int)resume_sending );
@@ -352,15 +531,15 @@ if ( (iptr = find_active_chan(peer_id)) )
//show error somewhere somehow
}
}
-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)) )
{
ret = PICA_cancel_file(iptr, (int)cancel_sending );
@@ -370,15 +549,15 @@ if ( (iptr = find_active_chan(peer_id)) )
//show error somewhere somehow
}
}
-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();//<<
if ( (iptr = find_active_chan(to)) )
{
@@ -389,7 +568,7 @@ if ( (iptr = find_active_chan(to)) )
if (ret != PICA_OK)
emit UnableToDeliver(to, msg);
- write_mutex.unlock();//>>
+
return;
}
@@ -399,9 +578,9 @@ 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);
+ ret = PICA_new_c2c(active_nodelink, (const unsigned char*)to.constData(), NULL, &chan);
QList<QString> l;
l.append(msg);
@@ -409,7 +588,7 @@ if ( (iptr = find_active_chan(to)) )
}
-write_mutex.unlock();//>>
+
if (ret != PICA_OK)
emit UnableToDeliver(to, msg);
@@ -418,7 +597,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,16 +645,16 @@ 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)
+if (!active_nodelink)
return NULL;
-struct PICA_chaninfo *iptr = nodelink->chan_list_head;
+struct PICA_c2c *iptr = active_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;
@@ -488,10 +667,10 @@ QList<QByteArray> SkyNet::filter_existing_chans(QList<QByteArray> peer_ids)
{
QList<QByteArray> ret = peer_ids;
- if (!nodelink)
+ if (!active_nodelink)
return ret;
- struct PICA_chaninfo *iptr = nodelink->chan_list_head;
+ struct PICA_c2c *iptr = active_nodelink->chan_list_head;
while(iptr)
{
@@ -594,17 +773,14 @@ 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);
}
//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);
@@ -617,14 +793,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 ("<<QByteArray((const char*)peer_id, PICA_ID_SIZE).toBase64()<<")\n";
+ qDebug()<<"c2c failed ("<<QByteArray((const char*)peer_id, PICA_ID_SIZE).toBase64()<<")\n";
}
int SkyNet::accept_cb(const unsigned char *caller_id)
@@ -649,12 +825,12 @@ void SkyNet::notfound_cb(const unsigned char *callee_id)
*/
}
-void SkyNet::channel_closed_cb(const unsigned char *peer_id, int reason)
+void SkyNet::c2c_closed_cb(const unsigned char *peer_id, int reason)
{
- qDebug()<<"channel closed ("<<QByteArray((const char*)peer_id, PICA_ID_SIZE).toBase64()
+ qDebug()<<"c2c closed ("<<QByteArray((const char*)peer_id, PICA_ID_SIZE).toBase64()
<<", error_code =" << reason << ")\n";
- skynet->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)
@@ -759,3 +935,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)
+{
+ skynet->nodelink_activated(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, 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 ebc78ff..bea1a21 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 <QObject>
#include <QMap>
+#include <QVector>
+#include <QPair>
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);
@@ -55,26 +55,29 @@ signals:
void OutgoingFileFinished(QByteArray peer_id);
void IncomingFileFinished(QByteArray peer_id);
- void ChannelClosed(QByteArray peer_id);
+ void c2cClosed(QByteArray peer_id);
private:
Nodes nodes;
- QList<NodeThread*> threads;
+ QList<QPair<struct PICA_c2n *, Nodes::NodeRecord> > connecting_nodes;
bool self_aware;
QString status;
- struct PICA_conninfo *nodelink;
+ struct PICA_c2n *active_nodelink;
+ struct PICA_acc *acc;
+ struct PICA_listener *listener;
Accounts::AccountRecord skynet_account;
- QMutex write_mutex;
+
QMap<QByteArray, QList<QString> > msgqueues;
QMap<QByteArray, QList<QString> > sndfilequeues;
- int timer_id;
- bool reconnect_enabled;
+ int retry_timer_id;
+ int event_loop_timer_id;
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<QByteArray> filter_existing_chans(QList<QByteArray> peer_ids);
+ bool open_account();
void emit_MessageReceived(QByteArray from, QString msg);
void emit_UnableToDeliver(QByteArray to, QString msg);
@@ -97,22 +100,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);
@@ -130,10 +133,20 @@ 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, int error);
+
+ 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);
};
diff --git a/tests/test_client b/tests/test_client
deleted file mode 100755
index a384dee..0000000
--- a/tests/test_client
+++ /dev/null
Binary files differ
diff --git a/tests/test_client.c b/tests/test_client.c
index f8ef157..c469c74 100755..100644
--- a/tests/test_client.c
+++ b/tests/test_client.c
@@ -1,47 +1,92 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <sys/select.h>
+#include <unistd.h>
#include "../PICA_client.h"
-
+#include "../PICA_proto.h"
struct sockaddr_in a;
-struct PICA_conninfo *c;
-struct PICA_chaninfo *chn;
+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;
-int _outgoing_chnl=0;
+int connected_to_node = 0;
+int c2c_active = 0;
+int c2c_in_progress = 0;
-unsigned char buf[64*1024];
+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];
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,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);
+
+ 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;
+ }
+
+ 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");
+ exit(1);
+ }
+
+ rmm_wait_for_reply = 0;
+ }
+
+ 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]");
+ delivery_acks_count++;
+ puts("[V]");
}
//создание канала с собеседником
-void channel_established_cb(const unsigned char *peer_id)
+void c2c_established_cb(const unsigned char *peer_id)
{
-puts("channel_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 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));
-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
@@ -49,191 +94,408 @@ chn=0;
//запрошенный пользователь не найден, в оффлайне или отказался от общения
void notfound_cb(const unsigned char *callee_id)
{
-puts("notfound_cb");
+ 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);
+ 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;
}
-struct PICA_client_callbacks cbs = {
- newmsg_cb,
- msgok_cb,
- channel_established_cb,
- channel_failed_cb,
- accept_cb,
- notfound_cb,
- channel_closed_cb,
- nodelist_cb,
- peer_cert_verify_cb
-};
-
-int main(int argc,char** argv)
+int accept_file_cb(const unsigned char *peer_id, uint64_t file_size, const char *filename, unsigned int filename_size)
{
-int ret;
-unsigned char peer_id[PICA_ID_SIZE];
+ 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);
-if (argc<4)
+ ret = PICA_accept_file(chn, namebuf, strlen(namebuf));
+
+ if (ret != PICA_OK)
{
- puts("usage: test_client address port cert_filename [peer id]");
- return 0;
+ printf("faild to accept file, errror %i\n", ret);
+ return 0;
}
-puts(SSLeay_version(SSLEAY_VERSION));
-printf("Calling PICA_init...\n");
+ return 2;
+}
+
+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));
+}
-PICA_client_init(&cbs);
+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("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);
+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));
+}
-printf("making connection...\n");
+void c2n_established_cb(struct PICA_c2n *c2n)
+{
+ connected_to_node = 1;
+ printf("c2n_established_cb: %p\n my_id %s\n", c2n, PICA_id_to_base64(c2n->acc->id, NULL));
+}
-//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)
-ret=PICA_new_connection(argv[1], atoi(argv[2]), /*"trusted_CA.pem"*/ argv[3], argv[3],argv[3],NULL,&c);
+void c2n_failed_cb(struct PICA_c2n *c2n, int error)
+{
+ printf("c2n_failed_cb: %p error_code %i\n", c2n, error);
+ c = NULL;
+}
-ERR_print_errors_fp(stdout);
+void c2n_closed_cb(struct PICA_c2n *c2n, int error)
+{
+ printf("c2n_closed_cb: %p error_code %i\n", c2n, error);
+ c = NULL;
+}
-if (ret==PICA_OK)
-printf("PICA_OK Connected to server...\n");
-else
+void listener_error(struct PICA_listener *lst, int errorcode)
{
-printf("PICA_new_connection: ret=%i\n",ret);
-return 1;
+ printf("listener_error: %p error code %i\n", lst, errorcode);
+ l = NULL;
}
-if (argc==5)
+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 ret, opt;
+ unsigned char peer_id[PICA_ID_SIZE];
+ struct PICA_c2n* c2ns[] = {NULL, NULL};
+
+ fd_set stdinfds;
+ struct timeval tv;
+
+ 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:f:tmr")) != -1)
{
- if (PICA_id_from_base64(argv[4], peer_id) == NULL)
+ 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 'f':
+ filetosend = optarg;
+ break;
+
+ case 'l':
+ locport = optarg;
+ break;
+
+ case 't':
+ directc2c_cfg = PICA_DIRECTC2C_CFG_CONNECTONLY;
+ break;
+
+ case 'm':
+ 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("invalid peer_id");
- return 1;
+ puts("echo mode and random test messages mode are mutually exclusive, please select only one of them");
+ return -1;
}
- printf("Creating channel to %s...\n",PICA_id_to_base64(peer_id, NULL));
-
- ret=PICA_create_channel(c,peer_id,&chn);
- //sleep(17);//timeout test
- if (ret!=PICA_OK)
- {
- printf("error: ret=%i\n",ret);
+ if (argc < 4 || !nodeaddr || !nodeport || !certfile)
+ {
+ 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\
+ -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;
+ }
+
+
+
+ puts(SSLeay_version(SSLEAY_VERSION));
+ printf("Calling PICA_init...\n");
+
+ PICA_client_init(&cbs);
+
+ printf("opening account...");
+ ret = PICA_open_acc(certfile, certfile, certfile, NULL, &acc);
+
+ if (ret != PICA_OK)
+ {
+ fprintf(stderr, "failed to open account, ret = %i\n", ret);
return 1;
- }
-
}
-do
+ if (localdirectaddr)
{
- if (chn && chn->state==PICA_CHANSTATE_ACTIVE)
+ 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)
{
- 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);
+ fprintf(stderr, "failed to create listener, error code: %i\n", ret);
+ l = NULL;
}
+
}
-while(PICA_read(c,100000) == PICA_OK && PICA_write(c) == PICA_OK);
-/*
-puts("Enter peer_id to talk with or . for waiting incoming sessions:");
-gets(buf);
-if (buf[0]=='.')
+ 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, nodeaddr, atoi(nodeport), directc2c_cfg, l, &c);
+
+ ERR_print_errors_fp(stdout);
+
+ if (ret == PICA_OK)
+ printf("PICA_OK started c2n connection to node...\n");
+ else
{
- unsigned int br;
- ret=PICA_read_conn(c,accept_cb,&chn);
+ printf("PICA_new_c2n: ret=%i\n", ret);
+ return 1;
+ }
+
+ c2ns[0] = c;
+
- if (ret==PICA_NEWCHAN)
+ 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)
+ {
+ if (PICA_id_from_base64(peerid, peer_id) == NULL)
{
- puts("PICA_NEWCHAN!");
+ puts("invalid peer_id");
+ return 1;
}
- else
- printf("read_conn error: ret=%i\n",ret);
-
- ret=PICA_read_msg(chn,buf,&br);
- switch(ret)
+
+ printf("Creating c2c to %s...\n", PICA_id_to_base64(peer_id, NULL));
+
+ ret = PICA_new_c2c(c, peer_id, l, &chn);
+ //sleep(17);//timeout test
+ if (ret != PICA_OK)
{
- case PICA_MSGUTF8:
- printf("%u (%u bytes): ",c->id,br);
- puts(buf);
- break;
- case PICA_MSGOK:
- puts("[v]");
- break;
+ printf("error: ret=%i\n", ret);
+ return 1;
+ }
+
+ printf("chn = %p\n", chn);
+ c2c_in_progress = 1;
+
+ }
+
+ if (random_message_mode && connected_to_node == 1 && c2c_active == 1 && rmm_wait_for_reply == 0)
+ {
+ static int test_stage = 0;
+
+ switch(test_stage)
+ {
+ //send zero-length message
+ case 0:
+ ret = PICA_send_msg(chn, NULL, 0);
+ test_stage++;
+ rmm_wait_for_reply = 1;
+ 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++;
+ rmm_wait_for_reply = 1;
+ 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++;
+ rmm_wait_for_reply = 1;
+ break;
+
default:
- printf("PICA_read_msg ret=%i\n",ret);
+ puts("waiting for test messages to be delivered");
}
- }
-else
- {
- peer_id=atoi(buf);
- printf("Creating channel to %u...\n",peer_id);
-
- ret=PICA_create_channel(c,peer_id,&chn,1);
- if (ret==PICA_OK)
+ 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)
{
- unsigned int msglen;
- puts("Channel 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);
+ 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)
+ {
+ perror("select() on stdin failed");
+ return 1;
+ }
+
+ 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);
+ }
+ }
+
+ 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;
}
- else
- printf("error: ret=%i\n",ret);
- }
-*/
-sleep(10);
-if (chn)
- {
- puts("--------");
- PICA_close_channel(chn);
}
-PICA_close_connection(c);
-return 0;
+
+ if (c)
+ PICA_close_c2n(c);
+
+ if(l)
+ PICA_close_listener(l);
+
+ return 0;
}