diff --git a/contrib/src/pjproject/0001-rfc6544.patch b/contrib/src/pjproject/0001-rfc6544.patch
index 44139814d1464bf1648b05fa9278e6731fa2b938..2ee2626c47371dbc86fd45dc23b04e628f385bfb 100644
--- a/contrib/src/pjproject/0001-rfc6544.patch
+++ b/contrib/src/pjproject/0001-rfc6544.patch
@@ -28,7 +28,7 @@ on behalf of Savoir-faire Linux.
  pjnath/src/pjnath-test/sess_auth.c      |   14 +-
  pjnath/src/pjnath-test/stun_sock_test.c |    7 +-
  pjnath/src/pjnath/ice_session.c         |  515 ++++++++++-
- pjnath/src/pjnath/ice_strans.c          |  771 +++++++++++++---
+ pjnath/src/pjnath/ice_strans.c          |  773 +++++++++++++---
  pjnath/src/pjnath/nat_detect.c          |    7 +-
  pjnath/src/pjnath/stun_session.c        |   15 +-
  pjnath/src/pjnath/stun_sock.c           | 1075 +++++++++++++++++++----
@@ -40,16 +40,16 @@ on behalf of Savoir-faire Linux.
  pjnath/src/pjturn-srv/server.c          |    2 +-
  pjsip-apps/src/samples/icedemo.c        |  116 ++-
  pjsip/src/pjsua-lib/pjsua_core.c        |    2 +-
- 21 files changed, 2509 insertions(+), 402 deletions(-)
+ 21 files changed, 2510 insertions(+), 403 deletions(-)
 
 diff --git a/pjnath/include/pjnath/ice_session.h b/pjnath/include/pjnath/ice_session.h
 index 8971220f0..39c197c29 100644
 --- a/pjnath/include/pjnath/ice_session.h
 +++ b/pjnath/include/pjnath/ice_session.h
 @@ -163,6 +163,52 @@ typedef enum pj_ice_cand_type
- 
+
  } pj_ice_cand_type;
- 
+
 +/**
 + * ICE candidates types like described by RFC 6544.
 + */
@@ -96,25 +96,25 @@ index 8971220f0..39c197c29 100644
 +
 +} pj_ice_tp_type;
 +
- 
+
  /** Forward declaration for pj_ice_sess */
  typedef struct pj_ice_sess pj_ice_sess;
 @@ -309,6 +355,11 @@ typedef struct pj_ice_sess_cand
       */
      pj_sockaddr		 rel_addr;
- 
+
 +    /**
 +     * Transport used (TCP or UDP)
 +     */
 +    pj_ice_cand_transport transport;
 +
  } pj_ice_sess_cand;
- 
- 
+
+
 @@ -324,6 +375,22 @@ typedef enum pj_ice_sess_check_state
       */
      PJ_ICE_SESS_CHECK_STATE_FROZEN,
- 
+
 +    /**
 +     * The following status is used when a packet sent via TURN got a
 +     * "Connection reset by peer". This mean that the peer didn't allow
@@ -137,7 +137,7 @@ index 8971220f0..39c197c29 100644
 @@ -331,6 +398,12 @@ typedef enum pj_ice_sess_check_state
       */
      PJ_ICE_SESS_CHECK_STATE_WAITING,
- 
+
 +    /**
 +     * A check has not been performed for this pair, but TCP socket
 +     * is currently connecting to the pair. Wait to finish the connection.
@@ -198,15 +198,15 @@ index 8971220f0..39c197c29 100644
 +                                        unsigned check_id);
 +
  } pj_ice_sess_cb;
- 
- 
+
+
 @@ -636,6 +755,7 @@ struct pj_ice_sess
      pj_bool_t            valid_pair_found;          /**< First pair found   */
      pj_status_t		 ice_status;		    /**< Error status.	    */
      pj_timer_entry	 timer;			    /**< ICE timer.	    */
 +    pj_timer_entry	 timer_connect;		    /**< ICE timer tcp timeout*/
      pj_ice_sess_cb	 cb;			    /**< Callback.	    */
- 
+
      pj_stun_config	 stun_cfg;		    /**< STUN settings.	    */
 @@ -855,6 +975,7 @@ PJ_DECL(pj_status_t) pj_ice_sess_set_prefs(pj_ice_sess *ice,
   * @param rel_addr	Optional related address.
@@ -223,13 +223,13 @@ index 8971220f0..39c197c29 100644
 -					  unsigned *p_cand_id);
 +					  unsigned *p_cand_id,
 +					  pj_ice_cand_transport transport);
- 
+
  /**
   * Find default candidate for the specified component ID, using this
 @@ -980,6 +1102,55 @@ PJ_DECL(pj_status_t) pj_ice_sess_on_rx_pkt(pj_ice_sess *ice,
  					   const pj_sockaddr_t *src_addr,
  					   int src_addr_len);
- 
+
 +/**
 + * Notification when ICE session get a new incoming connection
 + *
@@ -279,8 +279,8 @@ index 8971220f0..39c197c29 100644
 +PJ_DECL(void) ice_select_incoming_turn(pj_ice_sess *ice,
 +				       pj_ice_sess_checklist *clist,
 +				       unsigned check_id);
- 
- 
+
+
  /**
 diff --git a/pjnath/include/pjnath/ice_strans.h b/pjnath/include/pjnath/ice_strans.h
 index d0af76679..9eb74b35f 100644
@@ -289,7 +289,7 @@ index d0af76679..9eb74b35f 100644
 @@ -274,6 +274,13 @@ typedef struct pj_ice_strans_stun_cfg
       */
      pj_bool_t		 ignore_stun_error;
- 
+
 +    /**
 +     * Type of connection to the STUN server.
 +     *
@@ -298,12 +298,12 @@ index d0af76679..9eb74b35f 100644
 +    pj_stun_tp_type conn_type;
 +
  } pj_ice_strans_stun_cfg;
- 
- 
+
+
 @@ -289,6 +296,13 @@ typedef struct pj_ice_strans_turn_cfg
       */
      int			 af;
- 
+
 +    /**
 +     * If we want to use UDP or TCP as described by RFC 6544.
 +     * This will discover candidates via TCP sockets. Then it will
@@ -317,7 +317,7 @@ index d0af76679..9eb74b35f 100644
 @@ -368,6 +382,13 @@ typedef struct pj_ice_strans_cfg
       */
      int			 af;
- 
+
 +    /**
 +     * If we want to use UDP or TCP as described by RFC 6544.
 +     * This will discover candidates via TCP sockets. Then it will
@@ -335,7 +335,7 @@ index bee630ab4..3f2ecf739 100644
 @@ -174,6 +174,29 @@ typedef struct pj_stun_rx_data pj_stun_rx_data;
  /** Forward declaration for pj_stun_session */
  typedef struct pj_stun_session pj_stun_session;
- 
+
 +/**
 + * STUN transport types, which will be used both to specify the connection
 + * type for reaching STUN server and the type of allocation transport to be
@@ -359,13 +359,13 @@ index bee630ab4..3f2ecf739 100644
 +    PJ_STUN_TP_TLS = 255
 +
 +} pj_stun_tp_type;
- 
+
  /**
   * This is the callback to be registered to pj_stun_session, to send
 @@ -307,6 +330,38 @@ typedef struct pj_stun_session_cb
  				    const pj_sockaddr_t *src_addr,
  				    unsigned src_addr_len);
- 
+
 +    /**
 +     * Notification when STUN session get a ConnectionAttempt indication.
 +     *
@@ -399,8 +399,8 @@ index bee630ab4..3f2ecf739 100644
 +                           pj_sockaddr_t* remote_addr);
 +
  } pj_stun_session_cb;
- 
- 
+
+
 @@ -390,6 +445,7 @@ typedef enum pj_stun_sess_msg_log_flag
   * @param grp_lock	Optional group lock to be used by this session.
   * 			If NULL, the session will create one itself.
@@ -416,13 +416,13 @@ index bee630ab4..3f2ecf739 100644
 -					    pj_stun_session **p_sess);
 +					    pj_stun_session **p_sess,
 +					    pj_stun_tp_type conn_type);
- 
+
  /**
   * Destroy the STUN session and all objects created in the context of
 @@ -752,6 +809,22 @@ PJ_DECL(pj_status_t) pj_stun_session_on_rx_pkt(pj_stun_session *sess,
  PJ_DECL(void) pj_stun_msg_destroy_tdata(pj_stun_session *sess,
  					pj_stun_tx_data *tdata);
- 
+
 +/**
 + *
 + * @param sess     The STUN session.
@@ -439,7 +439,7 @@ index bee630ab4..3f2ecf739 100644
 + */
 +PJ_DECL(pj_stun_tp_type) pj_stun_session_tp_type(pj_stun_session *sess);
 +
- 
+
  /**
   * @}
 diff --git a/pjnath/include/pjnath/stun_sock.h b/pjnath/include/pjnath/stun_sock.h
@@ -460,7 +460,7 @@ index fff4df885..bfc9c1415 100644
 +#include <pj/pool.h>
  #include <pj/sock.h>
  #include <pj/sock_qos.h>
- 
+
 @@ -87,7 +91,17 @@ typedef enum pj_stun_sock_op
      /**
       * IP address change notification from the keep-alive operation.
@@ -477,13 +477,13 @@ index fff4df885..bfc9c1415 100644
 +     * TCP fails to connect
 +     */
 +    PJ_STUN_TCP_CONNECT_ERROR
- 
- 
+
+
  } pj_stun_sock_op;
 @@ -197,6 +211,11 @@ typedef struct pj_stun_sock_info
       */
      pj_sockaddr	    mapped_addr;
- 
+
 +    /**
 +     * If connected, the remote address will be stored here.
 +     */
@@ -495,19 +495,19 @@ index fff4df885..bfc9c1415 100644
 @@ -208,6 +227,11 @@ typedef struct pj_stun_sock_info
       */
      pj_sockaddr	    aliases[PJ_ICE_ST_MAX_CAND];
- 
+
 +    /**
 +     * The tranport type of the socket
 +     */
 +    pj_stun_tp_type conn_type;
 +
  } pj_stun_sock_info;
- 
- 
+
+
 @@ -343,6 +367,9 @@ PJ_DECL(void) pj_stun_sock_cfg_default(pj_stun_sock_cfg *cfg);
   *			the operation of this transport.
   * @param af		Address family of socket. Currently pj_AF_INET()
