remove p11-kit in gnutls.spec file
[platform/upstream/gnutls.git] / tests / eagain-common.h
1 #define min(x,y) ((x)<(y)?(x):(y))
2
3 extern const char *side;
4
5 #define HANDSHAKE_EXPECT(c, s, clierr, serverr) \
6   sret = cret = GNUTLS_E_AGAIN; \
7   do \
8     { \
9       if (cret == GNUTLS_E_AGAIN) \
10         { \
11           side = "client"; \
12           cret = gnutls_handshake (c); \
13           if (cret == GNUTLS_E_INTERRUPTED) cret = GNUTLS_E_AGAIN; \
14         } \
15       if (sret == GNUTLS_E_AGAIN) \
16         { \
17           side = "server"; \
18           sret = gnutls_handshake (s); \
19           if (sret == GNUTLS_E_INTERRUPTED) sret = GNUTLS_E_AGAIN; \
20         } \
21     } \
22   while ((cret == GNUTLS_E_AGAIN || (cret == 0 && sret == GNUTLS_E_AGAIN)) && (sret == GNUTLS_E_AGAIN || (sret == 0 && cret == GNUTLS_E_AGAIN))); \
23   if (cret != clierr || sret != serverr) \
24     { \
25       fprintf(stderr, "client: %s\n", gnutls_strerror(cret)); \
26       fprintf(stderr, "server: %s\n", gnutls_strerror(sret)); \
27       fail("Handshake failed\n"); \
28       exit(1); \
29     }
30
31 #define HANDSHAKE(c, s) \
32   HANDSHAKE_EXPECT(c,s,0,0)
33
34 #define HANDSHAKE_DTLS_EXPECT(c, s, clierr, serverr) \
35   sret = cret = GNUTLS_E_LARGE_PACKET; \
36   do \
37     { \
38       if (cret == GNUTLS_E_LARGE_PACKET) \
39         { \
40           unsigned int mtu = gnutls_dtls_get_mtu(s); \
41           gnutls_dtls_set_mtu(s, mtu/2); \
42         } \
43       if (cret < 0 && gnutls_error_is_fatal(cret) == 0) \
44         { \
45           side = "client"; \
46           cret = gnutls_handshake (c); \
47         } \
48       if (sret == GNUTLS_E_LARGE_PACKET) \
49         { \
50           unsigned int mtu = gnutls_dtls_get_mtu(s); \
51           gnutls_dtls_set_mtu(s, mtu/2); \
52         } \
53       if (sret < 0 && gnutls_error_is_fatal(sret) == 0) \
54         { \
55           side = "server"; \
56           sret = gnutls_handshake (s); \
57         } \
58     } \
59   while (((gnutls_error_is_fatal(cret) == 0 && gnutls_error_is_fatal(sret) == 0)) && (cret < 0 || sret < 0)); \
60   if (cret != clierr || sret != serverr) \
61     { \
62       fprintf(stderr, "client: %s\n", gnutls_strerror(cret)); \
63       fprintf(stderr, "server: %s\n", gnutls_strerror(sret)); \
64       fail("Handshake failed\n"); \
65       exit(1); \
66     }
67
68 #define HANDSHAKE_DTLS(c, s) \
69   HANDSHAKE_DTLS_EXPECT(c,s,0,0)
70
71 #define HANDSHAKE(c, s) \
72   HANDSHAKE_EXPECT(c,s,0,0)
73
74 #define TRANSFER2(c, s, msg, msglen, buf, buflen, retry_send_with_null) \
75   side = "client"; \
76   ret = record_send_loop (c, msg, msglen, retry_send_with_null); \
77   \
78   if (ret < 0) fail ("client send error: %s\n", gnutls_strerror (ret)); \
79   \
80   do \
81     { \
82       do \
83         { \
84           side = "server"; \
85           ret = gnutls_record_recv (s, buf, buflen); \
86         } \
87       while(ret == GNUTLS_E_AGAIN); \
88       if (ret == 0) \
89         fail ("server: didn't receive any data\n"); \
90       else if (ret < 0) \
91         { \
92           fail ("server: error: %s\n", gnutls_strerror (ret)); \
93         } \
94       else \
95         { \
96           transferred += ret; \
97         } \
98       side = "server"; \
99       ns = record_send_loop (server, msg, msglen, retry_send_with_null); \
100       if (ns < 0) fail ("server send error: %s\n", gnutls_strerror (ret)); \
101       do \
102         { \
103           side = "client"; \
104           ret = gnutls_record_recv (client, buf, buflen); \
105         } \
106       while(ret == GNUTLS_E_AGAIN); \
107       if (ret == 0) \
108         { \
109           fail ("client: Peer has closed the TLS connection\n"); \
110         } \
111       else if (ret < 0) \
112         { \
113           if (debug) \
114             fputs ("!", stdout); \
115           fail ("client: Error: %s\n", gnutls_strerror (ret)); \
116         } \
117       else \
118         { \
119           if (msglen != ret || memcmp (buf, msg, msglen) != 0) \
120             { \
121               fail ("client: Transmitted data do not match\n"); \
122             } \
123           /* echo back */ \
124           side = "client"; \
125           ns = record_send_loop (client, buf, msglen, retry_send_with_null); \
126           if (ns < 0) fail ("client send error: %s\n", gnutls_strerror (ret)); \
127           transferred += ret; \
128           if (debug) \
129             fputs (".", stdout); \
130         } \
131     } \
132   while (transferred < 70000)
133
134 #define TRANSFER(c, s, msg, msglen, buf, buflen) \
135   TRANSFER2(c, s, msg, msglen, buf, buflen, 0); \
136   TRANSFER2(c, s, msg, msglen, buf, buflen, 1)
137
138 static char to_server[64 * 1024];
139 static size_t to_server_len = 0;
140
141 static char to_client[64 * 1024];
142 static size_t to_client_len = 0;
143
144 #ifdef RANDOMIZE
145 #define RETURN_RND_EAGAIN(session) \
146   static unsigned char rnd = 0; \
147   if (rnd++ % 2 == 0) \
148     { \
149       gnutls_transport_set_errno (session, EAGAIN); \
150       return -1; \
151     }
152 #else
153 #define RETURN_RND_EAGAIN(session)
154 #endif
155
156 #ifndef IGNORE_PUSH
157 static ssize_t
158 client_push(gnutls_transport_ptr_t tr, const void *data, size_t len)
159 {
160         size_t newlen;
161         RETURN_RND_EAGAIN(tr);
162
163         len = min(len, sizeof(to_server) - to_server_len);
164
165         newlen = to_server_len + len;
166         memcpy(to_server + to_server_len, data, len);
167         to_server_len = newlen;
168 #ifdef EAGAIN_DEBUG
169         fprintf(stderr, "eagain: pushed %d bytes to server (avail: %d)\n",
170                 (int) len, (int) to_server_len);
171 #endif
172         return len;
173 }
174
175 #endif
176
177 static ssize_t
178 client_pull(gnutls_transport_ptr_t tr, void *data, size_t len)
179 {
180         RETURN_RND_EAGAIN(tr);
181
182         if (to_client_len == 0) {
183 #ifdef EAGAIN_DEBUG
184                 fprintf(stderr,
185                         "eagain: Not enough data by server (asked for: %d, have: %d)\n",
186                         (int) len, (int) to_client_len);
187 #endif
188                 gnutls_transport_set_errno((gnutls_session_t) tr, EAGAIN);
189                 return -1;
190         }
191
192         len = min(len, to_client_len);
193
194         memcpy(data, to_client, len);
195
196         memmove(to_client, to_client + len, to_client_len - len);
197         to_client_len -= len;
198 #ifdef EAGAIN_DEBUG
199         fprintf(stderr, "eagain: pulled %d bytes by client (avail: %d)\n",
200                 (int) len, (int) to_client_len);
201 #endif
202         return len;
203 }
204
205 static ssize_t
206 server_pull(gnutls_transport_ptr_t tr, void *data, size_t len)
207 {
208         //success ("server_pull len %d has %d\n", len, to_server_len);
209         RETURN_RND_EAGAIN(tr);
210
211         if (to_server_len == 0) {
212 #ifdef EAGAIN_DEBUG
213                 fprintf(stderr,
214                         "eagain: Not enough data by client (asked for: %d, have: %d)\n",
215                         (int) len, (int) to_server_len);
216 #endif
217                 gnutls_transport_set_errno((gnutls_session_t) tr, EAGAIN);
218                 return -1;
219         }
220
221         len = min(len, to_server_len);
222 #ifdef EAGAIN_DEBUG
223         fprintf(stderr, "eagain: pulled %d bytes by server (avail: %d)\n",
224                 (int) len, (int) to_server_len);
225 #endif
226         memcpy(data, to_server, len);
227
228         memmove(to_server, to_server + len, to_server_len - len);
229         to_server_len -= len;
230
231         return len;
232 }
233
234 #ifndef IGNORE_PUSH
235 static ssize_t
236 server_push(gnutls_transport_ptr_t tr, const void *data, size_t len)
237 {
238         size_t newlen;
239         RETURN_RND_EAGAIN(tr);
240
241 //  hexprint (data, len);
242
243         len = min(len, sizeof(to_client) - to_client_len);
244
245         newlen = to_client_len + len;
246         memcpy(to_client + to_client_len, data, len);
247         to_client_len = newlen;
248 #ifdef EAGAIN_DEBUG
249         fprintf(stderr, "eagain: pushed %d bytes to client (avail: %d)\n",
250                 (int) len, (int) to_client_len);
251 #endif
252
253         return len;
254 }
255
256 #endif
257
258 /* inline is used to avoid a gcc warning if used in mini-eagain */
259 inline static int server_pull_timeout_func(gnutls_transport_ptr_t ptr,
260                                            unsigned int ms)
261 {
262         int ret;
263
264         if (to_server_len > 0)
265                 ret = 1;        /* available data */
266         else
267                 ret = 0;        /* timeout */
268
269 #ifdef EAGAIN_DEBUG
270         fprintf(stderr,
271                 "eagain: server_pull_timeout: %d (avail: cli %d, serv %d)\n",
272                 ret, (int) to_client_len, (int) to_server_len);
273 #endif
274
275         return ret;
276 }
277
278 inline static int client_pull_timeout_func(gnutls_transport_ptr_t ptr,
279                                            unsigned int ms)
280 {
281         int ret;
282
283         if (to_client_len > 0)
284                 ret = 1;
285         else
286                 ret = 0;
287
288 #ifdef EAGAIN_DEBUG
289         fprintf(stderr,
290                 "eagain: client_pull_timeout: %d (avail: cli %d, serv %d)\n",
291                 ret, (int) to_client_len, (int) to_server_len);
292 #endif
293
294         return ret;
295 }
296
297 inline static void reset_buffers(void)
298 {
299         to_server_len = 0;
300         to_client_len = 0;
301 }
302
303 inline static int record_send_loop(gnutls_session_t session,
304                                    const void *data, size_t sizeofdata,
305                                    int use_null_on_retry)
306 {
307         int ret;
308         const void *retry_data;
309         size_t retry_sizeofdata;
310
311         if (use_null_on_retry) {
312                 retry_data = 0;
313                 retry_sizeofdata = 0;
314         } else {
315                 retry_data = data;
316                 retry_sizeofdata = sizeofdata;
317         }
318
319         ret = gnutls_record_send(session, data, sizeofdata);
320         while (ret == GNUTLS_E_AGAIN) {
321                 ret =
322                     gnutls_record_send(session, retry_data,
323                                        retry_sizeofdata);
324         }
325
326         return ret;
327 }