Está en la página 1de 535
Programacion de Socket Linux Sean Walton Traducci6n Clave Informatica I+D, S.A. indice de contenido Introduccién PARTEI Programacién de red desde la perspectiva del cliente Capitulo 1. Recetario del cliente de red ... Un mundo conectado mediante sockets .... Generalidades del direccionamiento TCP/IP Escucha del servidor: el algoritmo basico del cliente La llamada del sistema socket: procedimientos y advertencias Realizacién de la llamada: conexién al servidor Obtencién de la respuesta del servidor Cierre de la conexién .. Resumen: ¢qué ocurre entre bastidores? Capitulo 2. Elocuencia del lenguaje de red TCP/IP .... Generalidades de la numeracién IP ..... Tdentificacién de la computadora . Organizacién del 1D Internet Mascaras de subredes .. . Routers y resolucién de direcciones ... Direcciones desaprovechadas y especiales Numeros de puertos de host IP Ordenacién de bytes de red Uso de herramientas de transformacién de Internet Aplicaci6n de las herramientas y extensién del cliente . Diferentes clases de sockaddr .. Canales con nombre de UNIX Resumen: aplicacién de herramientas y numeracién IP Capitulo 3. Tipos de paquetes de Internet . El paquete de red fundamental Campo version . Campo header _len .. Campo serve type Campo ID .. Campo frag_offset y flags dont_frag y more_frags . Campo time_to_live (TTL) Campo protocol .. 37 Campo options Campo data .... Anilisis de varios paquetes Cuestiones relacionadas con los paquetes Tipos de paquete .... soo Como encajan los protocolos IP . Como escudrifar la red con Tepdump Escritura de un escudrifiador de red a medida Resumen: eleccién de los mejores paquetes para el envio de mensajes . Capitulo 4. Envio de mensajes entre peers .. éQué son los sockets basados en la conexién? Canales abiertos entre programas Comunicaciones fiables ... Conexiones de protocolo inferior Ejemplo: conexién al demonio HTTP Protocolo HTTP simplificado . Obtencién de una pagina HTTP {Qué son los sockets sin conexién? Configurando la direccién del socket Algunos programas sélo necesitan el mensaje Transaction TCP (T/TCP): un TCP sin conexion Envio de un mensaje directo Asociacién del puerto al socket . Cémo enviar el mensaje Cémo coger el mensaje Garantia de Hegada de un mensaje UDP Como fortalecer la fiabilidad de UDP Secuencia de los paquetes Redundancia de paquete Verificacién de la integridad de los datos Fallos imprevistos del flujo de datos ... Tareas enrevesadas: una introduccién a la multitarea .. Resumen: modelos conectados frente a modelos sin conexién Capitulo 5. Explicacién del modelo de capas de red ....... Solucién del desafio de red... Cuestiones de hardware de red Cuestiones de transmisin de red ... Interaccién de la red con el sistema operativo Interaccion de la red con el programa ... Modelo de red de interconexién de sistemas abiertos (OSI) . Capa 1: 101 102 103 104 105 Capa 2: enlace de datos .. 106 Capa 3: red . 107 Capa 4: transporte 107 Capa 5: sesion 108 Capa 6: presentacién 108 Capa 7: aplicacién ... 109 Paquete de protocolos de Internet 109 Capa 1: capa de acceso de red 109 Capa 2: capa de funcionamiento en Internet (IP) .. 110 Capa 2: extensiones de la gestion de mensajes de error-control (ICMP) .. 111 Capa 3: de host a host (UDP) 111 Capa 3: flujos de host (TCP) 12 Capa 4: capa de aplicacién ... 113 Diferencias fundamentales entre OSI e IP 113 éQué da servicio a qué? 114 Resumen: de la teoria a la practica .. 114 PARTE La perspectiva del servidor y el control de carga Capitulo 6. Generalidades sobre el servidor .. 119 Asignacién del socket: el flujo de programa general del servidor .. 121 Un servidor de eco sencillo ... 123 Asociar puertos a un socket .. 124 Creacion de una cola de espera de sockets .. 126 Aceptar conexiones de clientes 127 Comunicacién con el cliente 129 Reglas generales sobre la definicién de protocolos . 131 {Qué programa habla primero? .. 131 {Qué programa dirige la conversacién? 11 {Qué nivel de certificacién necesita? 132 iQué tipos de datos utilizar? ... 132 ~Como debe manejar los datos binarios’ 132, iCémo saber cuando se produce un interbloqueo? 133 éNecesita sincronizacién horaria? .. 133 Como y cuando reiniciar la conexidn? ... 134 (Cuando ha finalizado? 134 Un ejemplo extenso: un servidor de directorio HTTP 134 Resumen: los elementos basicos de un servidor .... 138 Capitulo 7. Divisién de la carga: multitarea .... 139 Definicién de multitarea: procesos frente a threads 141 Cuando se debe utilizar la multitarea . 143, Caracteristicas de la multitarea Diferencias en las tareas . {Cémo creo un proceso? Como creo un thread? La Hamada del sistema _clone(): la llamada de los valientes Comunicacién entre tareas ... Venciendo al reloj: condiciones de carrera y exclusiones mutuas (mutex) ... Condiciones de carrera Exclusién muitua (mutex) Problemas de exclusién mutua de Pthread .. Prevencion del interbloqueo .. Control de hijos y eliminacién de procesos zombis Preste més atencién a los hijos: prioridad y planificacion . Entierro de los procesos zombis: limpieza tras la finalizacion . Ampliacién de los clientes y servidores actuales ... Llamada de programas externos con el exec del servidor Resumen: distribucidn de la carga del proceso Capitulo 8. Cémo decidir cuando esperar E/S . Bloqueo de la E/S: por qué? . 2Cuiindo debo bloquear? ... Alternativas al bloqueo de la F/S Comparaciin de las diferentes interacciones de programacion de E/S . Sondeo de la E/S .. Un lector de sondeos Escritor de sondeo . Sondeo de las conexiones E/Sasincrona ... Lectura bajo demanda . Escrituras asincronas ... Conexiones bajo demanda . Resolucién de bloqueos de la E/S no deseados con poll() y select. Implementacién de los tiempos de espera .. Resumen: eleccién de las estrategias de E/S Capitulo 9. Cémo romper las barreras del rendimiento .. Creacién de serviets antes de la llegada del cliente ..... Colocacién de un tope en el mimero de conexiones cliente Preduplicacion de sus servidores Ajuste a diferentes niveles de carga Ampliacién del control con 1n select inteligente .. El asalto al planificador. 188, 194 195 198 199 201 202 205 207 211 211 214 216 219 219 Sobrecarga de select() Llegar a un compromiso con un select inteligente Problemas de implementacin Redistribucién de la carga .... Investigacion a fondo del control de sockets Opciones generales .. Opciones de socket especificas de IP Opciones de socket especificas de IPv6 Opciones de socket especificas de TCP Recuperacin del descriptor de socket . Envio antes de la recepcidn: mensajes entrelazados. Apunte sobre los problemas de E/S de archivos Utilizacién de E/S sobre la base de la demanda para recuperar tiempo de CPU Aumento de la velocidad de send( Descarga de recv() .. Envio de mensajes de prioridad alta .. Resumen: discusidn de las caracteristicas de rendimiento Capitulo 10. Disefio de Socket Linux robustos . Utilizacién de herramientas de conversion .. Controle los valores de retorno Captura de sefiales SIGTIPE.... SIGURG SIGCHLD SIGHUP SIGIO... SIGALARM Administracién de recursos Administracién de archivos La pila de la memoria Memoria de datos estaticos . CPU, memoria compartida, y procesos .. Servidores criticos 2Qué se califica como un servidor criti Interrupciones y eventos de comunicacién Cuestiones sobre la recuperacién de la sesion . Técnicas de recuperacién de la sesién .. Cuestiones sobre la concurrencia cliente-servidor Interbloqueo de la red Inanici6n de la red . Ataques de denegacién de servicio .. Resumen: servidores sélidos como una roca .. 246 247 249 249 251 251 251 PARTE IIL Examen objetivo de los sockets Capitulo 11. Cémo ahorrar tiempo con objetos . 263 La evolucién de la ingenieria del software 265 Programacién funcional paso a paso 266 Cémo ocultar detalles de implementacién con la programaci nm modular . 267 Los detalles no son necesarios: programacién abstracta 268 Cémo conseguir un pensamiento més natural mediante la Programacion orientada a objetos ..... 268 Como Hegar a la programacién Nirvana 269 Reusabilidad del trabajo .. 269 Consolidacién de la reusabilidad con la reubicabilidad (phuggability) 270 Presentacién de los fundamentos de los objetos 271 Encapsulacién de la implementacion 272 Herencia de métodos 273 Abstraccién de datos 274 Polimorfismo de métodos 275 Caracteristicas de los objetos 275 La clase 0 el objeto . 275 Atributos .. 276 Propiedades . 276 Métodos 277 Derechos de acceso 277 Relaciones 277 Extensién de los objetos 278 Plantillas ... 278 Persistencia .. 278 Generacién de flujos 279 Sobrecarga 279 Interfaces 279 Eventos y excepciones . 280 Formatos especiales 280 Registro-Estructura 280 Coleccién de funciones 281 Soporte del lenguaje ... 282 Soporte activado frente a soporte orientado 282 Como incluir objetos en los lenguajes no orientados a objetos 283 Resumen: mentalidad orientada a objetos . 285 Capitulo 12. Uso de la API de red de Java .. 287 Exploracion de diferentes sockets Java 289 Programacién de clientes y servidores Implementacion de mensajeros Envio a miiltiples destinos .. Conexién a través de B/S . Clasificacién de las clases de E/S .. Conversién entre clases de E/S ... Configuracién del socket Java Configuraciones compartidas por sockets Java ....... Configuraciones Java especificas de la multidifusién Mulltitarea de los programas Uso de threads en una clase Cémo afiadir threads a una clase Sincronizacién de métodos . Limitaciones de la implementacién Resumen: programacion de redes de tipe Java .. Capitulo 13. Disefio y uso de una estructura de socket en C++ .... ¢Por qué utilizar C++ para la programacién basada en sockets? ... Cémo simplificar la conexién con les sockets Cémo ocultar los detalles de implementacién . Implantacion de componentes reutilizables que faciliten el uso de las interfaces ... Demostracidn de los procesos del disefio del marco de trabajo . Disposicin del marco de trabajo .. Definicién de las caracteristicas generale: Agrupamiento en componentes principales .. Creacién de la jerarquia del marco de trabajo Definicién de las capacidades de cada clase Prueba del marco de trabajo basado en socke El cliente/servidor de eco ... Multitarea de igual a igual Limitaciones de implementacién . Envio de mensajes desconocidos o indefinidos Incorporacién de la multitarea ... Resumen: un marco de trabajo basado en sockets de C++ simplifica la programacién ... Capitulo 14. Limitaciones de los objetos .... Recordatorio sobre objetos Comience con buen pie Un mezclador no es un objeto Separacién entre anilisis y disefio El nivel de detalle apropiado La explosi6n de la herencia . Reutilizacién-Desaprovechamiento Uso correcto de la directiva friend de C++ El operador sobrecargado .... Los objetos no lo resuelven todo Las novedades llegan y evolucionan Infeccién de la herencia .. Cédigo inalcanzable Complejidad dar y tomar Simplificacién de programas con interfaces establecidas . El enigma de la herencia multiple . Incremento del tamaiio del codigo El dilema de la administracién de proyectos Obtencién del personal apropiado en el momento oportuno Fenémeno WISCY (“Whisky”) . Prueba de (des-)integracién .. Resumen: tenga cuidado con las pendientes ... PARTEIV Sockets avanzados: més prestaciones Capitulo 15, Encapsulado de red con Llamadas de procedimiento remoto (RCP) . - Repaso del modelo OSI .. Comparacién de programacién de red y procedimental .. Limitaciones del lenguaje Mantenimiento de sesiones conectadas Suministro de métodos middleware ... Stubbing en las Hamadas de red... Adicién de la implementacion de llamada Implementacién del nivel de presentacién .. je servicio Creacién de RPC con rpegen .... Lenguaje de interfaces de rpegen .. Creacién de Ilamadas con estado con conexiones abiertas Diagnosis del problema del estado Recuerde donde esté ... Seguimiento de una ruta especifica . Recuperacién desde un estado erréneo - Resumen: creacién de una caja de herramientas para RPC . Capitulo 16. Cémo afiadir seguridad a los programas de red y SSL. ........ Asignacién de permisos para trabajar . Niveles de identificacion . 375 375 Formas de intercambio .. El problema de Internet Todo esta visible .. Formas de ataque/ intrusion Pirateo del TCP/IP .. Como garantizar la seguridad en un nodo de red ‘Acceso restringido Firewalls Zonas desmilitarizadas (DMZ) . Cémo garantizar la seguridad del canal Cifrado de mensajes ... gCudles son los tipos de cifrado disponible: Algoritmos de cifrado publicos .. Problemas con el cifrado - Seguridad a nivel de sockets (SSL) ‘Uso de OpenSSL . Creacién de un cliente SSI Creacién de un servidor SSL .. Resumen: el servidor seguro ... Capitulo 17. Cémo no compartir mensajes con multidifusién, difusién y Mbone ... Difusién de mensajes a un dominio . Repaso de la estructura ID ... Programaci6n para activar la difus Limitaciones de la difusion ..... Multidifusion de mensajes a un grupo Uni6n a grupos de multidifusion Envio de mensajes de multidifusién Cémo la red proporciona la multidifus Salida del mensaje de multidifusi6n .. Limitaciones de la multidifusion ... Resumen: comparticion eficiente de los mensajes ... Capitulo 18. La potencia de los sockets raw ..... Cuando se deben usar sockets raw? ..... Explicacién de ICMP... Cémo controlar la cabecera IP Aceleracion a través de la red 4Cuiiles son las limitaciones? . Cémo poner los sockets raw a funcionar Seleccién del protocolo correcto Creacin de un paquete ICMP .. 376 377 377 378 379 379 380 380 381 384 386, 387 387 388 388 389 391 393 411 411 41 A412 412 AI3. 413, 413 Como calcular una suma de comprobacién Cémo controlar la cabecera IP .. Trafico de terceros .... gCémo opera ping? El receptor MyPing .. Elemisor MyPing ...., Cémo opera traceroute Resumen: toma de decisiones raw . Capitulo 19, IPv6: la proxima generacién de IP ... Problemas actuales de direccionamiento saeco Resolucién de la reduccién del espacio de direcciones IPv4 cA qué se parece IPV6? .... Cémo funcionan juntos IPv4 ¢ IPv6? Cémo poner a prueba IPV6 ... Configuracién del niicleo .. . Configuracin de las herramientas Transformacién de las llamadas IPv4 a IPv6 Transformacién de sockets raw a IPV6 .. Transformacién de sockets ICMPV6 a IPV6 EI nuevo protocolo multidifusién . Pros y contras de IPV6 .... Incorporacién esperada de Linux Resumen: traslado del cédigo hacia el futuro PARTEV Apéndices : primer parametro de socket() .. Tipos: segundo parametro de socket) Definiciones de protocolo ... Asignaciones estandar de puertos de Internet (100 primeros puertos) ... Cédigos de estado HTTP 1.1 Opciones de socket (get/setsockopt()) Definiciones de seiales Cédigos ICMP . Asignacién de multidifusion IPv4........ Asignacion de direcciones IPv6 propuesta Cédigos ICMPv6 .... Campo de ambito de multidifusin IPv6 Campo flag de muitidifusion IPv6 ... 44 415 415 416 4lo 417 418 420 437 438 446 447 448 450 455 457 458 459 460 460 461 Apéndice B, API de red .. Conexién a la red .. Comunicacién por un canal .. Terminacién de conexiones Conversiones de datos de re Herramientas de direccionamiento dered .. Controles de socket Apéndice C. Subconjunto API del nicleo Tareas Threads Bloqueo Sefales . Archivos y otros Apéndice D. Clases de objetos ... Excepciones de C++. Exception (Superclase) .. NetException (Clase) Clases de soporte C++ SimpleString (Clase) .. HostAddress (Clase) .. Clases de mensajeria C++ .. Message (Clase abstracta) TextMessage (Clase) Clases de sockets C++ Socket Guperclase) SocketStream (Clase) SocketServer (Clase SocketClient (Clase) Datagram (Clase) Broadcast (Clase) MessageGroup (Clase) . Excepciones de Java ... java.io. IOException (Clase) ... java.net SocketException (Clase Clases de soporte Java .. java.net. DatagramPacket (Clase) java.net.InetAddress (Clase) ... Clases Java de F/S .. java.io.InputStream (Abstract Clas: java.io. ByteArraylnputStream (Clase) java.io.ObjectinputStream (Clase) ... 465 472 483 484 489 493 499 507 511 514 518 531 533 533 533 java.io.OutputStream (Clase abstracta) . java.io. ByteArrayOutputStream (Clase) java.io. ObjectOutputStream (Clase) java.io BufferedReader (Clase) . java.io.PrintWriter (Clase) .. Clases de sockets Java ... java.net.Socket (Clase) . java.net ServerSocket (Clase) .. java.net.DatagramSocket (Clase) . java.net.MulticastSocket (Clase) indice alfabético ... 546 546 547 548 548 550 530 551 552 553, Acerca del autor Sean Walton obtuvo su titulacién en Ciencias de la computacién en 1990 en la Brigham Young University, en la especialidad de teoria de la multitarea y fusiones de lenguajes. En 1988 fue contratado por el departamento de ciencias de la compu- tacién de la BYU como ayudante para el desarrollo de teorfas y métodos para la administracién de procesos transputer, migracién y comunicacién. Comenzé a tra- bajar con sockets BSD cuando trabajé como administrador en el departamento de ciencias de la computacién. Durante su trabajo en Hewlett-Packard, desarrollé el método de deteccién automatica de lenguaje (entre PostScript y PCL), que imple- mentan hoy dia las impresoras LaserJet 4 y superiores. Asimismo, desarrollé un sistema operativo de micro en tiempo real para el microcontrolador 8052 que per- mite emular motores de impresion. Sean posee afios de experiencia profesional en varios tipos de programacién y administracién UNIX, incluido Linux, HPUX, Ultrix, SunOS y System V. Como consecuencia de su trabajo en diferentes sistemas, ha centrado su atencién en esti- los de programacién independientes del sistema, que permiten una facil portabili- dad. En los iiltimos afios, Sean ha trabajado como asistente profesional, autor-disefia- dor de cursos, y profesor de conceptos basicos de computadoras, obtencién de requisitos, OOA/D, Java y C++. A principios de 1998 comenzé a trabajar con sockets Java, integrando esta informacion en su curso de Java. Sus servicios como profesor estén muy solicitados. Durante su trabajo en el equipo Nationwide Finan- cial Process Improvement, definié los procesos de anélisis y disefio para integrar los nuevos desarrollos con los estandares existentes. Ha dirigido y disefiado el pro- ducto Nationwide Insurance Authentication, que incluye politicas y autenticacién divididas. Dedicatoria Al dador de todo bien v principe de la paz perfecta. Agradecimientos Soy consciente de que este libro no habria sido posible sin la colaboracién esen- cial de varias personas. En primer lugar, a mi amada esposa, Susan, que me ha ani- mado constantemente, dandome todo el tiempo que he necesitado para llevar a tér- mino este proyecto. En segundo lugar a Wendel, mi padre, que me enseié la importancia de una buena organizacién y presentacién. En tercer lugar, al movi- miento Linux que, de forma desinteresada, me ha proporcionado un sistema opera- tivo efectivo y fiable sobre el que poder trabajar. En cuarto lugar, a Beverly Scherf, quien me abrié los ojos y me mostré una forma efectiva de comunicarme. Por ulti- mo, no fui consciente de lo importante que cra este trabajo para mi profesionalmen- te hasta recibir el entusiasmo y el apoyo de mis amigos Charles Knutson y Mike Holstein. Introduccion Expansién del desafio en la programacion La mayoria de los objetivos en programacién tiene que ver de forma inmediata con funciones o tareas que se llevan a cabo en una computadora de sobremesa o un portatil. En contadas ocasiones, estas tarcas involucran la comunicacién con algo més que un ratén, un teclado, un monitor y un sistema de archivos. Un paso més all en la programacién nos levaria a considerar programas en varios equipos conectados a través de un canal de red. La programacién en red constituye una expansidn de este concepto, va que se precisa coordinar tarcas y enviar asignacio- nes, La unidad fundamental de toda la programacién de red en Linux (y en la mayo- ria de los sistemas operativos) es el socket, De la misma forma que la E/S de archi- vos permite la conexién con el sistema de archivos, el socket permite establecer conexidn con la red. El socket es un medio que el programa utiliza para direccionar, enviar y recibir mensajes. La programacién de socket o de red va mas alld que la programacién de tareas individuales o incluso de multitarea, debido a la mayor potencia y clementos intro- ducidos por el multiprocesamiento. La potencia ¢s algo obvio: Parallel Virtual Machines (PMV), o maquinas virtuales en paralelo, como Beowolf pueden llevar a cabo un volumen de procesamiento mucho mayor mediante la organizacion de bloques de tareas y la distribucion de éstas entre las computadoras de la red. Los temas a dilucidar aqui tienen que ver con la consecucién de un rendimiento 6pti- mo, la cuordinacién de las transferencias y la administracion de E/S. En este libro se describen y se ofrecen varias soluciones para dar respuesta a estos temas. Esta pensado para dar respuesta a las necesidades primarias y a medio plazo del programador de red profesional. Organizacién del libro Este libro entra en muchos aspectos particulares de la programacién en red. EstA organizado en cinco parte, cada una de las cuales se basa en el contenido de la par- te anterior: * Parte I: Programacisn de red desde la perspectiva del cliente. En esta parte se introducen los sockets y se definen los términos basicos. Se describen los distintos tipos de sockets, los esquemas de direccién y la teoria de redes. * Parte II: La perspectiva del servidor y el contro! de carga. La Parte Il amplia la programacién de socket con servidores, técnicas de multitarea, control E/S y opciones de socket. ° Parte IIL: Examen objetivo de los sockets. C no es el nico lenguaje de programacién que proporciona acceso a soc- kets. En esta parte se presentan algunas técnicas orientadas a objetos y se describen las ventajas y limitaciones de la tecnologia de objetos, en general. * Parte IV; Sockets avanzados: mas prestaciones En esta parte se presentan una gran cantidad de técnicas de programacion de redes avanzadas, que incluyen la seguridad, la difusion y la multidifusién, IPv6 y sockets raw. * Parte V: Apéndices. Los apéndices vienen a consolidar muchos de los recursos que son de importancia para los sockets. El primer apéndice incluye tablas y listados que son demasiado largos para incluirlos en los capitulos. El segundo y ter- cer apéndices describen las API Socket y Kernel. El sitio web que sirve de apoyo al libro y que contiene todo el cédigo fuente de los ejemplos incluidos en el mismo, lo puede obtener de nuestra pagina Web (www pearso- neducacion.com), en el “Area de descarga” de la secci6n “Informatica” Puede obtener mas informacién de la propia pagina web del autor, www linux: socket.org. Estilos del lector profesional Este libro esté pensado para el profesional de la programacién. Normalmente, el profesional necesita alguna de estas tres cosas: aprender una tecnologia nueva, solucionar un problema concreto, 0 buscar algtin ejemplo o definicién. Los capitu- los y apéndices intentan responder a cada uno de estos criterios. * Lectura lineal de principio a fin. Esta opcidn es la idénea cuando se desea aprender tema a tema, en sucesién. Cada apartado del capitulo se basa en el contenido de capitulos precedentes. El texto estd organizado en términos de complejidad creciente. La programacién de sockets puede resultar bas- tante intuitiva al principio. Sin embargo, al avanzar en este tema van sur- giendo cuestiones relativas a la temporalizacién, excepciones, rendimiento, etc, que pueden echar por tierra el mejor de los disefios. La lectura lineal facilita la compresién ordenada de los conceptos necesarios para realizar las tareas como es debido. * Hojear. Hojeando el libro se puede obtener la informacicn necesaria sin entrar en muchos detalles. Se supone que el profesional conoce bien el tema y desea ir directamente al punto de interés. De forma parecida a nave- gar por la Web, el hojeador va pasando de unos temas a otros hasta que localiza exactamente la informacién que anda buscando. © Consulta. El experto suele necesitar informacién (tablas, fragmentos de pro- grama, API concretas) rapidamente. La informacion ha de ser en este caso Jo mas sucinta posible y facil de localizar. El libro contiene toda Ja informacién fundamental necesaria para abordar las tareas mas habituales en este terreno. Ademas, hay muchos capitulos en los que existen porciones de texto apartadas de! contenido normal del tema. Estos frag- mentos contiene informacién adicional, detalles, notas para expertos y opiniones. La audiencia y la interaccion esperada El libro contiene muchos ejemplos de cédigo que ilustran los temas tratados. Lea los apartados y pruebe los programas. Para ello necesitara conocer como llevar a cabo lo siguiente: 1. Crear un archivo fuente C 0 Java (en cualquier editor) 2. Compilarlo usando un compilador C 0 Java 3. Ejecutar el programa. Algunos ejemplos requieren, ademas, modificar el nticleo (difusin o multidifu- sin). La mayoria de las distribuciones de Linux instalan y ejecutan la red aunque no exista una conexién fisica a la misma. Para poder ejecutar todos los programas que aparecen en ci libre necesita: * Programas y compilar cédigo C, C++ y Java. * Tener todos los compiladores instalados * Saber configurar el nucleo para redes, difusién y multidifusion. © Compilar e instalar el nucleo nuevo. Reservas y limitaciones Aunque todos los programas que figuran en el texto han sido probados, es posi- ble que alguno no funcione tal cual se presenta aqui, debido a que la configuracién del sistema cambia can el tiempo. En la mayoria de los casos, si algo no funciona, se debe a que ha cambiado la distribucion. Ademés, hay expertos que han verificado los programas en otros sistemas ope- rativos UNIX. Esto puede representar una ironia con respecto a la maxima de por- tabilidad. Sin embargo, si existe una discrepancia entre Linux y otras implementa- ciones, en el libro se incluyen siempre los listados para Linux (y se incluye, ademés, una nota descriptiva de este hecho). El libro esta centrado principalmente en Linux. Por ultimo, el libro no trata de otros sistemas operativos (Microsoft Windows o Macintosh). Algunos capitulos ponen de manifiesto algunas comparaciones, pero todos los algoritmos soportan Linux/UNIX. Convenios usados en el libro A lo largo del libro se han utilizado los siguientes convenios tipograficos: * Las lineas de cédigo, comandos, instrucciones, variables y cualquier texto que sc ha de teclear 0 que aparece en pantalla, se muestra en un tipo de letra de espacio fijoo sin adornos. E1 tipo de letra sin adornos se utiliza tam- bién para indicar las entradas del usuario. + Los marcadores de posicién en las descripciones sintacticas aparecen en un tipo de letra sin adornos y cursiva. Ha de reemplazar los marcadores de Pposicién por nombres de archivo, pardmetros © el elemento que éstos repre- senten, © Se ha usado el atributo de cursiva para resaltar términos técnicos cuando éstos son definidos. * Elicono ™ delante de una linea de cédigo representa la continuacién de la linea previa. A veces una linea de cédigo es demasiado larga para caber en una linea de texto en la pagina. Si ve este simbolo delante de una linea de cédigo, recuerde que forma parte de la linea anterior. * El texto incluye también referencias a documentos relativos a estandares de Internet, denominados Request For Comment (RFC). Estas citas aparecen entre corchetes, con el ndmero RFC correspondiente, come [RFC875]. Programacion de red desde la perspectiva del cliente En esta parte 1 Recetario del cliente de red 3 2 Elocuencia dei lenguaje de red TCP/IP 23 3 Tipos de paquetes de Internet 45 4 Envio de mensajes entre peers 71 5 Explicacién del modelo de capas de red 97 Parte | Capitulo | Recetario del cliente de red En este capitulo Un mundo conectado mediante sockets 7 Generalidades del direccionamiento TCP/IP 8B Escucha del servidor: el algoritmo basico del cliente 9 Resumen: gqué acurre entre bastidores? 21 jEsa maldita bateria RAM CMOS! Bien, :qué hora es? No se ve el reloj, Hamaré a Ia informacién horaria. 1-614-281-8211. Ring, “...son las ocho y veintitrés y cuarenta segundos”. Clic. ;Hummt! ca.m. o p.m.? ¢Esperan ellos que lo mire afuera? La computadora que utiliza probablemente se encuentra conectada a algtin tipo de red. Podria ser una intranet corporativa completa con firewalls dentro de Internet; © quiz un par de computadoras que conecta en su tiempo libre. La red conecta estaciones de trabajo, servidores, impresoras, arrays de discos, faxes, modems, etc. Y cada conexién de red utiliza o suministra un servicio. Algunos servicios ofrecen informacién sin ninguna interaccién. Igual que en una llamada a la informacién horaria, un cliente de red basico se conecta con un servidor y lo escucha. {Qué tipos de servicios ofrecen los servidores? Muchos. Todos los servicios se ajustan a cuatro categorias de recursos: comtin, restringida valiosa, compartida y delegada. He aqui algunos ejemplos de cada una: Comtin Espacio de disco (normalmente respaldado). Restringida Impresoras, médems, arrays de discos. Compartida Bases de datos, control de proyectos, documentacién. Delegada Programas remotos, consultas distribuidas En este capitulo se describe el codigo de un cliente basico que se conecta aun servidor. Este proceso ayuda a entender todo lo que envuelve a la escritura de pro- gramas de red. El cliente inicialmente se conecta al servicio de informacién horaria del servidor (0 a cualquier otro servicio que no necesite entrada de datos al inicio). Junto con el procedimiento, en este capitulo se explican las diferentes Hamadas, sus pardmetros y errores mas comunes. El programa cliente necesita una interfaz para enviar-recibir y una direccién para conectarse al servidor. Los clientes y los servidores necesitan utilizar sockets para conectarse y enviar mensajes independientemente de la situacién. Considere el ejemplo telefénico otra vez: el auricular tiene dos partes, un micrdfono (transmi- sion) y un altavoz (recepcién). Los sockets tienen también estos dos canales. Adicio- nalmente, el ntimero telefénico es en esencia la direccién nica para cl teléfono. De igual modo, el socket tiene dos partes o canales: uno para la escucha y otro para el envio (como el modo de lectura-escritura para un archivo de E/S). El cliente {0 la Hamada) se conecta con el servidor (o contestador) para comenzar una conver- sacién de red. Cada host ofrece varios servicios estandar (véase /etd/services en el sistema de archivos), como el mimero telefénico de informacién horaria correcta. EJECUCION DE LOS EJEMPLOS DEL LIBRO Se pueden ejecutar la mayor parte de los ejemplos del fibro sin estar conectado a la red, si se tiene habilitada la red en el nucleo y el demonio servidor de red, inetd, esta ejecutandose. De hecho, muchos ejemplos utilizan la direcci6n local (o loopback) de 127.0.0.1. Si no se tienen los controladores de red configurados y funcionando, la mayoria de las distribuciones Linux incluyen como minimo todo lo que se necesita para el funcionamiento en red del loopback. EI programa cliente debe seguir varios pasos para comunicarse con un equipo homélogo 0 servidor. Estos pasos tienen que seguir una secuencia particular. Por supuesto, se puede preguntar: “;por qué no se reemplazan todos estos pasos con menos Hlamadas?” En medio de cada paso, el programa puede scleccionar de muchas opciones. No obstante, algunos pasos son opcionales. Si el cliente omite algunos pasos, normalmente el sistema operativo rellena esas opciones con los valo- res predeterminados. Puede seguir algunos de estos pasos basicos para crear un socket, configurar el host de destino, establecer el canal a otro programa de red y cerrarlo. La Figura 1.1 muestra graficamente los pasos que el cliente toma para conectarse a un servidor. Cliente FIGURA 1.1 Cada cliente interactua con el sistema Operativo realizando varias llamadas en sucesién. En la siguiente lista se describe cada paso: 1. Crear un socket, Se selecciona de diversos dominios de red (por ejemplo, Internet) y clases de socket (como flujo). 2. Configurar las opciones del socket (opcional). Se dispone de muchas opcio- nes que afectan al comportamiento del socket. Una vez abierto el socket, el programa puede cambiar estas opciones en cualquier momento. (Para obte- ner més detalle véase el Capitulo 9, “Cémo romper Jas barreras del rendi- miento”.) 3. Asociar con una direccién-puerto (opcional). Se aceptan conexiones de todos 0 de una sola direccién IP, y se establece un puerto de servicio. Si se omite, el sistema operativo asume cualquier direccién IP y asigna un mimero de puer- to aleatorio. (En el Capitulo 2, “Elocuencia del lenguaje de red TCP/IP”, se tratan las direcciones y puertos en mayor detalle.) 4, Conectar a un equipo homélogo-servidor (opcional). Se extiende y establece un canal bidireccional entre el programa local y otro programa de red. Si se omite, el programa utiliza una comunicacién dirigida o sin conexd6n. 5, Cerrar la conexién parcialmente (opcional). Se restringe el canal de envio o de recepcién. Se puede utilizar este paso después de la duplicacién del canal. 6. Enviar-recibir mensajes (opcional), Una razén para prescindir de cualquier E/S podria incluir comprobacién de disponibilidad de host. 7. Cerrar la conexién. Por supuesto este paso es importante: si los programas no cierran las conexiones terminadas, los programas que consumen bastante tiempo de CPU pueden agotar casualmente los descriptores de archivo. En los siguientes apartados se describen algunos de estos pasos, definiendo las Hamadas del sistema y suministrando ejemplos. Un mundo conectado mediante sockets Hace varios afios, el funcionamiento en red implicaba a una linea serie dedicada de una computadora a otra. Ninguna otra computadora podia compartir el mismo cireuito, y UNIX utiliz6 UUCP (copia de UNIX a UNIX) para mover archivos entre sistemas. Como la tecnologia de transmision en la linea mejoré, se hizo posible el concepto de comparticién de la linea de transmisién. Esto implicaba que cada com- putadora necesitaba identificarse de forma tnica y habia que realizar turnos en la transmisi6n. Existen varios métodos diferentes para compartir la red en cl tiempo, y muchos de ellos funcionan bastante bien. A veces, las computadoras transmiten simulténeamente, causando una colisién de paquete. El hardware y los controladores de bajo nivel gestionan las cuestiones de colisio- nes y retransmisiones, ahora un objeto de programacion del pasado. Esto libera al disefio de fijar su atencidn en la transmision y recepcion de mensajes. La API de Socket (Interfaz de programacién de la aplicacién) suministra a los disefiadores el medio para recibir o enviar mensajes. La programacién de sockets se diferencia de la aplicacion o herramienta de tra- bajo normal, en que trabajamos con programas y sistemas que funcionan concurren- temente. Esto implica que necesita conocer la sincronizacion, temporizacién y administracién de recursos. Los sockets enlazan tareas asincronas con un tnico canal bidireccional. Esto podria conducir a problemas como el interbloqueo y la inanicién. Con conocimiento y Pplanificacion, puede evitar muchos de estos problemas. Puede obtener informa- cién de cémo gestionar cuestiones de mutitarea en el Capitulo 7, “Di mn de la carga: multitarea”, y construccién de sockets robustos en el Ca pitulo 10, “Disefio de sockets Linux robustos”. Normalmente, un servidor sobrecargado reduce su velocidad de respuesta a lo recibido de Internet. La administracién de recursos y la temporizacién reduce la carga del servidor, incrementando ei rendimiento de la red. Puede encontrar muchas ideas para mejorar el rendimiento en la Parte Il, “La perspectiva del servi- dor y el control de carga”, Internet fue disefado para funcionar con la conmutacién de paquetes. Todos los Paquetes necesitan tener toda la informacién necesaria para alcanzar el destino. Como una carta, un paqucte debe incluir la direccién de destino y de origen. El Paquete conmuta de una computadora a la proxima a través de las conexiones (0 enlaces). Si la red pierde un enlace mientras se transmite un mensaje, el paquete encuentra otra ruta (conmutacién de paquetes), y si no se alcanza el host, el router envia un error hacia el origen. Esto asegura la fiabilidad de los datos. Los caminos rotos en la red son pausas de red. Probablemente encontré alguna vez alguna pausa de red. Generalidades del direccionamiento TCP/IP Las redes soportan diferentes tipos de protocolos. Los programadores han utili- zado algunos protocols para controlar temas especiticos como radio-microondas; otros intentan resolver los problemas de fiabilidad de la red. TCP/IP (Protocolo para el control de la transmisién-Protocolo de Internet) fijé la atencién en el paque- te yen el potencial de pérdida en los canales de comunicacién. Siempre que falle un segmento de red, el protocolo intenta encontrar una ruta nueva. El rastreo de paquetes, deteccion de pérdida y retransmisién son algoritmos diff ciles, porque la temporizaci6n no ¢s el nico indicador. Afortunadamente, la expe- riencia industrial ha probado los algoritmos utitizados en el protocolo. Normalmen- te, se pueden ignorar estas cucstiones durante el disetio, porque las soluciones estan ecultas dentro del protocolo. TCP/IP esta compuesto por capas: los protocolos de nivel alto ofrecen mas fiabi- Iidad pero menos flexibilidad y los niveles inferiores ofrecen més flexibilidad pero sacrifican la fiabilidad. Con los diferentes niveles de flexibilidad y fiabilidad, la API de Socket ofrece todo to que las interfaces necesitan. Esto es una desviacion de la estrategia del UNIX esténdar en la que cada nivel tiene su propio conjunto de lla- madas, Elarchivo de E/S estandar utiliza también una estrategia por capas. Las compu- tadoras conectadas a través de TCP/IP utilizan sockets, en su mayoria, para comu- nicarse con el resto. Esto puede parecer extrafio, considerando que las distintas capas de protocolos disponibles para un programa han sido disefiados para que open() (el cual produce un descriptor de archivo) y fopen() (el cual produce una referencia de archivo) sean diferentes y casi incompatibles, Todas las capas de pro- tocolos estan disponibles a través de una: socket(). Esta Hamada tnica resume todos los detalles de implementacion de redes diferentes (TCP/IP, IPX, Rose). Fundamentalmente, cada paquete conticne los datos, la direccion de origen y la de destino, Cada capa del protocolo afade su propia firma y datos adicionales (envoltura) a la transmisién del paquete. Cuando se transmite, la envoltura ayuda al receptor a reenviar el mensaje hacia la capa apropiada que aguarda su lectura. Cada computadora conectada a Internet tiene una direccién IP (Protocolo de Internet), un Unico ndmero de 32 bits. Sin la unicidad, no hay forma de conocer el destino correcto de los paquetes. TCP/IP lleva el direccionamiento un paso mas allé con el concepto de puertos. Como los 3 6 5 digitos de extensiones telefénicas, cada direccién de la computadora tiene varios puertos a través de los cuales la computadora se comunica. Estos no son fisicos; mas bien, son abstracciones del sistema. Toda la informacién se dirige a través de la direccién de red como el numero telefénico principal. El formato de escritura estdndar para la direccién IP es {0-255].[0-255].[0- 255].(0-255]—por ejemplo, 123.45.6.78. Se debe observar que el cero y el 255 son mimeros especiales utilizados en mdscaras de red y multidifusion, asi que hay que tener cuidado con su uso (en el Capitulo 2 se trata la numeracién IP con mayor detalle). Los puertos Internet separan normalmente estos mameros con otro punto 0 dos puntos: [0-255].[0-255].[0-255] .[0-255]:[0-65535] Por ejemplo, 128.34.26.101:9090 (IP=128.34.26.101, puerto=9090). [0-255].[0-255].[0-255].[0-255].[0-65535] Por ejemplo, 64.3.24.24,9999 (IP=64.3.24.24, puerto=9999). PUERTOS CON DOS PUNTOS CONTRA PUNTO La notacin con dos puntos es mas comtn para los puertos que /a notacién punto decimal. Cada direccién IP ofrece efectivamente sobre 65.000 niimeros de puerto al que un socket se puede conectar. Véase el Capitulo 2 para mas informacion. Escucha del servidor: el algoritmo basico del cliente La conexién cliente-socket mas simple es la que abre una conexién a un servidor, envia una consulta y acepta la respuesta. Algunos de los servicios estandar incluso no esperan consultas. Un ejemplo es el servicio time-of-day hallado en el puerto 13. Desafortunadamente, muchas distribuciones de Linux no tienen ese servicio abierto sin que se revise el archivo /ete/inetd.conf. Si tiene acceso a una maquina BSD, HP- UX 0 Solaris, puede intentar conectarse a ese puerto. Existen varios servicios disponibles para probar con seguridad. Puede intentar en la méquina la ejecucién del comando Telnet para conectarse al servicio FIP puerto (21): % telnet 127.0.0.1 21 Después de la conexién, el programa obtiene el mensaje de bienvenida del servi- dor. No funciona muy bien el hacer Telnet para conectarse al servidor FTP, pero puede ver la interaccién basica. El ejemplo simple de cliente del Listado 1.1 se conecta al servidor, lee la bienvenida y luego se desconecta. Listado 1.1 Un algoritmo basico de cliente TCP [POCO RT ES AE NU RIE R ERAN RnR EEE hee nae tats | /*** Un algoritmo basico de cliente, wey [TA tee eneeennennn ae eeanaanenerennennnnreuussatasadnennenenee/ Crear un socket. Crear una direccién de destino para el servidor. Conectar con el servidor. Leer y visualizar cualquier mensaje. Cerrar la conexidn. El algoritmo del Listado 1.1 puede parecer demasiado simplificado, y a lo mejor lo es. Sin embargo, la conexién y la comunicacién con un servidor es realmente facil. Los siguientes apartados describen cada uno de estos pasos. Puede encontrar el programa fuente completo al final de este libro y en el CD-ROM adjunto. La llamada del sistema socket: procedimientos y advertencias La tinica herramienta que hace eficaz al receptor de mensajes y comienza el pro- ceso completo de envio y recepcin de mensajes de otra computadora es la Hamada del sistema socket(), Esta Hamada es la interfaz comtn entre todos los Protocolos disponibles en un sistema operativo Linux/UNIX. Al igual que la llamada del siste- ma open() crea un descriptor para acceder a los archivos y dispositivos en nuestro sistema, socket() crea un descriptor para acceder a las computadoras de la red. Esta Hamada necesita informacién que determine a qué capa quiere acceder. La sintaxis es como sigue: #include #include int socket(int domain, int type, int protocol); La llamada al sistema socket() acepta varios valores di intos. Para obtener una lista completa, vase el Apéndice A, “Tablas de datos”, Por ahora, encontrara algu- nos en la Tabla 1.1 Tabla 1.1 Valores de parametros seleccionados de la llamada de sistema socket() Parametro Valor Descripcién domain PF_INET PF_LOCAL PF_IPX PF_INET6 type SOCK_STREAM SOCK_RDM. SOCK_DGRAM SOCK _RAW protocol Protocolos de Internet I’v4; pila TCP/TP. Canales con nombre locales al estilo BSD. Normalmente utilizado en el registro del sistema o en una cola de impresi6n. Protocolos de Novell. Protocolos de Internet IPv6; pila TCP/IP. Fiable, flujo de datos secuencial (flujo de bytes} [Protoco- Jo para el control de la transmisién (TCP)]. Fiable, datos en paquetes (no implementado ya en muchos sistemas). No fiable, datos en paquetes (datagrama) [Protocolo de datagrama del usuario (UDP)]. No fiable, datos en paquetes de bajo nivel. Este es un entero de 32 bits en el orden de bytes de red (véase el apartado sobre la ordenacion de bytes de red en el Capitulo 2). Muchos tipos de conexién soportan s6lo el protocolo = 0 (cero). SOCK_RAW necesita especificar un valor de protocolo entre 0 y 255. Por ahora, los tinicos parametros que el ejemplo utiliza son domain=PF_INET, type=SOCK_STREAM y protocol=0 (cero). En este libro se utilizan los dominios PF_* (familia de protocols) en la llamada de socket, porque la forma correcta es el uso de las constantes de dominio FP_*. Sin embargo, muchos programas utilizan las constantes AF_* (familia de direcciones) de forma intercambiable. Tenga cuidado y no se confunda cuando observe el cédigo fuente que utiliza el estilo AF. (Los archivos de cabecera en C definen las constantes AF_* como PF_*.) Si desea, puede utilizar la notacién AF_* perfecta- mente, pero puede aparecer alguna incompatibilidad en un futuro. A continuacién aparece un ejemplo para una Hamada TCP/IP de generacién de flujo: int sd; sd = socket(PF_INET, SOCK_STREAM, 0); sd es el descriptor de socket. Funciona de la misma forma que un descriptor de archivo fd: int fd; fd = open(...); La llamada devuelve un valor negativo cuando ocurre un error y coloca el cédi- go de error en erro (la variable global estandar para los errores de biblioteca). He aqui algunos de los errores mas comunes que puede obtener: * EPROTONOSUPPORT. El tipo de protocolo o el protocolo especificado no se soporta dentro de este dominio. Esto ocurre cuando el dominio no soporta el protocolo que se demanda. Excepto para SOCK_RAW, muchos tipos de dominio sélo soportan el valor cero en el protocolo. * EACCES. El permiso para crear un socket del tipo especificado 0 protocolo se deniega. Nuestro programa es posible que no tenga los privilegios adecuados para crear un socket. SOCK_RAW y PF_PACKET necesitan los privilegios de root. * EINVAL. Se desconoce el protocolo o no se dispone de la familia de protocolo. Esto acurre cuando un valor en cualquier campo dominio o tipo es invalido, Para obtener un listado completo de valores validos, véase el Apéndice A. Por supuesto, necesita conocer los archivos de cabecera mds importantes a incluir. Para Linux, son estos: Hinclude J* Define tunciones estandar. */ #include {* Tipos de datos del sistema estandar, */ #include {* Define los tipos de datos que se necesitan. */ El archivo sys/socket.h tiene las definiciones de funcién que se necesitan para la API de Socket (incluyendo, por supuesto, la funcién socket()). sys/types-h incorpora muchos de los tipos de datos que se utilizan con los sockets. USO DE RESOLV.H FRENTE A SYS/TYPES:H En este libro se utiliza el archivo resolv.h para la definicion de los tipos de datos. Se debe observar que otras distribuciones de Linux o versiones UNIX pueden utili- zar sysitypes.h, el archivo de inclusién més estandarizado. Durante la escritura de este libro, tos ejemplos se comprobaron sobre Mandrake 6.0-7.0, el cual utiliza archivos de inclusion muy peculiares. (Parece que estas versiones de distribucién tienen el archivo sys/types.h erréneo el cual no incluye el archivo netinev/in.h que se necesita para los tipos de direccién.) La llamada del sistema socket() sdlo crea las colas para el envio y recepcién de datos, de forma contraria a la llamada del sistema para la apertura de archivos, la cual abre el archivo y lee el primer bloque. Sdlo cuando el programa ejecuta una lla- mada del sistema bind(, el sistema operativo conecta la cola a la ted. Se utilizara de nuevo el ejemplo del teléfono, el socket es el auricular sin teléfono © conexidn de red. Si se ejecuta bind), connect) o alguna E/S se conecta el auricu- lar al teléfono y éste a la red. (Si el programa no realiza explicitamente la llamada bind0, el sistema operativo realiza implicitamente la llamada por él. Para obtener mas informacién consulte el Capitulo 4, “Envio de mensajes entre peers”.) Realizacién de la llamada: conexi6n al servidor Después de la creacién del socket, se puede obtener el primer “zhola?” a través de la conexién al servidor. La llamada del sistema connect() es similar en varios aspectos a la llamada de alguien por teléfono: * Se identifica el destino utilizando un numero de teléfono. Cuando se Hama a un numero de teléfono, se identifica a un teléfono especifico ubicado en cual- quier lugar del mundo de la red telefénica. La direccién IP identifica de la misma forma a la computadora. Al igual que los ntimeros de teléfono tienen un formato especifico, se requiere que la conexion posea un formato especifi- co para definir a qué computadora se conecta y cémo conectarse. ‘+ La conexién ofrece el canal para los mensajes. Una vez que se descuelga el auricular, existe un canal a través de cual dos o mas personas pueden conver- sar. Su numero de teléfono no es importante a menos que la persona tenga que liamarle. camino de regreso hasta su auricular esta oculto dentro del sistema telefé- nico. La red telefénica tiene varios caminos compartidos, al igual que una red de computadoras. Es importante tener un camino de regreso para obtener los mensajes de vuelta a su auricular. El equipo de destino o servidor obtiene la direccién y el puerto de su programa para poder responder utilizando un camino similar. El numero telefénico tiene que estar publicado para que otros le amen. Si su programa acepta Hamadas, debe especificar un tnico canal ( puerto) y publicarlo a sus clientes. La llamada del sistema connect() se define como sigue: Hinclude #include int connect(int sd, struct sockaddr *server, int addr_len); El primer parémetro (sd) es el descriptor de socket que se creé con Ia llamada socket(). El tiltimo parametro es la longitud de Ja estructura sockaddr. El segundo pardmetro apunta hacia diferentes tipos y tamaiios de estructuras. Esto es impor- tante, porque es lo que hace diferentes las Hlamadas socket() de las llamadas de E/S de archivos. Recuerde que la llamada del sistema socket() soporta al menos dos dominios diferentes (PF_INET y PF_IPX). Cada dominio de red (PF_*) tiene su propia estructu- ra para describir la direccién. Todos ellos tienen un padre comtin—el mismo que se usa en la definicién connect()—struct sockaddr. Consulte el Apéndice A para obte- ner un listado completo de todas las declaraciones de estructura. AY) Ret eeeezs uaitgdbeBbevreteeachadee cay ROSTRACHON BE BATOS SGCKABBR La interfaz sockaddr utiliza abstraccién de datos. La abstraccién de datos simpli ca las interfaces asegurando que mientras los tipos de datos pueden cambiar, los algoritmos permanecen igual. Por ejemplo, una pila puede contener diferentes tipos de datos, pero la funcion de la pila sigue siendo la misma: meter, sacar y asi sucesivamente. Para utilizar una interfaz abstracta, el primer campo de la estruc- tura sockaddr debe tener el mismo significado. Todas las estructuras tienen un campo comin: ..._family. El tipo del campo es un entero de 16 bits sin signo. El valor de este campo determina qué clase de dominio de red utilizar. DE FAMILIA SOCKADDR —————____________ El tipo de dominio que se establecié en la llamada del sistema socket() debe ser ef mismo valor que el primer campo en la familia sockaddr. Por ejemplo, si el pro- grama creo un socket PF_INET6, el campo de la estructura debe ser AF_INET6 para que el programa trabaje correctamente. He aqué el registro genérico y el registro INET para que pueda compararlos (con los archivos de cabecera): struct sockaddr { steuct sockaddr_in { unsigned short int sa_family; sa_family_t sin_family; unsigned char sa_data[14]; unsigned short int sin_port; ti struct in_addr sin_addr; unsigned char pad}; i Se debe observar que sa_family y sin_family son comunes a las dos estructuras. La tarea que cada procedimiento de llamada ejecuta cuando recibe este registro es comprobar el primer campo. Se observa que éste es el Unico campo que esté en ef orden de bytes del host (véase el Capitulo 2). El campo de relleno (denominado sa_data y __pad) puede ser comtn para todas las familias de sockaddr. Por con- vencién, la estructura genérica sockaddr y la estructura INET sockaddr_in tienen que ser de 16 bytes de tamaiio (la estructura IPv6, sockaddr_in6, es de 24 bytes). Asi, el campo de relleno completa la estructura con los bytes sin usar. Puede observar que la longitud del campo de relleno en sockaddr_in esta ausen- te. Esto es meramente una convencién. Como el relleno se tiene que establecer a cero, el tamaiio real no es importante. (En esta definicién de sockaddr_in, es 8 bytes de tamafio.) Algunas implementaciones pueden definir campos adicionales para cdlculos internos. No se preocupe de ellos —y no los use, porque no se puede garantizar la disponibilidad de estos campos de un sistema a otro y de una version a otra, Cualquier cambio en los campos no estandarizados puede paralizar al pro- grama. En todos los casos, es mejor una iniciacién a cero de la instancia entera de la estructura. En la siguiente tabla se describe cada campo. También se ofrecen ejemplos de posibles valores. Nombre de campo _Descripcién Orden de bytes _Ejemplo sin_family La familia de protocolos Host, nativo AF sin_port El nimero de puerto del Red 13 Gnformacion servidor horaria) sin_addr La direccin IP numérica Red 127.0.0.1 del servidor (localhost) El programa rellena cada campo antes de la invocacién a la Hamada del sistema connect(). Linux tiene enmascarada levemente la llamada del sistema, asi que no es necesario transformar sockaddr_in en sockaddr. Por transportabilidad, puede seguir las convenciones todavia y aplicar las transformaciones. Be 38 Beh ine ee PSU TSY HERS s SU BBE Con otros $O compatibles con UNIX, puede trasformar cualquiera de los miem- bros de la familia sockaddr_* a sockaddr para evitar advertencias de compilacion. Los ejemplos aqui mostrados no utilizan ninguna transformacion simplemente para ahorrar espacio (y porque Linux lo permite). El cédigo puede parecerse al del Listado 1.2. Listado 1.2 Ejemplo de connect() [RRR ERM E AER E TREATIES | J*** Trozo de cédigo mostrando la iniciacion e wees s*** invocacién de la llamada del sistema connect(). wey [RARER NR eR RR ERE R ORT E AENEAN E ERE] define PORT_TIME 13 struct sockaddr_in dest; char *host = "127.0.0.1"; int sd; /**** Crear el socket y hacer otro trabajo. ****/ bzero(&dest, sizeof(dest)); /* Comenzar con una pizarra limpia. *! (continua) Listado 1.2 _Ejemplo de connect() (continuacién) dest.sin_family = AF_INET; /* Seleccionar la red deseada. */ dest.sin_port = htons(PORT_TIME); /* Seleccionar el puerto. */ inet_aton(host, &dest.sin_addr); {* Direccién remota, */ if ( connect(sd, &dest, sizeof(dest)) { ®@) /* iConectar! */ perror( "Socket connection"); abort (); En este cédigo, la llamada del sistema connect() requiere de varios pasos prepa- ratorios antes de que se conecte el socket al servidor. Primero, crear una estructura sockaddr_in. Utilizar la direccién del servidor para la segunda linea. Si se desea conectar a un servidor diferente, coloque la direccién IP apropiada en esta cadena. El programa prosigue con otras iniciaciones, incluyendo la llamada del sistema soc- ket(). Cuando comienza el funcionamiento con la estructura, se pone a cero con la funcién bzero(). El programa establece a familia a AF_INET. Luego, el programa establece el puerto y la direccién IP. Las herramientas de transformacién htons() y inet_aton() utilizadas aqui se tratardn en el Capitulo 2. La siguiente Hamada es la conexién al servidor. Se debe observar que el frag- mento de cédigo comprueba los valores devueltos para cada llamada de procedi- miento. Esta politica es una de las muchas claves para la tealizacién de programas de red robustos. Después de que el programa establezca la conexion, el descriptor del socket, sd, se convierte en un canal de lectura/escritura entre los dos programas. Muchos ser- vidores a los que estamos acostumbrados ofrecen transacciones individuales y lue- go cortan la comunicacién (por ejemplo, un servidor HTTP 1.0 envia el archivo pedido y luego cierra la conexidn), Para interactuar con estos tipos de servidor, los programas tienen que enviar la consulta, obtener la respuesta y cerrar la conexién. Obtencién de la respuesta del servidor Ei socket se abre y el canal se establece. Ahora, se puede obtener el primer “hola”. Algunos servidores inician la conversacién como la persona responde al teléfono. Una vez que la conexién esta abierta, se puede utilizar la biblioteca estan- dar de llamadas de E/S de bajo nivel para la comunicacién. He aqui la Hamada del sistema read(): #include ssize_t read(int fd, void “buf, size_t count); Probablemente se encuentra familiarizado con esta llamada. Aparte de su capa- cidad especial para utilizar el descriptor socket (sd) en lugar del descriptor de archi- vo (fd), todo lo demas es aproximadamente lo mismo que la lectura de un archivo. Puede incluso utilizar la llamada del sistema read() como en el siguiente fragmento de cédigo: int sd, bytes_read; sd = socket(PF_INET, SOCK STREAM, 0}; /* Crear el socket. */ i**** Conectar al host ****/ bytes_read = read(sd, buffer, MAXBUF); /* Leer el mensaje. */ if ( bytes_read < @ } f* Informar del error de la conexién; rutina de salida. */ De hecho, se puede transformar el descriptor de socket a un FILE* para E/S de nivel bajo. Por ejemplo, para utilizar fscanf(), puede seguir el ejemplo de abajo. (Las lineas en negrita indican los cambios del listado previo.) char Name[NAME], Address[ADDRESS], Phone[ PHONE]; FILE “sp; int sd; sd = socket(PF_INET, SOCK_STREAN, 0); y* Crear el socket. */ y**** Conectar al host ****/ if ( (sp = fdopen(sd, *r")) == NULL} /* Transformar @ FILE*. */ perror(*FILE* conversion failed"); else if ( fscanf(sp, “S*s, %*s, %*s\n", J* Utilizar como siempre. */ NAME, Name, ADDRESS, Address, PHONE, Phone) < @ ) perror(*FScanf"}; Unicamente los sockets de flujo se pueden transformar de forma fiable a un flujo FILE*, La razon es simple: los sockets de datagramas son normalmente sin conexién— un mensaje se envia y ya esta. También, los sockets de flujo ofrecen integridad de datos y fiabilidad del mensaje, mientras que los datagramas son poco fiables. Los datagramas son similares a la colocacién de un mensaje en un sobre con destino y sello que se envia a través del sistema postal: el mensaje puede no llegar en absolu- to. Una conexién FILE* debe ser un canal abierto, Si intenta transformar un datagra- ma, puede perder datos criticos. En el Capitulo 3 “Distintos tipos de paquetes de Internet”, se puede obtener mas informacién de flujos contra datagramas. Las conexiones de socket FILE* ofrecen recursos excelentes de busqueda y de andlisis gramatical para el programador de red. Sin embargo, cuando se utilizan, se deben comprobar todos los valores devueltos, incluyendo *printf() y *scanf(). Se debe observar en el ejemplo anterior: si el valor devuelto de fscanf() es menor que cero, habia un error. SEGURIDAD Y FIABILIDAD DE LA RED La seguridad y fiabilidad son de extrema importancia cuando se crean los progra- mas de red. En el momento de la escritura de este libro, los sistemas operatives Microsoft han afrontado varios problemas de seguridad fundamentales, algunos involucrados con las conexiones de red. Cuando se escriben programas, hay que asegurarse que los buffers no se puedan desbordar y que todos os valores devueltos se comprueben. En un software de configuracién de bazar, se puede solicitar la entrada de otros en el cédigo fuente. La revision del punto de este software bazar es un recurso inmenso de conocimiento y experiencia—utilicelo. Con la llamada del sistema read(}, se pueden obtener cualquiera de los siguien- tes errores: * EAGAIN. Una E/S no bloqueada esta seleccionada, y no existen datos dispo- nibles. Este error indica al programa que intente la liamada de nuevo. * EBADF. fd no es un descriptor de archivo valido o no esta abierto para lectu- ra. Esto puede ocurrir si la llamada del socket no tuvo éxito o el programa cerré el canal de entrada (creandolo de sdlo escritura). * EINVAL. fd se ha conectado a un objeto que ¢s inadecuado para la lectura. La Hamada del sistema read() no ofrece un control especial sobre la forma en que utiliza el socket. Linux ofrece otra Hamada del sistema estandar, recv(). Se pue- de utilizar directamente recv() con el descriptor de socket para obtener la informa- cidn mientras ofrece mas control: #include #include int recv(int sd, void "buf, int len, unsigned int flags); La llamada recv() sélo se diferencia de la Hamada read() en las sefializaciones. Las sefializaciones dan un mayor control sobre el qué obtener, e incluso ofrece con- trol de flujo. Estos valores pueden agruparse con el operador O (FLAG1 | FLAGZ | Dentro de cireuinstancias normales, el pardmetro se establece a cero. Podria pre- guntarse por qué no se utiliza la Hamada del sistema read() cuando las sefializacio- nes son cero, ya que en este caso no se diferencian en nada. Como sugerencia, utili- ce recu() en lugar de read()—esto puede ayudarle mas adelante cuando el programa se hace més complejo. También, generalmente hablando, es mejor utilizar un conjunto de herramientas que herramientas mezcladas, Finalizando, read() com- prueba que tipo de descriptor de E/S envié y ejecuta la llamada del sistema mas apropiada. He aqui las sefializaciones mas usuales que se pueden utilizar para controlar la Hamada del sistema recv(). Se puede encontrar un listado mas completo en el Apén- dice B, “API de red”. © MSG_OOB. Se procesan los datos fuera de banda. Se usa en los mensajes de alta prioridad. Algunos protocolos permiten elegir entre una prioridad nor- mal 9 alta cuando se envia un mensaje. Se establece esta sefializacién para indicar al administrador de cola que busque y devuelva los mensajes fuera de banda en vez de los datos normales. Se puede ver el Capitulo 10 para obtener mayor informacion. * MSG_PEEK. Se lee de forma no destructiva. Se utiliza para indicar al adminis- trador de cola que lea de la cola de mensajes sin mover el puntero de indice de lectura. (En otras palabras, una lectura posterior produce al menos los mismos datos cada vez. Mire la caja de texto en la proxima pagina.) * MSG_WAITALL. Se utiliza para que no devuelva el mensaje hasta que el buffer suministrado esté completo. Algunas veces se obtiene un buffer semilleno, porque el resto de los datos estan en trénsito. Si conoce cuanta informa esta enviando el servidor y no desea recomponerla, utilice esta senalizacion para terminar de rellenar el buffer (o esperar indefinidamente}. « =MSG_DONTWAIT. Se utiliza para que el mensaje no se bloquce si la cola esta vacia. Es similar al establecimiento de la caracteristica de no bloqueo en el socket, tinico requisito de esta opcion en esta Hamada del sistema recv() exclusivamente. Normalmente, si no existen datos de mensaje disponibles, el proceso espera (se bloquea) hasta que leguen algunos datos. Si se utiliza esta sefalizacin y la cola no tiene datos disponibles a la hora de la llamada, la Ila- mada del sistema devuelve un cédigo de error EWOULDBLOCK inmediata- mente. (Linux no soporta actualmente esta opcién en la Iamada recv(). Se puede utilizar O_NOBLOCK con la llamada del sistema fentlQ. Esto hace que el socket no se bloquee indefinidamente.) OBTENCION DE PAQUETES FRAEMENTABOS Los programas se ejecutan mucho més rapido que las redes. Algunas veces un paquete llega a la computadora en trozos, porque los routers de red lo fragmen- tan para adaptarlo a las limitaciones de la red. Si se llama a recv() cuando esto ocurre, se puede obtener un mensaje incompleto. Esta es la razon de por qué MSG. PEEK puede dar diferentes resultados en Hlamadas consecutivas: la primera llamada puede dar 500 bytes y la segunda puede ser de 750 bytes. Asimismo, ésta es la razén de por qué existe una sefializacion MSG_WAITALL. La Mamada del sistema recv() es mas flexible que read(), permitiendo el uso de distintas sefializaciones para modificar su comportamiento. Para realizar una lectu- ra normal desde un canal de socket (equivalente a read()), haga lo que se indica a continuacion: int bytes_read; bytes_read = recv(sd, buffer, MAXBUF, @); Para leer de forma no destructiva desde el canal de socket, haga lo siguiente: int bytes_read; bytes_read = recv(sd, buffer, MAXBUF, MS@_PEEK) ; Para leer de forma no destructiva los datos fuera de banda del socket, haga lo siguiente: int bytes_read; bytes_read = reov(sd, buffer, MAXBUF, MSG_OOB | MSG_PEEK); El primer ejemplo obtiene la informacién del servidor proporcionando un buffer, un tamafio y ninguna sefalizacién. El segundo ejemplo muestra la informacién. Existe un flujo intencionado aqui: ,qué ocurre si el servidor envia més informacién que la que pueda aceptar el buffer? No es un error critico; nada fallara. El algoritmo puede simplemente perder los datos que no se lean. La llamada del sistema recv() produce cédigos de error similares a read(}, y adi- cionalmente los cédigos siguientes: « ENOTCONN. sd no esta conectado. El descriptor de socket proporcionado no esta conectado a otro equipo homélogo 0 al servidor. * ENOTSOCK. sd noes un socket. El descriptor de socket proporcionado no tic- ne la firma que indica que viene de una llamada del sistema socket() Se debe observar que si se utiliza la Ilamada del sistema read() con un descriptor de socket se pueden obtener atin estos cédigos de error, debido a que read() ejecuta internamente a la llamada recv(). Cierre de la conexién Una vez que se obtuvo la informacion que necesitaba del servidor y que todo se realizé bien, se debe cerrar la conexién. De nuevo, existen dos formas para poder cerrar la conexién. Muchos programas utilizan la llamada del sistema close() de la E/S estandar: #include int close(int fd); Una vez mas, el descriptor de socket (sd) se puede substituir por el descriptor de archivo (fd), funciona igual. Si se ejecuta con éxito, el valor devuelto es cero. Esta llamada produce un s6lo error: * EBADF. fd no es un descriptor de archivo valido. SIEMPRE HAY QUE CERRAR DESCRIPTORES DE SOCKET — = Siempre se deben cerrar manualmente los descriptores, particularmente los sockets. Por omisidn, el sistema operativo cierra todos los descriptores y vacia los buffers. Si el descriptor hace referencia a un archivo, el proceso funciona sin afec- tar a otros sistemas. Los sockets, por el contrario, pueden tardar mas de lo nece- sario, bloqueando recursos y haciendo la conexién dificil a otros clientes. La Hamada del sistema shutdown() da mayor control del cierre de canales, por- que se puede cerrar cualquier canal entrante o saliente. Esta llamada es especial- mente titil cuando se utilizan sockets para reemplazar a stdin o stdout. SOR be hee pe scum CONFUSION EN LSS COMANDOS DE-CERRE: La llamada del sistema shutdown) es distinta al comando shutdown (seccién 8 de los manuales en linea de UNIX) para cerrar el sistema operativo. Con la llamada del sistema shutdown(), se puede cerrar cualquier direccién de flujo de datos de! canal de comunicacién, estableciendo el camino de sdlo lectura o s6lo escritura: #include int shutdown(int s, int how); El parametro how puede tener tres valores: valor Funcién 0 (cero) Sélo escritura (pensar en “O" de “output”). 1 (uno) Sélo lectura (pensar en “T” de “input”). 2 Cerrar la entrada y la salida. Resumen: g¢qué ocurre entre bastidores? Varias cosas ocurren entre bastidores cuando el programa abre un socket y se conecta a un servidor TCP. Lo tinico que realiza la llamada socket es crear una cola de mensajes. Realmente, ocurren més cosas cuando el programa se conecta. (Se pue- de obtener un listado del programa completo en el CD adjunto,) La Tabla 1.2 mues- tra lo que ocurre en la parte del cliente y del servidor. Es bastante para una llamada connect() simple. Este proceso se puede complicar mucho mas, especialmente entre los equipos de encaminamiento (como la adminis- traci6n de encaminamiento, verificacién de paquetes, fragmentacion y defragmen- tacién, conversién de protocolos, tunneling, etc.). La API de Socket simplifica consi- derablemente Ia comunicacién de red. Tabla 1.2 Pasos para la creacion y conexion de un socket Acciones del cliente Acciones del servidor 1, Llama a socket(): crea una cola (Esperando una conexién) y establece las senalizaciones para los protocolos de la comunicacién. 2. Llama a connect(): el sistema (Esperando) operative asigna un ntimero de puerto temporal si el socket no tiene un niimero de puerto. asignado a través de bind. 3. Envia un mensaje al servidor solicitando una conexién, indicando qué numero de puerto esté usando. (Esperando al servidor) 4. Coloca la peticién de conexién en la cola de escucha. (Esperando) 5. Lee la cola de conexidn, acepta la conexign y crea un canal de socket individual. (Esperando) 6. Algunas veces, crea una tarea o thread tinico para interactuar con el programa. (sperando) 7. Envia de regreso una confirmacién de que la conexi6n es aceptada. Envia un mensaje al puerto 0 espera una consulta del programa. El servidor puede cerrar el canal después del envio de los datos, si ofrece un mensaje de boletin simple (como la hora actual) 8. Empieza la correspondencia de los datos. La red requiere un lenguaje y algoritmo muy particulares con objeto de estable- cer una conexién. Ante todo, con la Hamada del sistema socket() se inicia el roda- miento del balén con la creacién del auricular del teléfono, Este auricular permite a un programa enviar y recibir mensajes si esta conectado. El programa puede utili- zar las funciones normales read() y writeQ como se usan en los canales y descripto- res de archivo. Alternativamente, se pueden utilizar las Iamadas del sistema mas especializadas como recv(). La red IP tiene varias caracterfsticas que necesitan de una mayor explicaci6n. En el préximo capitulo se trata la numeracién IP, los puertos y la ordenacién de bytes. ‘También se explican hetramientas muy utiles para transformar la informacién, sim- plificando los esfuerzos de programacién. Capitulo II Elocuencia del lenguaje de red TCP/IP En este capitulo Generalidades de la numeracién IP 25 Neimeros de puertos de host IP 32 Ordenacién de bytes de red 34 Diferentes clases de sockaddr 41 Canales con nombre de UNIX 42 Resumen: aplicacion de herramientas y numeracion IP 43 Cuando se trabaja con Internet se necesita conocer como dirigir los mensajes con cl fin de que leguen correctamente. La direccion es una parte importante de la crea- Gién de un mensaje. Como en el teléfono, una computadora debe tener una direc- cién o ID para que pueda obtener los mensajes correctos y otras computadoras puedan dirigir el tréfico como corresponda. En el capitulo anterior se introdujo el concepto el socket. En este capitulo se amplia el tema con la API de Socket. Primero se trata el sistema de numeracién IP, de cémo el encaminamiento funciona en un nivel abstracto, los formatos binarios correctos y diferentes tipos de socket. Generalidades de la numeracién IP La numeracién IP utiliza una direccién de longitud fija. Esta restriccin requirié una gran planificacién cuando se dise’é el protocolo. El protocolo ofrecié solucio- nes a varias cuestiones durante su época de vida: identificacién de computadoras, organizacién de red, encaminamiento y resolucion de direcciones. Ahora afronta cuestiones nuevas como el crecimiento explosivo y la pérdida de direcciones. Identificacién de la computadora Las redes implican la comparticién de un unico recurso (el cable de red) con varias computadaras. Debido a que toda esa informacion podria fluir en un medio de red, cada computadora debe aceptar la informacién. Sin embargo, si cada com- putadora de nuestra red se Ilamara Bert o Ernie, otros hosts no serian capaces de determinar el destino real. Cada computadora de red necesita una unica identifica- cién (ID). Pero eso no es todo. COMO AFRONTAR LA COLISION DE DIRECCION -——_- Una estacién de trabajo no trabaja bien con la red cuando comparte una direc- cidn (colisién de red). Alguien que haya intentado localizar una colision de red puede confirmar que es bastante duro arreglarlo, Es atin peor cuando una de las, computadoras esta utilizando alguna asignacién de direccién dinamica (como DHCP). La forma més obvia (y laboriosa) de resolver este problema es mirar cada computadora del lugar. Las redes son dindmicas y tienden a aumentar en complejidad. La computadora tiene que ser localizable fécilmente por su ID tanto como se amplie la red. Toda informaci6n colocada en la red consume una porcién de ese valioso recurso, asi que cualquier informacién innecesaria no se deberia incluir en el mensaje. Algunos sistemas en red incluyen un mapa de rutas en ¢l mensaje. Cada servi- dor de la lista coge el mensaje y lo pasa al siguiente servidor. Este método reduce el rendimiento de Ia red al descender el porcentaje de los datos reales con la cabecera. Si se codifica la direccién del destino en la propia direccién, el mapa de rutas es innecesario. Las computadoras de red conectadas tienen todavia un tnico ID llamado Con- trol de acceso al medio (MAC); un ejemplo es el ID ethernet. La computadora utiliza este ID para arrancar en red (sistemas sin disco que s6lo tienen memoria RAM y todo el almacenamiento esté en el servidor). FE] 1D ethernet tiene seis bytes de tama- fio, y usualmente lo veremos escrito en hexadecimal: 00:20:45:FE:A9:0B. Cada tarje- ta ethernet tiene uno y es unico. Desafortunadamente, no se puede utilizar ese ID para identificar a la computa- dora exclusivamente. Tiene dos problemas fundamentales. Primero, cada servidor de encaminamiento debe obtener cada ID de la red. La base de datos de los ID podria ser muy grande y reducir significativamente el tiempo de encaminamiento para cada mensaje. Segundo, todas las interfaces no tienen una MAC (PPP, por ejemplo). ELID de la computadora podria tener un mecanismo incorporado para el enca- minamiento del mensaje. Este mecanismo es como una direccién de una carta: de lo mas general a lo mas especifico. Los ID Internet resuelven los problemas de unici- dad mientras ofrecen indicadores para las cuestiones de encaminamiento. Una direccion IP tiene mas ventajas que una MAC. El ntimero puede cambiar (no es fijo), asf la implantacién de clusters consistentes de direcciones es més facil, y Jos equipos portatiles no se encuentran con problemas. La red puede asignar la IP a la MAC utilizando el Procolo de resolucién de direcciones (ARP). Véase la RFC 826 en el CD-ROM adjunto. essen quam npn sr pe EO" DE DIRECCIONES (ARP) ARP es una tabla de traduccién simple que asigna a una IP su MAC asociada. Todos los mensajes de la red deben tener una MAC para que el adaptador (0 los controladores) puedan recoger el mensaje. El origen puede desconocer la MAC del host destinatario, el cual se puede ocultar detras de varios routers. El router mas bien envia el mensaje a los routers que controlan tas subredes definidas en la direccién IP del destinatario. Cuando el mensaje alcanza un router con ARP, éste comprueba las tablas. Si el router encuentra la direccién IP, la MAC del paquete consigue el destino correcto. En otro caso, el router envia un mensaje de difusién a la subred para resolver la direccion IP. Organizacion del ID Internet EL ID Internet utiliza un esquema de direccionamiento de lo mas general a lo mis especifico. Cada ID es un ntimero de cuatro bytes, como el ID ethernet. El pri- mer ntimero, leyendo de izquierda a derecha, es la clase de red. Observe la Figu- ra2.1. La direccidn IP acta como un mapa de carreteras para los routers. Cada parte de la direccién ofrece una informacién mas especifica sobre dénde se encuentra ¢l destino. Comienza con la clase de red y termina con el mimero de host. Puede com- pararlo facilmente a ta direccion de una carta: la primera linea es el destinatario, luego la calle o apartado de correos. E! detalie se reduce en la direcci6n hasta el esta- do o pais. Clase do red rm 26.188.15.21 Ce FIGURA 2.1 La direccion IP tiene varios componentes que identifican la dimensién de la red. El direccionamiento de Internet tiene cinco clases basicas de direcciones. Cada clase es un conjunto de asignaciones de red con distinta dimensién. El plan de direccionamiento de Internet se encuentra organizado para que las empresas pue- dan comprar segmentos del espacio de direcciones. Las clases estan etiquetadas de la AalaE: Clase Direccion Rango de direcciones, descripcion 0.0.0.0 a 0.255.255.255 (Reservadas) A 1.0.0.0 a 126.255.255.255 234.2 6 16.777.214 de nodos por cada asignacion de segmento. Esta clase tiene 126 segmentos. Utilizadas en organizaciones grandisimas que dividen la red en subredes como se necesite, como por ejemplo un proveedor de servicio de Internet (ISP). 127.0.0.0.a 127.255.255.255 (Reservadas para la interfaz de loopback). B 128.XXX.0.0 a 191.XXX.255.255 216-2 6 65.534 nodos para cada asignacién de segmento. Esta clase tiene 64*256 segmentos disponibles. Utilizadas en organizaciones grandes como empresas y universidades. Se pueden crear subredes. La XXX es la subred asignada (por ejemplo, 129.5.0.0 es una red asignada). Nota: Este espacio de direcciones se encuentra poco utilizado. Clase Direccién Rango de direcciones, descripcion Cc 192.XXX.XXX.0 a 223.XXX.XXX.255 28-2 6 254 nodos por cada asignacion de segmento. Esta clase tiene 32%65.536 segmentos disponibles. Utilizadas en empresas pequeiias o por particulares. La direccién tiene varios espacios disponibles. D 224.0.0.0a 239.255.255.255 228.2 6 268.435.454 nodos. Estas direcciones no se encuentran asignadas pero se reservan para direcciones de multidifusion. om 240.0.0.0 a 255.255.255.255 28-2 6 268,435,454 nados. Estas estan reservadas para un uso futuro. Se debe observar que 255.255.255.255 es una direccién IP de difusi6n general. Nunea es una direccién valida Las clases de red se encuentran numeradas de forma peculiar, porque el direc- cionamiento utiliza los primeros bits de la direccién para determinar la clase. Por ejemplo, fa red de Clase A tiene un cero en el primer bit de la direccién. De igual modo, la Clase B tiene un uno en el primer bit y un cero en el segundo: Clase A: 0 (0000,0000) a 126 (0111,1110). Clase B: 128 (1000,0000) a 191 (10111111). Clase C: 192 (1100,0000) a 223 (1101,1111). Clase D: 224 (1110,0000) a 239 (1110,1111). Clase E; 240 (1111,0000) a 255 (11111111). Con el uso de esta estrategia, los routers pucden répidamente determinar (con cuatro bits) como encaminar el mensaje. Hoy en dia, se encamina mejor utilizando el encaminamiento de dominio de Internet sin clase (CIDR). Estas definiciones nue- vas (localizadas en las RFC 1517-1519) identifican la localizacién y el camino de un Aost utilizando los bits superiores de la direccion. Con el protocolo IP se introdujo este esquema de numeracién para la identifica- cién de la computadora y sus agrupaciones de forma eficiente. Con esto, un router puede determinar rapidamente si intercepta un paquete o lo mueve a la interfaz que conduce a la subred de destino. La propagacion es muy importante: simple recepcién de un paquete, se comprueba y se pasa si no se acepta. Cada bit que el router acepta significa un retardo en la red. El router no deber retardar mas bits que Jos necesarios para determinar la relevancia del mensaje. En otras palabras, no debe haber retardos. Por ejemplo, la conmutacién de teléfono normal en los Estados Uni- dos de América no intenta resolver el ntimero telefénico completo; los primeros tres digitos indican un rea o region, y los siguientes tres digitos indican la estacion. Mascaras de subredes Algunas de las clases necesitan mas filtrado que otras. Una red con 16 millones de nodos es excesiva si todos se encuentran agrupados en un Unico espacio. Como uno mismo se configura la computadora Linux y la red, puede haber observado el término mascara de subred. La liegada de CIDR ha simplificado la complejidad de grandes subredes [RFC950]. La mascara de subred se especifica para identificar el grupo de direcciones conti- guas que una interfaz puede alcanzar cn una red. Con esto se obtiene un filtro adi- cional que permite a ciertos mensajes especificos pasar de un lado a otro. Cuando un mensaje Hega, el router utiliza la mascara de subred en fa direccién de destino del mensaje. Si coincide, el router deja pasar el mensaje. Puede construir mascaras de la forma que desee, pero el conjunto de bits menos significativo especifica la subred. Por ejemplo, si tenia una red pequefia de ocho maquinas, y previé que el grupo creciera no mas de cinco maquinas, podria establecer la mascara de subred del rou- tera 187.35.209.176. El tiltimo bit en la direccién esta en 176 (1901,0000). El rango de direcciones estd en la parte 'X’ (subred activa) de 1101,XXXX. A partir de aqui, puede repartir las direcciones: 187.35.209.176 (router), 187.35.209.177 (host numero 1), hasta la 187.35.209.232. Puede tener cualquier combinacién, pero el bit del conjunto menos significativo es ei marcador. MASCARAS DE SUBRED Y DIRECCIONES POR OMISION Alusar la mascara de red como una direccin host puede causar conflicto y pérdi- da de paquetes. Esto es debido a la direccién especial 0 (cero). El ejemplo, 187.35.209.0, tiene los ultimos ocho bits a cero. Si la direccion se corresponde con la mascara de red, esa es la direccién cero. Deberia siempre reservar la direccion cero para la direccién de red de la mascara. Asimismo, puede haber observado que el ejemplo omite 187.35.209.223. Si fuera a usar ese ID, ese host nunca podra ver un mensaje. E} numero 223 tiene la subred activa todos a unos: 1101,1111. Esta es una direccién de difusion. No deberia usar ésa como una direccién de host. En muchos casos no necesita preocuparse de cémo configurar routers, la confi- guracidn esté mds alld del Ambito de este libro. Normalmente, cuando observa ta mascara de subred en la configuracién de red, puede aceptar la mascara que el script le ofrece. Routers y resolucién de direcciones Las redes de drea local (LAN) pueden Ilegar a estar muy sobrecargadas por todos los mensajes entre los hosts. Cada computadora en Internet podria potencial- mente escuchar cada mensaje. Pero con todo el trafico, las redes son muy confusas, los paquetes colisionan con otros (en transmisiones simultaneas), y el rendimiento cae cercano a cero. Las LAN utilizan el direccionamiento y las submascaras para limitar el trafico dentro de grupos (0 clusters) de computadoras. Mas alla del paso de mensajes a las interfaces apropiadas, los routers actéan como puertas de control de informacién. El trafico local permanece dentro del cluster, y el tréfico externo pasa de un lado a otro. Los hosts utilizan la mascara de subred para determinar si tiene que pasar un mensaje al router. Todos los mensajes destinados al exterior pasan a través del rou- ter, y los mensajes locales permanecen dentro de la subred. Este proceso reduce la congestion en el backbone de la red. Los routers también dirigen los mensajes hacia el destino utilizando sus tablas de rutas. Cada router indica a otros routers de la red cuales son sus rutas de red para que le envien los mensajes que pueda encaminar correctamente. Las redes de drea ancha (WAN) utilizan esta caracteristica para enviar mensajes. Cada router a lo largo del camino entre el origen y el destino mira en la direccién IP, comparando las redes con las tablas de rutas. Los routers trasladan el mensaje cada vez mas hacia un destino especifico. El primer salto intenta resolverlo en el cluster, el segundo traslada el mensaje para resolverlo en la subred, asi sucesiva- mente, hasta que se resuelve la clase. Tan pronto como el router encuentra una correspondencia (general o especifica), traslada el mensaje en esa direccién, utilizando la direccién MAC para enviar el mensaje al siguiente router. Eventualmente el cluster correspondido obtiene el men- saje, y el ARP del router reemplaza su MAC con la MAC del destino. Un adaptador de red ethernet acepta unicamente mensajes con su ID, En cuanto el host se inicia y estabiliza, comunica a todos los de la red su ID ethernet y su direc- cién IP. Esta es la funcién de ARP, como mencionamos anteriormente. Direcciones desaprovechadas y especiales Como mencionamos antes, existen algunas direcciones reservadas. La subred activa de un mascara de subred tiene dos direcciones reservadas: todo a cero (direc- cién de red) y todo a uno (direccién de difusién). Significa que cuando cuenta las direcciones que tiene en su disposicién, debe restar 2 a ese niimero. Considere esto: si crea 100 subredes, pierde efectivamente 200 direcciones. Esta pérdida es justo al principio. Dos grandes bloques de direcciones estén reservadas para uso interno: del 0.0.0.0 al 0.255.255.255 y del 127.0.0.0 al 127.255.255.255. El primer grupo de direcciones significa “esta red” en nomencla- tura [P (véase la nota sombreada a continuacién). Si tiene una direccién de la red 128.187.0.0, usando el valor 0.0.25.31 en el mensaje resulta 128.187.25.31, implici- tamente. En 1992, el Comité de arquitectura de Internet (IAB—véase la RFC 1160 para el discho, ingenieria y administracién de Internet), llegé a estar muy preocupado con cl crecimiento explosivo de Internet—incluso con todas las técnicas de direcciona- miento y planificacién esmeradas. La adjudicacién de direcciones sobrepasé los 450 millones de nodos. El comité vio que el incremento en las asignaciones acabaria con el espacio de direcciones disponibles. Sin embargo, sélo el 2% de las asignaciones fueron realmente utilizadas. ;Dénde estaban el resto de todas las direcciones? IAB asigna rangos de direcciones a compaitias en bloques enteros. Las compafias, anticipndose a usos adicionales y con el fin de mantener sus direcciones lo més contiguas posible, compraban rangos muy superiores a sus necesidades reales. fNFEA DE ASHENACIONES® En un lugar pequefio donde trabajé me mostraron su asignacion de 128 direccio- nes; sdlo 30 estaban en uso a la vez. Me asignaron 10 unidades. Nunca utilice mas de 2. A dia de hoy, creo que aquelias direcciones pueden seguir asignadas a mi, aunque dejé la compajiia hace cuatro afios. En todo, las excepciones de direccién y las asignaciones desperdiciadas han comido la mayor parte del espacio de direcciones, Estimaciones recientes indican que las redes de Clase B y C estén completas. Los ISP estan utilizando més de clase ‘A. Dentro de poco tiempo, la demanda puede utilizar todas las direcciones. 2Qué va hacer Internet con el espacio de direcciones perdido? ¢Cémo pucde el direccionamiento IP actual utilizarse mejor? LAB, ahora llamado Internet corpora- tion for assigned names and numbers (ICANN), no puede reclamar facilmente las unidades inutilizadas vendidas a las compaitias, porque los departamentos IT de las compaitias han ya asignado esas direcciones dentro de la organizacién. Muchas compaiias ahora utilizan Dynamic host contiguration protocol (DHCP) IRFC2131], lo cual asigna una direccién IP una vez iniciado. El host no posee una direccién IP de forma fija. DHCP ayuda también con la seguridad: los crackers de computadoras adoran las direcciones IP fijas. Si recuerda, bootp envia un men- saje de difusion para encontrar un servidor bootp. Cuando se encuentra, el servidor emite una direccién IP, De forma similar, un host normal carga su generador de peticiones durante el inicio. El generador de peticiones envia un mensaje de difu- sién para encontrar un servidor DHCP activo. Cuando lo encuentra, el servidor asigna una direccién de su grupo de direcciones disponibles y se la pasa (junto con la mascara de red apropiada) al generador de peticiones. El generador de peticiones DHCP acepta la informacién y configura los protoco- los de red del host local. En algunos casos esto puede llevar varios segundos, debi- do a la congestion de la red. Hasta que el host local es configurado correctamente, puede sufrir de amnesia IP (el host no conoce su propia direccién). Lele Ben sanauion sea nagiresaes Ses We AMNESTA “HOST © TP La amnesia de host o IP también sucede cuando el nombre de la red y el host no estén correctamente configurados, Puede ser un problema serio. Hasta ejecutar un ping 127.0.0.1 puede no funcionar. Si el host tiene amnesia, compruebe la dis- tribucién, La distribucién RedHat (y derivados) utiliza /etc/sysconfig/network y Jetdsysconfiginetwork-scripts/ifetg-* para definir y establecer los valores. Otra solucién es prolongar el tamaiio de la direccién IP. Introduciendo: iIPv6 IRFC2460]! IPv6 en resumidas cuentas es cuatro veces el tamaiio de una direccién IP: 128 bits contra 32 bits. [Pv6 también cambié la apariencia de forma dramética: 8008:4523:FOE1:23:830:CF09:1;:385 El resultado es una direccién dificil de recordar. La ventaja principal de IPv6 es que tiene el espacio de direcciones mas grande para trabajar. Con més de 3x1038 direcciones elimina probablemente cualquier pro- blema de limitaciones de direcciones por muchisimo tiempo. Para obtener mas informacién véase el Capitulo 17, “Cémo compartir mensajes con multidifusién, difusién y Mbone’. Numeros de puertos de host IP Todos los mensajes legan a una o més direcciones reconocidas. $i un programa acepta estos mensajes, puede recibir informacion destinada para otros programas en ejecucién. El sistema operativo tiene poca consideracién hacia dénde se dirige el mensaje, con tal de que se entregue. La pila TCP/IP afiade el concepto de puerto. Un sistema puede tener varios puertos disponibles, todos asociados con la misma direccién. La pila TCP/IP afade los puertos para abstraer la red y facilitar la programa- . Estos no son puertos fisicos reales. Son canales que el subsistema de red utiliza para redireccionar la informacién al programa apropiado. Todos los programas de red no reciben todos los mensajes que llegan; sino que sélo reciben los mensajes de su puerto. En la red basada en Internet, cada paquete peculiar de datos IP tiene la direccién del host y el mimero de puerto. Cuando un paquete llega de la red, un campo de 16 bits en la cabecera del paquete indica el ntimero de puerto de destino. El sistema operativo lee este campo y coloca el paquete nuevo en la cola de puertos. Desde alli, el programa lee el socket (con la llamada del sistema read() 0 recv()). Asimismo, cuando el programa transmite un mensaje (mediante la llamada del sistema write() © send0), el sistema operativo coloca los datos en la cola saliente del puerto. Por omisién, s6lo un programa posee un puerto. De hecho, si se intenta ejecutar dos programas que asignan el mismo numero de puerto en la misma computadora, Ja Hamada del sistema devuelve un cédigo de error EINVAL. Se puede compartir un puerto utilizando SO_REUSEADDR (véase el Capitulo 9, “Como romper las barreras del rendimiento”). COMO COMPARTIR PUERTOS EN SMP La regla de que dos sockets no pueden compartir el mismo puerto se aplica tam- bién a los procesadores simétricos. La razén es simple: los procesadores, como recursos, comparten la memoria y el sistema operativo. Si se tienen dos sistemas operativos funcionando, se pueden tener tedricamente dos sockets en programas separados en ejecucion con el mismo numero de puerto, con tal de que estos resi- dan en diferentes espacios del sistema operativo. Todos los servicios estandar tienen asignados mimeros de puerto. Se puede ver la lista completa en /ete/services, en el Apéndice A, “Tablas de datos”, y en la esta- cién de trabajo Linux. A continuacién se muestran unos pocos puertos ésténdar: Puerto _ Nombre del servicio, alias Descripcion 1 tepmux ‘Multiplexor del servicio de puertos TCP. 7 echo Servidor eco. 9 discard Como /dev/null. 13 daytime Fecha y hora del sistema, 20 ftp-data Puerto de datos FTP. 2 ftp Conexién FTP principal. 2 telnet Conexién Telnet, 25 smtp, mail Correo UNIX 9 time, timeserver Servidor de hora. 2 nameserver Resolucion de nombres (DNS). 70 gopher Informacién con memis de texto. 79 finger Usuarios actuales. 80 www, http Servidor web. Se puede encontrar una lista mas completa en el Apéndice A. Probablemente reconozca algunos de estos servicios. El formato del archivo es legible: numero de puerto, nombre de servicio, alias y descripcidn. Puede interac- tuar con muchos de ellos usando Telnet o e] programa mostrado anteriormente. ‘Tenga presente que, aunque /etd/services puede incluir un servidor, la computadora puede que no tenga el servidor asociado ejecutandose (por ejemplo, la distribucién Mandrake no habilita los servicios de hora). Todos los puertos incluidos en el archi- vo fetc/services estan reservados, por lo que su uso puede causar conflictos. Fl programa basado en sockets utiliza algunos puertos locales para toda la comunicacién: esto es responsabilidad elemental de bind). Aunque no se utilice la Hamada del sistema bind0, ya que el programa utiliza el socket para cualquier E/S, el sistema operative asigna un puerto local disponible al socket. Como parte de /a seguridad del nticleo, ios puertos con valor menor a 1024 requiere acceso de root o privilegiado. Por ejemplo, si desea crear un servidor de hora (puerto 13), el usuario root debe de ejecutar el programa (o con SUID de root). SUID es un acronime de “Set user ID” (establece el D de! usuario). Cada Programa en el sistema de archivos puede permitir a los usuarios que lo ejecuten como si el propietario del programa lo hiciera. Normalmente, cuando un usuario ejecuta un programa, este programa tiene los mismos permisos del usuario. Algu- nas veces el programa necesita permisos diferentes o adicionales. Al cambiar el identificador del usuario, el programa se puede ejecutar como si lo hiciera el pro- pietario. Por ejempio, /usr/bin/at necesita acceder a las tablas cron (propiedad del root). Para que esto ocurra, /ust/bin/at cambia automaticamente el acceso a root. Para obtener mas informacién, se puede consultar la documentacién del UNIX estandar. Precaucién: el SUID de root es una fuente potencial de riesgos de segu- ridad. Nunca se debe crear o establecer el SUID mientras se es root, a menos que se conozca el programa muy bien y se conozcan todos los riesgos. Como se ha advertido previamente, si no se realiza la asignacién de un puerto a un socket, el sistema operativo asigna uno autométicamente, Estos Ppuertos asigna- dos dinémicamente y automaticamente se Haman puertos efimeros. Linux parece seguir el estilo BSD en la asignacién de puertos: asigna los puertos efimeros a partir del puerto 1024. Al experimentar con diferentes puertos, se pueden sequir estas reglas simples: Ejecutar y depurar un programa como un usuario corriente (no como root). Usar puertos y direcciones que no afecten a otros o causen riesgos de seguridad. Registrar el origen de todos los mensajes entrantes. Ordenaci6n de bytes de red Muchos tipos distintos de computadoras pueden residir en una red, pero es posible que no utilicen el mismo procesador. Todos los procesadores no almacenan sus numeros binarios de la misma forma. Las computadoras usan dos tipos de almacenamiento de nuimeros binarios basicus: big-endian y little-endian. Simple- mente, los mtimeros big-endian se leen de izquierda a derecha; los némeros ittle-endian se leen de derecha a izquierda. Por ejemplo, considere el ntimero 214.259.635. En hexadecimal, el nimero se lee como #0CC557B3. Un procesador big-endian almacena este valor como sigue: Direccién: 00 @1 2 3 04 Datos: eo CS 57) og Se debe observar que el byte mas significative (OC) est listado primero. El pro- cesador little-endian lo almacena al revés: Direccion: 20 O 02 3 04 Datos: B3 57 cs ec aoe Se debe observar que el byte menos significativo (B3) esta listado primero. La utilidad de los distintos endianness es un asunto largo de debate. Aqui no se resucitan estas discusiones, sélo se apuntan los usos importantes y las diferencias. Por supuesto, zpor qué no se puede utilizar sencillamente ASCII hexadecimal? La representacién es ineficaz, doblando el ntimero de bytes que se necesitan. Para que las computadoras de una red heterogénea se comuniquen eficientemente, tienen que usar binario y deben establecer un endianness. El endianness de una computa- dora 0 host es el orden de bytes de host. De la misma forma, el endianness de una red se denomina orden de bytes de red. Fl orden de bytes de red es siempre big-endian. Uso de herramientas de transformaci6n de Internet Hace muchos aiios, se eligié que el protocolo de red entendiera big-endian. Esto es bueno para procesadores big-endian, pero zqué hay de los little-endian? Se dis- ponen de varias herramientas que ayudan a realizar la transformacién. Los progra- mas de red utifizan estas herramientas todo el tiempo para rellenar la estructura struct sockaddr_*, sin preocuparse del endianness del proceso. Ahora, otra dificul- tad: todos los campos de la estructura no estén ordenados en bytes de red. Algunos son ordenados en bytes de host. Considere el extracto de cédigo del Capitulo 1, “Recetario del cliente de red”: [AIR TE EEE REREAD R EERE i*** Ejemplo de herramientas de transformacién: ey J*** cémo rellenar sockaddr_in. weep [RRR ARR RR EAR AT RAE a ES struct sockaddr_in dest; char *dest_addr = "127.0.0.1 dest.sin_family = AF_INET; dest.sin_port = htons(13}); /* Puerto n?13 (servidor de hora). */ 1) if ( inet_aton(dest_addr, &dest.sin_addr) = El cédigo rellena tres campos: sin_family, sin_port y sin_addr. sin_family es un campo ordenado en bytes de host, asi que no necesita transformacién. Los otros dos estén ordenados en bytes de red. El campo sin_port de dos bytes transforma el puerto 13 utilizando htons(). Existen varias herramientas transformadoras como a continuacion: Llamada__Significado Descripcion htons De hosta red (short) Convierte 16 bits binarios a big-endian. hton! De hosta red (long) Convierte 32 bits binarios a big-endian. ntohs De red a host (short) Convierte 16 bits binarios a formato de host. ntohl De red a host (long) Convierte 32 bits binarios a formato de host. En el Apéndice B, “API de red”, se muestran estas funciones con mayor detalle. Es de interés, que la utilizacin de estas herramientas no consume ningun tiempo de CPU si la computadora es big-endian (orden en bytes de red). La siguiente llamada del ejemplo, inet_aton(), transforma la direccién IP ASCII (usando notacién punto) al binario equivalente. También se convierte a la ordena- cion de red (no se necesita llamar a htonl() en el resultado). A continuacién se muestran otras llamadas: Llamada Descripcion inet_aton() Transforma la notacién punto (###.###.#44.8##) al binario ordenado en red. Devuelve cero si falla y distinto de cero si la direccién es valida, inet_addr() Obsoleta (la misma que inet_aton). No gestiona los errores correctamente. Si acurre un error, devuclve -1 (255.255.255.255—la direccién de difusién general). inet_ntoaQ) Transforma un binario IP ordenado en red a un ASCII en notacién, punto decimal, gethostbyname() —_ Pregunta al servidor de nombres para transformar el nombre (como por ejemplo www.linux.org) a una e mas direcciones IP. getservbynameQ) —_Obtiene ef puerto v protocolo asociado a un servicio del archive fetdservices. Las bibliotecas ofrecen muchas mas herramientas de funcién que éstas. En este libro se trata sdlo unas pocas que se consideran utiles. Para obtener mas informa- cidn de estas lamadas de funcién, se puede consultar el Apéndice B. ALCANCE DE ‘EA TRANSPORTABIEIDAD Para quienes piensan que probablemente no tengan que preocuparse sobre estas herramientas de transformacién, deben considerar esto: la idea global del des- arrollo del software Linux es realizarlo compatible con todos los sistemas, (es correcto? Al usar esas llamadas no se hace dafio a nada a pesar de la plataforma. Generalmente, es una buena practica de programacién programar como si fuera a ser trasladado a otro procesador. Si esta probando a transformar de un formato a otro, puede encontrar ja funcién transformadora adecuada en alguna biblioteca. Esa es la belleza del uso de la tecno- logia establecida como la compatibilidad de POSIX. Por supuesto, eso significa que existen muchas herramientas para examinar, lo cual ayuda a tener las herramientas agrupadas por su funcién. (Esa es la raz6n por la cual este libro incluye varias pagi- nas de manual aplicables en los apéndices.) Aplicacién de las herramientas y extensién del cliente El proximo paso es extender la funcionalidad del lector de hora con la capacidad de enviar un mensaje y conseguir la respuesta. De nuevo, un descriptor de socket se puede intercambiar con un descriptor de archivo. Al igual puede utilizar read(), puede utilizar write(): f#include ssize_t write(int fd, const void ‘buf, size_t count); He aqui algunos errores comunes que se pueden encontrar: * EBADE. fd no es un descriptor de archivo valido o no se puede abrir para escritura. Por ejemplo, el programa cerré ya el descriptor de socket, o el socket nunca fue abierto correctamente (comprobar el valor devuclto de la llamada socket()). * EINVAL. fd esta asociado a un objeto que es inadecuado para la escritura. Esto puede ocurrir si el programa habia cerrado previamente el canal de escritura * EFAULT. Se especificd una direccién de espacio de usuario no valida en un pardmetro. Fl puntero buf no apunta a un espacio valido. Cuando la Hamada intenté acceder a la regién de memoria, obtuvo una infraccién de segmenta- cin. © EPIPE. fd estd conectado a un canal o socket cuyo fin de lectura esta cerrado. Cuando esto ocurre el proceso de escritura recibe una seival SIGPIPE; si se atrapa, bloquea © ignora esto, se devuelve el error EPIPE. Este error ocurre solo en la segunda Hamada write(). Un escenario puede ser: 1. Uncliente se conecta a un servidor y envia algunos datos. 2. Elservidor lee parte del mensaje, luego cierra la conexion (0 falla). 3. No se conoce ningtin problema, el cliente envia el siguiente bloque de datos. De igual modo que en la llamada write(), puede substituir el descriptor de archi- vo (fd) con un descriptor de socket (sd). Como ejemplo, a continuacién puede ver parte de una salida de socket tipica con write(): int sd, bytes_written = @, retval; sd = socket(AF_INET, SOCK STREAN, 9); + /*** Conectar al host. ***/ while ( bytes_written < len ) /* Repetir hasta que todos */ { 1*,,.1os bytes del mensaje son enviados. */ retval = write(sd, buffertbytes written, len); if ( retval >= 0) bytes_written += retval; else /*+-Informar de error de conexidn,--*/*/ Por otro lado, a continuacién se muestra parte de Ja salida de un socket tipico con fprintf() a través de la transformacién del descriptor de socket a FILE*: FILE “sp; int sd; sd = socket (AF_INET, SOCK_STREAM, 0); - /*** Conectar al host. ***/ sp = fdopen(sd, *w"); /* Crear FILE* desde 61 socket. */ if ( sp == NULL ) perror(*FILE* conversion failed"); fprintf(sp, "es, %s, %s\n*,Name, Address, Phone); Se debe observar en cl primer ejemplo, que el programa tiene que realizar un bucle con writeQ) para obtener todos los bytes externos. Aunque esto es un flujo de socket, no puede garantizar que el programa envie todos los bytes en seguida. El segundo ejemplo no tiene esta limitacion, porque FILE* tiene su propio subsistema de gestion de buffers de datos. Cuando se escribe en un biifer FILE*, el subsistema obliga a esperar hasta que se envfan todos los bytes. Hay, por supuesto, un socket dedicado para escribir la Hamada: send(). Como la lamada recv(), da al programador mas control sobre la ejecucion de la transmisién. La dectaracién del prototipo es: #include #include int send(int sd, const void *msg, int len, unsigned int flags); Todos los pardmetros son los mismos que en write() excepto el ultimo—flags. La llamada del sistema send() tiene varias opciones que ayudan a revisar el funcio- namiento de la Hamada: * MSG_OOB. Envia datos “fuera de banda” (OOB). Como se utiliz6 antes, eso permite enviar un byte a un equipo homélogo, cliente o servidor para indicar una condicién urgente. El receptor tiene un solo byte dedicado para datos OB; subsiguientes mensajes OOB sobreescriben el tiltimo mensaje. Cuando un mensaje OOB llega, el sistema operativo emite una SIGURG (sefial urgen- te) al programa responsable. * MSG_DONTROUTE. No permite el encaminamiento del paquete. Esto ocasio- na que el paquete omita las tablas de rutas, obligando a la red a intentar con- tactar directamente con el receptor. Si el destino es inaccesible directamente, la llamada produce un error ENETUNREACH (red inalcanzable). Solamente utilizan esta opciénprogramas de diagndstico o de encaminamiento. * MSG_DONTWAIT. No espera a que send() finalice. Esta opcién permite al programa proceder como si send() estuviera hecho (o delegado). Si se utiliza, el sistema operativo emite una sefial SIGIO, para indicar una operacién write() completa. Si la operacin se bloquea porque la cola de send) esta lle- na, la llamada devuelve un error y establece EAGAIN en errno. * MSG_NOSIGNAL. No emite ninguna sefal SIGPIPE. Si el otro extremo cierra pronto, y siel programa local envia otro mensaje, se puede obtener una sefial SIGPIPE, Si no se esta preparado para esta seal, el programa detiene su eje- cucién. El uso de la llamada del sistema send() es similar al uso de recv(). Si quiere agre- gar las sefializaciones, utilice el operador aritmético O: [ERAN REE RAE E EE ETE y*** Realizar una escritura normal con un canal de socket.***/ RRR en EU REE REARS OAM R ERT EE ET int bytes_sent; bytes_sent = send(sd, buffer, MAXBUF, 0); /*Enviar cualquier dato fuera de banda desde el canal de socket.*/ int bytes_sent; bytes_sent = send(sd, buffer, MAXBUF, MSG_OOB | MSG_NOSIGNAL); El segundo ejemplo selecciona MSG_OOB y MSG_NOSIGNAL. Se puede recor- dar que estos ejemptos se diferencian en la llamada del sistema write() al afiadir un pardmetro nuevo para el control del socket. Ademés, el socket se debe conectar al servidor o host con objeto de usar write(). Aqui estan algunos errores con los que se puede encontrar: * EBADF. Se especificé un descriptor invalido. La causa mas probable es que el programa no comprobé cl valor devuelte de la llamada socket0. * ENOTSOCK. El argumento no es un socket. A lo mejor se mezclan los descrip- tores de socket y de archivo. * EMSGSIZE. El socket pidié al nticleo enviar atémicamente el mensaje, y el tamafio del mensaje a ser enviado, hizo esto imposible. Los mensajes de difu- sidn no pucden ser fragmentados, o el programa establece la opcién de soc- ket a “no fragmentar”. * EAGAIN. El socket se marca como no bloqueante y la operacién solicitada bloquearia. Fste no es un error, simplemente es un “no preparado todavia”. Intentar el envio otra vez mis tarde . * EPIPE. El extremo local ha sido cerrado en un socket orientado a la conexidn. En este caso, el proceso recibe también un SIGPIPE, a menos que MSG_ NOSIGNAL esté establecido. (Idéntico a EPIPE en la lamada del sistema wri- te().) Utilice la Hamada del sistema send() para investigar un servidor. Por ejemplo, si quiere utilizar el programa finger en un servidor, abra un canal al puerto (79) del servidor, envie el nombre de usuario y lea la respuesta. Este algoritmo es normal- mente lo que hace el cliente. No necesita ninguna opcién especial para realizar esta tarca. Sin embargo, pue- de desear leer tanta informacién como el servidor le envie. Algunas veces la res- puesta puede ser més grande que el tamaiio del buffer. El siguiente trozo de listado de programa muestra la implementacién del algoritmo. Puede conseguir el listado de programa completo en el CD-ROM que acompaiia a este libro. /*** Extension del comprobador de puertos, afade la capacidad **/ f*** de acceder a cualquier puerto y enviar un mensaje. “******>/ int main(int count, char ‘strings[]) { aint sockfd; struct sockaddr_in dest; char buffer [MAXBUF] ; s*--- Grear un socket y asignar un numero de puerto. sockfd = socket (AF_INET, SOCK STREAM, 0); bzero(adest, sizeof (dest)); dest.sin_family = AF_INET; “itt dest.sin_port = htons(ato1(strings(2j)); inet_addr(strings[1], &dest.sin_addr.s_addr); /*--- Conectar a un servidor y enviar la peticién. ---*/*/ if ( connect(sockfd, &dest, sizeof(dest)) != @ ) PANIC("connect() failed’); printf(buffer, ‘%s\n", strings(3]); send(sockfd, buffer, strlen(buffer), 0); i*--- Vaciar el buffer y leer la respuesta CORTA. ---*/*/ bzero(buffer, MAXBUF); recv(sockfd, buffer, MAXBUF-1, @); printf("%s", buffer); close(sockfd) ; return @; Si quiere utilizar este algoritmo para obtencr una respuesta larga, necesita cam- biar la ultima seccién a lo siguiente: PODER EHEC UID OD IEEE IODIDE REISER EEE / J*** Revision del cédigo para obtener respuestas largas. ***/ PO RAR eee Aaa ERR OUR RAUL ORAM RNR REELS }*—- Vaciar el buffer y leer la respuesta CORTA. —-*/*/ do { bzero(buffer, WAXBUF); bytes = recv(sockfd, butter, MAXBUF, @); printt("%s", buffer); t while ( bytes > 0); close(sockfd); Este cambio funciona correctamente si el servidor cierra la conexin después del envio de los datos. De otro modo, el programa espera indefinidamente los datos. La espera de la informacién es un problema particular con Ia programacion de sockets, Algunas veces puede confiar en que el servidor cierre la conexién cuando el envio esté hecho. Sin embargo, algunos servidores dejan el canal abierto hasta que el cliente lo cierra. Hay que ser consciente de que si el programa espera por mucho tiempo, puede estar afrontando este tipo de problema. Diferentes clases de sockaddr Las redes soportan varios tipos de protocolos distintus. Cada protocolo tiene funciones y caracteristicas especificas. Para la red, s6lo son paquetes. Los tipos de paquete incluyen: Sockets con nombre PF_LOCAL Actualmente no se conecta a Ja red. Este tipo se usa estrictamente para colas de procesamiento en cl sistema de archivos. Protocolo de Internet PF_INET (Demostrado ya). Protocolo de Novell PF_IPX Para la comunicacién con redes Novell. AppleTalk PE_APPLETALK — Para la comunicacién con redes AppleTalk. Puede encontrar mas protocolos soportados y definidos en el Apéndice A. Cada tipo utiliza su propio sistema de nombrado y convenciones, y todos ellos usan la API de Socket. Esto deberia realizar la programaci6n mas directa. Lamentablemen- te, hay demasiado contenido para incluir aqui, asf que este libro fija su atencién principalmente en el protocolo de Internet. Canales con nombre de UNIX Considere por unos instantes cémo funciona syslog. El problema que surge es el siguiente: ¢c6mo se podrian coordinar varias aplicaciones que son susceptibles de emitir errores © mensajes en diferentes momentos? Syslog es una herramienta que acepta mensajes como éstos. La API de Socket tiene ya incorporado este tipo de eoordinacién. Los sockets con nombre permiten que varios programas locales se envien men- sajes (o paquetes). Ellos tienen nombre, porque crean realmente un archivo en el sis- tema de archivos. La comunicacién es s6lo local; nada pasa a través de Ia red, y un cliente de red no puede conectarse a él. Funciona como un socket normal: puede crear una conexién de flujo o de data- grama. Como se dijo anteriormente, la dnica diferencia es el sockaddr. He aqui cémo configurar el canal con nombre: PARES R TREE ERR ARETE ERENT TS RARE MRRH ES / s*** Ejemplo de socket con nombre de unix. nee PODS OIC U II ren TREE nei bees nneneaaen eee! #include int socktd; struct sockaddr_un addr; sockfd = socket(PF_LOCAL, SOCK STREAM, ); bzero(aaddr, sizeof(addr}); addr.sun_family = AF_LOCAL; strepy(addr.sun_path, "/tmp/mysocket’); /* Asignar nombre. */ if ( bind(sockfd, &addr, sizeof(addr)) I= 0 } perror("bind() failed"); Todo deberia parecer relativamente familiar. E] campo sun_path permite un camino de hasta 104 bytes (incluyendo la terminacién NULL). Desde aqui, puede usar todas las llamadas API normales. Es lo mismo para todos los protocolos sopor- tados, Después de ejecutar este fragmento, puede mirar en /Atmp para observar el archi- vo nuevo. Aseptirese de borrar este archivo antes de la ejecucién de nuevo del pro- grama. Resumen: aplicacién de herramientas y numeracion IP La API de Socket es una herramienta de interaccién muy flexible para la progra- macin en red. Esta soporta varios protocolos distintos, permitiendo conectar ¢ interconectar con otros protocolos de funcionamiento en red. El protocolo de Internet utiliza direccionamiento que incorpora en los mensajes de encaminamiento y los grupos de clustering de las computadoras, Esto hace a cada mensaje aut6nomo del gestor del origen: un mensaje dejado en la red puede conseguir el destino a través del encaminamiento y las tablas ARP. Sin embargo, debido a la flexibilidad del direccionamiento y la asignacién escasa, la asignacion de direccionamiento esta perdiendo bloques de direcciones validas. Parte de la pila TCP/IP resume la red con puertos. La mayoria de conexiones utilizan puertos para comunicarse con programas especificos en otras computado- ras de red como si poseyeran la conexién de red, Esta caracteristica facilita la programacién y reduce la inundacién de mensajes que el programa podria recibir realmente. La red utiliza tipos y ordenaciones de bytes (endianness) especiticos para pasar los mensajes de una parte a otra. sockaddr define el protocolo, direccién y puerto de la conexién. Debido a todos estos formatos de datos distintos, la API de Socket ofrece muchas herramientas de transformacién para el direccionamiento (por ejem- plo, inet_addr(Q), inet_aton(), inet_ntoa()) y para el endianness (htons(}, ntohs(), htonl()). TCP y UDP ofrecen al programa niveles de interaccién distintos. En el proximo capitulo se definen los distintos tipos y capacidades de cada protocolo dentro de TP. Capitulo III Tipos de paquetes de Internet En este capitulo El paquete de red fundamental 47 Anilisis de varios paquetes 53 Como encajan los protocolos IP 67 Cémo escudrifiar la red con Tepdump 67 Escritura de un escudrifiador de red a medida 69 Resumen: eleccién de los mejores paquetes para el envio de mensajes 70 La red fisica soporta distintos tipos de redes légicas como Novell (IPX), Micro- soft (NetBEUD, AppieTalk y por supuesto, TCP/IP. Cada red ldgica utiliza mensa- jes de datos distintos llamados paquetes, como se definié en el capitulo anterior. Los paquetes pueden ser mensajes reales en la linea de transmisién (los cuales tie- nen mucha mas informacién incluida) o solamente el mensaje que se est enviando. Fl paquete de red logico en un nivel genérico consta de informacién sobre el ori- gen, destino y datos de carga util. Cada red légica ofrece diversos grados de carac- teristicas ¢ interfaces (protocolos). Con la programacién de red, estan disponibles todos los tipos de paquetes y protocolos. Cada tipo tiene puntos fuertes y débiles significativos. Como en la compra de herramientas, la eleccién del tipo de paquete depende de como se use. Se puede elegir de entre cuatro protocolos de paquetes de Internet: IP raw, ICMP, UDP (generacién de mensajes no fiables), y TCP (generacién de flujo), basa- dos todas ellos en capas ubicadas encima de la red fisica (véase la Figura 3.3). En este capitulo se describe cada tipo y se presenta sus ventajas, desventajas y usos tipicos. Mensajeria fable ‘Mensajeria no fable FIGURA 3.1 La API de Sockets ofrece distintos niveles de mensajes fiables. El paquete de red fundamental Si se pudiera realmente observar los bits que viajan de una computadora a otra, zqué se veria? Cada protocolo es muy distinto, pero todos comparten una caracte- ristica necesaria en comtin: todos transportan el mensaje del programa. Algunos protocolos incluyen la direccién origen, mientras otros requieren la del destino. Se puede pensar que no requerir un destino es un poco usual, pero algunos protocolos (como UUCP) utilizan la conexién como la direccién de destino. EI protocolo de Internet (IP) [RFC791] requiere que un paquete tenga tres ele- mentos basicos: origen, destino y datos. (La carga util de datos incluye su tamaio.) Estos elementos ofrecen un nivel de autonomia al paquete. No importa donde esta el paquete, se puede identificar de dénde viene, dénde va y cémo es de grande. La autonomia del paquete es una caracteristica de Internet. Mientras el paquete esté vivo (los datos son oportunos y relevantes), los routers trasladan los datos a su destino cuando el paquete estd activado sobre la red. ALIASING DE PAQUETE La autonomia que tiene el paquete también conlleva una parte negativa. Mien- tras un paquete ofrece ia forma de llegar a cualquier sitio desde cualquier parte, un programador malicioso puede facilmente engafiar a la red. La red no requiere que ia direccién del host origen esté validada. Hacer aliasing 0 spoofing (enmas- <_——— 8 bits —————>> ° version Longitud Tipo de servicio 2 Longitud de paquete. 4 10 de paquete 6 | 0 [or [mr Desplazamiento de fragmento 8 Tempo de vida Protocolo 10 ‘Suma de comprobacian de cabecera ve f- =< Direecion origen IPv4 --- : 16 20-60 Datos (hasta 65535 bytes -cabecera) FIGURA 3.2 Esquema de la cabecera IP. Se observa que la estructura del paquete incluye muchos mas campos de los cua- tro campos basicos vistos anteriormente en este capitulo. El subsistema IP utiliza estos campos adicionales para controlar el paquete. Por ejemplo, el campo dont_frag especifica a Ja red que, en lugar de desmenuzar el mensaje en trozos pequefios, se deberia aceptar el mensaje completamente o rechazarlo. Los comentarios al lado de los campos ofrecen una descripcién suficiente. Los siguientes apartados definen los campos IP que se pueden modificar o usar. Este libro no es exhaustivo, si desea aprender més sobre cada campo, puede consultar una buena documentacién en los RFC de los protocolos TCP/IP. Campo version Este primer campo IP es el ntimero de version del protocolo IP. Muchos de estos valores estan reservados 0 sin asignar; por ejemplo, IPv4 coloca un 4 en este campo. Los pocos valores definidos estan incluidos en la Tabla 3.1. Tabla 3.1 Valores del campo version valor Descripcion/Uso IPva. Modo de datagrama IP de flujo (I? experimental). IPve. TP/IX (el “proximo” protocolo de Internet) El protocolo de Internet “P”. TUBA. Ce ND & El tinico cambio que tiene que hacer en este campo es cuando crea un socket raw y decide rellenar la cabecera (utilizando la opcién de socket IP_HDRINCL). Incluso entonces, debe establecer el campo a 0. El cero indica al micleo que complete este campo con el valor apropiado. Campo header _len Este campo indica al receptor la longitud de la cabecera utilizando words de 32 bits, Desde el valor 0, que esta reservado (y que no tiene significado), al tamaiio mayor de 15 words o 60 bytes. De nuevo, la tnica situacion en la que debe rellenar este campo es cuando utiliza un paquete socket raw y IP_LHDRINCL. Como todas las cabeceras IP tienen al menos 20 bytes, el valor minimo de este campo es de 5 (20/4) bytes. Campo serve_type El campo serve_type indica cémo administrar el paquete. Tiene dos subcampos: un subcampo precedence (ignorado en muchos sistemas) y un subcampo de tipo de servicio (TOS). Normalmente estableceré TOS con la llamada del sistema setsockpt(). TOS tiene cuatro opciones: retardo minimo, rendimiento maximo, fia- bilidad maxima y coste minimo (monetario). Si no selecciona ningtin servicio espe- cial significa una administraci6n normal. (Para obtener un mayor detalle de setsockopt() y sus valores véase el Capitulo 9, “Cémo romper las barreras del ren- dimiento”.) Campo ID El subsistema IP le da a cada paquete un ID unico. Con un campo de sélo 16 bits, puede uno imaginarse que se alcanzan rapidamente los nuimeros usados con ante- rioridad. Sin embargo, el subsistema IP reutiliza un ID por medio de la hora del sis- tema, el paquete que se envio previamente del mismo valor probablemente haya caducado ya. El ID ayuda a recomponer paquetes fragmentados. Si decide administrar la cabecera (TP_HDRINCL), debe administrar los ID también. $i decide manipular la cabecera recuerde que su programa no es e} unico que puede enviar mensajes. El subsistema IP sigue la pista de los ID. Debe tener pre- caucion (y utilizar programacién adicional) para reducir la probabilidad de selec- cionar un ID que el subsistema pueda usar o haya usado. Campo frag_offset y flags dont_frag y more_frags Estos flags controlan cémo fragmentar los paquetes o si se fragmentan. Cuando un paquete extenso atraviesa la red y se encuentra con un segmento de red reduci- do (uno que no pueda soportar el tamafio de trama del paquete), el router puede intentar dividir el paquete en trozos mas pequefios (fragmentacidn). Un paquete fragmentado permanece fragmentado hasta que llega al destino. Puesto que cada fragmento tiene su propia cabecera IP, la sobrecarga fija disminuye el rendimiento de la red. ade ie ttbe gts So bear agtanieene Le pant tock GESTOR DE-RECOMPOSICION: - DE PAQUETES DEL NUCLEO lH_-_______ Cuando el host es un router se puede elegir que el nucleo de Linux recomponga los paquetes fragmentados. Esta opcién es parte de la seccion firewall/router en la configuracion del niicleo. Se debe observar que la recomposicién de los paque- tes requiere tiempo, especialmente si éstos estan dispersos y llegan a distinto tiempo. Sin embargo, como el destino tiene que recomponer los paquetes de cualquier forma, seleccionando esta opcién se reduce el trafico de red dentro del firewall (en la intranet del destino). El bit dont_frag indica al router o host que no divida el paquete. Si establece este bit y el paquete es demasiado grande para un segmento de red reducido, el router descarta el paquete y devuelve un paquete de error (ICMP). El bit more_frags indica al destino que existen mas trozos del paquete fragmen- tado. El ultimo fragmento establece este bit a 0. (Un paquete no fragmentado tiene este bit a 0.) Si configura la cabecera manualmente, deberd establecer siempre este bit a 0. El campo frag_offset indica a qué zona del paquete pertenece el fragmento. Puesto que los fragmentos de los paquetes pueden viajar a través de diferentes rutas en la red, pueden [legar a su destino en momentos diferentes. El destino tiene que recomponer el paquete, y utiliza el offset para colocar el fragmento en su locali- zaci6n correcta. El campo frag_offset es de sdlo 13 bits de Jargo—demasiado pequeito para un paquete que puede Hegar a ser de 64KB. El offset se multiplica por 8 para colocar la posicién del byte real en el paquete. Esto significa que cada fragmento (excepto el ultimo) debe ser un miltiplo de 8. El subsistema IP administra completamente la fragmentacion y recomposicién del paqucte, no se debe preocupar de ello. Con estos campos y el ID del paquete, el subsistema IP puede fragmentar y recomponer el paquete. Si el subsistema no puede conseguir todos los trozos dentro de un tiempo especifico, descarta el paquete y devuelve un error al origen. Campo time_to_live (TTL) Este campo contaba originalmente el ntimero de segundos que un paquete podia perdurar en la red durante su transito. Mas tarde, el significado cambio al ntimero de saltos de router. Un salto es la transicién a través de un host o router (nodo) don- de el nodo traslada activamente un paquete de una red a otra. Este campo de 8 bits permite hasta 255 saltos de router antes de ser descartado. Cuando un router o host de reenvio obtiene el paquete, resta este campo en uno. Si el campo es igual a cero antes de la llegada al destino, el nodo descarta el paquete y envia un error al origen. El campo TTL evita que existan paquetes dando vueltas indefinidamente en fa red. Se puede utilizar la opcién de socket IP_TTL para establecer este valor (véase el Capitulo 9). Alternativamente, se puede establecer la opcién directamente si se clige el tratamiento de cabecera IP directo (IP_LHDRINCL). Campo protocol Cada paquete en Internet tiene un valor de protocolo asignado, ¢ ICMP (IPPRO- TO_ICMP 0 1), UDP (IPPROTO_UDP 0 17) y TCP (IPPROTO_TCP o 6) poseen cada uno un cédigo. El protocolo indica al sistema como tratar e] paquete entrante. Pue- de establecer este valor con la opcién SOCK_RAW en Ia lamada del sistema socket(). El valor de protocolo es el ultimo parémetro de la llamada. El archivo de cabecera netinet/iin.h del nicleo contiene muchos mis valores. (Se recuerda que aunque el nticleo incluya una definicion de protocolo, éste puede que no lo sopor- te.) Campo options El subsistema IP puede pasar varias opciones con cada paquete. Estas opciones incluyen informacién de encaminamiento, marcas de tiempo, medidas de seguri- dad, registro de encaminamiento y alarmas de caminos. Este campo puede legar a ser de hasta 40 bytes de longitud. Puesto que algunas de estas opciones dependen del sistema, nunca debe tocar estas opciones directamente. Campo data El mensaje se incluye aqui y puede alcanzar hasta 65.535 bytes (menos 60 bytes, del tamaito maximo de la cabecera). Esta seccién de datos incluye cualquier infor- macién de cabecera que los protocolos de las capas superiores necesitan, Por ejem- plo, ICMP necesita 4 bytes, UDP necesita 8 bytes y TCP necesita de 20 a 60 bytes. El sistema de paquetes de Internet basa todos sus paquetes IPv4 en esta estructu- ra. Cada capa superior afiade caracteristicas y fiabilidad. Analisis de varios paquetes IP ofrece varios protocolos de paquetes que se clasifican desde muy rapidos a muy fiables. Todos ellos se apoyan en la capa mas baja—el paquete basico IP. Sin embargo, cada capa se ha desarrollado para resolver problemas especificos. Para seleccionar el tipo de paquete apropiado, se debe conocer lo que se transmite. Los tipos de paquetes que probablemente sean més de interés son: TCP, UDP, ICMP y raw. El conocimiento de las ventajas y desventajas de cada tipo le puede ayudar a elegir el mas apropiado para la aplicacion. Cada tipo de paquete tiene dis- tintas ventajas, como se encuentras resumidas en la Tabla 3.2. Tabla 3.2 Ventajas de cada tipo de paquete Raw ICMP UDP TOP Sobrecarga fija (bytes) 20-40 20-60+18) 20-60+120-60] Tamano del mensaje (bytes) 65,535 65,535 {ilimitado) Fiabilidad Baja Baja Alta Tipo de mensaje Datagrama Datagrama —Datagrama_—Flujo Rendimiento Alto Alto Medio Bajo Integridad de los datos Baja Baja Media Alta Fragmentacion Si Si Si Baja En esta tabla, se observa que cada tipo de paquete contiene contraposiciones. Una fiabilidad de valor baja solo significa que no se puede confiar en el protecolo para conseguir la fiabilidad. A pesar de que las diferencias pueden ser extremas, se recuerda que son meramente comparaciones, Cuestiones relacionadas con los paquetes Cada protaocolo controla ciertos aspectos en la transmisién. Los siguientes apar- tados definen cada aspecto y categoria de la Tabla 3.2. Puede ayudarle a entender por qué ciertos protocolos implementan algunas caracteristicas y omiten otras. Sobrecarga fija de protocolo En la sobrecarga fija de protocolo se incluyen dos cosas: el tamafio de cabecera en bytes y la cantidad de interaccién que el protocolo requiere. Una sobrecarga alta fija de paquete puede reducir el rendimiento, porque la red tiene que gastar mas tiempo en trasladar cabeceras y menos tiempo de lectura de datos. Un protocolo robusto en sincronizacion e intercambio de senales incrementa la interaccién de sobrecarga fija. Esto es mas costoso en la red WAN debido a la pro- pagacién de retardos. La Tabla 3.2 no incluye esta medida. Tamaiio de mensaje de protocolo Para calcular el rendimiento de la red, necesita conocer el tamafio de paquete y la sobrecarga fija del protocolo. El tamaio de transmisién le da el tamafio maximo. de un mensaje enviado, Todos menos TCP utilizan un tmico mensaje, esta limita- cin es debida normalmente a las limitaciones del paquete IP (65.535 bytes). La can- tidad de datos que el programa transmite por paquete es el tamafio de transmisién menos las cabeceras. Fiabilidad de protocolo Parte del problema con las redes es la posibilidad de perder mensajes. Un men- saje se puede corromper o desechar cuando se traslada de un host o routera otro, 0 si falla o se rompe el propio host o router. En cada caso, un mensaje se puede sim- plemente perder, y el programa tendra que repetirlo. Es probable también, que quiera asegurarse que el destino procesa los paquetes en el orden correcto. Por ejemplo, puede componer un mensaje que no cabe bien en un paquete. Si el segundo paquete llega antes que el primero, el receptor debe cono- cer cémo identificar y corregir el problema. Sin embargo, el orden no es importante cuando cada mensaje es independiente y autocontrolado. La fiabilidad del paquete indica la certeza de seguridad de la llegada de los men- sajes y su orden. Baja fiabilidad significa que el protocolo no puede garantizar que el paquete alcance el destino o que los paquetes estén en orden. Tipo de mensaje de protocolo Algunos mensajes son autocontrolados e independientes de otros mensajes. Fotos, documentos, mensajes de e-mail, ete. son algunos ejemplos que se pueden adaptar al tamato del paquete. Otros se parecen mas a un flujo de corriente, como sesiones Telnet, canales abiertos de HTTP [RFC2616], documentos, fotos 0 archivos grandes. EI tipo de mensaje define qué estilo se adapta mejor a cada protocolo. PROTOCOLO HTTP HTTP 1.0 podria efectivamente utilizar UDP para la transferencia de mensajes en vez de TCP. El cliente envia simplemente la consulta de un documento especifico, y el servidor responde con el archivo. Efectivamente, no se efectua ninguna con- versacién entre el cliente y el servidor. Rendimiento de protocolo Bl aspecto mas notable de la transmisién de datos es el rendimiento de la red. Al conseguir el valor maximo los usuarios se muestran felices. Para obtener €l mejor funcionamiento, necesita conocer el rendimiento. A menudo, los bits por segundo es una pequefia parte de la ecuacién entera; indicando como la red puede rendir bajo circunstancias idéneas. El rendimiento de protocolo mide cuantos datos reales puede enviar el origen al destino dentro de un periodo de tiempo. Si las cabeceras son grandes y los datos pequefios, el resultado es un rendimiento bajo. La demanda de un acuse de recibo para cada mensaje reduce drasticamente el rendimiento. Por defecto, alta fiabilidad e integridad implican un bajo rendimiento y viceversa. Integridad de los datos de protocolo La tecnologia del funcionamiento en red tiene actualmente bastantes medidas de seguridad para la integridad de los datos. Algunas interfaces de red incluyen una suma de comprobacién o verificacién por redundancia ciclica (CRC) en cada men- saje de bajo nivel. También incluyen tecnologia hardware especial que puede filtrar el ruido y obtener el mensaje auténtico. Adicionalmente, cada protocole incluye medidas para detectar errores en ios datos. Estos errores pueden o no pueden ser importantes para el programador. La importancia de la integridad de los datos depende de los propios datos; es decir, algunos datos requieren un seguimiento con mucho cuidado, mientras que datos menos importantes son menos criticus. A continuaciOn se describen algunos tipos de datos: * Fallo intolerable. Datos criticos de vida. Cualquier cosa que pueda afectar a la salud o vida privada o publica. Por ejemplo, sefales de vida 0 sefiales vitales del equipo médico y comandos de lanzamiento de misiles. * Critico. Datos importantes y responsables. Datos que si estan fucra de secuencia o defectuosos pueden causar dao a la propiedad o seguridad. Por ejemplo, transacciones financieras, tarjetas de crédito, mameros PIN, firmas digitales, dinero electrénico, secretus comerciales, actualizaciones de escaner de virus y actualizaciones de productos. * Importante. Datos que necesitan un funcionamiento correcto. Cualquier pér- dida puede causar un mal funcionamiento. Por ejemplo, conexiones X11, des- cargas de FTP, paginas web, direcciones de servidor 0 router, y conexiones Telnet. * Informativo. Datos que pueden tener menos del 100% de fiabilidad para un funcionamiento correcto. Por ejemplo, e-mail, flujo de noticias, publicidad y paginas web. * Temporal. Datos que estan asociados a la fecha y hora. A menos que el pro- gtama utilice esta informacin dentro de un tiempo especifico, se reduce su importancia. Por ejemplo, datos climaticos, datos de supervision y datos horarios. * Desechable. Datos que pueden degenerarse sin perder su utilidad. Son nor- malmente video y sonido. Por ejemplo, peliculas, archivos de sonido, fotos y spam (por supuesto). Previamente a la eleccién del tipo de paquete © protocolo, se tienen que clasificar los datos de acuerdo a esta lista. También se tiene que incluir las restricciones adi cionales (0 externas) del programa. Estas también pueden ser restricciones adminis- trativas. Fragmentaci6n de protocolo Mensajes grandes en redes lentas pueden frustrar a los usuarios. Todas las redes definen un tamaiio de trama maximo para que esos mensajes grandes no avasallen la red. Se recuerda que los host de encaminamiento pueden dividir, o fragmentar, los mensajes grandes que atraviesan una red estrecha. Cada protocolo tiene una probabilidad distinta de fragmentacién. Puesto que la recomposicién de mensajes fragmentados es funcién de IP, la reagrupaciGn se pue- de realizar de forma transparente a los protocolos de la capa superior. Sin embargo, existen ocasiones en las que se requiere que el mensaje esté completo. Esto es parti- cularmente importante para el rendimiento de la red. Cuando los routers dividen el Paquete en trozos pequeiios, el router pierde tiempo en dividir el mensaje, y los Paquetes resultantes incrementan la sobrecarga fija. Al bloquear la fragmentacién, la red descarta el paquete y devuclve un mensaje de error (paquete demasiado grande) al programa. Tipos de paquete En los apartados siguientes se describen cada tipo de paquete, se muestran sus estadisticas y se define la cabecera (si existe). En cada apartado se utiliza una tabla que ayuda a visualizar rapidamente las caracteristicas de cada protocolo. Fl uso de esta tabla ayuda a elegir el paquete correcto para la aplicacién. El paquete raw Un paquete raw tiene acceso directo al paquete y Ia cabecera IP. Se utiliza en la ptogramacién de protocolos especiales o a medida. Sus atributos estén listados en ja Tabla 3.3. Tabla 3.3. Atributos del paquete raw Tamafio dei mensaje (bytes) 65.535 (65.515 maxima carga util de datos). Sobrecarga fija (bytes) De 20a 60. Fiabilidad Baja (Ja red puede descartar o reconfigurar los paquetes). Tipo de mensaje Datagrama. Rendimiento Alto (baja sobrecarga fija del sistema). Integridad de los datos Baja (el sistema no valida el mensaje), Fragmentacién Si Linux ofrece la opcin de funcionar con capas distintas en la pila IP (para obte- ner una definicién completa de la pila IP y las capas se puede consultar el Capitulo 5, “Bxplicacién del modelo de capas de red”). El mensaje TCP/IP mas basico es et mensaje IP’ raw. No tiene informacién aparte de la mas bésica. Puede utilizar el paquete IP para crear la capa mis basica y asi crear los propios protocolos a medida. Para acceder al paquete IP seleccione SOCK RAW en la Hama da del sistema socket(). Por seguridad, debe tener privilegios de root para cjecutar un programa socket raw. El socket raw permite trabajar con las tripas del paquete IP. Puede configurar el socket para que funcione con dos niveles de detalle: tratamiento de cabecera y datos © sélo de datos. El tratamiento de los datos es parecido a la transmisién de datos UPD sin soporte de puertos. El tratamiento de la cabecera permite establecer direc- tamente los campos cabecera. Con el uso de este mensaje se obtiene ventajas y desventajas, Al ser un mensaje datagrama, no se ofrece garantia de la llegada o de la integridad de los datos. Sin embargo, se puede enviar o recibir mensajes casi a la velocidad de la red. Para con- sultar mas informacion de la administracién de paquetes raw se puede consultar el Capitulo 18, “La potencia de los sockets raw”. Gestion de mensajes de error y control IP (ICMP) El Protocolo de mensajes de control en Internet (ICMP) es una de las capas cons- truidas encima del paquete basico IP. Todas las computadoras conectadas a Internet (hosts, clientes, servidores y routers) utilizan ICMP para el control o los mensajes de error. Se utiliza para el envio de mensajes de error o control. Algunos programas de usuario también implantan este protocolo, como por ejemplo traceroute y ping. Los atributos de [CMP estan incluidos en la Tabla 3.4. Tabla 3.4 Atributos de ICMP. Tamaio del mensaje (bytes) 65.535 (65.511 maxima carga util de datos) Sobrecarga fija (bytes) De 24a 64. Fiabilidad Baja (el mismo que IP raw). Tipo de mensaje Datagrama. Rendimiento Alto (el mismo que IP raw) Integridad de los datos Baja (el mismo que IP raw). Fragmentacién Si (pero es improbable). Si implanta ICMP en el programa puede reutilizar cl socket para enviar mensa- jes a hosts distintos sin volver a abrir el socket. Los mensajes se pueden enviar ugan- do la llamada del sistema sendmsg() 0 sendto() (como se describird en el proximo. capitulo). Estas llamadas necesitan una direccién de destino. Con un socket indivi- dual, se pueden enviar mensajes a tantos puntos como se desee. Las ventajas y desventajas de un paqucte ICMP son esencialmente las mismas que en IP raw (y otros datagramas), Sin embargo, el paquete incluye una suma de comprobacién para la validacién de los datos. También, la probabilidad de que la red pueda fragmentar un paquete ICMP es muy pequeiia. Esto se debe a la natura- leza de los mensajes ICMP: se usan para indicar los estados, los errores y el control. El mensaje no seré muy grande, asi que nunca necesitaré la recomposicién. Aunque pueda usar ICMP en los mensajes propios, se utiliza habitualmente para mensajes de error y de control. Todos los errores del funcionamiento en red viajan por la red dentro de un mensaje ICMP. El paquete tiene una cabecera que incluye los cédigos de error, y la parte de los datos puede contener un mensaje mas especifico describiendo el error. Como parte del protocolo IP, ICMP obtiene una cabecera IP y ahade su propia cabecera. El Listado 3.2 muestra una definicin de la estructura. Listado 3.2 Definicién de la estructura ICMP PERE RECUR U NUE RE EET OER AEM HIRE] (*** Definicién de la estructura ICMP, tee *** Definicién formal en netinet/ip_icmp.h very [ORO U EOD UN OI UO I Er DEEL Ee takin a ae Et anes / typedef unsigned char ui8; (continiia) Listado 3.2 Oefinicién de la estructura ICMP (continuacién) typedef unsigned short int vité; struct ICMP_header { ui8 type; /* Tipo de error. */ ui8 code; ¢* Gédigo de error. */ ui16 checksum; /* Suma de comprobacién del mensaje. */ uchar msg[]; /* Descripcién de datos adicionales. */ oa : mn a oa [a an 22-62 ‘Suma de comprobacion ICMP FIGURA 3.3 Esquema ICMP. El tipo y el cédigo definen qué error se produjo. msg puede ser cualquier infor- macién adicional para buscar detalladamente lo que salié mal. Para obtener un lis- tado completo de tipos y cédigos, véase el Apéndice A. Protocolo de datagrama de usuario (UDP) El Protocolo de datagrama de usuario (UDP) se utiliza principalmente para las comunicaciones sin conexién (mensajes independientes). Este puede enviar mensa- jes a diferentes destinos sin volver a crear los sockets y actualmente es el protocolo sin conexién mas comin. Los atributos de UDP estan incluidos en la Tabla 3.5. Tabla 3.5 9 Atributos UDP Tamario del mensaje (bytes) 65.535 (65.507 maxima carga util de datos). Sobrecarga fija (bytes) De 28 a 68. Fiabilidad Baja. Tipo de mensaje De un solo uso. Rendimiento Medio. Integridad de los datos Medio. Fragmentacién Si. Cada capa superior de la pila IP fija mas su atencién en los datos y menos en la ted. UDP oculta algunos detalles de los mensajes de error y de cémo el niicleo transmite los mensajes. También, recompone un mensaje fragmentado. Un mensaje que se envia a través de UDP cs como un mensaje e-mail: el destino, origen y datos es toda la informacién que se necesita. El micleo toma el mensaje y lo coloca en la red pero no verifica su legada. Al igual que el paquete ICMP, puede enviar a multiples destinos desde un socket individual, utilizando distintas llama- das del sistema send(). No obstante, sin la verificacién, se pueden alcanzar rendi- mientos maximos Sin verificar la Hegada, la red puede perder la fiabilidad de los datos. La red pue- de perder paquetes o fragmentos, o corromper el mensaje. Los programas que utili- zan UDP, o bien siguen la pista de los mensajes, 0 no les importa si se pierden o quedan corrompidos. (Se debe observar que, aunque los datagramas son poco fia~ bles, esto no significa que algo salga mal. Sélo significa que el protocolo se efecttia sin garantias.) De los distintos tipos de datos (definidos anteriormente), Informativo, Temporal y Desechable se adaptan mejor a los servicios UDP. La raz6n principal es su toleran- cia a la pérdida de paquetes. Si la camara web falla para actualizar todos los nave- gadores, el usuario final es improbable que lo advierta o le importe. Otro posible uso es un servicio horario exacto. Debido a que la hora exacta es Temporal, un host puede descartar un par de instantes de reloj sin la pérdida de integridad. UDP ofrece la ventaja de mayor velocidad. Ademds, se puede incrementar su fiabilidad de las siguientes formas: * Dividir paquetes grandes. Se toma cada mensaje y se divide en porciones asigndndole un ntimero (por ejemplo, 2 de 5). El equipo del otro extremo recompone el mensaje. Se recuerda que mas sobrecarga fija y menos envio de datos reducen el rendimiento. + Seguir la pista de cada paquete. Se asigna un niimero tnico a cada paquete Se fuerza al equipo homélogo a mandar un acuse de recibo de cada paquete, porque sin acuse de recibo, cl programa reenvia el tiltimo paquete. Si el equi- po homdlogo no obtiene el paquete esperado, solicita un reenvio con el iilti- mo numero de mensaje o envia un mensaje de reanudacién. * Afiadir una suma de comprobacién o CRC. Se verifican los datos de cada paquete con una suma de datos. Un CRC es mis fiable que una suma de com- probacién, pero ta suma de comprobacién es mas facil de calcular. Si el equi- po homélogo descubre que los datos estén corruptos, le indica al programa que reenvie el mensaje. * Usar tiempos de espera. Se puede asumir que un tiempo de espera expirado implica que ha fallado. El origen puede retransmitir el mensaje, y el receptor puede enviar un recordatorio al emisor. Los tipos de datos Critico e Importante requieren la fiabilidad de TCP o una mejor. El tipo Fallo intolerable requiere mucho mas de lo que ofrecen cualquiera de estos protocolo. Estos pasos esquematizados imitan la fiabilidad de TCP. UDP confia en las caracteristicas y los servicios de IP, Cada paquete de datagra- ma UDP recibe una cabecera UDP e IP. En el listado 3.3 se define la estructura UDP. Listado 3.3 Definicion de la estructura UDP PIO GIAO Ra ER EERE RE REE EERE [*** Definicién de la estructura UDP (datagrama). sey [*** (Definicién formal en netinet/udp.h.} wy [RENE AA Ar A RRS EASE ARR aE typedef unsigned char uia; typedef unsigned short int uil6; struct UDP_header { uil6 src_port; /* Nimero de puerto del origen. */ uil6 dst_port; /* Numero de puerto del destino. */ uil6 length; J* Tamafio del mensaje. */ uil6 checksum; — /* Suma de comprobacién del mensaje. */ uchar data[]; /* Datos del mensaje. */ ys ° Cabecera IP (20-60 bytes) \ 20-60 Numero de puerto de origen UDP 22-62 Niimero de puerto de destino UDP 24-64 Longitud de mensaje UDP 26-66 ‘Suma de comprobacién de mensaje UDP 28-68 ‘Oates (hasta 65636 bytes - cabeceras) FIGURA 3.4 Esquema UDP. UDP crea un receptaculo de red virtual para cada mensaje en forma de puertos. Con el puerto, IP puede repartir rapidamente los mensajes al propietario correcto. Aunque no se defina un puerto con bind(), el subsistema IP crea uno temporal para el programa de la lista de puertos efimeros (véase el Capitulo 2). Protocolo para el control de la transmisi6n (TCP) Protocol para el contro! de la transmisi6n (TCP) es el protocolo de socket utiliza- do de forma més habitual en Internet. Se pueden utilizar read() y write(), y se requiere volver a crear un socket para cada conexidn. Los atributos TCP estan incluidos en la Tabla 3.6, Tabia 3.6 = Atributos TCP Tamaiio del mensaje (bytes) —_(Ilimitado). Sobrecarga fija (bytes) De 40a 120. Fiabilidad Alta (El recibe de los datos comprobado). Tipo de mensaje Flujo. Rendimiento Bajo (comparado con otros protocolos). Integridad de los datos Alta (inciuye suma de comprobacién). Fragmentacién Improbable Para conseguir una mayor fiabilidad se requiere la garantia de que el destino obtenga cl mensaje exacto que el emisor envis. UDP tiene velocidad pero no tiene la fiabilidad que necesitan muchos programas. TCP resuelve el problema de la fiabili- dad. La red, sin embargo, tiene varios problemas fundamentales que la hacen poco fiable. Estos problemas no son una limitacion. De hecho, son inherentes al disefto de la red. Para conseguir fiabilidad, mensajes con capacidad de flujo a través de la web entrelazada, TCP/IP tiene que incorporar muchas de las ideas sugeridas en el apar- tado de UDP. Internet tiene tres obstéculos: conexiones dindmicas, pérdida de datos y caminos reducidos, como se tratardn en los siguientes apartados. Conexiones dinamicas Un Rost envia un mensaje a otro host. Ese mensaje viaja a través de las redes, atravesando varios routers y gateways. Cada mensaje enviado puede utilizar un camino distinto. Los segmentos de red (conexiones entre computadoras) a menudo aparecen y desaparecen cuando los servidores se inician y apagan. La potencia de Internet es su capacidad para adaptarse a estos cambios y encaminar la informacién de forma consecuente. La adaptabilidad es una de las fuerzas impulsivas detras de Internet. La compu- tadora puede realizar una consulta, y la red intenta posibles vias para completar la orden. Desafortunadamente, esta ventaja implica que el camino entre la computa- dora y el servidor o equipo homélogo puede cambiar, alargando o acortando la dis- tancia. Si el camino se alarga, el tiempo de propagacién se incrementa. Esto significa que el programa pucde enviar mensajes sucesivos y muchos Hegarn a distinto tiempo, muchas veces desordenados. TCP garantiza que el destino ha recibido correctamente el tiltimo mensaje antes de enviar el siguiente. Se puede comparar esto a una serie de mensajes numerados {asf es como funciona realmente TCP). El programa puede enviar 10 mensajes suce- sivos. TCP toma cada mensaje, te adjunta un mimero tinico, y lo envia. El destino acepta el mensaje y responde con un acuse de recibo. Una ver. recibido cl acuse de recibo, TCP permite al programa enviar el siguiente mensaje. PROTOCOLO DE VENTANA DIVIDIDA TCP utiliza una técnica mejor que el protocolo enviar-esperar (0 ACK/NACK), el cual es demasiado lento para la paciencia de cualquiera. En lugar de eso, utiliza una ventana dividida: mide cuando y con qué frecuencia responder con un ACK (acuse de recibo). Las conexiones lentas o malas pueden incrementar fos mensajes de acuse de recibo. Conexiones rapidas y con menos pérdidas permiten que se envien mas mensajes antes de la recepcién de un acuse de recibo. Es parte del algoritmo de Nagle. Se puede deshabilitar utilizando opciones de sockets (véase el Capitulo 9). Pérdida de datos Cuando el destino obtiene el mensaje, determina la integridad de los datos. Los datos pueden viajar a lo largo de caminos de comunicacién poco éptimos, que puc- den desechar 0 corromper los bits del mensaje. Se debe recordar que la red envia cada mensaje de bit en bit. TCP envia con el mensaje una suma de comprobacién para verificar las datos. TCP es la tltima capa que puede detectar y remediar datos exréneos. Si el destino detecta cualquier error, envia al emisor un error, solicitande una retransmision al programa, Asimismo, si la computadora no obtiene un acuse de recibo dentro de un tiempo determinado, cl subsistema TCP reenvia automatica- mente el mensaje sin la intervencién del programa. Caminos reducidos Regresando al mensaje individual enviado a un host particular, suponga que el mensaje es demasiado grande para los segmentos que intervienen en el camino. Los problemas que el paquete encuentra cuando pasa a través de la red son las distintas tecnologias y las portadoras de transmisién. Algunas computadoras en red permi- ten paquetes extensos; otras colocan limites en el tamaito. UDP intenta enviar el mensaje tan grande como se pueda. Esto puede ser un problema con los camninos reducidos de datos. Los algoritmos IP se adelantan a que los routers puedan fragmentar los datos. De igual modo, IP espera que recompon- gan el mensaje entrante. TCP, por otra parte, limita cada paquete a trozos pequefios. TCP divide mei jes grandes, antes de que la red tenga la oportunidad de cogerlos. TCP elige el tama- fio en uno que las mayorias de las redes pueden dejarlo intacto. Por omision, TCP utiliza 536 bytes y negocia normalmente hasta 1,500. Para incrementar ese tamano manualmente, establezca la opcién de socket TCP MSS (tamario de segmento maxi mo) (véase el Capitulo 9). El receptor se puede encontrar que los paquetes del mensaje estén desordena- dos, TCP los ordena antes de pasar el mensaje al programa. La solucién a todos estos problemas de red es afiadir sobrecarga fija de cabecera y protocolo al algoritmo TCP. Por supuesto, la sobrecarga fija afiadida de todas las técnicas TCP reducen el rendimiento notablemente. Definicién de la cabecera TCP TCP tuvo que afiadir bastante informacién a su cabecera para soportar todas las caracteristicas que ofrece. El tamajio, en bytes, de la cabecera TCP es unas tres veces el de la cabecera UDP. En el Listado 3.4 se observa la definicién de la estructura TCP. Listado 3.4 Definicién de la estructura TCP DERE AON ERA RA ER EERIE EMER N ERAN RES | /*** Definicién de la estructura TCP (socket de flujo). **#/ s*** (Definicion formal en netinet/tcp.h). my eee eee eee TEE TeES EEO Eee eee eee eet eeeee gs typedef unsigned char uia; typedef unsigned short int ui16; typedef unsigned int ui92; ‘typedef unsigned int uint; struct TCP_neader { ui16 src_port; /* Numero de puerto del origen. */ uil6 dst_port; /* Numero de puerto del destino. */ ui82 seq_num; /* Numero de secuencia. */ ui32 ack_aum; 1* Numero de acuse de recibo. */ uint data_off:4; /* Offset de los datos. */ vint __res:6; /* (Reservado.) */ uint urg_fla /* Urgente, mensaje fuera de banda. */ uint ack flag: j /* Gampo de acuse de recibo valido. */ uint psh_flag:1; /* Colocar el mensaje a procesar inmediatamente. */ uint rst_flag:1; /* Reiniciar 1a conexién debido a errores. */ uint syn_flag:1; /* Abrir una conexién virtual (canal). */ uint fin_flag:1; /* Conexién cerrada. */ ui16 window; /* Cudntos bytes se permiten recibir. */ Ui16 checksum; —/* Suma de comprobacién del mensaje. */ uil6 urg_pos; /* Ultimo byte de un mensaje urgente. */ (continua) Listado 3.4 Definicién de la estructura TCP (continuacién) ui8 options{]; — /* Opciones TCP. */ ui8 _padding[]; /* (Necesitado para alinear data(1)- */ uchar data[]j /* Datos del mensaje. */ h t—_———- 8 bits 8 bits —————} ° Cabecera IP (20-80 bytes) 20-60 Numero de puerto de origen TCP. 22-62 Numero de puerto de destino TCP 24-64 Nim, de secuencia TOP = ---- zea f------- ---- Nomero de reconcimiento TOP - 32-72} Despi. de datos (veservado) rg fack/psn] rst [syn] tn 34-74 Tamefo de ventana de receptor TCP 36-76 ‘Suma de comprobacion de mensaje TCP 38-78 Mensaje urgente TCP-posicién de bytes 40-80 Ay ‘Opciones TCP \ Datos (hasta 65595 bytes - cabecorns) FIGURA 3.5 Esquema TCP. La cabecera puede tener un tamaio variable, asi el campo data_off apunta hacia el principio de los datos. Para guardar el espacio de cabecera, este campo acttia como el campo header_len de IP: asigna el numero de words de 32 bits que fisica- mente precede los datos. TCP utiliza algunos de los campos exclusivamente para la apertura de la conexién, control de flujo y cierre de la conexiGn, Durante una sesién de comunicacién, algu- nas de las cabeceras estén vacias. Los siguientes apartados describen algunos cam- pos interesantes. La cabecera TCP utiliza el mismo numero de puerto encontrado en UDP. Pero seq_num y ack_num ofrecen seguimiento al flujo. Cuando envia un mensaje, el subsistema IP adjunta un ntimero de secuencia (seq_num). El receptor responde que obtuvo el mensaje con un ntimero de acuse de recibo (ack_num) que es supe- rior en 1 al ntimero de secuencia. Esta caracteristica permite que los paquetes de acuse de recibo transporten también datos. Observacién de las interacciones TCP Cuando se abre una conexién de generacién de flujo, el programa y el servidor intercambian una serie de mensajes, los cuales aparecen relacionados y descritos en Ia Tabla 3.7. Tabla 3.7 Intercambio de sefales de tres direcciones Envios del cliente Envios del servidor Descripcion SYNeI (syn_flag) Consulta una conexién virtual (canal). ACK=0 (ack_flag) Establece el nimero de secuencia. SYN=1 (syn_flag) Permite y acusa recibo de una conexion virtual. ACKs=1 (ack flag) SYN-0 (syn_flag) ACK=1 (ack_flag) Establece una conexidn virtual. Esto se llama intercambio de senales de tres direcciones. Durante las transferen- cias, el cliente y el servidor especifican el tamatio de buffer de sus buffers de recep- cin (ventanas). Por otra parte, el cierre de una conexién no es una tarea tan simple como puede parecer en un principio, debido a que puede darse el caso de que existan datos en transito, Cuando el cliente cierra una conexién puede ocurrir la interaccién mostra- da en la Tabla 3.8. Tabla 3.8 Cierre de una conexién TCP Cliente Servidor Descripcién FIN=I (fin_flag) Transmite datos El cliente solicita cerrar. Recibe datos ACK=1 Transmite mas El servidor vacia los canales. Recibe mas ACK=1 FIN=1 Cierre aceptado. El servidor cierra y espera un ACK del cliente. ACK=1 El cliente cierra su lado. El cierre de la conexién TCP hace imposible la reutilizacin del socket para otras conexiones. Por ejemplo, si se conecta a un servidor, la nica forma de cortar la conexidn es cerrando el canal, lo cual cierra también el socket. $i entonces quiere conectarse a otro servidor, debe crear un socket nuevo. Los otros protocolos no tie- nen esta limitacién. Cémo encajan los protocolos IP Mientras tinene lugar la interaccidn con la red, tal vez. se pregunte como encajan entre si todo este conjunto de protocolos. En algunos casos, puede parecer que no existe una adaptacién plena. Algunos de ellos utilizan ciertas caracteristicas de otros, pero realmente no funcionan tan estrechamente juntos que parezcan insepa- tables. Los protocolos IP raw, ICMP, UDP y TCP desempefian papeles especificos. Pue- de utilizar estos protocolos para adaptar sus necesidades cuando disefia la aplica- cién de red. Por supuesto, mientras TCP tiene mas fiabilidad y caracteristicas que los otros protocolos, no puede reemplazar ICMP con TCP. Debido a que los subsis- temas Linux requieren caracteristicas distintas de TCP/IP, cada tipo de paquete es importante para que el sistema funcione correctamente. Los paquetes ICMP, UDP y TCP fisicamente confian en el paquete IP raw. Sus cabeceras y datos residen en la seccién de datos IP, siguiendo a la cabecera IP. Cémo escudrifiar la red con Tcpdump La observacién de paquetes en una red en funcionamiento muestra de forma efectiva qué hace con los mensajes el micleo y cémo el subsistema de red resuelve consultas de direccin. Desde el paquete IP raw a TCP, tcpdump es una herramien- ta que visualiza los datos de la red. Por seguridad, se necesita acceso de root para cjecutar tcpdump. Por omisién, tepdump utiliza el modo promiscuo asi que puede ver todo en la red. El modo promiscuo manipula la interfaz hardware directamente para aceptar todos los mensajes. EL EQUILIBRIO DELTAS EHEAS BE RED ——______ El conocimiento de como hacer muchas cosas es muy poderoso y soporta bastan- te responsabilidad. Con privilegios de root, puede hacer mucho bien y mucho dafio a la red. Cuando instala Linux en la computadora, la distribucion asume que actua con las mismas buenas intenciones como aquellas a quien le ofrecié |a habi- lidad de fisgonear otros paquetes. Una forma efectiva de destruir el movimiento Free Software es abusar de la potencia y confianza que la gente buena y bien intencionada dan. Normaltmente, el adaptador de interfaz hardware recoge solamente aquellos mensajes de Ia direccin ethernet que cs capaz. de reconocer. Se puede recordar del Capitulo 2 que cada adaptador de hardware ethernet tiene un nico ID de 6 bytes. El adaptador utiliza este ID para ignorar todos los paquetes excepto los que coinci- den con el ID. 1D ETHERNET PROGR NIRBEES Algunos OEM (fabricantes de equipos originales) ofrecen sus tarjetas de interfaz de red (PCI o PCMACIA) las cuales soportan direccién MAC programable (o |D ethernet), Esto hace posible la produccién en serie para algunos fabricantes de tarjetas mientras se sirven a varios cientos de marcas de empresa, Desafortunada- mente, se puede obtener una tarjeta que tiene un 1D falso, porque no se ha pro- gramado correctamente la marca de la empresa. Este error puede hacer que la tarjeta no sea Unica en la red. Si no desea modo promiscuo, puede desconectarlo con una de las opciones. Tepdump tiene muchas opciones que le ayudan a filtrar mensajes no deseados y seleccionar redirecciones de datos y datos visualizados. A continuacién estan algu- nas opciones interesantes de la linea de comandos: « -a Intenta asignar nombres de red y direcciones de difusion. Esto requiere acceder al servidor de nombres. * -c — Finaliza después de alcanzar la cuenta especifica de mensajes. eon No convierte las direcciones de los nodos a sus nombres (esto es util cuando no se tiene un servidor de nombres). ° -p No coloca la interfaz en modo promiscuo. Si se tiene una red pequefia o cluster, viendo todos los paquetes que pueden ser interesantes. De otra manera, con el modo promiscuo, habilitado, la red puede facilmente abrumar a la computadora. ov Visualiza una captura con alguna informacién. Incluye el campo de tiempo de vida (TTL). ° ow Visualiza una captura con bastante informacién. * -we Escribe el paquete raw al archivo. Tcpdump puede ejecutarlo sin ninguna opcién, y visualizaré mas informacién de la que necesita. Puede también ver interacciones interesantes, cémo ARP (Proto- colo de resolucién de direcciones) pregunta por el ID ethernet y lo adquiere de la direcci6n IP. A continuacién se muestra un ejemplo de captura de 100 paquetes con informacién y sin marca de tiempo: tcpdump -v -t -c 100 La opcién -t suprime la marca de tiempo. Ya que a menudo los mensajes se des- plazan fuera de la pantalla muy rapidamente, puede desear redireccionar el resultado a un archivo. Tepdump tiene unas pocas anomalias; por ejemplo, no recoge los mensajes de él mismo. No observa los paquetes de ping 127.0.0.1, porque el subsistema de red no envia estos mensajes a las capas inferiores donde tcpdump trabaja. Escritura de un escudrifador de red a medida {Como trabaja tcpdump? Puede leer el extenso programa Open Source, o escri- bir su propio escudrifiador de red (una especie de tcpdump). La tinica cosa que necesita conocer es cémo capturar cualquier mensaje para un host. La herramienta que en este apartado se describe le ayuda a escribir un escudriftador de red que des- ensamble paquetes deseados para un host. No soporta el modo promiscuo, sin embargo. Por seguridad (como tepdump), necesita ser root para ejecutar un escudrifiador de red. Fl escudrifiador captura todos los mensajes destinados a la computadora. Para obtener todos los mensajes, utilice las siguientes lamadas: sd = socket(PF_INET, SOCK PACKET, filter); bytes _read = recvfrom(sd, buffer, sizeof(buffer), ®, @, 0); Observe el tipo de socket nuevo: SOCK_PACKET. Es un socket a nivel hardware de sélo lectura. Puede utilizar varios filtros para SOCK_PACKET. Los filtros le indican a la capa IP qué clase de paquete desea capturar. A continuacién se muestra varios de estos filtros: © ETH_P_802_3 Tramas 802.3. © ETH_P_AX25 Tramas AX.25. © ETH PALL Todas las tramas (jcuidado!). © ETH_P.802.2 Tramas 802.2. El filtro a utilizar es ETH_P_ALL. Como indica la nota, cuidado con este filtro, porque cuando lo selecciona, se lo da todo. El resultado de la Hamada es: sd - socket (PF_INET, SOCK_PACKET, ETH P_ALL); Después de que la llamada haya terminado con éxito, cada llamada del sistema recvfrom() que realice devuelve una trama de red (un mensaje de red fisico). La tra- ma de red incluye la direccién hardware (por ejemplo, la direccién ethernet) y la cabecera. Fl SOCK_PACKET ofrece acceso a las tramas de nivel hardware y a todos los datos asociados de cada transmisién. Con ello puede observar cémo el subsistema de red construye las tramas. Puede utilizar la estructura IP definida al principio de este capitulo. Sin embar- go, recuerde que el almacenamiento esta condicionado al hardware, asi que los bits de los campos pueden estar en el orden equivocado. La estructura asume que el bit numero 0 es el primer bit en el flujo de la trama. El programa ejemplo del sitio web, snooper.c, reconfigura los campos para hacerlos coincidir con la trama hardware real para un procesador little-endian (compatible con Intel) y un compilader GNU. Si tiene un procesador diferente (incluso un compilador diferente), debe de modificar levemente la estructura, Resumen: eleccién de los mejores paquetes para el envio de mensajes Puede utilizar tcpdump y el escudrifiador para visualizar las clases distintas de paquetes que la computadora envia y recibe. Estos paquetes, en el caso de IP, pue- den ser paquetes IP raw, paquetes ICMP del gestor de mensajes de error, datagra- mas UDP o mensajes de flujo TCP, Cada tipo de paquete completa un papel especi- fico mientras deja suficiente espacio para la expansion. Cada paquete tiene su propia cabecera. ICMP, UDP y TCP adjuntan sus cabece- rasa la cabecera IP. El rango total del tamaiio dedicado a estas cabeceras es de 20a 120 bytes. El equilibrio entre las cabeceras y los datos verdaderos afectan al rendi- mienio de la red. ‘TCP tiene el menor rendimiento debido a la proporcién entre cabecera y datos. Al ofrecer la comunicacién més fiable entre dos computadoras, es el protocolo més usado en Internet. TCP ofrece una interfaz de generacién de flujo que le permite uti- lizar funciones de E/S de la biblioteca superior, tal como fprintf() y fgets(). Puede utilizar UDP para enviar mensajes individuales a hosts distintos sin conectar de nuevo. Eso virtualiza la red usando puertos, al hacerlo parece que la conexién tiene acceso exclusive a la red. UDP ofrece rendimiento bueno pero una transmisién poco fiable. F1 protocolo que mas se utiliza es TCP, debido a su fiabilidad. UDP lo sigue detras a lo lejos. La red de hoy ha dado un paso adelante desde el experimento de utilizar las interfaces y paquetes de muy bajo nivel hacia el envio de mensajes. El rendimiento no es tan importante como la fiabilidad, pero los usuarios contingan observando el asunto de! rendimiento. Capitulo IV Envio de mensajes entre peers En este capitulo {Qué son los sockets basados en la conexién? 73 Ejemplo: conexién al demonio HTTP 77 {Qué son los sockets sin conexién? 80 Envio de un mensaje directo 85 Garantia de llegada de un mensaje UDP 90 Tareas enrevesadas: una introducci6n a la multitarea 94 Resumen: modelos conectados frente a modelos sin conexién 95 Se puede pensar en el pase de mensajes desde dos angulos distintos: continuo y sin interrupcién (TCP) 0 paquetes discontinuos de informacion (UDP). Mientras el flujo de datos continue es como una transmisién tclefdnica, el paquete discontinuo es como una carta en un sobre con direccin. El flujo continuo requiere que se tenga una conexién establecida con el destino. Esto asegura que la informacién no se pierde durante el intercambio y que esta ordenada cuando Hega. Los mensajes discontinuos permiten que se realice una conexién para facilitar simplemente la programacién. Sin una conexi6n, el progra- ma ticne que colocar una direccién en cada mensaje. En este capitulo se trata las interfaces sin conexion y las basadas en la conexién, Las comparaciones y ejemplos le pueden ayudar a elegir el tipo mas apropiado para Jas aplicaciones. Qué son los sockets basados en la conexi6n? Linux (y todos los sistemas operativos tipo UNIX) ofrece esencialmente tres niveles distintos de comunicacién para los programas. Todos los niveles requieren la utilizacién de la Hamada del sistema socket(). Estos niveles le dan a conocer las dindmicas de la programacién de red y pueden realizar una programacién desafiante. Los tres protocolos bésicos (IP raw, UDP y TCP que se encuentran definidos en el Capitulo 3, “Distintos tipos de paquetes de red”) abstraen la red y aftaden fiabili- dad mientras se reduce necesariamente el rendimiento. El nivel mas alto, TCP, tiene la fiabilidad mas grande de todos los niveles de protocolo. Lo cual garantiza que los datos alcancen el destino correctamente y Heguen ordenados. Es tan fiable que se puede considerar como un archivo o un canal de interproceso. Esa es la razon de que los sockets TCP son sockets basados en Ja conexi6n. Canales abiertos entre programas Los sockets TCP ofrecen un canal bidireccional abierto entre dos programas. Como un micréfono del auricular, el canal envia y recibe informacién de flujo sin cortes. Los programas pueden enviar simulténeamente informacién a otros sin tener que recomponer el dialogo del mensaje individual. TCP también recuerda a quién se est hablando, Cada mensaje en niveles infe- riores del protocolo IP tiene que suministrar la direccién de destino con cada men- saje. Es como marcar el ntimero de un amigo cada vez que se desea volver a hablar. Cuando se conecta al otro programa (utilizando la llamada del sistema con- nect()), et socket entonces se acuerda de la direccién de destino y el puerto. Tam- bién, puede utilizar las llamadas de biblioteca de alto nivel disefiadas para la E/S de flujo, como fprintf0) y fgets(. Lo que simplifica enormemente la programacién. Como disefiador del programa, el protocolo TCP le ayuda a evitar los problemas de pérdida de datos que pueden ocurrir con otros protocolos. Esta simplicidad Ie permite fijar la atencion en el programa. Comunicaciones fiables TCP es una E/$ de flujo, de alta fiabilidad y acceso a la E/S de alto nivel, impli- cando que el camino de los datos esta limpio y sin trabas. TCP garantiza comunica- ciones fiables: el equipo homélogo recibe todo lo que el programa necesita. E] sub- sistema de red que incluye los dispositivos y las pilas de protocolos (en el servidor 0 cliente) aceptan un mensaje, lo comprueban y lo pasan al programa. Si la comprobacién falla y el subsistema detecta un error, el subsistema se encar- ga de reclamar una retransmisién. Ambos extremos del camino de comunicacién ejecutan este chequeo de validacién. Como se describié en el capitulo anterior, algu- nos mensajes tienen un ID de paquete tinico y secuencial. E] ID es importante para asegurar la fiabilidad y la ordenacién. Obtiene esta caracteristica cuando selecciona el protocolo TCP. Los dos problemas més grandes con la comunicacién de red son la pérdida y la reordenacién de paquetes. Suponga que cl programa envia un mensaje. Los progra- mas no pueden detectar absolutamente que el destino consigue el mensaje a menos que reciba una respuesta del destino. Por ejemplo, el programa envia el mensaje, y el destino espera la Hegada del paquete. Si el destino no recibe nada en un rato, envia un mensaje al programa indicando el ultimo niimero de secuencia que recibié bien. Esta colaboracién estrecha acopla el programa con el destino. Por otra parte, el destino puede recibir algunas partes del mensaje desordenadas con el resto del mensaje. Cuando esto ocurre, el destino aguanta el fragmento del mensaje hasta que obtiene los segmentos intermedios. E] destino entonces recompo- ne el mensaje utilizando el ntimero de secuencia como clave de ordenacién. Como se debié observar antes, las llamadas de biblioteca de alto nivel cuentan con un canal abierto y también requieren que el camino de comunicacién sea fiable. El protocolo TCP fija la atencién en el canal del mensaje con objeto de que Ia infor- macion aparezca como un flujo sin paquetes. Alternativamente, los protocols de bajo nivel fijan la atenci6n en los paquetes, con lo que no pueden soportar llamadas de biblioteca de E/S de alto nivel como printf(). Los protocolos menos fiables ofrecen enviar mensajes al programa con un canal muy rapido. UDP, en particular, intenta obtener el mensaje r4pidamente sin tener en cuenta la ordenacion. Similarmente, el destino acepta cada mensaje indepen- diente, sin esperar ninguna ordenacion. La ordenacién es un asunto importante para el disefio. Puede esperar que ios datos no estén ordenados cuando, en realidad, pueden estarlo. A continuacién se

También podría gustarte