Index: trunk/src/VBox/Devices/Network/slirp/ip_icmp.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/ip_icmp.c	(revision 15357)
+++ trunk/src/VBox/Devices/Network/slirp/ip_icmp.c	(revision 15365)
@@ -146,5 +146,7 @@
     struct udphdr *udp;
     struct tcphdr *tcp;
-    struct socket *head_socket, *so;
+    struct socket *head_socket;
+    struct socket *last_socket;
+    struct socket *so;
     struct in_addr laddr, faddr;
     u_int lport, fport;
@@ -191,4 +193,5 @@
             laddr.s_addr = ip->ip_src.s_addr;
             lport = udp->uh_sport;
+            last_socket = udp_last_so;
             /* fall through */
 
@@ -202,6 +205,15 @@
                 laddr.s_addr = ip->ip_src.s_addr;
                 lport = tcp->th_sport;
+                last_socket = tcp_last_so;
             }
-            for (so = head_socket->so_next; so != head_socket; so = so->so_next)
+            /* check last socket first */
+            if (   last_socket->so_faddr.s_addr == faddr.s_addr
+                && last_socket->so_fport == fport
+                && last_socket->so_hlport == lport)
+            {
+                found = 1;
+                goto sofound;
+            }
+            for (so = head_socket->so_prev; so != head_socket; so = so->so_prev)
             {
                 /* Should be reaplaced by hash here */
@@ -209,17 +221,7 @@
                 if (   so->so_faddr.s_addr == faddr.s_addr
                     && so->so_fport == fport
-#if 0
-                    && so->so_hladdr.s_addr == laddr.s_addr
-#endif
                     && so->so_hlport == lport)
                 {
-                    icm = malloc(sizeof(struct icmp_msg));
-                    icm->im_m = so->so_m;
                     found = 1;
-                    LogRel(("hit:%R[natsock]\n", so));
-                    /*XXX: this storage not very long,
-                     * better add flag if it should removed from lis
-                     */
-                    LIST_INSERT_HEAD(&pData->icmp_msg_head, icm, im_list);
                     break;
                 }
@@ -229,4 +231,18 @@
         default:
             LogRel(("%s:ICMP: unsupported protocol(%d)\n", __FUNCTION__, ip->ip_p));
+    }
+    sofound:
+    if (found == 1 && icm == NULL)
+    {
+        icm = malloc(sizeof(struct icmp_msg));
+        icm->im_m = so->so_m;
+        icm->im_so = so;
+        found = 1;
+        LogRel(("hit:%R[natsock]\n", so));
+        /*XXX: this storage not very long,
+         * better add flag if it should removed from lis
+         */
+        LIST_INSERT_HEAD(&pData->icmp_msg_head, icm, im_list);
+        return (icm);
     }
     if (found == 1)
Index: trunk/src/VBox/Devices/Network/slirp/ip_icmp.h
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/ip_icmp.h	(revision 15357)
+++ trunk/src/VBox/Devices/Network/slirp/ip_icmp.h	(revision 15365)
@@ -177,4 +177,5 @@
     LIST_ENTRY(icmp_msg) im_list;
     struct mbuf *im_m;
+    struct socket *im_so;
 };
 
Index: trunk/src/VBox/Devices/Network/slirp/socket.c
===================================================================
--- trunk/src/VBox/Devices/Network/slirp/socket.c	(revision 15357)
+++ trunk/src/VBox/Devices/Network/slirp/socket.c	(revision 15365)
@@ -794,4 +794,5 @@
     struct mbuf *m;
     struct icmp_msg *icm;
+    uint8_t proto;
 
     ip = (struct ip *)buff;
@@ -821,4 +822,5 @@
 
     ip = mtod(m, struct ip *);
+    proto = ip->ip_p;
     /* Now ip is pointing on header we've sent from guest */
     if (icp->icmp_type == ICMP_TIMXCEED)
@@ -853,4 +855,30 @@
     LIST_REMOVE(icm, im_list);
     /* Don't call m_free here*/
+#if 0
+    if (icp->icmp_type == ICMP_TIMXCEED)
+    {
+        switch (proto)
+        {
+            case  IPPROTO_UDP:
+                /*XXX: so->so_m already freed so we shouldn't call sofree */
+                if (so == udp_last_so)
+                    udp_last_so = &udb;
+                closesocket(icm->im_so->s);
+                icm->im_so->s = 1;
+                icm->im_so->so_state = SS_NOFDREF;
+                if(so->so_next && so->so_prev) {
+                    remque(pData, so);
+                    free(icm->im_so);
+                }
+            break;
+            case  IPPROTO_TCP:
+                /*close tcp should be here */
+            break;
+            default:
+            /* do nothing */
+            break;
+        }
+    }
+#endif
     free(icm);
 }
