Index: pjproject/trunk/pjnath/include/pjnath/stun_msg.h
===================================================================
--- pjproject/trunk/pjnath/include/pjnath/stun_msg.h	(revision 2233)
+++ pjproject/trunk/pjnath/include/pjnath/stun_msg.h	(revision 2234)
@@ -291,10 +291,10 @@
     PJ_STUN_ATTR_LIFETIME	    = 0x000D,/**< TURN LIFETIME attr.	    */
     PJ_STUN_ATTR_MAGIC_COOKIE	    = 0x000F,/**< MAGIC-COOKIE attr (deprec)*/
-    PJ_STUN_ATTR_BANDWIDTH	    = 0x0010,/**< TURN BANDWIDTH attr.	    */
+    PJ_STUN_ATTR_BANDWIDTH	    = 0x0010,/**< TURN BANDWIDTH (deprec)   */
     PJ_STUN_ATTR_PEER_ADDR	    = 0x0012,/**< TURN PEER-ADDRESS attr.   */
     PJ_STUN_ATTR_DATA		    = 0x0013,/**< DATA attribute.	    */
     PJ_STUN_ATTR_REALM		    = 0x0014,/**< REALM attribute.	    */
     PJ_STUN_ATTR_NONCE		    = 0x0015,/**< NONCE attribute.	    */
-    PJ_STUN_ATTR_RELAY_ADDR	    = 0x0016,/**< RELAY-ADDRESS attribute.  */
+    PJ_STUN_ATTR_RELAYED_ADDR	    = 0x0016,/**< RELAYED-ADDRESS attribute.*/
     PJ_STUN_ATTR_REQ_ADDR_TYPE	    = 0x0017,/**< REQUESTED-ADDRESS-TYPE    */
     PJ_STUN_ATTR_REQ_PROPS	    = 0x0018,/**< REQUESTED-PROPS	    */
@@ -306,5 +306,5 @@
     PJ_STUN_ATTR_PRIORITY	    = 0x0024,/**< PRIORITY		    */
     PJ_STUN_ATTR_USE_CANDIDATE	    = 0x0025,/**< USE-CANDIDATE		    */
-    PJ_STUN_ATTR_XOR_INTERNAL_ADDR  = 0x0026,/**< XOR-INTERNAL-ADDRESS	    */
+    PJ_STUN_ATTR_ICMP		    = 0x0030,/**< ICMP (TURN)		    */
 
     PJ_STUN_ATTR_END_MANDATORY_ATTR,
@@ -312,5 +312,5 @@
     PJ_STUN_ATTR_START_EXTENDED_ATTR= 0x8021,
 
-    PJ_STUN_ATTR_SERVER		    = 0x8022,/**< SERVER attribute.	    */
+    PJ_STUN_ATTR_SOFTWARE	    = 0x8022,/**< SOFTWARE attribute.	    */
     PJ_STUN_ATTR_ALTERNATE_SERVER   = 0x8023,/**< ALTERNATE-SERVER.	    */
     PJ_STUN_ATTR_REFRESH_INTERVAL   = 0x8024,/**< REFRESH-INTERVAL.	    */
@@ -346,4 +346,5 @@
     PJ_STUN_SC_STALE_NONCE	        = 438,  /**< Stale Nonce	    */
     PJ_STUN_SC_TRANSITIONING		= 439,  /**< Transitioning.	    */
+    PJ_STUN_SC_WRONG_CREDENTIALS	= 441,	/**< TURN Wrong Credentials */
     PJ_STUN_SC_UNSUPP_TRANSPORT_PROTO   = 442,  /**< Unsupported Transport or
 						     Protocol (TURN) */
@@ -515,6 +516,5 @@
 /**
  * This structure represents generic STUN string attributes, such as STUN
- * USERNAME, PASSWORD, SERVER, REALM, and NONCE attributes. Note that for REALM and
- * NONCE attributes, the text MUST be quoted with.
+ * USERNAME, PASSWORD, SOFTWARE, REALM, and NONCE attributes.
  */
 typedef struct pj_stun_string_attr
