Index: /pjproject/trunk/pjlib/include/pj/sock.h
===================================================================
--- /pjproject/trunk/pjlib/include/pj/sock.h	(revision 4859)
+++ /pjproject/trunk/pjlib/include/pj/sock.h	(revision 4860)
@@ -617,4 +617,30 @@
 } pj_ip_mreq;
 
+/* Maximum number of socket options. */
+#define PJ_MAX_SOCKOPT_PARAMS 4
+
+/**
+ * Options to be set for the socket. 
+ */
+typedef struct pj_sockopt_params
+{
+    /* The number of options to be applied. */
+    unsigned cnt;
+
+    /* Array of options to be applied. */
+    struct {
+	/* The level at which the option is defined. */
+	int level;
+
+	/* Option name. */
+	int optname;
+
+	/* Pointer to the buffer in which the option is specified. */
+	void *optval;
+
+	/* Buffer size of the buffer pointed by optval. */
+	int optlen;
+    } options[PJ_MAX_SOCKOPT_PARAMS];
+} pj_sockopt_params;
 
 /*****************************************************************************
@@ -1306,4 +1332,15 @@
 					 int optlen);
 
+/**
+ * Set socket options associated with a socket. This method will apply all the 
+ * options specified, and ignore any errors that might be raised.
+ *
+ * @param sockfd	The socket descriptor.
+ * @param params	The socket options.
+ *
+ * @return		PJ_SUCCESS or the last error code. 
+ */
+PJ_DECL(pj_status_t) pj_sock_setsockopt_params( pj_sock_t sockfd,
+					       const pj_sockopt_params *params);					       
 
 /**
Index: /pjproject/trunk/pjlib/include/pj/ssl_sock.h
===================================================================
--- /pjproject/trunk/pjlib/include/pj/ssl_sock.h	(revision 4859)
+++ /pjproject/trunk/pjlib/include/pj/ssl_sock.h	(revision 4860)
@@ -750,4 +750,20 @@
     pj_bool_t qos_ignore_error;
 
+    /**
+     * Specify options to be set on the transport. 
+     *
+     * By default there is no options.
+     * 
+     */
+    pj_sockopt_params sockopt_params;
+
+    /**
+     * Specify if the transport should ignore any errors when setting the 
+     * sockopt parameters.
+     *
+     * Default: PJ_TRUE
+     * 
+     */
+    pj_bool_t sockopt_ignore_error;
 
 } pj_ssl_sock_param;
Index: /pjproject/trunk/pjlib/src/pj/sock_bsd.c
===================================================================
--- /pjproject/trunk/pjlib/src/pj/sock_bsd.c	(revision 4859)
+++ /pjproject/trunk/pjlib/src/pj/sock_bsd.c	(revision 4860)
@@ -27,4 +27,6 @@
 #include <pj/unicode.h>
 
+#define THIS_FILE	"sock_bsd.c"
+
 /*
  * Address families conversion.
@@ -766,9 +768,49 @@
 					int optlen)
 {
-    PJ_CHECK_STACK();
-    if (setsockopt(sock, level, optname, (const char*)optval, optlen) != 0)
+    int status;
+    PJ_CHECK_STACK();
+    
+#if (defined(PJ_WIN32) && PJ_WIN32) || (defined(PJ_SUNOS) && PJ_SUNOS)
+    /* Some opt may still need int value (e.g:SO_EXCLUSIVEADDRUSE in win32). */
+    status = setsockopt(sock, 
+		     level, 
+		     ((optname&0xff00)==0xff00)?(int)optname|0xffff0000:optname, 		     
+		     (const char*)optval, optlen);
+#else
+    status = setsockopt(sock, level, optname, (const char*)optval, optlen);
+#endif
+
+    if (status != 0)
 	return PJ_RETURN_OS_ERROR(pj_get_native_netos_error());
     else
 	return PJ_SUCCESS;
