diff options
Diffstat (limited to 'PICA_client.h')
| -rw-r--r--[-rwxr-xr-x] | PICA_client.h | 308 |
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 |
