Free (GPLv2) TCP/IP stack developed by TASS Belgium

Fork of PicoTCP by Daniele Lacamera

Revision:
49:40fc4462265c
Parent:
29:1a47b7151851
--- a/stack/pico_socket.c	Thu Jul 25 09:36:23 2013 +0000
+++ b/stack/pico_socket.c	Fri Aug 02 07:28:05 2013 +0000
@@ -24,6 +24,10 @@
 #if defined (PICO_SUPPORT_TCP) || defined (PICO_SUPPORT_UDP)
 
 
+#define PROTO(s) ((s)->proto->proto_number)
+#define PICO_SOCKET4_MTU 1480 /* Ethernet MTU(1500) - IP header size(20) */
+#define PICO_SOCKET6_MTU 1460 /* Ethernet MTU(1500) - IP header size(40) */
+
 #ifdef PICO_SUPPORT_MUTEX
 static void * Mutex = NULL;
 #define LOCK(x) {\
@@ -596,7 +600,7 @@
 
 #ifdef PICO_SUPPORT_MCAST
   do {
-    uint8_t filter_mode = 0;
+    int filter_mode;
     struct pico_tree_node *index = NULL, *_tmp = NULL, *index2 = NULL, *_tmp2 = NULL;
     struct pico_mcast_listen *listen = NULL;
     struct pico_ip4 *source = NULL;
@@ -612,7 +616,8 @@
           pico_free(source);
         }
         filter_mode = pico_socket_aggregate_mcastfilters(&listen->mcast_link, &listen->mcast_group);
-        pico_ipv4_mcast_leave(&listen->mcast_link, &listen->mcast_group, 1, filter_mode, &MCASTFilter);
+        if (filter_mode >= 0) 
+          pico_ipv4_mcast_leave(&listen->mcast_link, &listen->mcast_group, 1, filter_mode, &MCASTFilter);
         pico_tree_delete(s->MCASTListen, listen);
         pico_free(listen);
       }
@@ -971,6 +976,7 @@
 {
   struct pico_frame *f;
   struct pico_remote_duple *remote_duple = NULL;
+  int socket_mtu = PICO_SOCKET4_MTU;
   int header_offset = 0;
   int total_payload_written = 0;
 #ifdef PICO_SUPPORT_IPV4
@@ -1006,6 +1012,7 @@
 
 #ifdef PICO_SUPPORT_IPV4
   if (IS_SOCK_IPV4(s)) {
+    socket_mtu = PICO_SOCKET4_MTU;
     if ((s->state & PICO_SOCKET_STATE_CONNECTED)) {
       if  (s->remote_addr.ip4.addr != ((struct pico_ip4 *)dst)->addr ) {
         pico_err = PICO_ERR_EADDRNOTAVAIL;
@@ -1028,11 +1035,10 @@
       }
 #     endif
     }
-  }
-#endif
-
-#ifdef PICO_SUPPORT_IPV6
-  if (IS_SOCK_IPV6(s)) {
+    #endif
+  } else if (IS_SOCK_IPV6(s)) {
+    socket_mtu = PICO_SOCKET6_MTU;
+    #ifdef PICO_SUPPORT_IPV6
     if (s->state & PICO_SOCKET_STATE_CONNECTED) {
       if (memcmp(&s->remote_addr, dst, PICO_SIZE_IP6))
         return -1;
@@ -1052,8 +1058,8 @@
       }
 #     endif
     }
+#endif
   }