+}
+
+/*
+ * Set socket option.
+ */
+PJ_DEF(pj_status_t) pj_sock_setsockopt_params( pj_sock_t sockfd,
+					       const pj_sockopt_params *params)
+{
+    unsigned int i = 0;
+    pj_status_t retval = PJ_SUCCESS;
+    PJ_CHECK_STACK();
+    PJ_ASSERT_RETURN(params, PJ_EINVAL);
+    
+    for (;i<params->cnt && i<PJ_MAX_SOCKOPT_PARAMS;++i) {
+	pj_status_t status = pj_sock_setsockopt(sockfd, 
+					(pj_uint16_t)params->options[i].level,
+					(pj_uint16_t)params->options[i].optname,
+					params->options[i].optval, 
+					params->options[i].optlen);
+	if (status != PJ_SUCCESS) {
+	    retval = status;
+	    PJ_PERROR(4,(THIS_FILE, status,
+			 "Warning: error applying sock opt %d",
+			 params->options[i].optname));
+	}
+    }
+
+    return retval;
 }
 
Index: /pjproject/trunk/pjlib/src/pj/sock_linux_kernel.c
===================================================================
--- /pjproject/trunk/pjlib/src/pj/sock_linux_kernel.c	(revision 4859)
+++ /pjproject/trunk/pjlib/src/pj/sock_linux_kernel.c	(revision 4860)
@@ -36,4 +36,6 @@
 #include <asm/ioctls.h>		/* FIONBIO	*/
 #include <linux/utsname.h>	/* for pj_gethostname() */
+
+#define THIS_FILE   "sock_linux_kernel.c"
 
 /*
@@ -627,4 +629,32 @@
 
 /*
+ * Set socket option.
+ */
+PJ_DEF(pj_status_t) pj_sock_setsockopt_params( pj_sock_t sockfd,
+					       const pj_sockopt_params *params)
+{
+    unsigned int i = 0;
+    pj_status_t retval = PJ_SUCCESS;
+    PJ_CHECK_STACK();
+    PJ_ASSERT_RETURN(params, PJ_EINVAL);
+    
+    for (;i<params->cnt && i<PJ_MAX_SOCKOPT_PARAMS;++i) {
+	pj_status_t status = pj_sock_setsockopt(sockfd, 
+						params->options[i].level,
+						params->options[i].optname,
+						params->options[i].optval, 
+						params->options[i].optlen);
+	if (status != PJ_SUCCESS) {
+	    retval = status;
+	    PJ_PERROR(4,(THIS_FILE, status,
+			 "Warning: error applying sock opt %d",
+			 params->options[i].optname));
+	}
+    }
+
+    return retval;
+}
+
+/*
  * Shutdown socket.
  */
Index: /pjproject/trunk/pjlib/src/pj/ssl_sock_common.c
===================================================================
--- /pjproject/trunk/pjlib/src/pj/ssl_sock_common.c	(revision 4859)
+++ /pjproject/trunk/pjlib/src/pj/ssl_sock_common.c	(revision 4860)
@@ -41,4 +41,6 @@
     param->qos_type = PJ_QOS_TYPE_BEST_EFFORT;
     param->qos_ignore_error = PJ_TRUE;
+
+    param->sockopt_ignore_error = PJ_TRUE;
 
     /* Security config */
Index: /pjproject/trunk/pjlib/src/pj/ssl_sock_ossl.c
===================================================================
--- /pjproject/trunk/pjlib/src/pj/ssl_sock_ossl.c	(revision 4859)
+++ /pjproject/trunk/pjlib/src/pj/ssl_sock_ossl.c	(revision 4860)
@@ -1651,4 +1651,12 @@
 	goto on_return;
 
+    /* Apply socket options, if specified */
+    if (ssock->param.sockopt_params.cnt) {
+	status = pj_sock_setsockopt_params(ssock->sock, 
+					   &ssock->param.sockopt_params);
+	if (status != PJ_SUCCESS && !ssock->param.sockopt_ignore_error)
+	    goto on_return;
+    }
+
     /* Update local address */
     ssock->addr_len = src_addr_len;
