]> git.llucax.com Git - z.facultad/75.74/practicos.git/blobdiff - practicas/pipi/src/ipout.cpp
Se agrega opción para recibir paquetes de un host específico y se mejora el
[z.facultad/75.74/practicos.git] / practicas / pipi / src / ipout.cpp
index 9c6d705dab25a7272ae9e702e18e9a9be3bdb439..84a3733f7b32e330dc1d9a74283e950c8007c465 100644 (file)
@@ -34,17 +34,6 @@ bool IPOut::send(const std::string& data, uint8_t proto, IPAddr dst, IPAddr src,
         bool df, uint8_t ttl, uint16_t id)
     throw (std::runtime_error)
 {
-    // Mando todo lo que tengo para forwardear
-    while (to_forward())
-    {
-        std::string buf = forward_que.receive();
-        IPHeader iph(buf);
-#ifdef DEBUG
-        std::cout << "IPOut::send (" << ip << "): A forwardear\n";
-#endif
-        send(iph, buf.substr(iph.header_len()));
-    }
-    // Mando el paquete en sí
     // Armamos cabecera
     if (!src)
         src = ip;
@@ -52,6 +41,7 @@ bool IPOut::send(const std::string& data, uint8_t proto, IPAddr dst, IPAddr src,
         id = get_id();
     IPHeader iph(4, IPHeader::header_len() + data.size(), id, df, 0, 0,
             ttl, proto, src, dst);
+    // Enviamos
     return send(iph, data);
 }
 
@@ -67,14 +57,14 @@ bool IPOut::send(IPHeader iph, std::string data) throw (std::runtime_error)
         return false;
     }
     // No quieren fragmentar
-    if (iph.df && (IPHeader::header_len() + data.size() > r->iface->mtu))
+    if (iph.df && (IPHeader::header_len() + data.size() > r->mtu))
     {
         // Silencioso
         drop("Tamaño de paquete más grande que MTU y DF=1", iph);
         return false;
     }
     // Fragmenta (de ser necesario)
-    int max_payload = r->iface->mtu - IPHeader::header_len();
+    int max_payload = r->mtu - IPHeader::header_len();
     int cant_frag = data.size() / max_payload;
     if (data.size() % max_payload)
         ++cant_frag;
@@ -99,18 +89,28 @@ bool IPOut::send(IPHeader iph, std::string data) throw (std::runtime_error)
     return true;
 }
 
-/// Obtiene un identificador para el paquete
-uint16_t IPOut::get_id() const
+/// Realiza el forwarding de paquetes (en un loop infinito)
+void IPOut::forward_loop()
+    throw (std::runtime_error)
 {
-    return time(NULL);
+    while (true)
+    {
+        std::string buf = forward_que.receive();
+        IPHeader iph(buf);
+#ifdef DEBUG
+        std::cout << "IPOut::forward_loop (" << ip << "): A forwardear (id "
+                << iph.id << ", offset " << iph.offset << ")\n";
+#endif
+        send(iph, buf.substr(iph.header_len()));
+    }
 }
 
-/// Se fija si hay paquetes a forwardear (y devuelve cuantos hay)
-unsigned IPOut::to_forward()
+/// Obtiene un identificador para el paquete
+uint16_t IPOut::get_id() const
 {
-    struct msqid_ds minfo;
-    msgctl(forward_que.que_id, IPC_STAT, &minfo);
-    return minfo.msg_qnum;
+    static uint16_t st = time(NULL);
+    uint16_t tt = time(NULL);
+    return (tt == st) ? ++st : tt;
 }
 
 // vim: set et sw=4 sts=4 :