X-Git-Url: https://git.llucax.com/z.facultad/75.74/practicos.git/blobdiff_plain/99005a685dba8392d7ef48657854b498686223c3..c1b28b595a388df043997c87faf75c06959405d0:/practicas/pipi/src/ipout.cpp?ds=sidebyside diff --git a/practicas/pipi/src/ipout.cpp b/practicas/pipi/src/ipout.cpp index 6829d2f..84a3733 100644 --- a/practicas/pipi/src/ipout.cpp +++ b/practicas/pipi/src/ipout.cpp @@ -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); } @@ -62,17 +52,19 @@ bool IPOut::send(IPHeader iph, std::string data) throw (std::runtime_error) RouteTable::Route* r = rtable.get(iph.dst); if (!r) { - drop("No existe una ruta para el destino", iph); + // ICMP + drop("No existe una ruta para el destino -> ICMP", iph); 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; @@ -97,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 :