summaryrefslogtreecommitdiffstats
path: root/PICA_client.h
diff options
context:
space:
mode:
Diffstat (limited to 'PICA_client.h')
-rw-r--r--[-rwxr-xr-x]PICA_client.h308
1 files changed, 211 insertions, 97 deletions
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