summaryrefslogtreecommitdiffstats
path: root/PICA_client.h
blob: d98a60709d756635599bf2646c4185c1dabafee9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#ifndef PICA_CLIENT_H
#define PICA_CLIENT_H

#include <time.h>

#ifdef WIN32

#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>

typedef unsigned __int16 uint16_t;

#else

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <signal.h>

#ifdef PICA_MULTITHREADED
#include <pthread.h>
#endif

#define SOCKET int
#define SOCKET_ERROR -1

#endif

#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/bio.h>
#include <openssl/rand.h>

#ifdef PICA_MULTITHREADED

#define OPENSSL_THREAD_DEFINES
#include <openssl/opensslconf.h>
#if defined(OPENSSL_THREADS)
  // thread support enabled
#else
#error "THREAD SUPPORT IS NOT ENABLED IN OPENSSL!"
#endif

#endif

//#define PICA_MSGOK 3
//#define PICA_MSGUTF8 2
#define PICA_NEWCHAN 1
#define PICA_OK 0
#define PICA_ERRINVARG -1
#define PICA_ERRNOMEM -2
#define PICA_ERRSSL -3
#define PICA_ERRSOCK -4
#define PICA_ERRSERV -5
//#define PICA_ERRVERDIFFER -6
#define PICA_ERRNOTFOUND -7
#define PICA_ERRNOPEERCERT -8
#define PICA_ERRINVPEERCERT -9
#define PICA_ERRDISCONNECT -10
#define PICA_ERRINVCERT -11
#define PICA_ERRMSGSIZE -12
#define PICA_ERRDNSRESOLVE -13

#define PICA_ERRPROTOOLD -14
#define PICA_ERRPROTONEW -15

//#define PICA_CHNMSGBUFLEN 104

#define PICA_CHANREADBUFSIZE 65536
#define PICA_CHANWRITEBUFSIZE 4096
#define PICA_CONNREADBUFSIZE 65536
#define PICA_CONNWRITEBUFSIZE 4096

#define PICA_CHANSTATE_ACTIVE 13
#define PICA_CONNSTATE_CONNECTING 17
#define PICA_CONNSTATE_CONNECTED 19

#define PICA_CHAN_ACTIVATE_TIMEOUT 30

struct PICA_conninfo;
struct PICA_chaninfo;

struct PICA_conninfo
{
//#warning "sockaddr!"
struct sockaddr_in srv_addr; // sockaddr !!
unsigned int id;
SSL_CTX* ctx;
SOCKET sck_comm;
SSL* ssl_comm;
//сертификат клиента
// unsigned char r_buf[128];
// unsigned int r_pos;

int state;

unsigned char *read_buf;
unsigned char *write_buf;
unsigned int read_pos;
unsigned int write_pos;
unsigned int write_buflen;

struct PICA_chaninfo *chan_list_head;
struct PICA_chaninfo *chan_list_end;

int init_resp_ok;
unsigned char node_ver_major, node_ver_minor;
};

struct PICA_chaninfo
{
struct PICA_conninfo *conn;//соединение с сервером, через которое установлен данный логический канал связи
unsigned int peer_id;//номер собеседника
SOCKET sck_data;
SSL *ssl;
int outgoing;//1 если создание канала инициировано локальным клиентом, 0 - если собеседником
X509 *peer_cert;
//unsigned char msgbuf[PICA_CHNMSGBUFLEN];

unsigned char *read_buf;
unsigned char *write_buf;
unsigned int read_pos;
unsigned int write_pos;
unsigned int write_buflen;

struct PICA_chaninfo *next;
struct PICA_chaninfo *prev;
int state;
time_t timestamp;
};

struct PICA_client_callbacks
{
//получение сообщения.
void (*newmsg_cb)(unsigned int peer_id,char* msgbuf,unsigned int nb,int type);
//получение подтверждения о доставке сообщения
void (*msgok_cb)(unsigned int peer_id);
//создание канала с собеседником
void (*channel_established_cb)(unsigned int peer_id);
//создать канал не удалось		
void (*channel_failed)(unsigned int peer_id);
//входящий запрос на создание канала от пользователя с номером caller_id
//возвращаемое значение: 0 - отклонить запрос, ненулевое значение - принять запрос
int (*accept_cb)(unsigned int caller_id);
//запрошенный пользователь не найден, в оффлайне или отказался от общения
void (*notfound_cb)(unsigned int callee_id);
//
void (*channel_closed_cb)(unsigned int peer_id, int reason);

void (*nodelist_cb)(int type, void *addr_bin, const char *addr_str, unsigned int port);
//сертификат собеседника в формате PEM. Функция должна сравнить предъявленный сертификат с сохранённым (если есть) и вернуть 1 при успешной проверке, 0 - при неуспешной
int (*peer_cert_verify_cb)(unsigned int peer_id, const char *cert_pem, unsigned int nb);
};

 	

#ifdef __cplusplus
extern "C" {
#endif

int PICA_get_id_from_cert(const char *cert_file, unsigned int *p_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* password,
          int (*password_cb)(char *buf, int size, int rwflag, void *userdata),
	  struct PICA_conninfo **ci);

int PICA_create_channel(struct PICA_conninfo *ci,unsigned int uid,struct PICA_chaninfo **chn);
int PICA_read_c2n(struct PICA_conninfo *ci);

int PICA_read(struct PICA_conninfo *ci,int timeout);
int PICA_write(struct PICA_conninfo *ci);

int PICA_send_msg(struct PICA_chaninfo *chn, char *buf,unsigned int len);
int PICA_read_msg(struct PICA_chaninfo *chn,char *buf,unsigned int *n);

void PICA_close_channel(struct PICA_chaninfo *chn);
void PICA_close_connection(struct PICA_conninfo *cid);

#ifdef __cplusplus
}
#endif


#endif