diff --git a/ChangeLog b/ChangeLog index 83e5826..f991d56 100644 --- a/ChangeLog +++ b/ChangeLog @@ -233,6 +233,18 @@ Version 1.8.0 Version 1.6.10 ******************************************************************************* +2010-11-10 Fabrice Fontaine + + Add --disable-blocking-tcp-connections flag. + + Currently, pupnp is using a blocking connect to sends GENA + notifications. As a result, when there is a lot of notifications with + CPs which were disconnected without unsusbcribing, all the pupnp + threads are blocked for 20s (timeout). To correct this issue, this + patch replace the call to connect with a call to private_connect and add + a compilation flag to disable blocking TCP connections, so if we are not + able to connect to the CP, the notification is lost. + 2010-11-07 Stefan Sommerfeld Several patches for windows compatibility and fixing warnings. diff --git a/build/inc/autoconfig.h b/build/inc/autoconfig.h index 7f0ec25..40d846b 100644 --- a/build/inc/autoconfig.h +++ b/build/inc/autoconfig.h @@ -114,6 +114,9 @@ /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 +/* see upnpconfig.h */ +#define UPNP_ENABLE_BLOCKING_TCP_CONNECTIONS 1 + /* see upnpconfig.h */ /* #undef UPNP_ENABLE_IPV6 */ diff --git a/configure.ac b/configure.ac index 03eb4d1..60c6a0d 100644 --- a/configure.ac +++ b/configure.ac @@ -295,6 +295,11 @@ if test "x$enable_notification_reordering" = xyes ; then AC_DEFINE(UPNP_ENABLE_NOTIFICATION_REORDERING, 1, [see upnpconfig.h]) fi +RT_BOOL_ARG_ENABLE([blocking_tcp_connections], [yes], [blocking TCP connections]) +if test "x$enable_blocking_tcp_connections" = xyes ; then + AC_DEFINE(UPNP_ENABLE_BLOCKING_TCP_CONNECTIONS, 1, [see upnpconfig.h]) +fi + RT_BOOL_ARG_ENABLE([samples], [yes], [compilation of upnp/sample/ code]) diff --git a/upnp/src/genlib/net/http/httpreadwrite.c b/upnp/src/genlib/net/http/httpreadwrite.c index fa5bf0d..7666106 100644 --- a/upnp/src/genlib/net/http/httpreadwrite.c +++ b/upnp/src/genlib/net/http/httpreadwrite.c @@ -93,7 +93,10 @@ const int CHUNK_TAIL_SIZE = 10; #define CHUNK_TAIL_SIZE 10 -#ifdef UPNP_BLOCKING_CONNECT +#ifndef UPNP_ENABLE_BLOCKING_TCP_CONNECTIONS + +/* in seconds */ +#define DEFAULT_TCP_CONNECT_TIMEOUT 5 /************************************************************************ @@ -152,8 +155,6 @@ static int Make_Socket_Blocking(int sock) return 0; } -/* in seconds */ -#define DEFAULT_TCP_CONNECT_TIMEOUT 5 /************************************************************************ * Function : Check_Connect_And_Wait_Connection @@ -201,7 +202,7 @@ static int Check_Connect_And_Wait_Connection(int sock, int connect_res) #ifndef WIN32 } else { int valopt = 0; - socklen_t len; + socklen_t len = 0; if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *) &valopt, &len) < 0) { /* failed to read delayed error */ return -1; @@ -216,14 +217,14 @@ static int Check_Connect_And_Wait_Connection(int sock, int connect_res) return 0; } -#endif /* UPNP_BLOCKING_CONNECT */ +#endif /* UPNP_ENABLE_BLOCKING_TCP_CONNECTIONS */ static int private_connect( SOCKET sockfd, const struct sockaddr *serv_addr, socklen_t addrlen) { -#ifdef UPNP_BLOCKING_CONNECT +#ifndef UPNP_ENABLE_BLOCKING_TCP_CONNECTIONS int ret = Make_Socket_NoBlocking(sockfd); if (ret != - 1) { ret = connect(sockfd, serv_addr, addrlen); @@ -236,7 +237,7 @@ static int private_connect( return ret; #else return connect(sockfd, serv_addr, addrlen); -#endif /* UPNP_BLOCKING_CONNECT */ +#endif /* UPNP_ENABLE_BLOCKING_TCP_CONNECTIONS */ } @@ -336,7 +337,7 @@ SOCKET http_Connect( } sockaddr_len = url->hostport.IPaddress.ss_family == AF_INET6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in); - ret_connect = connect(connfd, + ret_connect = private_connect(connfd, (struct sockaddr *)&url->hostport.IPaddress, sockaddr_len); if (ret_connect == -1) { #ifdef WIN32