aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2018-02-27 23:16:00 +0100
committerChristian Grothoff <christian@grothoff.org>2018-02-27 23:16:00 +0100
commit46bbae5663de2e71f613728df2e0849bfcfb573e (patch)
treeb46961b32f80575451def61dda501378d5477fea
parent11f599e039f8581eb6402a469e1dfdf0ec088ccd (diff)
downloadlibmicrohttpd-46bbae5663de2e71f613728df2e0849bfcfb573e.tar.gz
libmicrohttpd-46bbae5663de2e71f613728df2e0849bfcfb573e.zip
fix a few memory leaks in test_upgrade logic
-rw-r--r--src/microhttpd/test_upgrade.c116
1 files changed, 61 insertions, 55 deletions
diff --git a/src/microhttpd/test_upgrade.c b/src/microhttpd/test_upgrade.c
index db2efe38..fa4ffd21 100644
--- a/src/microhttpd/test_upgrade.c
+++ b/src/microhttpd/test_upgrade.c
@@ -143,7 +143,7 @@ gnutlscli_connect (int *sock,
143/** 143/**
144 * Wrapper structure for plain&TLS sockets 144 * Wrapper structure for plain&TLS sockets
145 */ 145 */
146struct wr_socket_strc 146struct wr_socket
147{ 147{
148 /** 148 /**
149 * Real network socket 149 * Real network socket
@@ -179,18 +179,6 @@ struct wr_socket_strc
179 179
180 180
181/** 181/**
182 * Pseudo type for plain&TLS sockets
183 */
184typedef struct wr_socket_strc* wr_socket;
185
186
187/**
188 * Invalid value of wr_socket
189 */
190#define WR_BAD (NULL)
191
192
193/**
194 * Get underlying real socket. 182 * Get underlying real socket.
195 * @return FD of real socket 183 * @return FD of real socket
196 */ 184 */
@@ -199,34 +187,34 @@ typedef struct wr_socket_strc* wr_socket;
199 187
200/** 188/**
201 * Create wr_socket with plain TCP underlying socket 189 * Create wr_socket with plain TCP underlying socket
202 * @return created socket on success, WR_BAD otherwise 190 * @return created socket on success, NULL otherwise
203 */ 191 */
204static wr_socket 192static struct wr_socket *
205wr_create_plain_sckt(void) 193wr_create_plain_sckt(void)
206{ 194{
207 wr_socket s = (wr_socket)malloc(sizeof(struct wr_socket_strc)); 195 struct wr_socket *s = malloc(sizeof(struct wr_socket));
208 if (WR_BAD == s) 196 if (NULL == s)
209 return WR_BAD; 197 return NULL;
210 s->t = wr_plain; 198 s->t = wr_plain;
211 s->fd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); 199 s->fd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
212 if (MHD_INVALID_SOCKET != s->fd) 200 if (MHD_INVALID_SOCKET != s->fd)
213 return s; 201 return s;
214 free(s); 202 free(s);
215 return WR_BAD; 203 return NULL;
216} 204}
217 205
218 206
219/** 207/**
220 * Create wr_socket with TLS TCP underlying socket 208 * Create wr_socket with TLS TCP underlying socket
221 * @return created socket on success, WR_BAD otherwise 209 * @return created socket on success, NULL otherwise
222 */ 210 */
223static wr_socket 211static struct wr_socket *
224wr_create_tls_sckt(void) 212wr_create_tls_sckt(void)
225{ 213{
226#ifdef HTTPS_SUPPORT 214#ifdef HTTPS_SUPPORT
227 wr_socket s = (wr_socket)malloc(sizeof(struct wr_socket_strc)); 215 struct wr_socket *s = malloc(sizeof(struct wr_socket));
228 if (WR_BAD == s) 216 if (NULL == s)
229 return WR_BAD; 217 return NULL;
230 s->t = wr_tls; 218 s->t = wr_tls;
231 s->tls_connected = 0; 219 s->tls_connected = 0;
232 s->fd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); 220 s->fd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
@@ -256,7 +244,7 @@ wr_create_tls_sckt(void)
256 } 244 }
257 free(s); 245 free(s);
258#endif /* HTTPS_SUPPORT */ 246#endif /* HTTPS_SUPPORT */
259 return WR_BAD; 247 return NULL;
260} 248}
261 249
262 250
@@ -264,15 +252,15 @@ wr_create_tls_sckt(void)
264 * Create wr_socket with plain TCP underlying socket 252 * Create wr_socket with plain TCP underlying socket
265 * from already created TCP socket. 253 * from already created TCP socket.
266 * @param plain_sk real TCP socket 254 * @param plain_sk real TCP socket
267 * @return created socket on success, WR_BAD otherwise 255 * @return created socket on success, NULL otherwise
268 */ 256 */
269static wr_socket 257static struct wr_socket *
270wr_create_from_plain_sckt(MHD_socket plain_sk) 258wr_create_from_plain_sckt(MHD_socket plain_sk)
271{ 259{
272 wr_socket s = (wr_socket)malloc(sizeof(struct wr_socket_strc)); 260 struct wr_socket *s = malloc(sizeof(struct wr_socket));
273 261
274 if (WR_BAD == s) 262 if (NULL == s)
275 return WR_BAD; 263 return NULL;
276 s->t = wr_plain; 264 s->t = wr_plain;
277 s->fd = plain_sk; 265 s->fd = plain_sk;
278 return s; 266 return s;
@@ -287,7 +275,7 @@ wr_create_from_plain_sckt(MHD_socket plain_sk)
287 * @return zero on success, -1 otherwise. 275 * @return zero on success, -1 otherwise.
288 */ 276 */
289static int 277static int
290wr_connect(wr_socket s, 278wr_connect(struct wr_socket *s,
291 const struct sockaddr *addr, 279 const struct sockaddr *addr,
292 int length) 280 int length)
293{ 281{
@@ -312,7 +300,8 @@ wr_connect(wr_socket s,
312 300
313#ifdef HTTPS_SUPPORT 301#ifdef HTTPS_SUPPORT
314/* Only to be called from wr_send() and wr_recv() ! */ 302/* Only to be called from wr_send() and wr_recv() ! */
315static bool wr_handshake(wr_socket s) 303static bool
304wr_handshake(struct wr_socket *s)
316{ 305{
317 int res = gnutls_handshake (s->tls_s); 306 int res = gnutls_handshake (s->tls_s);
318 if (GNUTLS_E_SUCCESS == res) 307 if (GNUTLS_E_SUCCESS == res)
@@ -336,7 +325,7 @@ static bool wr_handshake(wr_socket s)
336 * to get socket error. 325 * to get socket error.
337 */ 326 */
338static ssize_t 327static ssize_t
339wr_send (wr_socket s, 328wr_send (struct wr_socket *s,
340 const void *buf, 329 const void *buf,
341 size_t len) 330 size_t len)
342{ 331{
@@ -372,7 +361,7 @@ wr_send (wr_socket s,
372 * to get socket error. 361 * to get socket error.
373 */ 362 */
374static ssize_t 363static ssize_t
375wr_recv (wr_socket s, 364wr_recv (struct wr_socket *s,
376 void *buf, 365 void *buf,
377 size_t len) 366 size_t len)
378{ 367{
@@ -404,7 +393,7 @@ wr_recv (wr_socket s,
404 * @return zero on succeed, -1 otherwise 393 * @return zero on succeed, -1 otherwise
405 */ 394 */
406static int 395static int
407wr_close (wr_socket s) 396wr_close (struct wr_socket *s)
408{ 397{
409 int ret = (MHD_socket_close_(s->fd)) ? 0 : -1; 398 int ret = (MHD_socket_close_(s->fd)) ? 0 : -1;
410#ifdef HTTPS_SUPPORT 399#ifdef HTTPS_SUPPORT
@@ -414,7 +403,7 @@ wr_close (wr_socket s)
414 gnutls_certificate_free_credentials (s->tls_crd); 403 gnutls_certificate_free_credentials (s->tls_crd);
415 } 404 }
416#endif /* HTTPS_SUPPORT */ 405#endif /* HTTPS_SUPPORT */
417 free(s); 406 free (s);
418 return ret; 407 return ret;
419} 408}
420 409
@@ -427,7 +416,7 @@ static pthread_t pt;
427/** 416/**
428 * Will be set to the upgraded socket. 417 * Will be set to the upgraded socket.
429 */ 418 */
430static wr_socket usock; 419static struct wr_socket *usock;
431 420
432/** 421/**
433 * Thread we use to run the interaction with the upgraded socket. 422 * Thread we use to run the interaction with the upgraded socket.
@@ -440,20 +429,34 @@ static pthread_t pt_client;
440static volatile bool done; 429static volatile bool done;
441 430
442 431
432/**
433 * Callback used by MHD to notify the application about completed
434 * requests. Frees memory.
435 *
436 * @param cls client-defined closure
437 * @param connection connection handle
438 * @param con_cls value as set by the last call to
439 * the #MHD_AccessHandlerCallback
440 * @param toe reason for request termination
441 */
443static void 442static void
444notify_completed_cb (void *cls, 443notify_completed_cb (void *cls,
445 struct MHD_Connection *connection, 444 struct MHD_Connection *connection,
446 void **con_cls, 445 void **con_cls,
447 enum MHD_RequestTerminationCode toe) 446 enum MHD_RequestTerminationCode toe)
448{ 447{
448 pthread_t* ppth = *con_cls;
449
449 (void)cls; (void)connection; /* Unused. Silent compiler warning. */ 450 (void)cls; (void)connection; /* Unused. Silent compiler warning. */
450 if ( (toe != MHD_REQUEST_TERMINATED_COMPLETED_OK) && 451 if ( (toe != MHD_REQUEST_TERMINATED_COMPLETED_OK) &&
451 (toe != MHD_REQUEST_TERMINATED_CLIENT_ABORT) && 452 (toe != MHD_REQUEST_TERMINATED_CLIENT_ABORT) &&
452 (toe != MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN) ) 453 (toe != MHD_REQUEST_TERMINATED_DAEMON_SHUTDOWN) )
453 abort (); 454 abort ();
454 if (! pthread_equal (**((pthread_t**)con_cls), pthread_self ())) 455 if (! pthread_equal (**((pthread_t**)con_cls),
456 pthread_self ()))
455 abort (); 457 abort ();
456 free (*con_cls); 458 if (NULL != ppth)
459 free (*con_cls);
457 *con_cls = NULL; 460 *con_cls = NULL;
458} 461}
459 462
@@ -561,7 +564,7 @@ make_blocking (MHD_socket fd)
561 564
562 565
563static void 566static void
564send_all (wr_socket sock, 567send_all (struct wr_socket *sock,
565 const char *text) 568 const char *text)
566{ 569{
567 size_t len = strlen (text); 570 size_t len = strlen (text);
@@ -572,8 +575,8 @@ send_all (wr_socket sock,
572 for (off = 0; off < len; off += ret) 575 for (off = 0; off < len; off += ret)
573 { 576 {
574 ret = wr_send (sock, 577 ret = wr_send (sock,
575 &text[off], 578 &text[off],
576 len - off); 579 len - off);
577 if (0 > ret) 580 if (0 > ret)
578 { 581 {
579 if (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ())) 582 if (MHD_SCKT_ERR_IS_EAGAIN_ (MHD_socket_get_error_ ()))
@@ -592,7 +595,7 @@ send_all (wr_socket sock,
592 * get '\r\n\r\n'. 595 * get '\r\n\r\n'.
593 */ 596 */
594static void 597static void
595recv_hdr (wr_socket sock) 598recv_hdr (struct wr_socket *sock)
596{ 599{
597 unsigned int i; 600 unsigned int i;
598 char next; 601 char next;
@@ -637,7 +640,7 @@ recv_hdr (wr_socket sock)
637 640
638 641
639static void 642static void
640recv_all (wr_socket sock, 643recv_all (struct wr_socket *sock,
641 const char *text) 644 const char *text)
642{ 645{
643 size_t len = strlen (text); 646 size_t len = strlen (text);
@@ -685,6 +688,8 @@ run_usock (void *cls)
685 "Finished"); 688 "Finished");
686 MHD_upgrade_action (urh, 689 MHD_upgrade_action (urh,
687 MHD_UPGRADE_ACTION_CLOSE); 690 MHD_UPGRADE_ACTION_CLOSE);
691 free (usock);
692 usock = NULL;
688 return NULL; 693 return NULL;
689} 694}
690 695
@@ -698,18 +703,18 @@ run_usock (void *cls)
698static void * 703static void *
699run_usock_client (void *cls) 704run_usock_client (void *cls)
700{ 705{
701 wr_socket *sock = cls; 706 struct wr_socket *sock = cls;
702 707
703 send_all (*sock, 708 send_all (sock,
704 "GET / HTTP/1.1\r\nConnection: Upgrade\r\n\r\n"); 709 "GET / HTTP/1.1\r\nConnection: Upgrade\r\n\r\n");
705 recv_hdr (*sock); 710 recv_hdr (sock);
706 recv_all (*sock, 711 recv_all (sock,
707 "Hello"); 712 "Hello");
708 send_all (*sock, 713 send_all (sock,
709 "World"); 714 "World");
710 recv_all (*sock, 715 recv_all (sock,
711 "Finished"); 716 "Finished");
712 wr_close (*sock); 717 wr_close (sock);
713 done = true; 718 done = true;
714 return NULL; 719 return NULL;
715} 720}
@@ -979,6 +984,7 @@ run_mhd_loop (struct MHD_Daemon *daemon,
979 abort (); 984 abort ();
980} 985}
981 986
987
982static bool test_tls; 988static bool test_tls;
983 989
984/** 990/**
@@ -992,7 +998,7 @@ test_upgrade (int flags,
992 unsigned int pool) 998 unsigned int pool)
993{ 999{
994 struct MHD_Daemon *d = NULL; 1000 struct MHD_Daemon *d = NULL;
995 wr_socket sock; 1001 struct wr_socket *sock;
996 struct sockaddr_in sa; 1002 struct sockaddr_in sa;
997 const union MHD_DaemonInfo *real_flags; 1003 const union MHD_DaemonInfo *real_flags;
998 const union MHD_DaemonInfo *dinfo; 1004 const union MHD_DaemonInfo *dinfo;
@@ -1039,7 +1045,7 @@ test_upgrade (int flags,
1039 if (!test_tls || TLS_LIB_GNUTLS == use_tls_tool) 1045 if (!test_tls || TLS_LIB_GNUTLS == use_tls_tool)
1040 { 1046 {
1041 sock = test_tls ? wr_create_tls_sckt () : wr_create_plain_sckt (); 1047 sock = test_tls ? wr_create_tls_sckt () : wr_create_plain_sckt ();
1042 if (WR_BAD == sock) 1048 if (NULL == sock)
1043 abort (); 1049 abort ();
1044 sa.sin_family = AF_INET; 1050 sa.sin_family = AF_INET;
1045 sa.sin_port = htons (dinfo->port); 1051 sa.sin_port = htons (dinfo->port);
@@ -1059,7 +1065,7 @@ test_upgrade (int flags,
1059 return 4; 1065 return 4;
1060 } 1066 }
1061 sock = wr_create_from_plain_sckt (tls_fork_sock); 1067 sock = wr_create_from_plain_sckt (tls_fork_sock);
1062 if (WR_BAD == sock) 1068 if (NULL == sock)
1063 abort (); 1069 abort ();
1064#else /* !HTTPS_SUPPORT || !HAVE_FORK || !HAVE_WAITPID */ 1070#else /* !HTTPS_SUPPORT || !HAVE_FORK || !HAVE_WAITPID */
1065 abort (); 1071 abort ();
@@ -1069,7 +1075,7 @@ test_upgrade (int flags,
1069 if (0 != pthread_create (&pt_client, 1075 if (0 != pthread_create (&pt_client,
1070 NULL, 1076 NULL,
1071 &run_usock_client, 1077 &run_usock_client,
1072 &sock)) 1078 sock))
1073 abort (); 1079 abort ();
1074 if (0 == (flags & MHD_USE_INTERNAL_POLLING_THREAD) ) 1080 if (0 == (flags & MHD_USE_INTERNAL_POLLING_THREAD) )
1075 run_mhd_loop (d, real_flags->flags); 1081 run_mhd_loop (d, real_flags->flags);