@@ -740,12 +740,10 @@
 
 /**
- * This describes STUN SERVER attribute.
- * The server attribute contains a textual description of the software
- * being used by the server, including manufacturer and version number.
- * The attribute has no impact on operation of the protocol, and serves
- * only as a tool for diagnostic and debugging purposes.  The value of
- * SERVER is variable length.
- */
-typedef struct pj_stun_string_attr pj_stun_server_attr;
+ * This describes STUN SOFTWARE attribute.
+ * The SOFTWARE attribute contains a textual description of the software
+ * being used by the agent sending the message.  It is used by clients
+ * and servers.  Its value SHOULD include manufacturer and version
+ * number. */
+typedef struct pj_stun_string_attr pj_stun_software_attr;
 
 
@@ -933,10 +931,10 @@
 
 /**
- * This describes the STUN RELAY-ADDRESS attribute.
- * The RELAY-ADDRESS is present in Allocate responses.  It specifies the
+ * This describes the STUN RELAYED-ADDRESS attribute.
+ * The RELAYED-ADDRESS is present in Allocate responses.  It specifies the
  * address and port that the server allocated to the client.  It is
  * encoded in the same way as XOR-MAPPED-ADDRESS.
  */
-typedef struct pj_stun_sockaddr_attr pj_stun_relay_addr_attr;
+typedef struct pj_stun_sockaddr_attr pj_stun_relayed_addr_attr;
 
 
@@ -965,7 +963,7 @@
  * #PJ_STUN_SET_PROP_TYPE().
  * 
- * This attribute allows the client to request certain properties for
- * the relayed transport address that is allocated by the server.  The
- * attribute is 32 bits long.  Its format is:
+ * This attribute allows the client to request that the allocation have
+ * certain properties, and by the server to indicate which properties
+ * are supported.  The attribute is 32 bits long.  Its format is:
 
  \verbatim
@@ -982,9 +980,30 @@
  * desired property.  The rest of the attribute is RFFU (Reserved For
  * Future Use) and MUST be set to 0 on transmission and ignored on
- * reception.  The values of the "Prop-type" field are:
- * 
- *    0x00  (Reserved)
- *    0x01  Even port number
- *    0x02  Pair of ports 
+ * reception.
+ *
+ * The "Prop-type" field is formatted as follows:
+
+ \verbatim
+
+      0 1 2 3 4 5 6 7 
+     +-+-+-+-+-+-+-+-+
+     |E|R|P|         |
+     +-+-+-+-+-+-+-+-+
+
+ \endverbatim
+
+   The bits in "Prop-type" are:
+
+   E: If 1, the port number for the relayed-transport-address must be
+      even.  If 0, the port number can be even or odd.
+
+   R: If 1, the server must reserve the next highest port for a
+      subsequent allocation.  If 0, no such reservation is requested.
+      If the client sets the R bit to 1, it MUST also set the E bit to 1
+      (however, the E bit may be 1 when the R bit is 0).
+
+   P: If 1, the allocation must be a Preserving allocation.  If 0, the
+      allocation can be either Preserving or Non-Preserving.
+
  */
 typedef struct pj_stun_uint_attr pj_stun_req_props_attr;
@@ -1091,14 +1110,4 @@
 
 /**
- * This structure describes STUN XOR-INTERNAL-ADDRESS attribute from
- * draft-wing-behave-nat-control-stun-usage-00.
- * This attribute MUST be present in a Binding Response and may be used
- * in other responses as well.  This attribute is necessary to allow a
- * STUN client to 'walk backwards' and communicate directly with all of
- * the STUN-aware NATs along the path.
- */
-typedef pj_stun_sockaddr_attr pj_stun_xor_internal_addr_attr;
-
-/**
  * This describes the STUN TIMER-VAL attribute.
  * The TIMER-VAL attribute is used only in conjunction with the Set
@@ -1117,4 +1126,9 @@
  */
 typedef struct pj_stun_uint64_attr pj_stun_ice_controlled_attr;
+
+/**
+ * This describes TURN ICMP attribute
+ */
+typedef struct pj_stun_uint_attr pj_stun_icmp_attr;
 
 /**
Index: pjproject/trunk/pjnath/include/pjnath/turn_session.h
===================================================================
--- pjproject/trunk/pjnath/include/pjnath/turn_session.h	(revision 2233)
+++ pjproject/trunk/pjnath/include/pjnath/turn_session.h	(revision 2234)
@@ -237,5 +237,7 @@
     /**
      * The requested BANDWIDTH. Default is zero to not request any
-     * specific bandwidth.
+     * specific bandwidth. Note that this attribute has been deprecated
+     * after TURN-08 draft, hence application should only use this
+     * attribute when talking to TURN-07 or older version.
      */
     int	    bandwidth;