-  *			and pj_AF_INET6() are supported. 
+  *			and pj_AF_INET6() are supported.
 + * @param conn_type     Connection type to the STUN server. Both TCP and UDP are
 + *			supported.
 + *
@@ -525,7 +525,7 @@ index fff4df885..bfc9c1415 100644
 @@ -485,6 +513,43 @@ PJ_DECL(pj_status_t) pj_stun_sock_sendto(pj_stun_sock *stun_sock,
  					 const pj_sockaddr_t *dst_addr,
  					 unsigned addr_len);
- 
+
 +
 +#if PJ_HAS_TCP
 +/**
@@ -573,7 +573,7 @@ index e4d306174..35388809f 100644
 @@ -623,6 +623,17 @@ PJ_DECL(pj_status_t) pj_turn_sock_bind_channel(pj_turn_sock *turn_sock,
  					       const pj_sockaddr_t *peer,
  					       unsigned addr_len);
- 
+
 +/**
 + *  Check if peer is a dataconn
 + *
@@ -585,7 +585,7 @@ index e4d306174..35388809f 100644
 +PJ_DECL(pj_bool_t) pj_turn_sock_has_dataconn(pj_turn_sock *turn_sock,
 +					     const pj_sockaddr_t *peer);
 +
- 
+
  /**
   * @}
 diff --git a/pjnath/src/pjnath-test/concur_test.c b/pjnath/src/pjnath-test/concur_test.c
@@ -630,7 +630,7 @@ index 055eaad61..1d07bf299 100644
  	return -200;
 @@ -575,8 +577,12 @@ static int run_client_test(const char *title,
      }
- 
+
      /* Send the request */
 -    status = pj_stun_session_send_msg(client->sess, NULL, PJ_FALSE, PJ_TRUE, &server->addr,
 -				      pj_sockaddr_get_len(&server->addr), tdata);
@@ -651,7 +651,7 @@ index fff4fad26..e7f8b84eb 100644
      pj_bzero(&cb, sizeof(cb));
      cb.on_status = &stun_sock_on_status;
      cb.on_rx_data = &stun_sock_on_rx_data;
