Added simple check for bmpstring decoding.
[gnutls.git] / tests / eagain-common.h
blobc9aa0324eb94385cd8b1d0e593b381a060a04f8e
1 #define min(x,y) ((x)<(y)?(x):(y))
3 extern const char* side;
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 } \
14 if (sret == GNUTLS_E_AGAIN) \
15 { \
16 side = "server"; \
17 sret = gnutls_handshake (s); \
18 } \
19 } \
20 while ((cret == GNUTLS_E_AGAIN || (cret == 0 && sret == GNUTLS_E_AGAIN)) && (sret == GNUTLS_E_AGAIN || (sret == 0 && cret == GNUTLS_E_AGAIN))); \
21 if (cret != clierr || sret != serverr) \
22 { \
23 fprintf(stderr, "client: %s\n", gnutls_strerror(cret)); \
24 fprintf(stderr, "server: %s\n", gnutls_strerror(sret)); \
25 fail("Handshake failed\n"); \
26 exit(1); \
29 #define HANDSHAKE(c, s) \
30 HANDSHAKE_EXPECT(c,s,0,0)
32 #define HANDSHAKE_DTLS_EXPECT(c, s, clierr, serverr) \
33 sret = cret = GNUTLS_E_LARGE_PACKET; \
34 do \
35 { \
36 if (cret == GNUTLS_E_LARGE_PACKET) \
37 { \
38 unsigned int mtu = gnutls_dtls_get_mtu(s); \
39 gnutls_dtls_set_mtu(s, mtu/2); \
40 } \
41 if (cret < 0 && gnutls_error_is_fatal(cret) == 0) \
42 { \
43 side = "client"; \
44 cret = gnutls_handshake (c); \
45 } \
46 if (sret == GNUTLS_E_LARGE_PACKET) \
47 { \
48 unsigned int mtu = gnutls_dtls_get_mtu(s); \
49 gnutls_dtls_set_mtu(s, mtu/2); \
50 } \
51 if (sret < 0 && gnutls_error_is_fatal(sret) == 0) \
52 { \
53 side = "server"; \
54 sret = gnutls_handshake (s); \
55 } \
56 } \
57 while (((gnutls_error_is_fatal(cret) == 0 && gnutls_error_is_fatal(sret) == 0)) && (cret < 0 || sret < 0)); \
58 if (cret != clierr || sret != serverr) \
59 { \
60 fprintf(stderr, "client: %s\n", gnutls_strerror(cret)); \
61 fprintf(stderr, "server: %s\n", gnutls_strerror(sret)); \
62 fail("Handshake failed\n"); \
63 exit(1); \
66 #define HANDSHAKE_DTLS(c, s) \
67 HANDSHAKE_DTLS_EXPECT(c,s,0,0)
69 #define HANDSHAKE(c, s) \
70 HANDSHAKE_EXPECT(c,s,0,0)
72 #define TRANSFER(c, s, msg, msglen, buf, buflen) \
73 do \
74 { \
75 side = "client"; \
76 ret = gnutls_record_send (c, msg, msglen); \
77 } \
78 while(ret == GNUTLS_E_AGAIN); \
80 if (ret < 0) fail ("client send error: %s\n", gnutls_strerror (ret)); \
82 do \
83 { \
84 do \
85 { \
86 side = "server"; \
87 ret = gnutls_record_recv (s, buf, buflen); \
88 } \
89 while(ret == GNUTLS_E_AGAIN); \
90 if (ret == 0) \
91 fail ("server: didn't receive any data\n"); \
92 else if (ret < 0) \
93 { \
94 fail ("server: error: %s\n", gnutls_strerror (ret)); \
95 } \
96 else \
97 { \
98 transferred += ret; \
99 } \
100 do \
102 side = "server"; \
103 ns = gnutls_record_send (server, msg, msglen); \
105 while (ns == GNUTLS_E_AGAIN); \
106 if (ns < 0) fail ("server send error: %s\n", gnutls_strerror (ret)); \
107 do \
109 side = "client"; \
110 ret = gnutls_record_recv (client, buf, buflen); \
112 while(ret == GNUTLS_E_AGAIN); \
113 if (ret == 0) \
115 fail ("client: Peer has closed the TLS connection\n"); \
117 else if (ret < 0) \
119 if (debug) \
120 fputs ("!", stdout); \
121 fail ("client: Error: %s\n", gnutls_strerror (ret)); \
123 else \
125 if (msglen != ret || memcmp (buf, msg, msglen) != 0) \
127 fail ("client: Transmitted data do not match\n"); \
129 /* echo back */ \
130 do \
132 side = "client"; \
133 ns = gnutls_record_send (client, buf, msglen); \
135 while (ns == GNUTLS_E_AGAIN); \
136 if (ns < 0) fail ("client send error: %s\n", gnutls_strerror (ret)); \
137 transferred += ret; \
138 if (debug) \
139 fputs (".", stdout); \
142 while (transferred < 70000)
144 static char to_server[64*1024];
145 static size_t to_server_len = 0;
147 static char to_client[64*1024];
148 static size_t to_client_len = 0;
150 #ifdef RANDOMIZE
151 #define RETURN_RND_EAGAIN(session) \
152 static unsigned char rnd = 0; \
153 if (rnd++ % 2 == 0) \
155 gnutls_transport_set_errno (session, EAGAIN); \
156 return -1; \
158 #else
159 #define RETURN_RND_EAGAIN(session)
160 #endif
162 #ifndef IGNORE_PUSH
163 static ssize_t
164 client_push (gnutls_transport_ptr_t tr, const void *data, size_t len)
166 size_t newlen;
167 RETURN_RND_EAGAIN(tr);
169 len = min(len, sizeof(to_server)-to_server_len);
171 newlen = to_server_len + len;
172 memcpy (to_server + to_server_len, data, len);
173 to_server_len = newlen;
174 #ifdef EAGAIN_DEBUG
175 fprintf(stderr, "eagain: pushed %d bytes to server (avail: %d)\n", (int)len, (int)to_server_len);
176 #endif
177 return len;
180 #endif
182 static ssize_t
183 client_pull (gnutls_transport_ptr_t tr, void *data, size_t len)
185 RETURN_RND_EAGAIN(tr);
187 if (to_client_len == 0)
189 #ifdef EAGAIN_DEBUG
190 fprintf(stderr, "eagain: Not enough data by server (asked for: %d, have: %d)\n", (int)len, (int)to_client_len);
191 #endif
192 gnutls_transport_set_errno ((gnutls_session_t)tr, EAGAIN);
193 return -1;
196 len = min(len, to_client_len);
198 memcpy (data, to_client, len);
200 memmove (to_client, to_client + len, to_client_len - len);
201 to_client_len -= len;
202 #ifdef EAGAIN_DEBUG
203 fprintf(stderr, "eagain: pulled %d bytes by client (avail: %d)\n", (int)len, (int)to_client_len);
204 #endif
205 return len;
208 static ssize_t
209 server_pull (gnutls_transport_ptr_t tr, void *data, size_t len)
211 //success ("server_pull len %d has %d\n", len, to_server_len);
212 RETURN_RND_EAGAIN(tr);
214 if (to_server_len == 0)
216 #ifdef EAGAIN_DEBUG
217 fprintf(stderr, "eagain: Not enough data by client (asked for: %d, have: %d)\n", (int)len, (int)to_server_len);
218 #endif
219 gnutls_transport_set_errno ((gnutls_session_t)tr, EAGAIN);
220 return -1;
223 len = min(len, to_server_len);
224 #ifdef EAGAIN_DEBUG
225 fprintf(stderr, "eagain: pulled %d bytes by server (avail: %d)\n", (int)len, (int)to_server_len);
226 #endif
227 memcpy (data, to_server, len);
229 memmove (to_server, to_server + len, to_server_len - len);
230 to_server_len -= len;
232 return len;
235 #ifndef IGNORE_PUSH
236 static ssize_t
237 server_push (gnutls_transport_ptr_t tr, const void *data, size_t len)
239 size_t newlen;
240 RETURN_RND_EAGAIN(tr);
242 // hexprint (data, len);
244 len = min(len, sizeof(to_client)-to_client_len);
246 newlen = to_client_len + len;
247 memcpy (to_client + to_client_len, data, len);
248 to_client_len = newlen;
249 #ifdef EAGAIN_DEBUG
250 fprintf(stderr, "eagain: pushed %d bytes to client (avail: %d)\n", (int)len, (int)to_client_len);
251 #endif
253 return len;
256 #endif
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, unsigned int ms)
261 int ret;
263 if (to_server_len > 0)
264 ret = 1; /* available data */
265 else
266 ret = 0; /* timeout */
268 #ifdef EAGAIN_DEBUG
269 fprintf(stderr, "eagain: server_pull_timeout: %d (avail: cli %d, serv %d)\n", ret, (int)to_client_len, (int)to_server_len);
270 #endif
272 return ret;
275 inline static int client_pull_timeout_func(gnutls_transport_ptr_t ptr, unsigned int ms)
277 int ret;
279 if (to_client_len > 0)
280 ret = 1;
281 else
282 ret = 0;
284 #ifdef EAGAIN_DEBUG
285 fprintf(stderr, "eagain: client_pull_timeout: %d (avail: cli %d, serv %d)\n", ret, (int)to_client_len, (int)to_server_len);
286 #endif
288 return ret;
291 inline static void reset_buffers(void)
293 to_server_len = 0;
294 to_client_len = 0;