@@ -582,4 +584,6 @@
  *			a ChannelData packet.
  * @param pkt_len	The length of the packet.
+ * @param parsed_len	Optional argument to receive the number of parsed
+ *			or processed data from the packet.
  *
  * @return		The function may return non-PJ_SUCCESS if it receives
@@ -589,5 +593,6 @@
 PJ_DECL(pj_status_t) pj_turn_session_on_rx_pkt(pj_turn_session *sess,
 					       void *pkt,
-					       unsigned pkt_len);
+					       unsigned pkt_len,
+					       unsigned *parsed_len);
 
 
Index: pjproject/trunk/pjnath/include/pjnath/types.h
===================================================================
--- pjproject/trunk/pjnath/include/pjnath/types.h	(revision 2233)
+++ pjproject/trunk/pjnath/include/pjnath/types.h	(revision 2234)
@@ -98,6 +98,6 @@
 
 This version of PJNATH implements the following STUN-bis draft:
-- <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-behave-rfc3489bis-15.txt">
-  <B>draft-ietf-behave-rfc3489bis-15</b></A>: Session Traversal 
+- <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-behave-rfc3489bis-18.txt">
+  <B>draft-ietf-behave-rfc3489bis-18</b></A>: Session Traversal 
     Utilities for (NAT) (STUN),
 
@@ -110,6 +110,6 @@
 This version of PJNATH implements both TCP and UDP client transport and it
 complies with the following TURN draft:
- - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-behave-turn-07.txt">
-   <B>draft-ietf-behave-turn-07</B></A>: Obtaining Relay Addresses 
+ - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-behave-turn-09.txt">
+   <B>draft-ietf-behave-turn-09</B></A>: Obtaining Relay Addresses 
    from Simple Traversal Underneath NAT (STUN)
 
Index: pjproject/trunk/pjnath/src/pjnath-test/server.c
===================================================================
--- pjproject/trunk/pjnath/src/pjnath-test/server.c	(revision 2233)
+++ pjproject/trunk/pjnath/src/pjnath-test/server.c	(revision 2234)
@@ -310,6 +310,6 @@
     pj_stun_msg_add_uint_attr(pool, resp, PJ_STUN_ATTR_LIFETIME, lifetime);
     if (lifetime != 0) {
-	/* Add RELAY-ADDRESS */
-	pj_stun_msg_add_sockaddr_attr(pool, resp, PJ_STUN_ATTR_RELAY_ADDR, PJ_TRUE, &alloc->alloc_addr,
+	/* Add RELAYED-ADDRESS */
+	pj_stun_msg_add_sockaddr_attr(pool, resp, PJ_STUN_ATTR_RELAYED_ADDR, PJ_TRUE, &alloc->alloc_addr,
 				      pj_sockaddr_get_len(&alloc->alloc_addr));
 	/* Add XOR-MAPPED-ADDRESS */
Index: pjproject/trunk/pjnath/src/pjnath-test/stun.c
===================================================================
--- pjproject/trunk/pjnath/src/pjnath-test/stun.c	(revision 2233)
+++ pjproject/trunk/pjnath/src/pjnath-test/stun.c	(revision 2234)
@@ -695,5 +695,5 @@
 		       (pj_uint8_t*)v->tsx_id, &msg);
 
-    pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_SERVER, 
+    pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_SOFTWARE, 
 				pj_cstr(&s1, "test vector"));
 
Index: pjproject/trunk/pjnath/src/pjnath/stun_msg.c
===================================================================
--- pjproject/trunk/pjnath/src/pjnath/stun_msg.c	(revision 2233)
+++ pjproject/trunk/pjnath/src/pjnath/stun_msg.c	(revision 2234)
@@ -67,4 +67,5 @@
     { PJ_STUN_SC_STALE_NONCE,		    "Stale Nonce"},
     { PJ_STUN_SC_TRANSITIONING,		    "Active Destination Already Set"},
+    { PJ_STUN_SC_WRONG_CREDENTIALS,	    "Wrong Credentials"},
     { PJ_STUN_SC_UNSUPP_TRANSPORT_PROTO,    "Unsupported Transport Protocol"},
     { PJ_STUN_SC_INVALID_IP_ADDR,	    "Invalid IP Address"},