@@ -2453,6 +2461,16 @@
 				&ssock->param.qos_params, 2, 
 				ssock->pool->obj_name, NULL);
+
     if (status != PJ_SUCCESS && !ssock->param.qos_ignore_error)
 	goto on_error;
+
+    /* Apply socket options, if specified */
+    if (ssock->param.sockopt_params.cnt) {
+	status = pj_sock_setsockopt_params(ssock->sock, 
+					   &ssock->param.sockopt_params);
+
+	if (status != PJ_SUCCESS && !ssock->param.sockopt_ignore_error)
+	    goto on_error;
+    }
 
     /* Bind socket */
@@ -2537,4 +2555,13 @@
     if (status != PJ_SUCCESS && !ssock->param.qos_ignore_error)
 	goto on_error;
+
+    /* Apply socket options, if specified */
+    if (ssock->param.sockopt_params.cnt) {
+	status = pj_sock_setsockopt_params(ssock->sock, 
+					   &ssock->param.sockopt_params);
+
+	if (status != PJ_SUCCESS && !ssock->param.sockopt_ignore_error)
+	    goto on_error;
+    }
 
     /* Bind socket */
Index: /pjproject/trunk/pjsip/include/pjsip/sip_transport_tcp.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsip/sip_transport_tcp.h	(revision 4859)
+++ /pjproject/trunk/pjsip/include/pjsip/sip_transport_tcp.h	(revision 4860)
@@ -104,4 +104,12 @@
      */
     pj_qos_params	qos_params;
+
+    /**
+     * Specify options to be set on the transport. 
+     *
+     * By default there is no options.
+     * 
+     */
+    pj_sockopt_params	sockopt_params;
 
 } pjsip_tcp_transport_cfg;
Index: /pjproject/trunk/pjsip/include/pjsip/sip_transport_tls.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsip/sip_transport_tls.h	(revision 4859)
+++ /pjproject/trunk/pjsip/include/pjsip/sip_transport_tls.h	(revision 4860)
@@ -206,4 +206,21 @@
     pj_bool_t qos_ignore_error;
 
+    /**
+     * Specify options to be set on the transport. 
+     *
+     * By default there is no options.
+     * 
+     */
+    pj_sockopt_params sockopt_params;
+
+    /**
+     * Specify if the transport should ignore any errors when setting the 
+     * sockopt parameters.
+     *
+     * Default: PJ_TRUE
+     * 
+     */
+    pj_bool_t sockopt_ignore_error;
+
 } pjsip_tls_setting;
 
@@ -235,4 +252,5 @@
     tls_opt->qos_type = PJ_QOS_TYPE_BEST_EFFORT;
     tls_opt->qos_ignore_error = PJ_TRUE;
+    tls_opt->sockopt_ignore_error = PJ_TRUE;
 }
 
Index: /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 4859)
+++ /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 4860)
@@ -2297,4 +2297,12 @@
     pj_qos_params	qos_params;
 
+    /**
+     * Specify options to be set on the transport. 
+     *
+     * By default there is no options.
+     * 
+     */
+    pj_sockopt_params	sockopt_params;
+
 } pjsua_transport_config;
 
Index: /pjproject/trunk/pjsip/src/pjsip/sip_transport_tcp.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsip/sip_transport_tcp.c	(revision 4859)
+++ /pjproject/trunk/pjsip/src/pjsip/sip_transport_tcp.c	(revision 4860)
@@ -61,4 +61,5 @@
     pj_qos_type		     qos_type;
     pj_qos_params	     qos_params;
+    pj_sockopt_params	     sockopt_params;
 };
 
@@ -285,4 +286,6 @@
     pj_memcpy(&listener->qos_params, &cfg->qos_params,
 	      sizeof(cfg->qos_params));
+    pj_memcpy(&listener->sockopt_params, &cfg->sockopt_params,
+	      sizeof(cfg->sockopt_params));
 
     pj_ansi_strcpy(listener->factory.obj_name, "tcplis");
@@ -316,4 +319,8 @@
 	}
     }
