 pjlib/include/pj/sock.h    | 7 +++++++
 pjlib/src/pj/sock_bsd.c    | 9 +++++++++
 pjlib/src/pj/sock_common.c | 5 +++++
 pjlib/src/pj/sock_uwp.cpp  | 6 ++++++
 pjlib/src/pj/symbols.c     | 1 +
 5 files changed, 28 insertions(+)

diff --git a/pjlib/include/pj/sock.h b/pjlib/include/pj/sock.h
index 095a38335..e1349c52c 100644
--- a/pjlib/include/pj/sock.h
+++ b/pjlib/include/pj/sock.h
@@ -317,6 +317,7 @@ extern const pj_uint16_t PJ_SO_KEEPALIVE;
 extern const pj_uint16_t PJ_TCP_KEEPIDLE;
 extern const pj_uint16_t PJ_TCP_KEEPINTVL;
 extern const pj_uint16_t PJ_TCP_KEEPCNT;
+extern const pj_uint16_t PJ_TCP_USER_TIMEOUT;
 
 /** Set the protocol-defined priority for all packets to be sent on socket.
  */
@@ -360,6 +361,9 @@ extern const pj_uint16_t PJ_IP_DROP_MEMBERSHIP;
     /** Get #PJ_TCP_KEEPINTVL constant */
 #   define pj_TCP_KEEPINTVL() PJ_TCP_KEEPINTVL(void);
 
+    /** Get #PJ_TCP_USER_TIMEOUT constant */
+    PJ_DECL(pj_uint16_t) PJ_TCP_USER_TIMEOUT(void);
+
     /** Get #PJ_TCP_KEEPCNT constant */
 #   define pj_TCP_KEEPCNT() PJ_TCP_KEEPCNT(void);
 
@@ -405,6 +409,9 @@ extern const pj_uint16_t PJ_IP_DROP_MEMBERSHIP;
     /** Get #PJ_TCP_KEEPIDLE constant */
 #   define pj_TCP_KEEPIDLE() PJ_TCP_KEEPIDLE
 
+    /** Get #PJ_TCP_USER_TIMEOUT constant */
+#   define pj_TCP_USER_TIMEOUT() PJ_TCP_USER_TIMEOUT
+
     /** Get #PJ_TCP_KEEPINTVL constant */
 #   define pj_TCP_KEEPINTVL() PJ_TCP_KEEPINTVL
 
diff --git a/pjlib/src/pj/sock_bsd.c b/pjlib/src/pj/sock_bsd.c
index 0e9bfdbe9..e8bd94bee 100644
--- a/pjlib/src/pj/sock_bsd.c
+++ b/pjlib/src/pj/sock_bsd.c
@@ -162,6 +162,11 @@ const pj_uint16_t PJ_TCP_KEEPIDLE = TCP_KEEPIDLE;
 # ifdef TCP_KEEPINTVL
 const pj_uint16_t PJ_TCP_KEEPINTVL = TCP_KEEPINTVL;
 # endif
+# ifdef TCP_USER_TIMEOUT
+const pj_uint16_t PJ_TCP_USER_TIMEOUT = TCP_USER_TIMEOUT;
+#else
+const pj_uint16_t PJ_TCP_USER_TIMEOUT = 18;
+# endif
 # ifdef TCP_KEEPCNT
 const pj_uint16_t PJ_TCP_KEEPCNT = TCP_KEEPCNT;
 # endif
@@ -592,7 +597,11 @@ PJ_DEF(pj_status_t) pj_sock_socket(int af,
 			       &val, sizeof(val));
 	    pj_sock_setsockopt(*sock, pj_SOL_TCP(), pj_TCP_KEEPINTVL(),
 			       &val, sizeof(val));
+	    val = 30000;
+	    pj_sock_setsockopt(*sock, pj_SOL_TCP(), pj_TCP_USER_TIMEOUT(),
+			       &val, sizeof(val));
 	    val = 1;
+
 	}
 #if defined(PJ_SOCK_HAS_IPV6_V6ONLY) && PJ_SOCK_HAS_IPV6_V6ONLY != 0
 	if (af == PJ_AF_INET6) {
diff --git a/pjlib/src/pj/sock_common.c b/pjlib/src/pj/sock_common.c
index 6beb28590..1a0a38aee 100644
--- a/pjlib/src/pj/sock_common.c
+++ b/pjlib/src/pj/sock_common.c
@@ -1351,6 +1351,11 @@ PJ_DEF(pj_uint16_t) pj_SO_KEEPALIVE(void)
     return PJ_SO_KEEPALIVE;
 }
 
+PJ_DEF(pj_uint16_t) pj_TCP_USER_TIMEOUT(void)
+{
+    return PJ_TCP_USER_TIMEOUT;
+}
+
 PJ_DEF(pj_uint16_t) pj_TCP_NODELAY(void)
 {
     return PJ_TCP_NODELAY;
diff --git a/pjlib/src/pj/sock_uwp.cpp b/pjlib/src/pj/sock_uwp.cpp
index 34baebcee..4ba61cfd1 100644
--- a/pjlib/src/pj/sock_uwp.cpp
+++ b/pjlib/src/pj/sock_uwp.cpp
@@ -97,6 +97,12 @@ const pj_uint16_t PJ_SOL_TCP	= IPPROTO_TCP;
 const pj_uint16_t PJ_SOL_TCP	= 6;
 #endif /* SOL_TCP */
 
+#if defined(TCP_USER_TIMEOUT)
+const pj_uint16_t PJ_TCP_USER_TIMEOUT = TCP_USER_TIMEOUT;
+#else
+const pj_uint16_t PJ_TCP_USER_TIMEOUT = 18;
+#endif
+
 #if defined(SOL_KEEPALIVE)
 const pj_uint16_t PJ_SOL_KEEPALIVE = SOL_KEEPALIVE;
 #else
diff --git a/pjlib/src/pj/symbols.c b/pjlib/src/pj/symbols.c
index 966a9fc43..c71e49da4 100644
--- a/pjlib/src/pj/symbols.c
+++ b/pjlib/src/pj/symbols.c
@@ -262,6 +262,7 @@ PJ_EXPORT_SYMBOL(PJ_SOL_IP)
 PJ_EXPORT_SYMBOL(PJ_TCP_KEEPIDLE)
 PJ_EXPORT_SYMBOL(PJ_TCP_KEEPINTVL)
 PJ_EXPORT_SYMBOL(PJ_TCP_KEEPCNT)
+PJ_EXPORT_SYMBOL(PJ_TCP_USER_TIMEOUT)
 PJ_EXPORT_SYMBOL(PJ_SOL_TCP)
 PJ_EXPORT_SYMBOL(PJ_SOL_UDP)
 PJ_EXPORT_SYMBOL(PJ_SOL_IPV6)