@@ -310,5 +311,5 @@
     {
 	/* PJ_STUN_ATTR_RELAY_ADDRESS, */
-	"RELAY-ADDRESS",
+	"RELAYED-ADDRESS",
 	&decode_xored_sockaddr_attr,
 	&encode_sockaddr_attr,
@@ -421,9 +422,79 @@
     },
     {
-	/* PJ_STUN_ATTR_XOR_INTERNAL_ADDR, */
-	"XOR-INTERNAL-ADDRESS",
-	&decode_xored_sockaddr_attr,
-	&encode_sockaddr_attr,
-	&clone_sockaddr_attr
+	/* ID 0x0026 is not assigned */
+	NULL,
+	NULL,
+	NULL,
+	NULL
+    },
+    {
+	/* ID 0x0027 is not assigned */
+	NULL,
+	NULL,
+	NULL,
+	NULL
+    },
+    {
+	/* ID 0x0028 is not assigned */
+	NULL,
+	NULL,
+	NULL,
+	NULL
+    },
+    {
+	/* ID 0x0029 is not assigned */
+	NULL,
+	NULL,
+	NULL,
+	NULL
+    },
+    {
+	/* ID 0x002a is not assigned */
+	NULL,
+	NULL,
+	NULL,
+	NULL
+    },
+    {
+	/* ID 0x002b is not assigned */
+	NULL,
+	NULL,
+	NULL,
+	NULL
+    },
+    {
+	/* ID 0x002c is not assigned */
+	NULL,
+	NULL,
+	NULL,
+	NULL
+    },
+    {
+	/* ID 0x002d is not assigned */
+	NULL,
+	NULL,
+	NULL,
+	NULL
+    },
+    {
+	/* ID 0x002e is not assigned */
+	NULL,
+	NULL,
+	NULL,
+	NULL
+    },
+    {
+	/* ID 0x002f is not assigned */
+	NULL,
+	NULL,
+	NULL,
+	NULL
+    },
+    {
+	/* PJ_STUN_ATTR_ICMP, */
+	"ICMP",
+	&decode_uint_attr,
+	&encode_uint_attr,
+	&clone_uint_attr
     },
 