-#endif
 
   if ((s->state & PICO_SOCKET_STATE_BOUND) == 0) {
     s->local_port = pico_socket_high_port(s->proto->proto_number);
@@ -1078,9 +1084,9 @@
 
   while (total_payload_written < len) {
     int transport_len = (len - total_payload_written) + header_offset; 
-    if (transport_len > PICO_SOCKET_MTU)
-      transport_len = PICO_SOCKET_MTU;
-#ifdef PICO_SUPPORT_IPFRAG
+    if (transport_len > socket_mtu)
+      transport_len = socket_mtu;
+    #ifdef PICO_SUPPORT_IPFRAG
     else {
       if (total_payload_written)
         transport_len -= header_offset; /* last fragment, do not allocate memory for transport header */
@@ -1100,9 +1106,9 @@
       memcpy(f->info, remote_duple, sizeof(struct pico_remote_duple));
     }
 
-#ifdef PICO_SUPPORT_IPFRAG
-#  ifdef PICO_SUPPORT_UDP
-    if (PROTO(s) == PICO_PROTO_UDP && ((len + header_offset) > PICO_SOCKET_MTU)) {
+    #ifdef PICO_SUPPORT_IPFRAG
+    #ifdef PICO_SUPPORT_UDP
+    if (PROTO(s) == PICO_PROTO_UDP && ((len + header_offset) > socket_mtu)) {
       /* hacking way to identify fragmentation frames: payload != transport_hdr -> first frame */
       if (!total_payload_written) {
         frag_dbg("FRAG: first fragmented frame %p | len = %u offset = 0\n", f, f->payload_len);
@@ -1496,7 +1502,7 @@
     case PICO_IP_ADD_MEMBERSHIP:
       /* EXCLUDE mode */
       if (s->proto->proto_number == PICO_PROTO_UDP) {
-        uint8_t filter_mode = 0;
+        int filter_mode;
         struct pico_ip_mreq *mreq = NULL;
         struct pico_mcast_listen *listen = NULL, ltest = {0};
         struct pico_ipv4_link *mcast_link = NULL;
@@ -1562,7 +1568,7 @@
     case PICO_IP_DROP_MEMBERSHIP:
       /* EXCLUDE mode */
       if (s->proto->proto_number == PICO_PROTO_UDP) {
-        uint8_t filter_mode = 0;
+        int filter_mode = 0;
         struct pico_ip_mreq *mreq = NULL;
         struct pico_mcast_listen *listen = NULL, ltest = {0};
         struct pico_ip4 *source = NULL;
@@ -1621,7 +1627,7 @@
     case PICO_IP_UNBLOCK_SOURCE:
       /* EXCLUDE mode */
       if (s->proto->proto_number == PICO_PROTO_UDP) {
-        uint8_t filter_mode = 0;
+        int filter_mode = 0;
         struct pico_ip_mreq_source *mreq = NULL;
         struct pico_mcast_listen *listen = NULL, ltest = {0};
         struct pico_ip4 *source = NULL, stest = {0};
@@ -1681,7 +1687,7 @@
     case PICO_IP_BLOCK_SOURCE:
       /* EXCLUDE mode */
       if (s->proto->proto_number == PICO_PROTO_UDP) {
-        uint8_t filter_mode = 0;
+        int filter_mode = 0;
         struct pico_ip_mreq_source *mreq = NULL;
         struct pico_mcast_listen *listen = NULL, ltest = {0};
         struct pico_ip4 *source = NULL, stest = {0};
@@ -1746,7 +1752,7 @@
     case PICO_IP_ADD_SOURCE_MEMBERSHIP:
       /* INCLUDE mode */
       if (s->proto->proto_number == PICO_PROTO_UDP) {
-        uint8_t filter_mode = 0, reference_count = 0;
+        int filter_mode = 0, reference_count = 0;
         struct pico_ip_mreq_source *mreq = NULL;
         struct pico_mcast_listen *listen = NULL, ltest = {0};
         struct pico_ip4 *source = NULL, stest = {0};
@@ -1833,7 +1839,7 @@
     case PICO_IP_DROP_SOURCE_MEMBERSHIP:
       /* INCLUDE mode */
       if (s->proto->proto_number == PICO_PROTO_UDP) {
-        uint8_t filter_mode = 0, reference_count = 0;
+        int filter_mode = 0, reference_count = 0;
         struct pico_ip_mreq_source *mreq = NULL;
         struct pico_mcast_listen *listen = NULL, ltest = {0};
         struct pico_ip4 *source = NULL, stest = {0};
@@ -1993,9 +1999,9 @@
 #endif
 #ifdef PICO_SUPPORT_TCP
   if (PROTO(s) == PICO_PROTO_TCP) {
-      if(mode & PICO_SHUT_RDWR)
-          pico_socket_alter_state(s, PICO_SOCKET_STATE_SHUT_LOCAL | PICO_SOCKET_STATE_SHUT_REMOTE, 0, 0);
-      else if (mode & PICO_SHUT_WR)
+    if(mode & PICO_SHUT_RDWR)
+        pico_socket_alter_state(s, PICO_SOCKET_STATE_SHUT_LOCAL | PICO_SOCKET_STATE_SHUT_REMOTE, 0, 0);
+    else if (mode & PICO_SHUT_WR)
       pico_socket_alter_state(s, PICO_SOCKET_STATE_SHUT_LOCAL, 0, 0);
     else if (mode & PICO_SHUT_RD)
       pico_socket_alter_state(s, PICO_SOCKET_STATE_SHUT_REMOTE, 0, 0);
@@ -2089,6 +2095,22 @@
   return ret;
 }
 
+int pico_sockets_find(struct pico_socket *s)
+{
+        struct pico_tree_node *index = NULL;
+        pico_tree_foreach(index,&TCPTable) // for each sockport
+        {
+            struct pico_tree_node *sp_index = NULL;
+            struct pico_sockport * sp = (struct pico_sockport *)index->keyValue;
+            pico_tree_foreach(sp_index,&sp->socks) // for each socket in sockport
+            {
+                if(sp_index->keyValue == s)
+                    return 1;
+            }
+        }
+    return 0;
+}
+
 #define SL_LOOP_MIN 1
 
 
@@ -2149,7 +2171,7 @@
   start = sp_tcp;
 
   while (loop_score > SL_LOOP_MIN && sp_tcp != NULL) {
-    struct pico_tree_node * index;
+    struct pico_tree_node * index = NULL;
     pico_tree_foreach(index, &sp_tcp->socks){
       s = index->keyValue;
       loop_score = pico_tcp_output(s, loop_score);
@@ -2163,7 +2185,7 @@
     }
 
     /* check if RB_FOREACH ended, if not, break to keep the cur sp_tcp */
-    if (s != NULL)
+    if (index && index->keyValue)
       break;
 
     index_tcp = pico_tree_next(index_tcp);