]> git.llucax.com Git - z.facultad/75.74/practicos.git/commitdiff
Se agrega opción para recibir paquetes de un host específico y se mejora el
authorLeandro Lucarella <llucax@gmail.com>
Fri, 23 Jun 2006 05:46:49 +0000 (05:46 +0000)
committerLeandro Lucarella <llucax@gmail.com>
Fri, 23 Jun 2006 05:46:49 +0000 (05:46 +0000)
manejo de buffers para que almacene paquetes completos.

practicas/pipi/src/ipin.cpp
practicas/pipi/src/ipin.h

index c8ea64e8f783b9c3f7740c3f2d1dc1877ab4b075..73913abda23f59f33e1fbae858efacb309263a4a 100644 (file)
@@ -27,10 +27,34 @@ void IPIn::drop(const std::string& msg, const IPHeader& iph)
 }
 
 /// Recibe un paquete IP
-std::string IPIn::recv(uint8_t proto, IPAddr& src, IPAddr& dst) throw (std::runtime_error)
+std::string IPIn::recv(uint8_t proto, IPAddr& src, IPAddr& dst, bool filter)
+    throw (std::runtime_error)
 {
     while (true)
     {
+        // Reviso buffers completos a ver si puedo sacar algo
+        buffer_complete_type::iterator f = buffer_complete.find(proto);
+        if (f != buffer_complete.end()) // Hay algo
+        {
+            srcmap_type& srcmap = f->second;
+            srcmap_type::iterator b;
+            if (filter)
+                b = srcmap.find(src); // Si filtro, busco el que me interesa
+            else
+                b = srcmap.begin(); // Si no filtro, agarro el primero
+            if (b != srcmap.end())
+            {
+                src = b->first;
+                dst = (b->second).dst;
+                std::string data = b->second.data;
+                // Limpio buffers
+                srcmap.erase(src);
+                if (srcmap.empty())
+                    buffer_complete.erase(proto);
+                return data;
+            }
+        }
+        // Si no pude sacar nada, recibo
         std::string buf = dev.receive();
         // No es siquiera IP
         if (buf.size() < IPHeader::header_len())
@@ -87,8 +111,8 @@ std::string IPIn::recv(uint8_t proto, IPAddr& src, IPAddr& dst) throw (std::runt
         // Es para nosotros y somos un host
         // Guarda en buffer
         buffer[iph][iph.offset] = buf.substr(iph.header_len());
-        // Si tiene más fragmentos o es un protocolo distinto, sigo
-        if (iph.mf || (iph.proto != proto))
+        // Si tiene más fragmentos, sigo
+        if (iph.mf)
             continue;
         // No hay más fragmentos, reensamblamos (de ser necesario)
         std::string data;
@@ -103,6 +127,13 @@ std::string IPIn::recv(uint8_t proto, IPAddr& src, IPAddr& dst) throw (std::runt
                 << data << "'\n";
 #endif
         buffer.erase(iph);
+        // Si es un protocolo distinto o no es de quien quiero, rearmo paquete
+        // (ya sé que no hay más fragmentos) y guardo en buffer nomás
+        if ((iph.proto != proto) || (filter == true && src != iph.src))
+        {
+            buffer_complete[proto][iph.src] = BufferPkt(iph.dst, data);
+            continue;
+        }
         //TODO faltaría limpiar fragmentos viejos cada tanto (timer?)
         src = iph.src;
         dst = iph.dst;
index 86202784f477e7eb66e07fd396da89fff73e2963..ecdc93ebdfff71ecdc4a98d44a5867f0cb9ff75c 100644 (file)
@@ -47,6 +47,19 @@ struct IPIn
     typedef std::map< BufferKey, offsetmap_type > buffer_type;
     buffer_type buffer;
 
+    /// Buffers de paquetes completos
+    struct BufferPkt
+    {
+        uint32_t dst;
+        std::string data;
+        BufferPkt() {}
+        BufferPkt(const IPAddr& dst, const std::string& data):
+            dst(dst), data(data) {}
+    };
+    typedef std::map< IPAddr, BufferPkt > srcmap_type;
+    typedef std::map< uint8_t, srcmap_type > buffer_complete_type;
+    buffer_complete_type buffer_complete;
+
     /// Constructor
     IPIn(const IPAddr& ip, Dev& dev, Dev& forward_que, bool router = false,
         bool forward = false, std::ostream& log = std::cout);
@@ -56,7 +69,8 @@ struct IPIn
     void drop(const std::string& msg, const IPHeader& iph);
 
     /// Recibe un paquete IP
-    std::string recv(uint8_t proto, IPAddr& src, IPAddr& dst)
+    std::string recv(uint8_t proto, IPAddr& src, IPAddr& dst,
+            bool filter = false)
         throw (std::runtime_error);
 
     // Nada de andar copiando placas...