@@ -448,6 +519,6 @@
     },
     {
-	/* PJ_STUN_ATTR_SERVER, */
-	"SERVER",
+	/* PJ_STUN_ATTR_SOFTWARE, */
+	"SOFTWARE",
 	&decode_string_attr,
 	&encode_string_attr,
Index: pjproject/trunk/pjnath/src/pjnath/stun_msg_dump.c
===================================================================
--- pjproject/trunk/pjnath/src/pjnath/stun_msg_dump.c	(revision 2233)
+++ pjproject/trunk/pjnath/src/pjnath/stun_msg_dump.c	(revision 2234)
@@ -73,8 +73,7 @@
     case PJ_STUN_ATTR_REFLECTED_FROM:
     case PJ_STUN_ATTR_PEER_ADDR:
-    case PJ_STUN_ATTR_RELAY_ADDR:
+    case PJ_STUN_ATTR_RELAYED_ADDR:
     case PJ_STUN_ATTR_XOR_MAPPED_ADDR:
     case PJ_STUN_ATTR_XOR_REFLECTED_FROM:
-    case PJ_STUN_ATTR_XOR_INTERNAL_ADDR:
     case PJ_STUN_ATTR_ALTERNATE_SERVER:
 	{
@@ -123,4 +122,5 @@
     case PJ_STUN_ATTR_FINGERPRINT:
     case PJ_STUN_ATTR_REFRESH_INTERVAL:
+    case PJ_STUN_ATTR_ICMP:
 	{
 	    const pj_stun_uint_attr *attr;
@@ -139,5 +139,5 @@
     case PJ_STUN_ATTR_REALM:
     case PJ_STUN_ATTR_NONCE:
-    case PJ_STUN_ATTR_SERVER:
+    case PJ_STUN_ATTR_SOFTWARE:
 	{
 	    const pj_stun_string_attr *attr;
Index: pjproject/trunk/pjnath/src/pjnath/stun_session.c
===================================================================
--- pjproject/trunk/pjnath/src/pjnath/stun_session.c	(revision 2233)
+++ pjproject/trunk/pjnath/src/pjnath/stun_session.c	(revision 2234)
@@ -217,7 +217,7 @@
     pj_str_t realm, username, nonce, auth_key;
 
-    /* The server SHOULD include a SERVER attribute in all responses */
+    /* The server SHOULD include a SOFTWARE attribute in all responses */
     if (sess->srv_name.slen && PJ_STUN_IS_RESPONSE(msg->hdr.type)) {
-	pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_SERVER,
+	pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_SOFTWARE,
 				    &sess->srv_name);
     }
Index: pjproject/trunk/pjnath/src/pjnath/stun_transaction.c
===================================================================
--- pjproject/trunk/pjnath/src/pjnath/stun_transaction.c	(revision 2233)
+++ pjproject/trunk/pjnath/src/pjnath/stun_transaction.c	(revision 2234)
@@ -252,4 +252,6 @@
 						unsigned pkt_len)
 {
+    pj_status_t status;
+
     PJ_ASSERT_RETURN(tsx && pkt && pkt_len, PJ_EINVAL);
     PJ_ASSERT_RETURN(tsx->retransmit_timer.id == 0, PJ_EBUSY);
@@ -262,6 +264,43 @@
     tsx->require_retransmit = retransmit;
 
+    /* For TCP, schedule timeout timer after PJ_STUN_TIMEOUT_VALUE.
+     * Since we don't have timeout timer, simulate this by using
+     * retransmit timer.
+     */
+    if (!retransmit) {
+	unsigned timeout;
+
+	pj_assert(tsx->retransmit_timer.id == 0);
+	tsx->transmit_count = PJ_STUN_MAX_TRANSMIT_COUNT;
+
+	timeout = tsx->rto_msec * 16;
+	tsx->retransmit_time.sec = timeout / 1000;
+	tsx->retransmit_time.msec = timeout % 1000;
+
+	/* Schedule timer first because when send_msg() failed we can
+	 * cancel it (as opposed to when schedule_timer() failed we cannot
+	 * cancel transmission).
+	 */;
+	status = pj_timer_heap_schedule(tsx->timer_heap, 
+					&tsx->retransmit_timer,
+					&tsx->retransmit_time);
+	if (status != PJ_SUCCESS) {
+	    tsx->retransmit_timer.id = 0;
+	    return status;
+	}
+    }
+
     /* Send the message */
-    return tsx_transmit_msg(tsx);
+    status = tsx_transmit_msg(tsx);
+    if (status != PJ_SUCCESS) {
+	if (tsx->retransmit_timer.id != 0) {
+	    pj_timer_heap_cancel(tsx->timer_heap, 
+				 &tsx->retransmit_timer);
+	    tsx->retransmit_timer.id = 0;
+	}
+	return status;
+    }
+
+    return PJ_SUCCESS;
 }
 
Index: pjproject/trunk/pjnath/src/pjnath/turn_session.c
===================================================================
--- pjproject/trunk/pjnath/src/pjnath/turn_session.c	(revision 2233)
+++ pjproject/trunk/pjnath/src/pjnath/turn_session.c	(revision 2234)
@@ -915,5 +915,6 @@
 PJ_DEF(pj_status_t) pj_turn_session_on_rx_pkt(pj_turn_session *sess,
 					      void *pkt,
-					      unsigned pkt_len)
+					      unsigned pkt_len,
+					      unsigned *parsed_len)
 {
     pj_bool_t is_stun;
@@ -941,22 +942,43 @@
 	    options |= PJ_STUN_IS_DATAGRAM;
 	status=pj_stun_session_on_rx_pkt(sess->stun, pkt, pkt_len,
-					 options, NULL, NULL,
+					 options, NULL, parsed_len,
 					 sess->srv_addr,
 					 pj_sockaddr_get_len(sess->srv_addr));
 
-    } else if (sess->cb.on_rx_data) {
-
-	/* This must be ChannelData. Only makes sense when on_rx_data() is
-	 * implemented by application.
-	 */
+    } else {
+	/* This must be ChannelData. */
 	pj_turn_channel_data cd;
 	struct peer *peer;
 
-	PJ_ASSERT_RETURN(pkt_len >= 4, PJ_ETOOSMALL);
-
-	/* Lookup peer */
+	if (pkt_len < 4) {
+	    if (parsed_len) *parsed_len = 0;
+	    return PJ_ETOOSMALL;
+	}
+
+	/* Decode ChannelData packet */
 	pj_memcpy(&cd, pkt, sizeof(pj_turn_channel_data));
 	cd.ch_number = pj_ntohs(cd.ch_number);
 	cd.length = pj_ntohs(cd.length);
+
+	/* Check that size is sane */
+	if (pkt_len < cd.length+sizeof(cd)) {
+	    if (parsed_len) {
+		if (is_datagram) {
+		    /* Discard the datagram */
+		    *parsed_len = pkt_len;
+		} else {
+		    /* Insufficient fragment */
+		    *parsed_len = 0;
+		}
+	    }
+	    status = PJ_ETOOSMALL;
+	    goto on_return;
+	} else {
+	    if (parsed_len) {
+		*parsed_len = cd.length + sizeof(cd);
+	    }
+	}
+
+	/* Lookup peer */
 	peer = lookup_peer_by_chnum(sess, cd.ch_number);
 	if (!peer || !peer->bound) {
@@ -965,21 +987,11 @@
 	}
 
-	/* Check that size is correct, for UDP */
-	if (pkt_len < cd.length+sizeof(cd)) {
-	    status = PJ_ETOOSMALL;
-	    goto on_return;
-	}
-
 	/* Notify application */
-	(*sess->cb.on_rx_data)(sess, ((pj_uint8_t*)pkt)+sizeof(cd), 
-			       cd.length, &peer->addr,
-			       pj_sockaddr_get_len(&peer->addr));
-
-	status = PJ_SUCCESS;
-
-    } else {
-	/* This is ChannelData and application doesn't implement
-	 * on_rx_data() callback. Just ignore the packet.
-	 */
+	if (sess->cb.on_rx_data) {
+	    (*sess->cb.on_rx_data)(sess, ((pj_uint8_t*)pkt)+sizeof(cd), 
+				   cd.length, &peer->addr,
+				   pj_sockaddr_get_len(&peer->addr));
+	}
+
 	status = PJ_SUCCESS;
     }
@@ -1078,5 +1090,5 @@
 {
     const pj_stun_lifetime_attr *lf_attr;
-    const pj_stun_relay_addr_attr *raddr_attr;
+    const pj_stun_relayed_addr_attr *raddr_attr;
     const pj_stun_sockaddr_attr *mapped_attr;
     pj_str_t s;
@@ -1126,6 +1138,6 @@
      * address family.
      */
-    raddr_attr = (const pj_stun_relay_addr_attr*)
-		 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_RELAY_ADDR, 0);
+    raddr_attr = (const pj_stun_relayed_addr_attr*)
+		 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_RELAYED_ADDR, 0);
     if (raddr_attr == NULL && method==PJ_STUN_ALLOCATE_METHOD) {
 	on_session_fail(sess, method, PJNATH_EINSTUNMSG,
@@ -1342,4 +1354,5 @@
     pj_turn_session *sess;
     pj_stun_peer_addr_attr *peer_attr;
+    pj_stun_icmp_attr *icmp;
     pj_stun_data_attr *data_attr;
 
@@ -1357,4 +1370,12 @@
 		  pj_stun_get_method_name(msg->hdr.type)));
 	return PJ_EINVALIDOP;