+
+    /* Apply socket options, if specified */
+    if (cfg->sockopt_params.cnt)
+	status = pj_sock_setsockopt_params(sock, &cfg->sockopt_params);
 
     /* Bind address may be different than factory.local_addr because
@@ -918,4 +925,9 @@
 				2, listener->factory.obj_name, 
 				"outgoing SIP TCP socket");
+
+    /* Apply socket options, if specified */
+    if (listener->sockopt_params.cnt)
+	status = pj_sock_setsockopt_params(sock, &listener->sockopt_params);
+
 
     /* Bind to listener's address and any port */
@@ -1036,4 +1048,8 @@
 				2, listener->factory.obj_name, 
 				"incoming SIP TCP socket");
+
+    /* Apply socket options, if specified */
+    if (listener->sockopt_params.cnt)
+	status = pj_sock_setsockopt_params(sock, &listener->sockopt_params);
 
     /* tcp_create() expect pj_sockaddr, so copy src_addr to temporary var,
Index: /pjproject/trunk/pjsip/src/pjsip/sip_transport_tls.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsip/sip_transport_tls.c	(revision 4859)
+++ /pjproject/trunk/pjsip/src/pjsip/sip_transport_tls.c	(revision 4860)
@@ -350,4 +350,11 @@
 	      sizeof(ssock_param.qos_params));
 
+    ssock_param.sockopt_ignore_error = 
+				     listener->tls_setting.sockopt_ignore_error;
+    /* Copy the sockopt */
+    pj_memcpy(&ssock_param.sockopt_params, 
+	      &listener->tls_setting.sockopt_params,
+	      sizeof(listener->tls_setting.sockopt_params));
+
     has_listener = PJ_FALSE;
 
@@ -954,4 +961,11 @@
 	      sizeof(ssock_param.qos_params));
 
+    ssock_param.sockopt_ignore_error = 
+				     listener->tls_setting.sockopt_ignore_error;
+    /* Copy the sockopt */
+    pj_memcpy(&ssock_param.sockopt_params, 
+	      &listener->tls_setting.sockopt_params,
+	      sizeof(listener->tls_setting.sockopt_params));
+
     switch(listener->tls_setting.method) {
     case PJSIP_TLSV1_METHOD:
Index: /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c	(revision 4859)
+++ /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c	(revision 4860)
@@ -1965,4 +1965,8 @@
 				2, THIS_FILE, "SIP UDP socket");
 
+    /* Apply sockopt, if specified */
+    if (cfg->sockopt_params.cnt)
+	status = pj_sock_setsockopt_params(sock, &cfg->sockopt_params);
+
     /* Bind socket */
     status = pj_sock_bind(sock, &bind_addr, pj_sockaddr_get_len(&bind_addr));
@@ -2187,4 +2191,8 @@
 		  sizeof(cfg->qos_params));
 
+	/* Copy the sockopt */
+	pj_memcpy(&tcp_cfg.sockopt_params, &cfg->sockopt_params,
+		  sizeof(tcp_cfg.sockopt_params));
+	
 	/* Create the TCP transport */
 	status = pjsip_tcp_transport_start3(pjsua_var.endpt, &tcp_cfg, &tcp);
Index: /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c	(revision 4859)
+++ /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c	(revision 4860)
@@ -299,4 +299,8 @@
 				    2, THIS_FILE, "RTP socket");
 
+	/* Apply sockopt, if specified */
+	if (cfg->sockopt_params.cnt)
+	    status = pj_sock_setsockopt_params(sock[0], &cfg->sockopt_params);
+
 	/* Bind RTP socket */
 	pj_sockaddr_set_port(&bound_addr, acc->next_rtp_port);
@@ -321,4 +325,8 @@
 				    &cfg->qos_params,
 				    2, THIS_FILE, "RTCP socket");
+
+	/* Apply sockopt, if specified */
+	if (cfg->sockopt_params.cnt)
+	    status = pj_sock_setsockopt_params(sock[1], &cfg->sockopt_params);
 
 	/* Bind RTCP socket */