--    status = pj_stun_sock_create(cfg, NULL, GET_AF(use_ipv6), &cb, &sock_cfg, 
+-    status = pj_stun_sock_create(cfg, NULL, GET_AF(use_ipv6), &cb, &sock_cfg,
 -				 client, &client->sock);
 +    status = pj_stun_sock_create(cfg, NULL, GET_AF(use_ipv6),
 +				 PJ_STUN_TP_UDP,
@@ -663,7 +663,7 @@ index fff4fad26..e7f8b84eb 100644
  	PJ_LOG(3,(THIS_FILE, "     sending to %s", pj_sockaddr_print(&info.srv_addr, txt, sizeof(txt), 3)));
      }
      status = pj_stun_sock_sendto(client->sock, NULL, &ret, sizeof(ret),
--				 0, &info.srv_addr, 
+-				 0, &info.srv_addr,
 +				 0, &info.srv_addr,
  				 pj_sockaddr_get_len(&info.srv_addr));
      if (status != PJ_SUCCESS && status != PJ_EPENDING) {
@@ -673,7 +673,7 @@ index 2a4125bc5..85d3234c9 100644
 --- a/pjnath/src/pjnath/ice_session.c
 +++ b/pjnath/src/pjnath/ice_session.c
 @@ -18,6 +18,7 @@
-  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   */
  #include <pjnath/ice_session.h>
 +#include <pjnath/stun_session.h>
@@ -681,7 +681,7 @@ index 2a4125bc5..85d3234c9 100644
  #include <pj/array.h>
  #include <pj/assert.h>
 @@ -44,7 +45,10 @@ static const char *cand_type_names[] =
- static const char *check_state_name[] = 
+ static const char *check_state_name[] =
  {
      "Frozen",
 +    "Needs Retry",
@@ -698,9 +698,9 @@ index 2a4125bc5..85d3234c9 100644
 -    TIMER_KEEP_ALIVE		/**< ICE keep-alive timer.		*/
 +    TIMER_KEEP_ALIVE,		/**< ICE keep-alive timer.		*/
 +    TIMER_CONNECTION_TIMEOUT
- 
+
  };
- 
+
 @@ -123,6 +128,8 @@ typedef struct timer_data
  {
      pj_ice_sess		    *ice;
@@ -708,10 +708,10 @@ index 2a4125bc5..85d3234c9 100644
 +    /* TODO (remove), for now, needed for the NEEDS_FIRST_PACKET state */
 +    unsigned                first_packet_counter;
  } timer_data;
- 
- 
+
+
 @@ -133,6 +140,7 @@ typedef struct timer_data
- 
+
  /* Forward declarations */
  static void on_timer(pj_timer_heap_t *th, pj_timer_entry *te);
 +static void on_tcp_connect_timeout(pj_ice_sess *ice);
@@ -719,7 +719,7 @@ index 2a4125bc5..85d3234c9 100644
  static void ice_keep_alive(pj_ice_sess *ice, pj_bool_t send_now);
  static void ice_on_destroy(void *obj);
 @@ -291,7 +299,8 @@ static pj_status_t init_comp(pj_ice_sess *ice,
-     status = pj_stun_session_create(&ice->stun_cfg, NULL, 
+     status = pj_stun_session_create(&ice->stun_cfg, NULL,
  			            &sess_cb, PJ_TRUE,
  			            ice->grp_lock,
 -				    &comp->stun_sess);
@@ -727,7 +727,7 @@ index 2a4125bc5..85d3234c9 100644
 +				    PJ_STUN_TP_UDP);
      if (status != PJ_SUCCESS)
  	return status;
- 
+
 @@ -717,7 +726,8 @@ PJ_DEF(pj_status_t) pj_ice_sess_add_cand(pj_ice_sess *ice,
  					 const pj_sockaddr_t *base_addr,
  					 const pj_sockaddr_t *rel_addr,
@@ -762,7 +762,7 @@ index 2a4125bc5..85d3234c9 100644
 +	    --i;
 +	}
      }
- 
+
      /* Next remove a pair if its local and remote candidates are identical
 @@ -1183,6 +1205,9 @@ static void on_timer(pj_timer_heap_t *th, pj_timer_entry *te)
      case TIMER_KEEP_ALIVE:
@@ -777,7 +777,7 @@ index 2a4125bc5..85d3234c9 100644
 @@ -1619,6 +1644,43 @@ static pj_bool_t on_check_complete(pj_ice_sess *ice,
      return PJ_FALSE;
  }
- 
+
 +static void on_tcp_connect_timeout(pj_ice_sess* ice)
 +{
 +    pj_timer_heap_cancel_if_active(ice->stun_cfg.timer_heap,&ice->timer,
@@ -815,13 +815,13 @@ index 2a4125bc5..85d3234c9 100644
 +				    ice->grp_lock);
 +    }
 +}
- 
+
  /* Create checklist by pairing local candidates with remote candidates */
  PJ_DEF(pj_status_t) pj_ice_sess_create_check_list(
 @@ -1705,6 +1767,30 @@ PJ_DEF(pj_status_t) pj_ice_sess_create_check_list(
  		continue;
  	    }
- 
+
 +	    /* Section 6.2, RFC 6544 (https://tools.ietf.org/html/rfc6544)
 +	     * As with UDP, check lists are formed only by full ICE implementations.
 +	     * When forming candidate pairs, the following types of TCP candidates
@@ -846,7 +846,7 @@ index 2a4125bc5..85d3234c9 100644
 +		continue;
 +	    }
 +
- 
+
  	    chk->lcand = lcand;
  	    chk->rcand = rcand;
 @@ -1749,6 +1835,7 @@ PJ_DEF(pj_status_t) pj_ice_sess_create_check_list(
@@ -856,11 +856,11 @@ index 2a4125bc5..85d3234c9 100644
 +    td->first_packet_counter = 1;
      clist->timer.user_data = (void*)td;
      clist->timer.cb = &periodic_timer;
- 
+
 @@ -1761,6 +1848,36 @@ PJ_DEF(pj_status_t) pj_ice_sess_create_check_list(
      return PJ_SUCCESS;
  }
- 
+
 +static pj_status_t send_connectivity_check(pj_ice_sess *ice,
 +					   pj_ice_sess_checklist *clist,
 +					   unsigned check_id,
@@ -883,16 +883,16 @@ index 2a4125bc5..85d3234c9 100644
 +
 +    /* Initiate STUN transaction to send the request */
 +
-+    return pj_stun_session_send_msg(comp->stun_sess, msg_data, PJ_FALSE, 
++    return pj_stun_session_send_msg(comp->stun_sess, msg_data, PJ_FALSE,
 +				    pj_stun_session_tp_type(comp->stun_sess)==
 +				    PJ_STUN_TP_UDP,
-+				    &rcand->addr, 
++				    &rcand->addr,
 +				    pj_sockaddr_get_len(&rcand->addr),
 +				    check->tdata);
 +}
 +
  /* Perform check on the specified candidate pair. */
- static pj_status_t perform_check(pj_ice_sess *ice, 
+ static pj_status_t perform_check(pj_ice_sess *ice,
  				 pj_ice_sess_checklist *clist,
 @@ -1771,19 +1888,17 @@ static pj_status_t perform_check(pj_ice_sess *ice,
      pj_ice_msg_data *msg_data;
@@ -901,32 +901,32 @@ index 2a4125bc5..85d3234c9 100644
 -    const pj_ice_sess_cand *rcand;
      pj_uint32_t prio;
      pj_status_t status;
- 
+
      check = &clist->checks[check_id];
      lcand = check->lcand;
 -    rcand = check->rcand;
      comp = find_comp(ice, lcand->comp_id);
- 
+
 +    pj_log_push_indent();
-     LOG5((ice->obj_name, 
- 	 "Sending connectivity check for check %s", 
+     LOG5((ice->obj_name,
+ 	 "Sending connectivity check for check %s",
  	 dump_check(ice->tmp.txt, sizeof(ice->tmp.txt), clist, check)));
 -    pj_log_push_indent();
- 
+
      /* Create request */
-     status = pj_stun_session_create_req(comp->stun_sess, 
+     status = pj_stun_session_create_req(comp->stun_sess,
 @@ -1831,32 +1946,92 @@ static pj_status_t perform_check(pj_ice_sess *ice,
  				    &ice->tie_breaker);
- 
+
      } else {
 +	if (nominate) {
 +	    check->nominated = PJ_TRUE;
 +	}
- 	pj_stun_msg_add_uint64_attr(check->tdata->pool, check->tdata->msg, 
+ 	pj_stun_msg_add_uint64_attr(check->tdata->pool, check->tdata->msg,
  				    PJ_STUN_ATTR_ICE_CONTROLLED,
  				    &ice->tie_breaker);
      }
- 
+
 +#if PJ_HAS_TCP
 +    switch (lcand->transport) {
 +    case PJ_CAND_UDP:
@@ -989,14 +989,14 @@ index 2a4125bc5..85d3234c9 100644
 +#else
 +    status = send_connectivity_check(ice, clist, check_id, nominate, msg_data);
 +#endif
- 
--    /* Note that USERNAME and MESSAGE-INTEGRITY will be added by the 
+
+-    /* Note that USERNAME and MESSAGE-INTEGRITY will be added by the
 -     * STUN session.
 -     */
 -
 -    /* Initiate STUN transaction to send the request */
--    status = pj_stun_session_send_msg(comp->stun_sess, msg_data, PJ_FALSE, 
--				      PJ_TRUE, &rcand->addr, 
+-    status = pj_stun_session_send_msg(comp->stun_sess, msg_data, PJ_FALSE,
+-				      PJ_TRUE, &rcand->addr,
 -				      pj_sockaddr_get_len(&rcand->addr),
 -				      check->tdata);
 -    if (status != PJ_SUCCESS) {
@@ -1016,24 +1016,24 @@ index 2a4125bc5..85d3234c9 100644
 -	return status;
      }
 -
--    check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_IN_PROGRESS, 
+-    check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_IN_PROGRESS,
 -	            PJ_SUCCESS);
      pj_log_pop_indent();
 -    return PJ_SUCCESS;
 +    return status;
  }
- 
- 
+
+
 @@ -1893,39 +2068,95 @@ static pj_status_t start_periodic_check(pj_timer_heap_t *th,
      pj_log_push_indent();
- 
+
      /* Send STUN Binding request for check with highest priority on
 -     * Waiting state.
 +     * Retry state.
       */
 -    for (i=0; i<clist->count; ++i) {
 -	pj_ice_sess_check *check = &clist->checks[i];
- 
+
 -	if (check->state == PJ_ICE_SESS_CHECK_STATE_WAITING) {
 -	    status = perform_check(ice, clist, i, ice->is_nominating);
 -	    if (status != PJ_SUCCESS) {
@@ -1056,7 +1056,7 @@ index 2a4125bc5..85d3234c9 100644
  	    }
 +	}
 +    }
- 
+
 -	    ++start_count;
 -	    break;
 +    if (start_count == 0) {
@@ -1103,7 +1103,7 @@ index 2a4125bc5..85d3234c9 100644
 +	    }
  	}
      }
- 
+
      /* If we don't have anything in Waiting state, perform check to
       * highest priority pair that is in Frozen state.
       */
@@ -1112,7 +1112,7 @@ index 2a4125bc5..85d3234c9 100644
 +    if (start_count == 0) {
 +	for (i = 0; i < clist->count; ++i) {
  	    pj_ice_sess_check *check = &clist->checks[i];
- 
+
  	    if (check->state == PJ_ICE_SESS_CHECK_STATE_FROZEN) {
  		status = perform_check(ice, clist, i, ice->is_nominating);
 -		if (status != PJ_SUCCESS) {
@@ -1127,7 +1127,7 @@ index 2a4125bc5..85d3234c9 100644
 +	    }
 +	}
 +    }
- 
+
 +    if (start_count == 0) {
 +	// If all sockets are pending, do nothing
 +	for (i = 0; i < clist->count; ++i) {
@@ -1138,25 +1138,25 @@ index 2a4125bc5..85d3234c9 100644
  	    }
 @@ -1933,14 +2164,14 @@ static pj_status_t start_periodic_check(pj_timer_heap_t *th,
      }
- 
+
      /* Cannot start check because there's no suitable candidate pair.
 -     */
 +    */
      if (start_count!=0) {
  	/* Schedule for next timer */
  	pj_time_val timeout = {0, PJ_ICE_TA_VAL};
- 
+
  	pj_time_val_normalize(&timeout);
  	pj_timer_heap_schedule_w_grp_lock(th, te, &timeout, PJ_TRUE,
 -	                                  ice->grp_lock);
 +					  ice->grp_lock);
      }
- 
+
      pj_grp_lock_release(ice->grp_lock);
 @@ -2181,6 +2412,192 @@ static pj_status_t on_stun_send_msg(pj_stun_session *sess,
      return status;
  }
- 
+
 +static pj_ice_sess_check* get_current_check_at_state(pj_ice_sess *ice,
 +                                                     pj_sockaddr_t *remote_addr,
 +                                                     pj_ice_sess_check_state state,
@@ -1343,11 +1343,11 @@ index 2a4125bc5..85d3234c9 100644
 +		      &clist->checks[check_id]);
 +    on_check_complete(ice, &clist->checks[check_id]);
 +}
- 
+
  /* This callback is called when outgoing STUN request completed */
  static void on_stun_request_complete(pj_stun_session *stun_sess,
 @@ -2411,7 +2828,9 @@ static void on_stun_request_complete(pj_stun_session *stun_sess,
- 				      &check->lcand->base_addr, 
+ 				      &check->lcand->base_addr,
  				      &check->lcand->base_addr,
  				      pj_sockaddr_get_len(&xaddr->sockaddr),
 -				      &cand_id);
@@ -1355,19 +1355,19 @@ index 2a4125bc5..85d3234c9 100644
 +				      check->rcand->transport == PJ_CAND_UDP ?
 +				      PJ_CAND_UDP : PJ_CAND_TCP_PASSIVE);
  	if (status != PJ_SUCCESS) {
- 	    check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_FAILED, 
+ 	    check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_FAILED,
  			    status);
 @@ -2673,7 +3092,9 @@ static pj_status_t on_stun_rx_request(pj_stun_session *sess,
      msg_data->has_req_data = PJ_FALSE;
- 
+
      /* Send the response */
 -    status = pj_stun_session_send_msg(sess, msg_data, PJ_TRUE, PJ_TRUE,
 +    status = pj_stun_session_send_msg(sess, msg_data, PJ_TRUE,
 +                                      pj_stun_session_tp_type(sess) ==
 +                                      PJ_STUN_TP_UDP,
  				      src_addr, src_addr_len, tdata);
- 
- 
+
+
 @@ -2794,12 +3215,12 @@ static void handle_incoming_check(pj_ice_sess *ice,
      /* Just get candidate with the highest priority and same transport ID
       * for the specified  component ID in the checklist.
@@ -1375,7 +1375,7 @@ index 2a4125bc5..85d3234c9 100644
 -    for (i=0; i<ice->clist.count; ++i) {
 -	pj_ice_sess_check *c = &ice->clist.checks[i];
 -	if (c->lcand->comp_id == rcheck->comp_id &&
--	    c->lcand->transport_id == rcheck->transport_id) 
+-	    c->lcand->transport_id == rcheck->transport_id)
 +    for (i=0; i<ice->lcand_cnt; ++i) {
 +	pj_ice_sess_cand* lcand_tmp = &ice->lcand[i];
 +	if (lcand_tmp->comp_id == rcheck->comp_id &&
@@ -1387,21 +1387,21 @@ index 2a4125bc5..85d3234c9 100644
  	}
      }
 diff --git a/pjnath/src/pjnath/ice_strans.c b/pjnath/src/pjnath/ice_strans.c
-index 3cb350c2a..69df9f40a 100644
+index 3cb350c2a..bf7f98096 100644
 --- a/pjnath/src/pjnath/ice_strans.c
 +++ b/pjnath/src/pjnath/ice_strans.c
 @@ -69,6 +69,7 @@ enum tp_type
  #   define RELAY_PREF  0
  #endif
- 
+
 +#define MAX_RTP_SIZE 65536
- 
+
  /* The candidate type preference when STUN candidate is used */
  static pj_uint8_t srflx_pref_table[PJ_ICE_CAND_TYPE_MAX] =
 @@ -87,6 +88,14 @@ static pj_uint8_t srflx_pref_table[PJ_ICE_CAND_TYPE_MAX] =
  #endif
  };
- 
+
 +//////////////////////////////////////////////////////////////////////////////
 +
 +static pj_uint16_t GETVAL16H(const pj_uint8_t *buf1, const pj_uint8_t *buf2)
@@ -1410,13 +1410,13 @@ index 3cb350c2a..69df9f40a 100644
 +}
 +
 +//////////////////////////////////////////////////////////////////////////////
- 
+
  /* ICE callbacks */
  static void	   on_ice_complete(pj_ice_sess *ice, pj_status_t status);
 @@ -103,6 +112,24 @@ static void	   ice_rx_data(pj_ice_sess *ice,
  			       const pj_sockaddr_t *src_addr,
  			       unsigned src_addr_len);
- 
+
 +#if PJ_HAS_TCP
 +static pj_status_t ice_wait_tcp_connection(pj_ice_sess *ice,
 +					   pj_ice_sess_checklist *clist,
@@ -1435,13 +1435,13 @@ index 3cb350c2a..69df9f40a 100644
 +					    unsigned check_id);
 +#endif
 +
- 
+
  /* STUN socket callbacks */
  /* Notification when incoming packet has been received. */
 @@ -182,6 +209,16 @@ typedef struct pj_ice_strans_comp
  } pj_ice_strans_comp;
- 
- 
+
+
 +static pj_bool_t add_local_candidate(pj_ice_sess_cand *cand,
 +				     unsigned idx,
 +				     unsigned i,
@@ -1465,13 +1465,13 @@ index 3cb350c2a..69df9f40a 100644
 +    pj_uint16_t         rx_buffer_size;
 +    pj_uint16_t         rx_wanted_size;
 +
-+    unsigned            last_data_len; /**< What the application is waiting. */
++    pj_ssize_t          last_data_len; /**< What the application is waiting. */
  };
- 
- 
+
+
 @@ -261,6 +305,7 @@ PJ_DEF(void) pj_ice_strans_cfg_default(pj_ice_strans_cfg *cfg)
      pj_bzero(cfg, sizeof(*cfg));
- 
+
      cfg->af = pj_AF_INET();
 +    cfg->protocol = PJ_ICE_TP_UDP;
      pj_stun_config_init(&cfg->stun_cfg, NULL, 0, NULL, NULL);
@@ -1479,7 +1479,7 @@ index 3cb350c2a..69df9f40a 100644
      pj_ice_strans_turn_cfg_default(&cfg->turn);
 @@ -278,6 +323,7 @@ PJ_DEF(void) pj_ice_strans_stun_cfg_default(pj_ice_strans_stun_cfg *cfg)
      pj_bzero(cfg, sizeof(*cfg));
- 
+
      cfg->af = pj_AF_INET();
 +    cfg->conn_type = PJ_STUN_TP_UDP;
      cfg->port = PJ_STUN_PORT;
@@ -1493,12 +1493,12 @@ index 3cb350c2a..69df9f40a 100644
 +						    PJ_CAND_UDP :
 +						    PJ_CAND_TCP_PASSIVE;
      }
- 
+
      /* Allocate and initialize TURN socket data */
 @@ -428,6 +477,10 @@ static pj_status_t add_update_turn(pj_ice_strans *ice_st,
      data->comp = comp;
      data->transport_id = cand->transport_id;
- 
+
 +    if (turn_cfg->conn_type == PJ_TURN_TP_TCP) {
 +	turn_cfg->alloc_param.peer_conn_type = PJ_TURN_TP_TCP;
 +    }
@@ -1509,8 +1509,8 @@ index 3cb350c2a..69df9f40a 100644
 @@ -465,7 +518,7 @@ static pj_status_t add_update_turn(pj_ice_strans *ice_st,
      return PJ_SUCCESS;
  }
- 
--static pj_bool_t ice_cand_equals(pj_ice_sess_cand *lcand, 
+
+-static pj_bool_t ice_cand_equals(pj_ice_sess_cand *lcand,
 +static pj_bool_t ice_cand_equals(pj_ice_sess_cand *lcand,
  		    	         pj_ice_sess_cand *rcand)
  {
@@ -1519,7 +1519,7 @@ index 3cb350c2a..69df9f40a 100644
      if (lcand == NULL || rcand == NULL){
          return PJ_FALSE;
      }
--    
+-
 +
      if (lcand->type != rcand->type
          || lcand->status != rcand->status
@@ -1533,11 +1533,11 @@ index 3cb350c2a..69df9f40a 100644
      {
          return PJ_FALSE;
      }
--    
+-
 +
      return PJ_TRUE;
  }
- 
+
 -
  static pj_status_t add_stun_and_host(pj_ice_strans *ice_st,
  				     pj_ice_strans_comp *comp,
@@ -1549,11 +1549,11 @@ index 3cb350c2a..69df9f40a 100644
 +    cand->transport = stun_cfg->conn_type == PJ_STUN_TP_UDP ?
 +                                                PJ_CAND_UDP :
 +                                                PJ_CAND_TCP_PASSIVE;
- 
+
      /* Allocate and initialize STUN socket data */
      data = PJ_POOL_ZALLOC_T(ice_st->pool, sock_user_data);
 @@ -549,8 +605,9 @@ static pj_status_t add_stun_and_host(pj_ice_strans *ice_st,
- 
+
      /* Create the STUN transport */
      status = pj_stun_sock_create(&ice_st->cfg.stun_cfg, NULL,
 -				 stun_cfg->af, &stun_sock_cb,
@@ -1563,10 +1563,10 @@ index 3cb350c2a..69df9f40a 100644
 +				 &comp->stun[idx].sock);
      if (status != PJ_SUCCESS)
  	return status;
- 
+
 @@ -635,105 +692,154 @@ static pj_status_t add_stun_and_host(pj_ice_strans *ice_st,
  	}
- 
+
  	for (i = 0; i < stun_sock_info.alias_cnt &&
 -		    cand_cnt < stun_cfg->max_host_cands; ++i)
 +		    cand_cnt < stun_cfg->max_host_cands &&
@@ -1603,17 +1603,17 @@ index 3cb350c2a..69df9f40a 100644
 +            }
 +        }
 +    }
- 
+
 -	    if (max_cand_cnt==0) {
 -		PJ_LOG(4,(ice_st->obj_name, "Too many host candidates"));
 -		break;
 -	    }
 +    return status;
 +}
- 
+
 -	    /* Ignore loopback addresses if cfg->stun.loop_addr is unset */
 -	    if (stun_cfg->loop_addr==PJ_FALSE) {
--		if (stun_cfg->af == pj_AF_INET() && 
+-		if (stun_cfg->af == pj_AF_INET() &&
 -		    (pj_ntohl(addr->ipv4.sin_addr.s_addr)>>24)==127)
 -		{
 -		    continue;
@@ -1643,7 +1643,7 @@ index 3cb350c2a..69df9f40a 100644
 +    char addrinfo[PJ_INET6_ADDRSTRLEN+10];
 +    const pj_sockaddr *addr = &stun_sock_info.aliases[i];
 +    pj_ice_strans_stun_cfg *stun_cfg = &ice_st->cfg.stun_tp[idx];
- 
+
 -	    /* Ignore IPv6 link-local address, unless it is the default
 -	     * address (first alias).
 -	     */
@@ -1652,7 +1652,7 @@ index 3cb350c2a..69df9f40a 100644
 -		if (a->s6_addr[0] == 0xFE && (a->s6_addr[1] & 0xC0) == 0x80)
 -		    continue;
 -	    }
- 
+
 -	    cand = &comp->cand_list[comp->cand_cnt];
 -
 -	    cand->type = PJ_ICE_CAND_TYPE_HOST;
@@ -1663,7 +1663,7 @@ index 3cb350c2a..69df9f40a 100644
 -	    pj_sockaddr_cp(&cand->addr, addr);
 -	    pj_sockaddr_cp(&cand->base_addr, addr);
 -	    pj_bzero(&cand->rel_addr, sizeof(cand->rel_addr));
--            
+-
 -	    /* Check if not already in list */
 -	    for (j=0; j<comp->cand_cnt; j++) {
 -		if (ice_cand_equals(cand, &comp->cand_list[j])) {
@@ -1675,7 +1675,7 @@ index 3cb350c2a..69df9f40a 100644
 +	PJ_LOG(4,(ice_st->obj_name, "Too many host candidates"));
 +	return !PJ_SUCCESS;
 +    }
- 
+
 -	    if (cand_duplicate) {
 -		PJ_LOG(4, (ice_st->obj_name,
 -		       "Comp %d: host candidate %s (tpid=%d) is a duplicate",
@@ -1698,7 +1698,7 @@ index 3cb350c2a..69df9f40a 100644
 +            }
 +        }
 +    }
- 
+
 -		pj_bzero(&cand->addr, sizeof(cand->addr));
 -		pj_bzero(&cand->base_addr, sizeof(cand->base_addr));
 -		continue;
@@ -1707,7 +1707,7 @@ index 3cb350c2a..69df9f40a 100644
 -		cand_cnt++;
 -		max_cand_cnt--;
 -	    }
--            
+-
 -	    pj_ice_calc_foundation(ice_st->pool, &cand->foundation,
 -				   cand->type, &cand->base_addr);
 +    /* Ignore IPv6 link-local address, unless it is the default
@@ -1718,7 +1718,7 @@ index 3cb350c2a..69df9f40a 100644
 +	if (a->s6_addr[0] == 0xFE && (a->s6_addr[1] & 0xC0) == 0x80)
 +            return PJ_SUCCESS;
 +    }
- 
+
 -	    /* Set default candidate with the preferred default
 -	     * address family
 -	     */
@@ -1730,10 +1730,10 @@ index 3cb350c2a..69df9f40a 100644
 -	        comp->default_cand = (unsigned)(cand - comp->cand_list);
 -	    }
 +    cand = &comp->cand_list[comp->cand_cnt];
- 
+
 -	    PJ_LOG(4,(ice_st->obj_name,
 -		      "Comp %d/%d: host candidate %s (tpid=%d) added",
--		      comp->comp_id, comp->cand_cnt-1, 
+-		      comp->comp_id, comp->cand_cnt-1,
 -		      pj_sockaddr_print(&cand->addr, addrinfo,
 -					sizeof(addrinfo), 3),
 -					cand->transport_id));
@@ -1756,7 +1756,7 @@ index 3cb350c2a..69df9f40a 100644
 +            return !PJ_SUCCESS;
 +        }
      }
- 
+
 -    return status;
 -}
 +    if (cand_duplicate) {
@@ -1789,7 +1789,7 @@ index 3cb350c2a..69df9f40a 100644
 +    {
 +        comp->default_cand = (unsigned)(cand - comp->cand_list);
 +    }
- 
+
 +    if (transport == PJ_CAND_TCP_ACTIVE) {
 +        // Use the port 9 (DISCARD Protocol) for TCP active candidates.
 +        pj_sockaddr_set_port(&cand->addr, 9);
@@ -1803,14 +1803,14 @@ index 3cb350c2a..69df9f40a 100644
 +              cand->transport_id));
 +    return PJ_SUCCESS;
 +}
- 
+
  /*
   * Create the component.
 @@ -816,7 +922,7 @@ static pj_status_t alloc_send_buf(pj_ice_strans *ice_st, unsigned buf_size)
  {
      if (buf_size > ice_st->buf_size) {
          unsigned i;
--        
+-
 +
          if (ice_st->is_pending) {
              /* The current buffer is insufficient, but still currently used.*/
@@ -1819,16 +1819,16 @@ index 3cb350c2a..69df9f40a 100644
  	}
  	ice_st->buf_idx = ice_st->empty_idx = 0;
      }
--    
+-
 +
      return PJ_SUCCESS;
  }
- 
+
 @@ -906,7 +1012,7 @@ PJ_DEF(pj_status_t) pj_ice_strans_create( const char *name,
      /* To maintain backward compatibility, check if old/deprecated setting is set
       * and the new setting is not, copy the value to the new setting.
       */
--    if (cfg->stun_tp_cnt == 0 && 
+-    if (cfg->stun_tp_cnt == 0 &&
 +    if (cfg->stun_tp_cnt == 0 &&
  	(cfg->stun.server.slen || cfg->stun.max_host_cands))
      {
@@ -1837,7 +1837,7 @@ index 3cb350c2a..69df9f40a 100644
  			   pj_ice_get_cand_type_name(cand->type)));
  		return;
  	    }
--	    
+-
 +
  	    if (status == PJ_EUNKNOWN) {
  	    	status = cand->status;
@@ -1846,7 +1846,7 @@ index 3cb350c2a..69df9f40a 100644
  	    	    status = PJ_SUCCESS;
  	    }
  	}
--	
+-
 +
  	if (status != PJ_SUCCESS)
  	    break;
@@ -1861,7 +1861,7 @@ index 3cb350c2a..69df9f40a 100644
 +    ice_cb.reconnect_tcp_connection = &ice_reconnect_tcp_connection;
 +    ice_cb.close_tcp_connection     = &ice_close_tcp_connection;
 +#endif
- 
+
      /* Create! */
      status = pj_ice_sess_create(&ice_st->cfg.stun_cfg, ice_st->obj_name, role,
 @@ -1282,7 +1394,8 @@ PJ_DEF(pj_status_t) pj_ice_strans_init_ice(pj_ice_strans *ice_st,
@@ -1878,7 +1878,7 @@ index 3cb350c2a..69df9f40a 100644
  PJ_DEF(pj_status_t) pj_ice_strans_stop_ice(pj_ice_strans *ice_st)
  {
      PJ_ASSERT_RETURN(ice_st, PJ_EINVAL);
--    
+-
 +
      /* Protect with group lock, since this may cause race condition with
       * pj_ice_strans_sendto2().
@@ -1887,7 +1887,7 @@ index 3cb350c2a..69df9f40a 100644
      status = alloc_send_buf(ice_st, data_len);
      if (status != PJ_SUCCESS)
      	return status;
--    
+-
 +
      if (ice_st->is_pending && ice_st->empty_idx == ice_st->buf_idx) {
      	/* We don't use buffer or there's no more empty buffer. */
@@ -1896,36 +1896,44 @@ index 3cb350c2a..69df9f40a 100644
      pj_sockaddr_cp(&ice_st->send_buf[idx].dst_addr, dst_addr);
      ice_st->send_buf[idx].dst_addr_len = dst_addr_len;
      *buffer = ice_st->send_buf[idx].buffer;
--    
+-
 +
      if (ice_st->is_pending) {
          /* We'll continue later since there's still a pending send. */
      	return PJ_EPENDING;
      }
--    
+-
 +
      ice_st->is_pending = PJ_TRUE;
      ice_st->buf_idx = idx;
- 
-@@ -1659,16 +1772,40 @@ static pj_status_t send_data(pj_ice_strans *ice_st,
+
+@@ -1651,6 +1764,9 @@ static pj_status_t send_data(pj_ice_strans *ice_st,
+     	}
+     }
+
++    def_cand = &comp->cand_list[comp->default_cand];
++    pj_bool_t add_header = def_cand->transport != PJ_CAND_UDP;
++
+     /* If ICE is available, send data with ICE, otherwise send with the
+      * default candidate selected during initialization.
+      *
+@@ -1659,16 +1775,37 @@ static pj_status_t send_data(pj_ice_strans *ice_st,
       */
      if (ice_st->ice && ice_st->state == PJ_ICE_STRANS_STATE_RUNNING) {
  	status = pj_ice_sess_send_data(ice_st->ice, comp_id, buf, data_len);
--	
+-
 +
  	pj_grp_lock_release(ice_st->grp_lock);
--	
+-
 +
  	goto on_return;
--    } 
+-    }
 +    }
- 
+
      pj_grp_lock_release(ice_st->grp_lock);
- 
-     def_cand = &comp->cand_list[comp->default_cand];
--    
-+
-+    pj_bool_t add_header = def_cand->transport != PJ_CAND_UDP;
+
+-    def_cand = &comp->cand_list[comp->default_cand];
+-
 +    /* TCP, add header */
 +    if (add_header) {
 +	/*
@@ -1951,7 +1959,7 @@ index 3cb350c2a..69df9f40a 100644
 +
      if (def_cand->status == PJ_SUCCESS) {
  	unsigned tp_idx = GET_TP_IDX(def_cand->transport_id);
- 
+
 @@ -1730,6 +1867,11 @@ static pj_status_t send_data(pj_ice_strans *ice_st,
  	    status = pj_stun_sock_sendto(comp->stun[tp_idx].sock, NULL, buf,
  					 (unsigned)data_len, 0, dest_addr,
@@ -1963,9 +1971,9 @@ index 3cb350c2a..69df9f40a 100644
 +
  	    goto on_return;
  	}
- 
+
 @@ -1738,8 +1880,14 @@ static pj_status_t send_data(pj_ice_strans *ice_st,
- 
+
  on_return:
      /* We continue later in on_data_sent() callback. */
 -    if (status == PJ_EPENDING)
@@ -1977,14 +1985,14 @@ index 3cb350c2a..69df9f40a 100644
 +		}
      	return status;
 +	}
- 
+
      if (call_cb) {
      	on_data_sent(ice_st, (status == PJ_SUCCESS? data_len: -status));
 @@ -1771,7 +1919,7 @@ PJ_DEF(pj_status_t) pj_ice_strans_sendto( pj_ice_strans *ice_st,
      		       dst_addr_len, PJ_TRUE, PJ_FALSE);
      if (status == PJ_EPENDING)
      	status = PJ_SUCCESS;
--    
+-
 +
      return status;
  }
@@ -2016,7 +2024,7 @@ index 3cb350c2a..69df9f40a 100644
 @@ -1936,6 +2099,29 @@ static pj_status_t ice_tx_pkt(pj_ice_sess *ice,
  	       pj_sockaddr_get_port(dst_addr),
  	       tp_typ));
- 
+
 +    /* TCP, add header */
 +    if (comp->ice_st->cfg.stun_tp->conn_type == PJ_STUN_TP_TCP) {
 +	/*
@@ -2047,7 +2055,7 @@ index 3cb350c2a..69df9f40a 100644
      	    	if (status != PJ_SUCCESS) {
      	    	    goto on_return;
      	    	}
--    	    
+-
 +
      	    	pj_sockaddr_cp(&comp->dst_addr, dst_addr);
      	    	comp->synth_addr_len = pj_sockaddr_get_len(&comp->synth_addr);
@@ -2055,7 +2063,7 @@ index 3cb350c2a..69df9f40a 100644
 @@ -1969,9 +2155,13 @@ static pj_status_t ice_tx_pkt(pj_ice_sess *ice,
      	    dest_addr_len = dst_addr_len;
      	}
- 
+
 -	status = pj_stun_sock_sendto(comp->stun[tp_idx].sock, NULL,
 -				     buf, (unsigned)size, 0,
 -				     dest_addr, dest_addr_len);
@@ -2070,10 +2078,10 @@ index 3cb350c2a..69df9f40a 100644
  	pj_assert(!"Invalid transport ID");
  	status = PJ_EINVALIDOP;
 @@ -2017,7 +2207,7 @@ static void check_pending_send(pj_ice_strans *ice_st)
- 
+
      if (ice_st->num_buf > 0)
          ice_st->buf_idx = (ice_st->buf_idx + 1) % ice_st->num_buf;
--    
+-
 +
      if (ice_st->num_buf > 0 && ice_st->buf_idx != ice_st->empty_idx) {
  	/* There's some pending send. Send it one by one. */
@@ -2081,7 +2089,7 @@ index 3cb350c2a..69df9f40a 100644
 @@ -2031,6 +2221,237 @@ static void check_pending_send(pj_ice_strans *ice_st)
      }
  }
- 
+
 +static void on_peer_connection(pj_stun_session* sess,
 +                               pj_status_t status,
 +                               pj_sockaddr_t* remote_addr)
@@ -2319,27 +2327,27 @@ index 3cb350c2a..69df9f40a 100644
 @@ -2039,7 +2460,8 @@ static pj_bool_t on_data_sent(pj_ice_strans *ice_st, pj_ssize_t sent)
      if (ice_st->destroy_req || !ice_st->is_pending)
  	return PJ_TRUE;
- 
+
 -    if (ice_st->call_send_cb && ice_st->cb.on_data_sent) {
 +    if (ice_st->call_send_cb && ice_st->cb.on_data_sent
 +		&& sent == ice_st->last_data_len /* Only app data should be announced */) {
  	(*ice_st->cb.on_data_sent)(ice_st, sent);
      }
- 
+
 @@ -2196,7 +2618,7 @@ static pj_bool_t stun_on_status(pj_stun_sock *stun_sock,
  		{
  		    /* We get an IPv4 mapped address for our IPv6
  		     * host address.
--		     */		     
+-		     */
 +		     */
  		    comp->ipv4_mapped = PJ_TRUE;
- 
+
  		    /* Find other host candidates with the same (IPv6)
 @@ -2208,7 +2630,7 @@ static pj_bool_t stun_on_status(pj_stun_sock *stun_sock,
- 
+
  		        if (comp->cand_list[i].type != PJ_ICE_CAND_TYPE_HOST)
  		            continue;
--		        
+-
 +
  		        a1 = &comp->cand_list[i].addr;
  		        a2 = &cand->base_addr;
@@ -2348,21 +2356,21 @@ index 3cb350c2a..69df9f40a 100644
  		    pj_sockaddr_cp(&cand->base_addr, &info.mapped_addr);
  		    pj_sockaddr_cp(&cand->rel_addr, &info.mapped_addr);
  		}
--		
+-
 +
  		/* Eliminate the srflx candidate if the address is
  		 * equal to other (host) candidates.
  		 */
 @@ -2268,11 +2690,11 @@ static pj_bool_t stun_on_status(pj_stun_sock *stun_sock,
  					     sizeof(ipaddr), 3)));
- 
+
  		sess_init_update(ice_st);
--		
+-
 +
  		if (op == PJ_STUN_SOCK_MAPPED_ADDR_CHANGE &&
  		    ice_st->cb.on_ice_complete)
  		{
--		    (*ice_st->cb.on_ice_complete)(ice_st, 
+-		    (*ice_st->cb.on_ice_complete)(ice_st,
 +		    (*ice_st->cb.on_ice_complete)(ice_st,
  		    				  PJ_ICE_STRANS_OP_ADDR_CHANGE,
  		    				  status);
@@ -2376,11 +2384,11 @@ index 3cb350c2a..69df9f40a 100644
 +    default:
 +	break;
      }
- 
+
      return pj_grp_lock_dec_ref(ice_st->grp_lock)? PJ_FALSE : PJ_TRUE;
 @@ -2358,14 +2784,103 @@ static void turn_on_rx_data(pj_turn_sock *turn_sock,
      } else {
- 
+
  	/* Hand over the packet to ICE */
 -	status = pj_ice_sess_on_rx_pkt(comp->ice_st->ice, comp->comp_id,
 -				       data->transport_id, pkt, pkt_len,
@@ -2388,7 +2396,7 @@ index 3cb350c2a..69df9f40a 100644
 +	if (comp->ice_st->cfg.turn_tp->conn_type == PJ_TURN_TP_TCP && pkt_len > 0) {
 +	    unsigned parsed = 0;
 +	    pj_status_t status;
- 
+
 -	if (status != PJ_SUCCESS) {
 -	    ice_st_perror(comp->ice_st,
 -			  "Error processing packet from TURN relay",
@@ -2488,7 +2496,7 @@ index 3cb350c2a..69df9f40a 100644
 +			      status);
  	}
      }
- 
+
 diff --git a/pjnath/src/pjnath/nat_detect.c b/pjnath/src/pjnath/nat_detect.c
 index db0de10bc..808342bec 100644
 --- a/pjnath/src/pjnath/nat_detect.c
@@ -2502,12 +2510,12 @@ index db0de10bc..808342bec 100644
 +				    PJ_STUN_TP_UDP);
      if (status != PJ_SUCCESS)
  	goto on_error;
- 
+
 @@ -875,7 +876,9 @@ static pj_status_t send_test(nat_detect_session *sess,
- 
+
      /* Send the request */
      status = pj_stun_session_send_msg(sess->stun_sess, NULL, PJ_TRUE,
--				      PJ_TRUE, sess->cur_server, 
+-				      PJ_TRUE, sess->cur_server,
 +				      (pj_stun_session_tp_type(sess->stun_sess) ==
 +				       PJ_STUN_TP_UDP),
 +				      sess->cur_server,
@@ -2519,13 +2527,13 @@ index f2b4f7058..ed17b904f 100644
 --- a/pjnath/src/pjnath/stun_session.c
 +++ b/pjnath/src/pjnath/stun_session.c
 @@ -49,6 +49,8 @@ struct pj_stun_session
- 
+
      pj_stun_tx_data	 pending_request_list;
      pj_stun_tx_data	 cached_response_list;
 +
 +    pj_stun_tp_type	 conn_type;
  };
- 
+
  #define SNAME(s_)		    ((s_)->pool->obj_name)
 @@ -524,7 +526,8 @@ PJ_DEF(pj_status_t) pj_stun_session_create( pj_stun_config *cfg,
  					    const pj_stun_session_cb *cb,
@@ -2542,13 +2550,13 @@ index f2b4f7058..ed17b904f 100644
      sess->use_fingerprint = fingerprint;
      sess->log_flag = 0xFFFF;
 +    sess->conn_type = conn_type;
- 
+
      if (grp_lock) {
  	sess->grp_lock = grp_lock;
 @@ -1538,3 +1542,12 @@ on_return:
      return status;
  }
- 
+
 +PJ_DECL(pj_stun_session_cb *) pj_stun_session_callback(pj_stun_session *sess)
 +{
 +    return sess ? &sess->cb : NULL;
@@ -2563,9 +2571,9 @@ index 5fe825cf5..c4cd9b224 100644
 --- a/pjnath/src/pjnath/stun_sock.c
 +++ b/pjnath/src/pjnath/stun_sock.c
 @@ -40,6 +40,36 @@
- 
+
  enum { MAX_BIND_RETRY = 100 };
- 
+
 +#if PJ_HAS_TCP
 +// The head of a RTP packet is stored in a 16 bits header, so the max size of a
 +// packet is 65536
@@ -2607,7 +2615,7 @@ index 5fe825cf5..c4cd9b224 100644
 +    pj_stun_sock_cfg	 cfg;
      pj_stun_config	 stun_cfg;	/* STUN config (ioqueue etc)*/
      pj_stun_sock_cb	 cb;		/* Application callbacks    */
- 
+
 @@ -59,6 +91,13 @@ struct pj_stun_sock
      pj_dns_srv_async_query *q;		/* Pending DNS query	    */
      pj_sock_t		 sock_fd;	/* Socket descriptor	    */
@@ -2625,7 +2633,7 @@ index 5fe825cf5..c4cd9b224 100644
 @@ -68,6 +107,15 @@ struct pj_stun_sock
      pj_grp_lock_t	*grp_lock;	/* Session group lock	    */
  };
- 
+
 +//////////////////////////////////////////////////////////////////////////////
 +
 +static pj_uint16_t GETVAL16H(const pj_uint8_t *buf1, const pj_uint8_t *buf2)
@@ -2635,13 +2643,13 @@ index 5fe825cf5..c4cd9b224 100644
 +
 +//////////////////////////////////////////////////////////////////////////////
 +
- /* 
-  * Prototypes for static functions 
+ /*
+  * Prototypes for static functions
   */
 @@ -120,6 +168,24 @@ static void start_ka_timer(pj_stun_sock *stun_sock);
  /* Keep-alive timer callback */
  static void ka_timer_cb(pj_timer_heap_t *th, pj_timer_entry *te);
- 
+
 +
 +static pj_bool_t on_stun_sock_ready(pj_activesock_t *asock,
 +				    pj_status_t status);
@@ -2661,12 +2669,12 @@ index 5fe825cf5..c4cd9b224 100644
 +
 +
  #define INTERNAL_MSG_TOKEN  (void*)(pj_ssize_t)1
- 
- 
+
+
 @@ -160,12 +226,183 @@ static pj_bool_t pj_stun_sock_cfg_is_valid(const pj_stun_sock_cfg *cfg)
      return cfg->max_pkt_size > 1 && cfg->async_cnt >= 1;
  }
- 
+
 +/*
 + * Initialize.
 + */
@@ -2855,17 +2863,17 @@ index 5fe825cf5..c4cd9b224 100644
 -    unsigned i;
 -    pj_uint16_t max_bind_retry;
      pj_status_t status;
- 
+
      PJ_ASSERT_RETURN(stun_cfg && cb && p_stun_sock, PJ_EINVAL);
      PJ_ASSERT_RETURN(af==pj_AF_INET()||af==pj_AF_INET6(), PJ_EAFNOTSUP);
      PJ_ASSERT_RETURN(!cfg || pj_stun_sock_cfg_is_valid(cfg), PJ_EINVAL);
      PJ_ASSERT_RETURN(cb->on_status, PJ_EINVAL);
 +    PJ_ASSERT_RETURN(conn_type != PJ_STUN_TP_TCP || PJ_HAS_TCP, PJ_EINVAL);
- 
+
      status = pj_stun_config_check_valid(stun_cfg);
      if (status != PJ_SUCCESS)
  	return status;
- 
+
 -    if (name == NULL)
 -	name = "stuntp%p";
 +    if (name == NULL) {
@@ -2882,7 +2890,7 @@ index 5fe825cf5..c4cd9b224 100644
 +	    break;
 +	}
 +    }
- 
+
      if (cfg == NULL) {
  	pj_stun_sock_cfg_default(&default_cfg);
 @@ -204,9 +451,16 @@ PJ_DEF(pj_status_t) pj_stun_sock_create( pj_stun_config *stun_cfg,
@@ -2899,13 +2907,13 @@ index 5fe825cf5..c4cd9b224 100644
      pj_memcpy(&stun_sock->cb, cb, sizeof(*cb));
 +    /* Copy socket settings; QoS parameters etc */
 +    pj_memcpy(&stun_sock->cfg, cfg, sizeof(*cfg));
- 
+
      stun_sock->ka_interval = cfg->ka_interval;
      if (stun_sock->ka_interval == 0)
 @@ -226,140 +480,68 @@ PJ_DEF(pj_status_t) pj_stun_sock_create( pj_stun_config *stun_cfg,
      pj_grp_lock_add_handler(stun_sock->grp_lock, pool, stun_sock,
  			    &stun_sock_destructor);
- 
+
 -    /* Create socket and bind socket */
 -    status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &stun_sock->sock_fd);
 -    if (status != PJ_SUCCESS)
@@ -2920,7 +2928,7 @@ index 5fe825cf5..c4cd9b224 100644
 +    /* Create STUN session */
 +    {
 +	pj_stun_session_cb sess_cb;
- 
+
 -    /* Apply socket buffer size */
 -    if (cfg->so_rcvbuf_size > 0) {
 -	unsigned sobuf_size = cfg->so_rcvbuf_size;
@@ -2931,7 +2939,7 @@ index 5fe825cf5..c4cd9b224 100644
 -			  "Failed setting SO_RCVBUF"));
 -	} else {
 -	    if (sobuf_size < cfg->so_rcvbuf_size) {
--		PJ_LOG(4, (stun_sock->obj_name, 
+-		PJ_LOG(4, (stun_sock->obj_name,
 -			   "Warning! Cannot set SO_RCVBUF as configured, "
 -			   "now=%d, configured=%d",
 -			   sobuf_size, cfg->so_rcvbuf_size));
@@ -2948,9 +2956,9 @@ index 5fe825cf5..c4cd9b224 100644
 +	pj_bzero(&sess_cb, sizeof(sess_cb));
 +	sess_cb.on_request_complete = &sess_on_request_complete;
 +	sess_cb.on_send_msg = &sess_on_send_msg;
-+	status = pj_stun_session_create(&stun_sock->stun_cfg, 
++	status = pj_stun_session_create(&stun_sock->stun_cfg,
 +					stun_sock->obj_name,
-+					&sess_cb, PJ_FALSE, 
++					&sess_cb, PJ_FALSE,
 +					stun_sock->grp_lock,
 +					&stun_sock->stun_sess,
 +					conn_type);
@@ -2959,7 +2967,7 @@ index 5fe825cf5..c4cd9b224 100644
 -			  "Failed setting SO_SNDBUF"));
 -	} else {
 -	    if (sobuf_size < cfg->so_sndbuf_size) {
--		PJ_LOG(4, (stun_sock->obj_name, 
+-		PJ_LOG(4, (stun_sock->obj_name,
 -			   "Warning! Cannot set SO_SNDBUF as configured, "
 -			   "now=%d, configured=%d",
 -			   sobuf_size, cfg->so_sndbuf_size));
@@ -2971,13 +2979,13 @@ index 5fe825cf5..c4cd9b224 100644
 +	    return status;
  	}
      }
- 
+
 -    /* Bind socket */
 -    max_bind_retry = MAX_BIND_RETRY;
 -    if (cfg->port_range && cfg->port_range < max_bind_retry)
 -	max_bind_retry = cfg->port_range;
 -    pj_sockaddr_init(af, &bound_addr, NULL, 0);
--    if (cfg->bound_addr.addr.sa_family == pj_AF_INET() || 
+-    if (cfg->bound_addr.addr.sa_family == pj_AF_INET() ||
 -	cfg->bound_addr.addr.sa_family == pj_AF_INET6())
 -    {
 -	pj_sockaddr_cp(&bound_addr, &cfg->bound_addr);
@@ -2987,7 +2995,7 @@ index 5fe825cf5..c4cd9b224 100644
 -    if (status != PJ_SUCCESS)
 -	goto on_error;
 +    pj_stun_sock_alloc(stun_sock);
- 
+
 -    /* Create more useful information string about this transport */
 -#if 0
 -    {
@@ -2997,8 +3005,8 @@ index 5fe825cf5..c4cd9b224 100644
 +    *p_stun_sock = stun_sock;
 +    return PJ_SUCCESS;
 +}
- 
--	status = pj_sock_getsockname(stun_sock->sock_fd, &bound_addr, 
+
+-	status = pj_sock_getsockname(stun_sock->sock_fd, &bound_addr,
 -				     &addr_len);
 -	if (status != PJ_SUCCESS)
 -	    goto on_error;
@@ -3013,9 +3021,9 @@ index 5fe825cf5..c4cd9b224 100644
 +	return PJ_FALSE;
 +
 +    pj_grp_lock_acquire(stun_sock->grp_lock);
- 
+
 -	stun_sock->info = pj_pool_alloc(pool, PJ_INET6_ADDRSTRLEN+10);
--	pj_sockaddr_print(&bound_addr, stun_sock->info, 
+-	pj_sockaddr_print(&bound_addr, stun_sock->info,
 -			  PJ_INET6_ADDRSTRLEN, 3);
 +    /* TURN session may have already been destroyed here.
 +     * See ticket #1557 (http://trac.pjsip.org/repos/ticket/1557).
@@ -3026,7 +3034,7 @@ index 5fe825cf5..c4cd9b224 100644
 +	return PJ_FALSE;
      }
 -#endif
- 
+
 -    /* Init active socket configuration */
 -    {
 -	pj_activesock_cfg activesock_cfg;
@@ -3041,8 +3049,8 @@ index 5fe825cf5..c4cd9b224 100644
 -	pj_bzero(&activesock_cb, sizeof(activesock_cb));
 -	activesock_cb.on_data_recvfrom = &on_data_recvfrom;
 -	activesock_cb.on_data_sent = &on_data_sent;
--	status = pj_activesock_create(pool, stun_sock->sock_fd, 
--				      pj_SOCK_DGRAM(), 
+-	status = pj_activesock_create(pool, stun_sock->sock_fd,
+-				      pj_SOCK_DGRAM(),
 -				      &activesock_cfg, stun_cfg->ioqueue,
 -				      &activesock_cb, stun_sock,
 -				      &stun_sock->active_sock);
@@ -3056,7 +3064,7 @@ index 5fe825cf5..c4cd9b224 100644
 -	    goto on_error;
 -
 -	/* Init send keys */
--	pj_ioqueue_op_key_init(&stun_sock->send_key, 
+-	pj_ioqueue_op_key_init(&stun_sock->send_key,
 -			       sizeof(stun_sock->send_key));
 -	pj_ioqueue_op_key_init(&stun_sock->int_send_key,
 -			       sizeof(stun_sock->int_send_key));
@@ -3065,19 +3073,19 @@ index 5fe825cf5..c4cd9b224 100644
 +	pj_grp_lock_release(stun_sock->grp_lock);
 +	return PJ_FALSE;
      }
- 
+
 -    /* Create STUN session */
 -    {
 -	pj_stun_session_cb sess_cb;
 +    if (stun_sock->conn_type != PJ_STUN_TP_UDP)
 +	PJ_LOG(5,(stun_sock->obj_name, "TCP connected"));
- 
+
 -	pj_bzero(&sess_cb, sizeof(sess_cb));
 -	sess_cb.on_request_complete = &sess_on_request_complete;
 -	sess_cb.on_send_msg = &sess_on_send_msg;
--	status = pj_stun_session_create(&stun_sock->stun_cfg, 
+-	status = pj_stun_session_create(&stun_sock->stun_cfg,
 -					stun_sock->obj_name,
--					&sess_cb, PJ_FALSE, 
+-					&sess_cb, PJ_FALSE,
 -					stun_sock->grp_lock,
 -					&stun_sock->stun_sess);
 -	if (status != PJ_SUCCESS)
@@ -3089,7 +3097,7 @@ index 5fe825cf5..c4cd9b224 100644
 +					  stun_sock->cfg.max_pkt_size, 0);
 +    if (result != PJ_SUCCESS)
 +	return PJ_FALSE;
- 
+
      /* Associate us with the STUN session */
      pj_stun_session_set_user_data(stun_sock->stun_sess, stun_sock);
 @@ -369,25 +551,305 @@ PJ_DEF(pj_status_t) pj_stun_sock_create( pj_stun_config *stun_cfg,
@@ -3101,12 +3109,12 @@ index 5fe825cf5..c4cd9b224 100644
  	stun_sock->tsx_id[i] = (pj_uint16_t) pj_rand();
      }
      stun_sock->tsx_id[5] = 0;
- 
+
 -
      /* Init timer entry */
      stun_sock->ka_timer.cb = &ka_timer_cb;
      stun_sock->ka_timer.user_data = stun_sock;
- 
+
 -    /* Done */
 -    *p_stun_sock = stun_sock;
 -    return PJ_SUCCESS;
@@ -3115,7 +3123,7 @@ index 5fe825cf5..c4cd9b224 100644
 +	pj_grp_lock_release(stun_sock->grp_lock);
 +	return status;
 +    }
- 
+
 -on_error:
 -    pj_stun_sock_destroy(stun_sock);
 -    return status;
@@ -3127,7 +3135,7 @@ index 5fe825cf5..c4cd9b224 100644
 +    pj_grp_lock_release(stun_sock->grp_lock);
 +    return PJ_TRUE;
  }
- 
+
 +static pj_bool_t parse_rx_packet(pj_activesock_t *asock,
 +				 void *data,
 +				 pj_size_t size,
@@ -3408,7 +3416,7 @@ index 5fe825cf5..c4cd9b224 100644
 @@ -526,6 +988,26 @@ PJ_DEF(pj_status_t) pj_stun_sock_destroy(pj_stun_sock *stun_sock)
  	stun_sock->sock_fd = PJ_INVALID_SOCKET;
      }
- 
+
 +    for (int i = 0; i < stun_sock->incoming_nb ; ++i) {
 +	if (stun_sock->incoming_socks[i].sock != NULL) {
 +	    stun_sock->incoming_socks[i].fd = PJ_INVALID_SOCKET;
@@ -3433,7 +3441,7 @@ index 5fe825cf5..c4cd9b224 100644
  	pj_stun_session_destroy(stun_sock->stun_sess);
      }
 @@ -634,10 +1116,12 @@ static pj_status_t get_mapped_addr(pj_stun_sock *stun_sock)
-     
+
      /* Send request */
      status=pj_stun_session_send_msg(stun_sock->stun_sess, INTERNAL_MSG_TOKEN,
 -				    PJ_FALSE, PJ_TRUE, &stun_sock->srv_addr,
@@ -3445,12 +3453,12 @@ index 5fe825cf5..c4cd9b224 100644
 -    if (status != PJ_SUCCESS)
 +    if (status != PJ_SUCCESS && status != PJ_EPENDING)
  	goto on_error;
- 
+
      return PJ_SUCCESS;
 @@ -658,6 +1142,8 @@ PJ_DEF(pj_status_t) pj_stun_sock_get_info( pj_stun_sock *stun_sock,
- 
+
      pj_grp_lock_acquire(stun_sock->grp_lock);
- 
+
 +    info->conn_type = stun_sock->conn_type;
 +
      /* Copy STUN server address and mapped address */
@@ -3458,7 +3466,7 @@ index 5fe825cf5..c4cd9b224 100644
  	      sizeof(pj_sockaddr));
 @@ -770,13 +1256,241 @@ PJ_DEF(pj_status_t) pj_stun_sock_sendto( pj_stun_sock *stun_sock,
  	send_key = &stun_sock->send_key;
- 
+
      size = pkt_len;
 -    status = pj_activesock_sendto(stun_sock->active_sock, send_key,
 -                                  pkt, &size, flag, dst_addr, addr_len);
@@ -3607,11 +3615,11 @@ index 5fe825cf5..c4cd9b224 100644
 +            return status;
 +        }
 +    }
- 
+
      pj_grp_lock_release(stun_sock->grp_lock);
      return status;
  }
- 
+
 +PJ_DECL(pj_status_t) pj_stun_sock_connect_active(pj_stun_sock *stun_sock,
 +						 const pj_sockaddr_t *remote_addr,
 +						 int af)
@@ -3705,12 +3713,12 @@ index 5fe825cf5..c4cd9b224 100644
      pj_stun_sock *stun_sock;
      pj_ssize_t size;
 +    pj_status_t status;
- 
+
      stun_sock = (pj_stun_sock *) pj_stun_session_get_user_data(sess);
      if (!stun_sock || !stun_sock->active_sock) {
 @@ -800,9 +1515,29 @@ static pj_status_t sess_on_send_msg(pj_stun_session *sess,
      PJ_UNUSED_ARG(token);
- 
+
      size = pkt_size;
 -    return pj_activesock_sendto(stun_sock->active_sock,
 -				&stun_sock->int_send_key,
@@ -3739,25 +3747,25 @@ index 5fe825cf5..c4cd9b224 100644
 +#endif
 +    return status;
  }
- 
- /* This callback is called by the STUN session when outgoing transaction 
+
+ /* This callback is called by the STUN session when outgoing transaction
 @@ -942,8 +1677,6 @@ static pj_bool_t on_data_recvfrom(pj_activesock_t *asock,
  				  pj_status_t status)
  {
      pj_stun_sock *stun_sock;
 -    pj_stun_msg_hdr *hdr;
 -    pj_uint16_t type;
- 
+
      stun_sock = (pj_stun_sock*) pj_activesock_get_user_data(asock);
      if (!stun_sock)
 @@ -955,58 +1688,7 @@ static pj_bool_t on_data_recvfrom(pj_activesock_t *asock,
  	return PJ_TRUE;
      }
- 
+
 -    pj_grp_lock_acquire(stun_sock->grp_lock);
 -
 -    /* Check that this is STUN message */
--    status = pj_stun_msg_check((const pj_uint8_t*)data, size, 
+-    status = pj_stun_msg_check((const pj_uint8_t*)data, size,
 -    			       PJ_STUN_IS_DATAGRAM | PJ_STUN_CHECK_PACKET);
 -    if (status != PJ_SUCCESS) {
 -	/* Not STUN -- give it to application */
@@ -3779,7 +3787,7 @@ index 5fe825cf5..c4cd9b224 100644
 -     */
 -    if (!PJ_STUN_IS_RESPONSE(type) ||
 -	PJ_STUN_GET_METHOD(type) != PJ_STUN_BINDING_METHOD ||
--	pj_memcmp(hdr->tsx_id, stun_sock->tsx_id, 10) != 0) 
+-	pj_memcmp(hdr->tsx_id, stun_sock->tsx_id, 10) != 0)
 -    {
 -	/* Not STUN Binding response, or STUN transaction ID mismatch.
 -	 * This is not our message too -- give it to application.
@@ -3808,12 +3816,12 @@ index 5fe825cf5..c4cd9b224 100644
 -    return status!=PJ_EGONE ? PJ_TRUE : PJ_FALSE;
 +    return parse_rx_packet(asock, data, size, src_addr, addr_len);
  }
- 
+
  /* Callback from active socket about send status */
 @@ -1047,3 +1729,8 @@ static pj_bool_t on_data_sent(pj_activesock_t *asock,
      return PJ_TRUE;
  }
- 
+
 +pj_stun_session* pj_stun_sock_get_session(pj_stun_sock *stun_sock)
 +{
 +    return stun_sock ? stun_sock->stun_sess : NULL;
@@ -3853,7 +3861,7 @@ index dc6304d9f..a6e192e9f 100644
 +++ b/pjnath/src/pjnath/turn_sock.c
 @@ -894,12 +894,7 @@ static pj_bool_t on_data_sent(pj_turn_sock *turn_sock,
      }
- 
+
      if (turn_sock->cb.on_data_sent) {
 -	pj_ssize_t header_len, sent_size;
 -
@@ -3863,7 +3871,7 @@ index dc6304d9f..a6e192e9f 100644
 -	(*turn_sock->cb.on_data_sent)(turn_sock, sent_size);
 +	(*turn_sock->cb.on_data_sent)(turn_sock, sent);
      }
- 
+
      return PJ_TRUE;
 @@ -1766,3 +1761,20 @@ static void turn_on_connection_bind_status(pj_turn_session *sess,
  					      peer_addr, addr_len);
@@ -3891,9 +3899,9 @@ index 6f9f1ff1a..e56c510c8 100644
 --- a/pjnath/src/pjturn-client/client_main.c
 +++ b/pjnath/src/pjturn-client/client_main.c
 @@ -155,7 +155,7 @@ static int init()
- 
+
  	name[strlen(name)-1] = '0'+i;
- 	status = pj_stun_sock_create(&g.stun_config, name, pj_AF_INET(), 
+ 	status = pj_stun_sock_create(&g.stun_config, name, pj_AF_INET(),
 -				     &stun_sock_cb, &ss_cfg,
 +				     PJ_STUN_TP_UDP, &stun_sock_cb, &ss_cfg,
  				     &g.peer[i], &g.peer[i].stun_sock);
@@ -3918,7 +3926,7 @@ index 94dda29a3..95ad1793d 100644
 --- a/pjnath/src/pjturn-srv/server.c
 +++ b/pjnath/src/pjturn-srv/server.c
 @@ -156,7 +156,7 @@ PJ_DEF(pj_status_t) pj_turn_srv_create(pj_pool_factory *pf,
- 
+
      status = pj_stun_session_create(&srv->core.stun_cfg, srv->obj_name,
  				    &sess_cb, PJ_FALSE, NULL,
 -				    &srv->core.stun_sess);
@@ -3941,7 +3949,7 @@ index 07ccc31f0..3b93b9417 100644
 @@ -341,6 +342,12 @@ static pj_status_t icedemo_init(void)
      else
  	icedemo.ice_cfg.opt.aggressive = PJ_TRUE;
- 
+
 +    /* Connection type to STUN server */
 +    if (icedemo.opt.ice_tcp)
 +	icedemo.ice_cfg.stun.conn_type = PJ_STUN_TP_TCP;
@@ -3953,7 +3961,7 @@ index 07ccc31f0..3b93b9417 100644
  	char *pos;
 @@ -384,7 +391,7 @@ static pj_status_t icedemo_init(void)
  	icedemo.ice_cfg.turn.auth_cred.data.static_cred.data = icedemo.opt.turn_password;
- 
+
  	/* Connection type to TURN server */
 -	if (icedemo.opt.turn_tcp)
 +	if (icedemo.opt.ice_tcp)
@@ -3963,7 +3971,7 @@ index 07ccc31f0..3b93b9417 100644
 @@ -395,6 +402,10 @@ static pj_status_t icedemo_init(void)
  	icedemo.ice_cfg.turn.alloc_param.ka_interval = KA_INTERVAL;
      }
- 
+
 +    if (icedemo.opt.ice_tcp) {
 +	icedemo.ice_cfg.protocol = PJ_ICE_TP_TCP;
 +    }
@@ -3974,7 +3982,7 @@ index 07ccc31f0..3b93b9417 100644
 @@ -530,10 +541,27 @@ static int print_cand(char buffer[], unsigned maxlen,
      char *p = buffer;
      int printed;
- 
+
 -    PRINT("a=candidate:%.*s %u UDP %u %s %u typ ",
 +    /**   Section 4.5, RFC 6544 (https://tools.ietf.org/html/rfc6544)
 +     *    candidate-attribute   = "candidate" ":" foundation SP component-id SP
@@ -3998,12 +4006,12 @@ index 07ccc31f0..3b93b9417 100644
  	  (unsigned)cand->comp_id,
 +	  cand->transport == PJ_CAND_UDP? "UDP" : "TCP",
  	  cand->prio,
- 	  pj_sockaddr_print(&cand->addr, ipaddr, 
+ 	  pj_sockaddr_print(&cand->addr, ipaddr,
  			    sizeof(ipaddr), 0),
 @@ -542,6 +570,23 @@ static int print_cand(char buffer[], unsigned maxlen,
      PRINT("%s\n",
  	  pj_ice_get_cand_type_name(cand->type));
- 
+
 +    if (cand->transport != PJ_CAND_UDP) {
 +	PRINT(" tcptype");
 +	switch (cand->transport) {
@@ -4023,11 +4031,11 @@ index 07ccc31f0..3b93b9417 100644
 +
      if (p == buffer+maxlen)
  	return -PJ_ETOOSMALL;
- 
+
 @@ -608,6 +653,26 @@ static int encode_session(char buffer[], unsigned maxlen)
  				    sizeof(ipaddr), 0));
  	}
- 
+
 +	if (cand[0].transport != PJ_CAND_UDP) {
 +	    /** RFC 6544, Section 4.5:
 +	     * If the default candidate is TCP-based, the agent MUST include the
@@ -4062,7 +4070,7 @@ index 07ccc31f0..3b93b9417 100644
      char     comp0_addr[80];
 @@ -819,27 +884,43 @@ static void icedemo_input_remote(void)
  		    pj_sockaddr_set_port(&icedemo.rem.def_addr[1], (pj_uint16_t)port);
- 
+
  		} else if (strcmp(attr, "candidate")==0) {
 +		    /**   Section 4.5, RFC 6544 (https://tools.ietf.org/html/rfc6544)
 +		     *    candidate-attribute   = "candidate" ":" foundation SP component-id
@@ -4083,7 +4091,7 @@ index 07ccc31f0..3b93b9417 100644
  		    pj_ice_sess_cand *cand;
  		    pj_status_t status;
 +		    pj_bool_t is_tcp = PJ_FALSE;
- 
+
 -		    cnt = sscanf(sdpcand, "%s %d %s %d %s %d typ %s",
 +		    cnt = sscanf(sdpcand, "%s %d %s %d %s %d typ %s tcptype %s\n",
  				 foundation,
@@ -4100,18 +4108,18 @@ index 07ccc31f0..3b93b9417 100644
  			PJ_LOG(1, (THIS_FILE, "error: Invalid ICE candidate line"));
  			goto on_error;
  		    }
- 
+
 +		    if (strcmp(transport, "TCP") == 0) {
 +			is_tcp = PJ_TRUE;
 +		    }
 +
  		    cand = &icedemo.rem.cand[icedemo.rem.cand_cnt];
  		    pj_bzero(cand, sizeof(*cand));
- 		    
+
 @@ -855,6 +936,23 @@ static void icedemo_input_remote(void)
  			goto on_error;
  		    }
- 
+
 +		    if (is_tcp) {
 +			if (strcmp(tcp_type, "active") == 0)
 +			    cand->transport = PJ_CAND_TCP_ACTIVE;
@@ -4133,7 +4141,7 @@ index 07ccc31f0..3b93b9417 100644
  		    pj_strdup2(icedemo.pool, &cand->foundation, foundation);
  		    cand->prio = prio;
 @@ -879,6 +977,10 @@ static void icedemo_input_remote(void)
- 
+
  		    if (cand->comp_id > icedemo.rem.comp_cnt)
  			icedemo.rem.comp_cnt = cand->comp_id;
 +		} else if (strcmp(attr, "setup") == 0) {
@@ -4156,5 +4164,5 @@ index 474a8d07c..9257f07a4 100644
  				     NULL, sess, &sess->stun_sock);
  	if (status != PJ_SUCCESS) {
  	    char errmsg[PJ_ERR_MSG_SIZE];
--- 
-2.25.2
\ No newline at end of file
+--
+2.26.2