+    }
+
+    /* Check if there is ICMP attribute in the message */
+    icmp = (pj_stun_icmp_attr*)
+	   pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_ICMP, 0);
+    if (icmp != NULL) {
+	/* This is a forwarded ICMP packet. Ignore it for now */
+	return PJ_SUCCESS;
     }
 
Index: pjproject/trunk/pjnath/src/pjnath/turn_sock.c
===================================================================
--- pjproject/trunk/pjnath/src/pjnath/turn_sock.c	(revision 2233)
+++ pjproject/trunk/pjnath/src/pjnath/turn_sock.c	(revision 2234)
@@ -464,4 +464,5 @@
 {
     pj_turn_sock *turn_sock;
+    unsigned parsed_len;
     pj_bool_t ret = PJ_TRUE;
 
@@ -471,6 +472,12 @@
     if (status == PJ_SUCCESS && turn_sock->sess) {
 	/* Report incoming packet to TURN session */
-	PJ_TODO(REPORT_PARSED_LEN);
-	pj_turn_session_on_rx_pkt(turn_sock->sess, data,  size);
+	parsed_len = (unsigned)size;
+	pj_turn_session_on_rx_pkt(turn_sock->sess, data,  size, &parsed_len);
+	if (parsed_len < (unsigned)size) {
+	    *remainder = size - parsed_len;
+	    pj_memmove(data, ((char*)data)+parsed_len, *remainder);
+	} else {
+	    *remainder = 0;
+	}
     } else if (status != PJ_SUCCESS && 
 	       turn_sock->conn_type != PJ_TURN_TP_UDP) 
Index: pjproject/trunk/pjnath/src/pjturn-srv/allocation.c
===================================================================
--- pjproject/trunk/pjnath/src/pjturn-srv/allocation.c	(revision 2233)
+++ pjproject/trunk/pjnath/src/pjturn-srv/allocation.c	(revision 2234)
@@ -213,5 +213,5 @@
     /* Add RELAYED-ADDRESS attribute */
     pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg,
-				  PJ_STUN_ATTR_RELAY_ADDR, PJ_TRUE,
+				  PJ_STUN_ATTR_RELAYED_ADDR, PJ_TRUE,
 				  &alloc->relay.hkey.addr,
 				  pj_sockaddr_get_len(&alloc->relay.hkey.addr));
