From: Leandro Lucarella Date: Mon, 3 Jul 2006 21:35:05 +0000 (+0000) Subject: Se implementa el Resolver. X-Git-Tag: svn_import~14 X-Git-Url: https://git.llucax.com/z.facultad/75.74/practicos.git/commitdiff_plain/ac1d74a402f344ad8135f125cbac73ecda46172e?ds=inline Se implementa el Resolver. --- diff --git a/practicas/pipi/informe.rtf b/practicas/pipi/informe.rtf index eebe262..3f2c628 100644 --- a/practicas/pipi/informe.rtf +++ b/practicas/pipi/informe.rtf @@ -9,105 +9,105 @@ \red0\green0\blue0; \red255\green255\blue255;} {\stylesheet -{\s1\fi-431\li720\sbasedon28\snext28Contents 1;} -{\s2\fi-431\li1440\sbasedon28\snext28Contents 2;} -{\s3\fi-431\li2160\sbasedon28\snext28Contents 3;} -{\s8\fi-431\li720\sbasedon28Lower Roman List;} -{\s5\tx431\sbasedon24\snext28Numbered Heading 1;} -{\s6\tx431\sbasedon25\snext28Numbered Heading 2;} -{\s7\fi-431\li720Square List;} -{\*\cs11\sbasedon28Endnote Text;} -{\s4\fi-431\li2880\sbasedon28\snext28Contents 4;} -{\s9\fi-431\li720Diamond List;} -{\s10\fi-431\li720Numbered List;} +{\s1\fi-429\li720\sbasedon29\snext29Contents 1;} +{\s2\fi-429\li1440\sbasedon29\snext29Contents 2;} +{\s3\fi-429\li2160\sbasedon29\snext29Contents 3;} +{\s8\fi-429\li720\sbasedon29Lower Roman List;} +{\s5\tx431\sbasedon25\snext29Numbered Heading 1;} +{\s6\tx431\sbasedon26\snext29Numbered Heading 2;} +{\s7\fi-429\li720Square List;} +{\*\cs11\sbasedon29Endnote Text;} +{\s4\fi-429\li2880\sbasedon29\snext29Contents 4;} +{\s9\fi-429\li720Diamond List;} +{\s10\fi-429\li720Numbered List;} {\*\cs12\fs20\superEndnote Reference;} -{\s13\fi-431\li720Triangle List;} -{\s14\tx431\sbasedon26\snext28Numbered Heading 3;} -{\s15\fi-431\li720Dashed List;} -{\s16\fi-431\li720\sbasedon10Upper Roman List;} -{\s17\sb440\sa60\f0\fs24\b\sbasedon28\snext28Heading 4;} -{\s18\fi-431\li720Heart List;} -{\s34\fi-431\li720Box List;} -{\s20\fi-431\li720\sbasedon10Upper Case List;} -{\s21\fi-431\li720Bullet List;} -{\s22\fi-431\li720Hand List;} -{\*\cs23\fs20\sbasedon28Footnote Text;} -{\s24\sb440\sa60\f0\fs34\b\sbasedon28\snext28Heading 1;} -{\s25\sb440\sa60\f0\fs28\b\sbasedon28\snext28Heading 2;} -{\s19\qc\sb240\sa120\f0\fs32\b\sbasedon28\snext28Contents Header;} -{\s27\fi-431\li720Tick List;} -{\s26\sb440\sa60\f0\fs24\b\sbasedon28\snext28Heading 3;} -{\s29\fi-431\li720\sbasedon10Lower Case List;} -{\s30\li1440\ri1440\sa120\sbasedon28Block Text;} -{\s36\f2\sbasedon28Plain Text;} -{\s32\tx1584\sbasedon5\snext28Section Heading;} -{\s33\fi-431\li720Implies List;} -{\s28\f1\fs24\lang1034Normal;} -{\s35\fi-431\li720Star List;} -{\*\cs31\fs20\superFootnote Reference;} -{\s37\tx1584\sbasedon5\snext28Chapter Heading;}} -\kerning0\cf0\ftnbj\fet2\ftnstart1\ftnnar\aftnnar\ftnstart1\aftnstart1\aenddoc\revprop3{\info\uc1}\deftab720\viewkind1\paperw11905\paperh16837\margl1440\margr1440\widowctl +{\s13\fi-429\li720Triangle List;} +{\s14\tx431\sbasedon27\snext29Numbered Heading 3;} +{\s15\fi-429\li720Dashed List;} +{\s16\fi-429\li720\sbasedon10Upper Roman List;} +{\s17\sb440\sa60\f0\fs24\b\sbasedon29\snext29Heading 4;} +{\s18\fi-429\li720Heart List;} +{\s35\fi-429\li720Box List;} +{\*\cs20\fs20Reference;} +{\s21\fi-429\li720\sbasedon10Upper Case List;} +{\s22\fi-429\li720Bullet List;} +{\s23\fi-429\li720Hand List;} +{\*\cs24\fs20\sbasedon29Footnote Text;} +{\s25\sb440\sa60\f0\fs34\b\sbasedon29\snext29Heading 1;} +{\s26\sb440\sa60\f0\fs28\b\sbasedon29\snext29Heading 2;} +{\s19\qc\sb240\sa118\f0\fs32\b\sbasedon29\snext29Contents Header;} +{\s28\fi-429\li720Tick List;} +{\s27\sb440\sa60\f0\fs24\b\sbasedon29\snext29Heading 3;} +{\s30\fi-429\li720\sbasedon10Lower Case List;} +{\s31\li1440\ri1440\sa118\sbasedon29Block Text;} +{\s37\f2\sbasedon29Plain Text;} +{\s33\tx1584\sbasedon5\snext29Section Heading;} +{\s34\fi-429\li720Implies List;} +{\s29\f1\fs24\lang1034Normal;} +{\s36\fi-429\li720Star List;} +{\*\cs32\fs20\superFootnote Reference;} +{\s38\tx1584\sbasedon5\snext29Chapter Heading;}} +\kerning0\cf0\ftnbj\fet2\ftnstart1\ftnnar\aftnnar\ftnstart1\aftnstart1\aenddoc\revprop3{\info\uc1}\deftab720\viewkind1\paperw11905\paperh16837\margl1440\margr1440\widowctrl \sectd\sbknone\colsx360\pgncont\ltrsect -\pard\plain\ltrpar\qc\s28\itap0{\s28\f0\fs52\b\lang1034{\*\listtag0}\abinodiroverride\ltrch Sistemas Distribuidos I (75.74)}{\s28\f1\fs24\lang1034{\*\listtag1003}\par} -\pard\plain\ltrpar\qc\s28\itap0{\s28\f0\fs28\lang1034{\*\listtag0}\abinodiroverride\ltrch TP 2: Sistema de resoluci\'f3n de nombres sobre IP adaptado a sockets}{\s28\f0\fs28\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\qc\s28\itap0{\field\fdledit{\*\fldinst {\ TOC }}} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f1\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\sb440\sa60\s24\itap0{\s24\f0\fs34\b\lang1034{\*\listtag0}\abinodiroverride\ltrch DNS}{\s24\f0\fs34\b\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\sb440\sa60\s25\itap0{\s25\f0\fs28\b\lang1034{\*\listtag0}\abinodiroverride\ltrch Diagrama de secuencia}{\s25\f0\fs28\b\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch \page }{\s28\f1\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\sb440\sa60\s25\itap0{\s25\f0\fs28\b\lang1034{\*\listtag0}\abinodiroverride\ltrch Dise\'f1o de mensajes de intercambio de DNS.}{\s25\f0\fs28\b\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch Petici\'f3n de un nameserver}{\s28\f1\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs22\lang1034{\*\listtag0}\abinodiroverride\ltrch +------------+------------+------------+}{\s28\f2\fs22\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs22\lang1034{\*\listtag0}\abinodiroverride\ltrch | QUERY_TYPE | SIZE | NAME |}{\s28\f2\fs22\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs22\lang1034{\*\listtag0}\abinodiroverride\ltrch +------------+------------+------------+}{\s28\f2\fs22\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs22\lang1034{\*\listtag0}\abinodiroverride\ltrch /-- 1 byte --/- 2 bytes --/- variable -/}{\s28\f2\fs22\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f1\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch QUERY_TYPE en realidad es una cabecera com\'fan a las peticiones y respuestas, cuyos c\'f3digos pueden ser los siguientes:}{\s28\f1\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs22\b\lang1034{\*\listtag0}\abinodiroverride\ltrch Requests}{\s28\f2\fs22\b\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs22\lang1034{\*\listtag0}\abinodiroverride\ltrch RP_REQ_DIRECT -> B\'fasqueda directa (inter nameservers)}{\s28\f2\fs22\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs22\lang1034{\*\listtag0}\abinodiroverride\ltrch RP_REQ_RECURSIVE-> B\'fasqueda recursiva (para resolvers)}{\s28\f2\fs22\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs22\b\lang1034{\*\listtag0}\abinodiroverride\ltrch Responses}{\s28\f2\fs22\b\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs22\lang1034{\*\listtag0}\abinodiroverride\ltrch RP_RES_A -> OK, se devolvi\'f3 un registro A}{\s28\f2\fs22\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs22\lang1034{\*\listtag0}\abinodiroverride\ltrch RP_RES_NS -> OK, se devolvi\'f3 un registro NS (s\'f3lo en directo)}{\s28\f2\fs22\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs22\lang1034{\*\listtag0}\abinodiroverride\ltrch RP_RES_NOTFOUND -> No se encontr\'f3}{\s28\f2\fs22\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs22\lang1034{\*\listtag0}\abinodiroverride\ltrch RP_RES_TIMEOUT -> Tard\'f3 demasiado la consulta}{\s28\f2\fs22\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f1\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch SIZE es el tama\'f1o del string con el nombre a buscar, NAME es el string (de longitud variable). Faltar\'eda agregar un campo con un ID para evitar que se confundan unas respuestas o peticiones con otras.}{\s28\f1\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f1\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch Respuesta de un nameserver}{\s28\f1\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs20\lang1034{\*\listtag0}\abinodiroverride\ltrch +-----------+-----------+-----------+-----------+-----------+-----------+}{\s28\f2\fs20\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs20\lang1034{\*\listtag0}\abinodiroverride\ltrch | RET | TTL | COUNT | IP 1 | ... | IP N |}{\s28\f2\fs20\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs20\lang1034{\*\listtag0}\abinodiroverride\ltrch +-----------+-----------+-----------+-----------+-----------+-----------+}{\s28\f2\fs20\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs20\lang1034{\*\listtag0}\abinodiroverride\ltrch /-- 1 byte -/- 4 bytes -/-- 1 byte -/- 4 bytes -/- 4 bytes -/- 4 bytes -/}{\s28\f2\fs20\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f1\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch RET es del mismo tipo que QUERY_TYPE y se hizo as\'ed para poder reconocer si un paquete es un request o un response con s\'f3lo leer el 1er byte. TTL es el tiempo que puede vivir en el cache (en segundos), COUNT es la cantidad de IPs encontradas para ese registro e IP1 a IPN son las IP en s\'ed (cantidad variable).}{\s28\f1\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\sb440\sa60\s25\itap0{\s25\f0\fs28\b\lang1034{\*\listtag0}\abinodiroverride\ltrch Par\'e1metros y resultados de la funci\'f3n gethostbyname()}{\s25\f0\fs28\b\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs20\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs20\lang1034{\*\listtag0}\abinodiroverride\ltrch std::vector< IPAddr > gethostbyname(std::string name, int& result);}{\s28\f2\fs20\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs20\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch Esta funci\'f3n toma como par\'e1metro un string con el nombre de dominio a buscar (por ejemplo "mi.dominio.casa") y retorna un vector de IPs. Si hay un error o no encuentra ninguna el vector se devuelve vac\'edo y se pone el c\'f3digo de error en la variable result. El trabajo de la funci\'f3n es conectarse a todos los nameservers que conozca y env\'ede un pedido de resoluci\'f3n de nombre RECURSIVO, hasta que tenga \'e9xito o se acabe la lista de nameservers disponibles. Por falta de tiempo esta funci\'f3n no est\'e1 implementada del lado del resolver pero s\'ed del nameserver, y es muy muy similar (hace exactamente lo mismo).}{\s28\f1\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\sb440\sa60\s24\itap0{\s24\f0\fs34\b\lang1034{\*\listtag0}\abinodiroverride\ltrch IP}{\s24\f0\fs34\b\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\sb440\sa60\s25\itap0{\s25\f0\fs28\b\lang1034{\*\listtag0}\abinodiroverride\ltrch Dise\'f1o del paquete IP}{\s25\f0\fs28\b\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch \page }{\s28\f1\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch // Campos}{\s28\f2\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint8_t version;}{\s28\f2\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint16_t total_len;}{\s28\f2\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint16_t id;}{\s28\f2\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint16_t reserved_flag: 1;}{\s28\f2\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint16_t df: 1;}{\s28\f2\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint16_t mf: 1;}{\s28\f2\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint16_t offset: 13;}{\s28\f2\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint8_t ttl;}{\s28\f2\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint8_t proto;}{\s28\f2\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint16_t checksum;}{\s28\f2\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint32_t src;}{\s28\f2\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint32_t dst;}{\s28\f2\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch \page }{\s28\f1\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\sb440\sa60\s25\itap0{\s25\f0\fs28\b\lang1034{\*\listtag0}\abinodiroverride\ltrch Diagrama de secuencia}{\s25\f0\fs28\b\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch \page }{\s28\f1\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\sb440\sa60\s25\itap0{\s25\f0\fs28\b\lang1034{\*\listtag0}\abinodiroverride\ltrch Cambios}{\s25\f0\fs28\b\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch Se agreg\'f3 principalmente la clase DevTCP que implementa la capa f\'edsica a trav\'e9s de TCP. Por cada frame saliente a un destino en particular se crea una conexi\'f3n TCP (a menos que ya est\'e9 creada, en cuyo caso se reutiliza) y se escucha por conexiones entrantes para recibir frames (tambi\'e9n guard\'e1ndolas para reutilizarlas). A diferencia del DevQue se env\'eda el tama\'f1o del frame exacto (en realidad se agrega una peque\'f1a cabecera).}{\s28\f1\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\sb440\sa60\s24\itap0{\s24\f0\fs34\b\lang1034{\*\listtag0}\abinodiroverride\ltrch Lista de fuentes de informaci\'f3n}{\s24\f0\fs34\b\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch RFC 1034 - Domain names - concepts and facilities:}{\s28\f1\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch \tab http://www.faqs.org/rfcs/rfc1034.html}{\s28\f1\fs24\lang1034{\*\listtag0}\par} -\pard\plain\ltrpar\ql\s28\itap0{\s28\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch \tab Conceptos y desiciones de dise\'f1o del DNS.}{\s28\f1\fs24\lang1034{\*\listtag0}\par}} \ No newline at end of file +\pard\plain\ltrpar\qc\s29\sl240\slmult1\itap0{\s29\f0\fs52\b\lang1034{\*\listtag0}\abinodiroverride\ltrch Sistemas Distribuidos I (75.74)}{\s29\f0\fs52\b\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\qc\s29\sl240\slmult1\itap0{\s29\f0\fs28\lang1034{\*\listtag0}\abinodiroverride\ltrch TP 2: Sistema de resoluci\'f3n de nombres sobre IP adaptado a sockets}{\s29\f0\fs28\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f0\fs28\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\sb440\sa60\s25\sl240\slmult1\itap0{\s25\f0\fs34\b\lang1034{\*\listtag0}\abinodiroverride\ltrch DNS}{\s25\f0\fs34\b\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\sb440\sa60\s26\sl240\slmult1\itap0{\s26\f0\fs28\b\lang1034{\*\listtag0}\abinodiroverride\ltrch Diagrama de secuencia}{\s26\f0\fs28\b\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch \page }{\s29\f1\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\sb440\sa60\s26\sl240\slmult1\itap0{\s26\f0\fs28\b\lang1034{\*\listtag0}\abinodiroverride\ltrch Dise\'f1o de mensajes de intercambio de DNS.}{\s26\f0\fs28\b\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch Petici\'f3n de un nameserver}{\s29\f1\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs22\lang1034{\*\listtag0}\abinodiroverride\ltrch +------------+------------+------------+}{\s29\f2\fs22\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs22\lang1034{\*\listtag0}\abinodiroverride\ltrch | QUERY_TYPE | SIZE | NAME |}{\s29\f2\fs22\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs22\lang1034{\*\listtag0}\abinodiroverride\ltrch +------------+------------+------------+}{\s29\f2\fs22\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs22\lang1034{\*\listtag0}\abinodiroverride\ltrch /-- 1 byte --/- 2 bytes --/- variable -/}{\s29\f2\fs22\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs22\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch QUERY_TYPE en realidad es una cabecera com\'fan a las peticiones y respuestas, cuyos c\'f3digos pueden ser los siguientes:}{\s29\f1\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs22\b\lang1034{\*\listtag0}\abinodiroverride\ltrch Requests}{\s29\f2\fs22\b\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs22\lang1034{\*\listtag0}\abinodiroverride\ltrch RP_REQ_DIRECT -> B\'fasqueda directa (inter nameservers)}{\s29\f2\fs22\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs22\lang1034{\*\listtag0}\abinodiroverride\ltrch RP_REQ_RECURSIVE-> B\'fasqueda recursiva (para resolvers)}{\s29\f2\fs22\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs22\b\lang1034{\*\listtag0}\abinodiroverride\ltrch Responses}{\s29\f2\fs22\b\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs22\lang1034{\*\listtag0}\abinodiroverride\ltrch RP_RES_A -> OK, se devolvi\'f3 un registro A}{\s29\f2\fs22\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs22\lang1034{\*\listtag0}\abinodiroverride\ltrch RP_RES_NS -> OK, se devolvi\'f3 un registro NS (s\'f3lo en directo)}{\s29\f2\fs22\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs22\lang1034{\*\listtag0}\abinodiroverride\ltrch RP_RES_NOTFOUND -> No se encontr\'f3}{\s29\f2\fs22\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs22\lang1034{\*\listtag0}\abinodiroverride\ltrch RP_RES_TIMEOUT -> Tard\'f3 demasiado la consulta}{\s29\f2\fs22\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs22\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch SIZE es el tama\'f1o del string con el nombre a buscar, NAME es el string (de longitud variable). Faltar\'eda agregar un campo con un ID para evitar que se confundan unas respuestas o peticiones con otras.}{\s29\f1\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f1\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch Respuesta de un nameserver}{\s29\f1\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs20\lang1034{\*\listtag0}\abinodiroverride\ltrch +-----------+-----------+-----------+-----------+-----------+-----------+}{\s29\f2\fs20\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs20\lang1034{\*\listtag0}\abinodiroverride\ltrch | RET | TTL | COUNT | IP 1 | ... | IP N |}{\s29\f2\fs20\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs20\lang1034{\*\listtag0}\abinodiroverride\ltrch +-----------+-----------+-----------+-----------+-----------+-----------+}{\s29\f2\fs20\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs20\lang1034{\*\listtag0}\abinodiroverride\ltrch /-- 1 byte -/- 4 bytes -/-- 1 byte -/- 4 bytes -/- 4 bytes -/- 4 bytes -/}{\s29\f2\fs20\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs20\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch RET es del mismo tipo que QUERY_TYPE y se hizo as\'ed para poder reconocer si un paquete es un request o un response con s\'f3lo leer el 1er byte. TTL es el tiempo que puede vivir en el cache (en segundos), COUNT es la cantidad de IPs encontradas para ese registro e IP1 a IPN son las IP en s\'ed (cantidad variable).}{\s29\f1\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\sb440\sa60\s26\sl240\slmult1\itap0{\s26\f0\fs28\b\lang1034{\*\listtag0}\abinodiroverride\ltrch Par\'e1metros y resultados de la funci\'f3n gethostbyname()}{\s26\f0\fs28\b\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f0\fs28\b\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs20\lang1034{\*\listtag0}\abinodiroverride\ltrch result_t gethostbyname(std::string name, std::vector< IPAddr >& ips);}{\s29\f2\fs20\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs20\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch Esta funci\'f3n toma como par\'e1metro un string con el nombre de dominio a buscar (por ejemplo "mi.dominio.casa") y retorna un vector de IPs. Si hay un error o no encuentra ninguna el vector se devuelve intacto y se devuelve el c\'f3digo de error, que puede ser OK (respuesta v\'e1lida), HOST_NOT_FOUND (no se encuentra dicho host), NO_RECOVERY (error irreparable, por ejemplo, no hay nameservers) o TRY_AGAIN (rrror temporal, por ejemplo, timeout). El trabajo de la funci\'f3n es conectarse a todos los nameservers que conozca y enviar un pedido de resoluci\'f3n de nombre RECURSIVO, hasta que tenga \'e9xito o se acabe la lista de nameservers disponibles. }{\s29\f1\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\sb440\sa60\s25\sl240\slmult1\itap0{\s25\f0\fs34\b\lang1034{\*\listtag0}\abinodiroverride\ltrch IP}{\s25\f0\fs34\b\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\sb440\sa60\s26\sl240\slmult1\itap0{\s26\f0\fs28\b\lang1034{\*\listtag0}\abinodiroverride\ltrch Dise\'f1o del paquete IP}{\s26\f0\fs28\b\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch \page }{\s29\f1\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch // Campos}{\s29\f2\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint8_t version;}{\s29\f2\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint16_t total_len;}{\s29\f2\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint16_t id;}{\s29\f2\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint16_t reserved_flag: 1;}{\s29\f2\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint16_t df: 1;}{\s29\f2\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint16_t mf: 1;}{\s29\f2\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint16_t offset: 13;}{\s29\f2\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint8_t ttl;}{\s29\f2\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint8_t proto;}{\s29\f2\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint16_t checksum;}{\s29\f2\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint32_t src;}{\s29\f2\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f2\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch uint32_t dst;}{\s29\f2\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch \page }{\s29\f1\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\sb440\sa60\s26\sl240\slmult1\itap0{\s26\f0\fs28\b\lang1034{\*\listtag0}\abinodiroverride\ltrch Diagrama de secuencia}{\s26\f0\fs28\b\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch \page }{\s29\f1\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\sb440\sa60\s26\sl240\slmult1\itap0{\s26\f0\fs28\b\lang1034{\*\listtag0}\abinodiroverride\ltrch Cambios}{\s26\f0\fs28\b\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch Se agreg\'f3 principalmente la clase DevTCP que implementa la capa f\'edsica a trav\'e9s de TCP. Por cada frame saliente a un destino en particular se crea una conexi\'f3n TCP (a menos que ya est\'e9 creada, en cuyo caso se reutiliza) y se escucha por conexiones entrantes para recibir frames (tambi\'e9n guard\'e1ndolas para reutilizarlas). A diferencia del DevQue se env\'eda el tama\'f1o del frame exacto (en realidad se agrega una peque\'f1a cabecera).}{\s29\f1\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\sb440\sa60\s25\sl240\slmult1\itap0{\s25\f0\fs34\b\lang1034{\*\listtag0}\abinodiroverride\ltrch Lista de fuentes de informaci\'f3n}{\s25\f0\fs34\b\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch RFC 1034 - Domain names - concepts and facilities:}{\s29\f1\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch \tab http://www.faqs.org/rfcs/rfc1034.html}{\s29\f1\fs24\lang1034{\*\listtag0}\par} +\pard\plain\ltrpar\ql\s29\sl240\slmult1\itap0{\s29\f1\fs24\lang1034{\*\listtag0}\abinodiroverride\ltrch \tab Conceptos y desiciones de dise\'f1o del DNS.}{\s29\f1\fs24\lang1034{\*\listtag0}\par}} \ No newline at end of file diff --git a/practicas/pipi/resolver_ejemplo.txt b/practicas/pipi/resolver_ejemplo.txt new file mode 100644 index 0000000..5d53883 --- /dev/null +++ b/practicas/pipi/resolver_ejemplo.txt @@ -0,0 +1 @@ +10.10.10.1 diff --git a/practicas/pipi/rutas_ejemplo/mi_lan.txt b/practicas/pipi/rutas_ejemplo/mi_lan.txt index aa77b5c..7b67f56 100644 --- a/practicas/pipi/rutas_ejemplo/mi_lan.txt +++ b/practicas/pipi/rutas_ejemplo/mi_lan.txt @@ -1,4 +1,4 @@ 10.10.10.1 0.0.0.0 30 0 10.10.10.2 0.0.0.0 30 0 10.10.10.3 0.0.0.0 30 0 -10.10.10.141 0.0.0.0 30 0 +10.10.10.5 0.0.0.0 30 0 diff --git a/practicas/pipi/rutas_ejemplo/route_10.10.10.141_tcp.txt b/practicas/pipi/rutas_ejemplo/route_10.10.10.5_tcp.txt similarity index 100% rename from practicas/pipi/rutas_ejemplo/route_10.10.10.141_tcp.txt rename to practicas/pipi/rutas_ejemplo/route_10.10.10.5_tcp.txt diff --git a/practicas/pipi/src/Makefile b/practicas/pipi/src/Makefile index d116c96..983c3c1 100644 --- a/practicas/pipi/src/Makefile +++ b/practicas/pipi/src/Makefile @@ -19,6 +19,8 @@ CFLAGS += -ggdb -DDEBUG # Para más verbose CFLAGS += -DDEBUG2 +CFLAGS += -DDEBUG_RESOLV +CFLAGS += -DDEBUG_TRACE # Opciones para el compilador C++. CXXFLAGS = $(CFLAGS) -fno-inline @@ -30,7 +32,7 @@ CXXFLAGS = $(CFLAGS) -fno-inline CC=g++ # Programas -targets=ip dns +targets=ip dns res tests=test_send test_recv test_ipaddr test_ipin test_ipout test_devtcp \ test_poll test_resolvproto test_nameserver_file \ test_nameserver_resolvnext @@ -40,7 +42,7 @@ fuentes ?= $(wildcard *.cpp) $(wildcard *.c) ip_objs=ipout.o ipin.o ipaddr.o ipheader.o devque.o devtcp.o routetable.o \ libtcp.o -dns_objs=nameserver.o resolvproto.o +dns_objs=resolvproto.o # REGLAS ######### @@ -67,14 +69,17 @@ test_poll: test_poll.o libtcp.o test_resolvproto: test_resolvproto.o resolvproto.o ipaddr.o -test_nameserver_file: test_nameserver_file.o $(dns_objs) $(ip_objs) +test_nameserver_file: test_nameserver_file.o nameserver.o $(dns_objs) $(ip_objs) #FIXME no va libtcp.o, debe ir sobre mi implementación de ip. -test_nameserver_resolvnext: test_nameserver_resolvnext.o $(dns_objs) $(ip_objs) +test_nameserver_resolvnext: test_nameserver_resolvnext.o nameserver.o \ + $(dns_objs) $(ip_objs) ip: ip.o $(ip_objs) -dns: dns.o $(ip_objs) $(dns_objs) +dns: dns.o nameserver.o $(ip_objs) $(dns_objs) + +res: res.o resolver.o $(ip_objs) $(dns_objs) depend: @makedepend $(fuentes) > /dev/null 2>&1 @@ -213,6 +218,35 @@ nameserver.o: /usr/include/features.h /usr/include/sys/cdefs.h nameserver.o: /usr/include/gnu/stubs.h /usr/include/bits/wchar.h nameserver.o: /usr/include/bits/wordsize.h resolvproto.h ipin.h ipheader.h nameserver.o: ipout.h routetable.h +res.o: ipout.h ipaddr.h /usr/include/stdint.h /usr/include/features.h +res.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h +res.o: /usr/include/bits/wchar.h /usr/include/bits/wordsize.h ipheader.h +res.o: routetable.h dev.h ipin.h devtcp.h /usr/include/sys/poll.h +res.o: /usr/include/bits/poll.h devque.h resolver.h resolvproto.h +res.o: /usr/include/unistd.h /usr/include/bits/posix_opt.h +res.o: /usr/include/bits/types.h /usr/include/bits/typesizes.h +res.o: /usr/include/bits/confname.h /usr/include/getopt.h +res.o: /usr/include/fcntl.h /usr/include/bits/fcntl.h +res.o: /usr/include/sys/types.h /usr/include/time.h /usr/include/endian.h +res.o: /usr/include/bits/endian.h /usr/include/sys/select.h +res.o: /usr/include/bits/select.h /usr/include/bits/sigset.h +res.o: /usr/include/bits/time.h /usr/include/sys/sysmacros.h +res.o: /usr/include/bits/pthreadtypes.h /usr/include/bits/sched.h +res.o: /usr/include/sys/wait.h /usr/include/signal.h +res.o: /usr/include/bits/signum.h /usr/include/bits/siginfo.h +res.o: /usr/include/bits/sigaction.h /usr/include/bits/sigcontext.h +res.o: /usr/include/asm/sigcontext.h /usr/include/asm-i486/sigcontext.h +res.o: /usr/include/linux/compiler.h /usr/include/bits/sigstack.h +res.o: /usr/include/bits/sigthread.h /usr/include/sys/resource.h +res.o: /usr/include/bits/resource.h /usr/include/bits/waitflags.h +res.o: /usr/include/bits/waitstatus.h /usr/include/sys/ipc.h +res.o: /usr/include/bits/ipctypes.h /usr/include/bits/ipc.h +res.o: /usr/include/sys/msg.h /usr/include/bits/msq.h +resolver.o: resolver.h devque.h dev.h ipaddr.h /usr/include/stdint.h +resolver.o: /usr/include/features.h /usr/include/sys/cdefs.h +resolver.o: /usr/include/gnu/stubs.h /usr/include/bits/wchar.h +resolver.o: /usr/include/bits/wordsize.h resolvproto.h ipin.h ipheader.h +resolver.o: ipout.h routetable.h resolvproto.o: resolvproto.h ipaddr.h /usr/include/stdint.h resolvproto.o: /usr/include/features.h /usr/include/sys/cdefs.h resolvproto.o: /usr/include/gnu/stubs.h /usr/include/bits/wchar.h diff --git a/practicas/pipi/src/devque.cpp b/practicas/pipi/src/devque.cpp index 32b71a7..593f663 100644 --- a/practicas/pipi/src/devque.cpp +++ b/practicas/pipi/src/devque.cpp @@ -28,6 +28,9 @@ DevQue::DevQue(mac_type mac, key_t key, size_t mtu) void DevQue::transmit(const std::string& data, const mac_type& mac) throw (std::runtime_error, std::logic_error) { +#ifdef DEBUG_TRACE + std::cout << "DevQue[" << que_id << "]::transmit()\n"; +#endif if (data.size() > mtu) throw std::logic_error("Tamaño de datos mayor al MTU"); Frame* f = (Frame*) malloc(sizeof(Frame) + mtu); @@ -38,8 +41,8 @@ void DevQue::transmit(const std::string& data, const mac_type& mac) memcpy(f->frame, data.data(), data.size()); int res = msgsnd(que_id, f, mtu + sizeof(size_t), 0); #ifdef DEBUG2 - std::cout << "DevQue::transmit(msgtype/mac = " << f->mac << ", size = " - << f->size << ")\n"; + std::cout << "DevQue[" << que_id << "]::transmit(msgtype/mac = " + << f->mac << ", size = " << f->size << ")\n"; #endif free(f); if (res == -1) @@ -48,11 +51,17 @@ void DevQue::transmit(const std::string& data, const mac_type& mac) std::string DevQue::receive() throw (std::runtime_error) { +#ifdef DEBUG_TRACE + std::cout << "DevQue[" << que_id << "]::receive()\n"; +#endif return receive(mac); } std::string DevQue::receive(mac_type& mac) throw (std::runtime_error) { +#ifdef DEBUG_TRACE + std::cout << "DevQue[" << que_id << "]::receive(mac)\n"; +#endif Frame* f = (Frame*) malloc(sizeof(Frame) + mtu); if (!f) throw std::runtime_error("No se puede reservar memoria"); @@ -67,8 +76,8 @@ std::string DevQue::receive(mac_type& mac) throw (std::runtime_error) mac = f->mac; free(f); #ifdef DEBUG2 - std::cout << "DevQue::receive(msgtype/mac = " << mac << ", size = " - << s.size() << ")\n"; + std::cout << "DevQue[" << que_id << "]::receive(msgtype/mac = " + << mac << ", size = " << s.size() << ")\n"; #endif return s; } diff --git a/practicas/pipi/src/dns.cpp b/practicas/pipi/src/dns.cpp index f0846d4..eb7e706 100644 --- a/practicas/pipi/src/dns.cpp +++ b/practicas/pipi/src/dns.cpp @@ -63,31 +63,47 @@ int main(int argc, char* argv[]) perror("fork() send"); return 2; } - if (pid_send) // IPOut + if (pid_send) // Padre { - pid_t pid_fw = fork(); - if (pid_fw == -1) + pid_t pid_recv = fork(); + if (pid_recv == -1) { - perror("fork() forward"); + perror("fork() recv"); return 3; } - if (pid_fw) // Padre (Entrada por teclado) + if (pid_recv) // Padre { - int ret; - send_loop(ns); - kill(pid_send, SIGTERM); - waitpid(pid_send, &ret, 0); - kill(pid_fw, SIGTERM); - waitpid(pid_fw, &ret, 0); - return 0; + pid_t pid_req = fork(); + if (pid_req == -1) + { + perror("fork() req"); + return 3; + } + if (pid_req) // Padre (Entrada por teclado) + { + int ret; + send_loop(ns); + kill(pid_send, SIGTERM); + waitpid(pid_send, &ret, 0); + kill(pid_recv, SIGTERM); + waitpid(pid_recv, &ret, 0); + kill(pid_req, SIGTERM); + waitpid(pid_req, &ret, 0); + return 0; + } + else // Hijo 1 (Proceso de request DNS) + { + ns.req_loop(); + return 0; + } } - else // Hijo 1 (envío del DNS) + else // Hijo 2 (envío del DNS) { ns.send_loop(); return 0; } } - else // Hijo 2 (recepción del DNS) + else // Hijo 3 (recepción del DNS) { ns.recv_loop(); return 0; diff --git a/practicas/pipi/src/nameserver.cpp b/practicas/pipi/src/nameserver.cpp index 46e571c..4c64604 100644 --- a/practicas/pipi/src/nameserver.cpp +++ b/practicas/pipi/src/nameserver.cpp @@ -8,8 +8,6 @@ #include #endif -#define DEBUG_RESOLV - NameServer::Name::Name(const std::string& s) { std::istringstream iss(s); @@ -111,6 +109,12 @@ NameServer::NameServer(std::istream& is, IPIn& ipin, IPOut& ipout, std::cerr << "NameServer: " << z << "\n\n"; #endif } + +#ifdef DEBUG2 + std::cout << "NameServer: req_que_id = " << req_que.que_id + << ", res_que_id = " << res_que.que_id + << ", snd_que_id = " << snd_que.que_id << "\n"; +#endif } /// Devuelve la parte izquierda de n, si la parte derecha coincide exactamente @@ -217,6 +221,9 @@ struct search_zone: std::unary_function< NameServer::Zone, bool > /// Resuelve un nombre de forma directa (no recursiva) ResolvProtoResponse NameServer::resolv_direct(const Name& n) { +#ifdef DEBUG_TRACE + std::cout << "NameServer::resolv_direct()\n"; +#endif #ifdef DEBUG_RESOLV std::cerr << "resolv_direct -> tratando de resolver: " << n << "\n"; #endif @@ -280,6 +287,9 @@ ResolvProtoResponse NameServer::resolv_direct(const Name& n) /// Resuelve un nombre de forma recursiva ResolvProtoResponse NameServer::resolv_recursive(const Name& n) { +#ifdef DEBUG_TRACE + std::cout << "NameServer::resolv_recursive()\n"; +#endif ResolvProtoResponse rpr = resolv_direct(n); switch (rpr.ret) { @@ -302,6 +312,9 @@ ResolvProtoResponse NameServer::resolv_recursive(const Name& n) ResolvProtoResponse NameServer::resolv_recursive_r(const Name& n, ResolvProtoResponse rpr) { +#ifdef DEBUG_TRACE + std::cout << "NameServer::resolv_recursive_r()\n"; +#endif ResolvProtoResponse r; for (ResolvProtoResponse::ipvec_t::const_iterator ip = rpr.ips.begin(); ip != rpr.ips.end(); ++ip) @@ -337,6 +350,9 @@ ResolvProtoResponse NameServer::resolv_recursive_r(const Name& n, /// Consulta a otro name server sobre un nombre ResolvProtoResponse NameServer::query(const Name& n, const IPAddr& ip) { +#ifdef DEBUG_TRACE + std::cout << "NameServer::query()\n"; +#endif ResolvProtoRequest r(std::string(n), RP_REQ_DIRECT); #ifdef DEBUG_RESOLV std::cerr << "query -> pidiendo " << r << " a " << ip << "\n"; @@ -354,6 +370,9 @@ ResolvProtoResponse NameServer::query(const Name& n, const IPAddr& ip) void NameServer::recv_loop() { +#ifdef DEBUG_TRACE + std::cout << "NameServer::recv_loop()\n"; +#endif while (true) { IPAddr src, dst; @@ -391,38 +410,41 @@ void NameServer::recv_loop() void NameServer::send_loop() { +#ifdef DEBUG_TRACE + std::cout << "NameServer::send_loop()\n"; +#endif while (true) { - if (!req_que.empty()) - { - Dev::mac_type mac = 0; - ResolvProtoRequest req(req_que.receive(mac)); + Dev::mac_type mac = 0; + std::string buf = snd_que.receive(mac); #ifdef DEBUG_RESOLV - std::cout << "NameServer::send_loop() -> recibido " << req << "\n"; + std::cout << "NameServer::send_loop() -> envío request " + << ResolvProtoRequest(buf) << "\n"; +#endif + ipout.send(buf, RESOLV_PROTO, IPAddr(mac)); + } +} + +void NameServer::req_loop() +{ +#ifdef DEBUG_TRACE + std::cout << "NameServer::req_loop()\n"; #endif - ResolvProtoResponse res - = (req.query_type == RP_REQ_DIRECT) - ? resolv_direct(req.name) - : resolv_recursive(req.name); + while (true) + { + Dev::mac_type mac = 0; + ResolvProtoRequest req(req_que.receive(mac)); #ifdef DEBUG_RESOLV - std::cout << "NameServer::send_loop() -> respondo " << res << "\n"; + std::cout << "NameServer::req_loop() -> recibido " << req << "\n"; #endif - ipout.send(res, RESOLV_PROTO, IPAddr(mac)); - } - else if (!snd_que.empty()) // Hay un request para enviar - { - Dev::mac_type mac = 0; - std::string buf = snd_que.receive(mac); + ResolvProtoResponse res + = (req.query_type == RP_REQ_DIRECT) + ? resolv_direct(req.name) + : resolv_recursive(req.name); #ifdef DEBUG_RESOLV - std::cout << "NameServer::send_loop() -> envío request " - << ResolvProtoRequest(buf) << "\n"; + std::cout << "NameServer::req_loop() -> respondo " << res << "\n"; #endif - ipout.send(buf, RESOLV_PROTO, IPAddr(mac)); - } - else // No hay nada, esperamos un rato - { - usleep(10000); - } + snd_que.transmit(std::string(res), IPAddr(mac)); } } diff --git a/practicas/pipi/src/nameserver.h b/practicas/pipi/src/nameserver.h index 4165b58..2dab7a3 100644 --- a/practicas/pipi/src/nameserver.h +++ b/practicas/pipi/src/nameserver.h @@ -108,6 +108,9 @@ struct NameServer /// Loop que envía los paquetes de la cola de envío void send_loop(); + /// Loop que procesa los requests + void req_loop(); + private: /// Resuelve un nombre de forma recursiva entrando a otros ns ResolvProtoResponse resolv_recursive_r(const Name& n, diff --git a/practicas/pipi/src/res.cpp b/practicas/pipi/src/res.cpp new file mode 100644 index 0000000..1fb2335 --- /dev/null +++ b/practicas/pipi/src/res.cpp @@ -0,0 +1,125 @@ + +#include "ipout.h" +#include "ipin.h" +#include "ipaddr.h" +#include "routetable.h" +#include "devtcp.h" +#include "devque.h" +#include "resolver.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Uso: ./ip ip [routes_file servers_file forward port] + +void send_loop(Resolver& res); + +int main(int argc, char* argv[]) +{ + bool forward = false; + uint16_t port = DEVTCP_DEFAULT_PORT; + std::string rfile = "route.txt"; + std::string sfile = "resolver.txt"; + if (argc < 2) + { + std::cerr << "Uso: " << argv[0] << " ip [routes_file servers_file " + "forward port]\n"; + return 1; + } + IPAddr addr(argv[1]); + if (argc > 2) + rfile = argv[2]; + if (argc > 3) + sfile = argv[3]; + if (argc > 4) + forward = atoi(argv[4]); + if (argc > 5) + port = atoi(argv[5]); + // Abro archivos + std::ifstream rifs(rfile.c_str()); assert(rifs); + std::ifstream sifs(sfile.c_str()); assert(sifs); + // Creo medio físico y cola para forwarding + DevTCP dev(addr, port); + DevQue fwque(addr, DEVQUE_DEFAULT_KEY-1); + DevQue resresque(addr, DEVQUE_DEFAULT_KEY-5); + // Creo tabla de ruteo e IP + RouteTable table(dev); + add_routes(table, rifs, dev); + IPOut ipout(addr, table, fwque, std::cerr); + IPIn ipin(addr, dev, fwque, false, forward, std::cerr); + Resolver res(sifs, ipin, ipout, resresque); + // Creo procesos + pid_t pid_send = fork(); + if (pid_send == -1) + { + perror("fork() send"); + return 2; + } + if (pid_send) // IPOut + { + pid_t pid_fw = fork(); + if (pid_fw == -1) + { + perror("fork() forward"); + return 3; + } + if (pid_fw) // Padre (IPOut send) + { + int ret; + send_loop(res); + kill(pid_send, SIGTERM); + waitpid(pid_send, &ret, 0); + kill(pid_fw, SIGTERM); + waitpid(pid_fw, &ret, 0); + return 0; + } + else // Hijo 1 (IPOut forward) + { + ipout.forward_loop(); + return 0; + } + } + else // Hijo 2 (IPIn) + { + res.recv_loop(); + return 0; + } + return 0; +} + +void send_loop(Resolver& res) +{ + std::string name; + while (std::getline(std::cin, name)) + { + std::cout << "Resolviendo " << name << "...\n"; + Resolver::ipvec_t ips; + Resolver::result_t r = res.gethostbyname(name, ips); + switch (r) + { + case Resolver::OK: + std::cout << "Encontrado: " << ips << "\n"; + break; + case Resolver::HOST_NOT_FOUND: + std::cout << "No encontrado!\n"; + break; + case Resolver::NO_RECOVERY: + std::cout << "Error irrecuperable!\n"; + break; + case Resolver::TRY_AGAIN: + std::cout << "Error temporal, pruebe más tarde...\n"; + break; + } + } +} + +// vim: set et sw=4 sts=4 : diff --git a/practicas/pipi/src/resolver.cpp b/practicas/pipi/src/resolver.cpp new file mode 100644 index 0000000..3eee09c --- /dev/null +++ b/practicas/pipi/src/resolver.cpp @@ -0,0 +1,140 @@ +#include "resolver.h" +#include +#include +#include +#include +#include +#ifdef DEBUG +#include +#endif + +/// Parsea un archivo de nameservers +static std::istream& parseservers(std::istream& is, Resolver::ipvec_t& nss) + throw (std::runtime_error) +{ + std::string ns; + // [nameserver ip] + while (std::getline(is, ns)) + { + if (ns == "") continue; // Salteo líneas en blanco + nss.push_back(IPAddr(ns)); +#ifdef DEBUG_PARSER + std::cout << "parseservers: IP = " << IPAddr(ns) << "\n"; +#endif + } + return is; +} + +/// Constructor +Resolver::Resolver(std::istream& is, IPIn& ipin, IPOut& ipout, DevQue& res_que) + throw (std::runtime_error): + ipin(ipin), ipout(ipout), res_que(res_que) +{ + parseservers(is, nameservers); +} + +/// Obtiene la(s) IP de un host a través de su nombre de dominio +Resolver::result_t Resolver::gethostbyname(const std::string& name, + ipvec_t& ips) +{ + result_t result = NO_RECOVERY; + for (ipvec_t::const_iterator ip = nameservers.begin(); + ip != nameservers.end(); ++ip) + { + ResolvProtoResponse r = query(name, *ip); + switch (r.ret) + { + case RP_RES_A: + ips = r.ips; + return OK; + case RP_RES_NOTFOUND: + result = HOST_NOT_FOUND; + continue; + default: +#ifdef DEBUG_RESOLV + std::cout << "Resolver::gethostbyname ERROR!!! respuesta " + "inesperada: " << r << "\n"; +#endif + return TRY_AGAIN; + } + } + return result; +} + +/// Consulta a otro name server sobre un nombre +ResolvProtoResponse Resolver::query(const std::string& name, const IPAddr& ip) +{ + ResolvProtoRequest r(name, RP_REQ_RECURSIVE); +#ifdef DEBUG_RESOLV + std::cout << "query -> pidiendo " << r << " a " << ip << "\n"; +#endif + ipout.send(std::string(r), RESOLV_PROTO, ip); + Dev::mac_type mac = ip; + std::string buf = res_que.receive(mac); + ResolvProtoResponse resp(buf); +#ifdef DEBUG_RESOLV + std::cerr << "query -> recibido " << resp << " de " << ip << "\n"; +#endif + return resp; +} + +void Resolver::recv_loop() +{ + while (true) + { + IPAddr src, dst; + uint8_t proto; + std::string s = ipin.recv(proto, src, dst); +#ifdef DEBUG_RESOLV + std::cout << "NameServer::recv_loop() -> recibido len=" << s.size() + << " de " << src << " para " << dst << " (proto = " + << unsigned(proto) << ")\n"; +#endif + if (proto == RESOLV_PROTO) // Si es para nosotros + { + rp_pkt_type_t type; + memcpy(&type, s.data(), sizeof(uint8_t)); + switch (type) + { + // Request + case RP_REQ_DIRECT: + case RP_REQ_RECURSIVE: +#ifdef DEBUG_RESOLV + std::cout << "---> Recibido un REQUEST!!! Algo esta roto! " + << ResolvProtoRequest(s) << "\n"; +#endif + break; + // Response + default: +#ifdef DEBUG_RESOLV + std::cout << "---> " << ResolvProtoResponse(s) << "\n"; +#endif + res_que.transmit(s, src); // Encolo + } + } +#ifdef DEBUG_RESOLV + else + { + std::cout << "---> Recibido paquete IP desconocido (proto=" + << unsigned(proto) << "): " << s << "\n"; + } +#endif + } +} + +std::ostream& operator<< (std::ostream& os, const Resolver& res) +{ + return os << "Resolver(nameservers=" << res.nameservers << ")"; +} + +std::ostream& operator<< (std::ostream& os, const Resolver::ipvec_t& v) +{ + os << "["; + if (v.empty()) + return os << "]"; + std::copy(v.begin(), v.end() - 1, + std::ostream_iterator< IPAddr >(os, ", ")); + return os << v.back() << "]"; +} + +// vim: set et sw=4 sts=4 : diff --git a/practicas/pipi/src/resolver.h b/practicas/pipi/src/resolver.h new file mode 100644 index 0000000..27e8e89 --- /dev/null +++ b/practicas/pipi/src/resolver.h @@ -0,0 +1,59 @@ +#ifndef _RESOLVER_H_ +#define _RESOLVER_H_ + +#include "devque.h" +#include "ipaddr.h" +#include "resolvproto.h" +#include +#include +#include +#include +#include +#include + +/// Resolver de nombres +struct Resolver +{ + + /// Zonas para las que este servidor de nombres es autoridad + typedef ResolvProtoResponse::ipvec_t ipvec_t; + ipvec_t nameservers; + + /// IP + IPIn& ipin; + IPOut& ipout; + + /// Colas de recepción + DevQue& res_que; + + /// Constructor + Resolver(std::istream& is, IPIn& ipin, IPOut& ipout, DevQue& res_que) + throw (std::runtime_error); + + /// Resultado de la petición + enum result_t + { + OK, ///> Respuesta válida + HOST_NOT_FOUND, ///> No se encuentra dicho host + NO_RECOVERY, ///> Error irreparable (por ejemplo, no hay nameservers) + TRY_AGAIN ///> Error temporal (por ejemplo, timeout) + }; + + /// Obtiene la(s) IP de un host a través de su nombre de dominio + result_t gethostbyname(const std::string& name, ipvec_t& ips); + + /// Consulta a otro name server sobre un nombre + ResolvProtoResponse query(const std::string& name, const IPAddr& ip); + + /// Loop que recibe y carga los paquetes en las colas para ser procesados + void recv_loop(); + +}; + +/// Impresión (para debug) +std::ostream& operator<< (std::ostream& os, const Resolver& res); +std::ostream& operator<< (std::ostream& os, const Resolver::ipvec_t& ips); + +#endif // _RESOLVER_H_ + +// vim: set et sw=4 sts=4 : diff --git a/practicas/pipi/src/resolvproto.h b/practicas/pipi/src/resolvproto.h index 5874fbe..b554bcc 100644 --- a/practicas/pipi/src/resolvproto.h +++ b/practicas/pipi/src/resolvproto.h @@ -21,8 +21,7 @@ enum rp_pkt_type_t // responses RP_RES_A, ///> OK, se devolvió un registro A RP_RES_NS, ///> OK, se devolvió un registro NS (sólo en directo) - RP_RES_NOTFOUND, ///> No se encontró - RP_RES_TIMEOUT ///> Tardó demasiado la consulta + RP_RES_NOTFOUND ///> No se encontró }; /// Petición de un nameserver diff --git a/practicas/pipi/zonas_ejemplo/10.10.10.1.txt b/practicas/pipi/zonas_ejemplo/10.10.10.1.txt index 5381f9d..2fe0bd1 100644 --- a/practicas/pipi/zonas_ejemplo/10.10.10.1.txt +++ b/practicas/pipi/zonas_ejemplo/10.10.10.1.txt @@ -2,12 +2,12 @@ casa 600 0.0.0.0 burns A 10.10.10.1 homero A 10.10.10.2 marge A 10.10.10.3 -manuk A 10.10.10.141 +manuk A 10.10.10.5 juan A 100.10.100.5 pepe A 100.10.100.6 homero NS 10.10.10.2 marge NS 10.10.10.3 -manuk NS 10.10.10.141 +manuk NS 10.10.10.5 burns.casa 600 0.0.0.0 tito A 100.10.100.1 diff --git a/practicas/pipi/zonas_ejemplo/10.10.10.2.txt b/practicas/pipi/zonas_ejemplo/10.10.10.2.txt index 4cd1503..8343da8 100644 --- a/practicas/pipi/zonas_ejemplo/10.10.10.2.txt +++ b/practicas/pipi/zonas_ejemplo/10.10.10.2.txt @@ -8,5 +8,5 @@ pepe A 10.10.100.6 marge NS 10.10.10.3 todos NS 10.10.10.1 todos NS 10.10.10.3 -todos NS 10.10.10.141 +todos NS 10.10.10.5 diff --git a/practicas/pipi/zonas_ejemplo/10.10.10.3.txt b/practicas/pipi/zonas_ejemplo/10.10.10.3.txt index dc45182..dbe43a9 100644 --- a/practicas/pipi/zonas_ejemplo/10.10.10.3.txt +++ b/practicas/pipi/zonas_ejemplo/10.10.10.3.txt @@ -5,10 +5,10 @@ juan A 30.10.100.3 pepe A 30.10.100.4 juan A 30.10.100.5 pepe A 30.10.100.6 -manuk NS 10.10.10.141 +manuk NS 10.10.10.5 todos NS 10.10.10.1 todos NS 10.10.10.3 -todos NS 10.10.10.141 +todos NS 10.10.10.5 todos.homero.casa 9500 10.10.10.2 tito A 10.1.100.1 diff --git a/practicas/pipi/zonas_ejemplo/10.10.10.141.txt b/practicas/pipi/zonas_ejemplo/10.10.10.5.txt similarity index 100% rename from practicas/pipi/zonas_ejemplo/10.10.10.141.txt rename to practicas/pipi/zonas_ejemplo/10.10.10.5.txt