Index: pjproject/trunk/pjnath/src/pjturn-srv/listener_udp.c
===================================================================
--- pjproject/trunk/pjnath/src/pjturn-srv/listener_udp.c	(revision 2233)
+++ pjproject/trunk/pjnath/src/pjturn-srv/listener_udp.c	(revision 2234)
@@ -126,8 +126,7 @@
     for (i=0; i<concurrency_cnt; ++i) {
 	pj_pool_t *rpool = pj_pool_create(srv->core.pf, "rop%p", 
-					  sizeof(struct read_op)+1000, 
-					  1000, NULL);
-
-	udp->read_op[i] = PJ_POOL_ZALLOC_T(rpool, struct read_op);
+					  1000, 1000, NULL);
+
+	udp->read_op[i] = PJ_POOL_ZALLOC_T(pool, struct read_op);
 	udp->read_op[i]->pkt.pool = rpool;
 
Index: pjproject/trunk/pjnath/src/pjturn-srv/server.c
===================================================================
--- pjproject/trunk/pjnath/src/pjturn-srv/server.c	(revision 2233)
+++ pjproject/trunk/pjnath/src/pjturn-srv/server.c	(revision 2234)
@@ -552,4 +552,41 @@
 }
 
+/* Handle STUN Binding request */
+static void handle_binding_request(pj_turn_pkt *pkt,
+				   unsigned options)
+{
+    pj_stun_msg *request, *response;
+    pj_uint8_t pdu[200];
+    pj_size_t len;
+    pj_status_t status;
+
+    /* Decode request */
+    status = pj_stun_msg_decode(pkt->pool, pkt->pkt, pkt->len, options,
+				&request, NULL, NULL);
+    if (status != PJ_SUCCESS)
+	return;
+
+    /* Create response */
+    status = pj_stun_msg_create_response(pkt->pool, request, 0, NULL, 
+					 &response);
+    if (status != PJ_SUCCESS)
+	return;
+
+    /* Add XOR-MAPPED-ADDRESS */
+    pj_stun_msg_add_sockaddr_attr(pkt->pool, response, 
+				  PJ_STUN_ATTR_XOR_MAPPED_ADDR,
+				  PJ_TRUE,
+				  &pkt->src.clt_addr,
+				  pkt->src_addr_len);
+
+    /* Encode */
+    status = pj_stun_msg_encode(response, pdu, sizeof(pdu), 0, NULL, &len);
+    if (status != PJ_SUCCESS)
+	return;
+
+    /* Send response */
+    pkt->transport->sendto(pkt->transport, pdu, len, 0, 
+			   &pkt->src.clt_addr, pkt->src_addr_len);
+}
 
 /*
@@ -616,4 +653,12 @@
 	}
 
+	/* Special handling for Binding Request. We won't give it to the 
+	 * STUN session since this request is not authenticated.
+	 */
+	if (pkt->pkt[1] == 1) {
+	    handle_binding_request(pkt, options);
+	    return;
+	}
+
 	/* Hand over processing to STUN session. This will trigger
 	 * on_rx_stun_request() callback to be called if the STUN
