2. 2
2Sockets IPv4 en Linux
Fuentes y Referencias
● man
● Wikipedia
● Fuentes del kernel
● http://www.advancedlinuxprogramming.com/
3. 3
3Sockets IPv4 en Linux
Licencia, Agradecimientos y
Herramientas
● Agradecimientos a todas las personas que han
participado en los proyectos GNU y Linux. Gracias a la
compartición libre de ese conocimiento es que esta
presentación existe.
● Úsala, cópiala, difúndela, mejórala según los términos
de la licencia: CC BY-SA 3.0 ES
http://creativecommons.org/licenses/by-sa/3.0/es/
● Esta presentación ha sido realizada íntegramente con
KDE, LibreOffice y Chromium
4. 4
4Sockets IPv4 en Linux
Índice
● Familias y tipos de sockets.
● Sockets IPv4. TCP vs UDP. Diagrama de estados TCP.
● Sesiones. Puertos.
● Secuencias para servidor/cliente TCP/UDP.
● Modelos de Servidor.
● Funciones C.
● Interfaces de consola, utilidades, procfs.
● Anexo: Orden de bytes, Direcciones IPv4 y resolución de
nombres
5. 5
5Sockets IPv4 en Linux
Clasificación de sockets:
Familias y tipos
● Familias o Dominios: AF_... (AF = Address Family)
● Tipos: SOCK_...
● Cada familia tiene tipos. A veces un tipo corresponde a más de
una familia, ej. SOCK_RAW en AF_INET y AF_PACKET
● Más info en:
– man: socket(2), socket(7),...
– Fichero socket.h
6. 6
6Sockets IPv4 en Linux
Ejemplos de usos de sockets
según familias
● IPv4: AF_INET.
● Sockets Unix (también llamados sockets IPC): AF_UNIX o AF_LOCAL. Ver man unix(7)
– Para comunicación local (en un solo equipo)
– Conllevan un archivo en el sistema de ficheros, ej: sudo find / -type s -ls
– También pueden verse con netstat -xapn
● IPv6: AF_INET6. Ver man ipv6().
● Comunicación entre kernel y espacio de usuario:
AF_NETLINK. Ver man netlink(7).
● Paquetes a nivel de dispositivo (nivel OSI 2):
AF_PACKET. Ver man packet(7).
● Otras: Novell IPX, X.25, radio AX.25, AppleTalk, ATM PVCs,... Ver man ddp(7), x25(7).
● (Lista completa en fichero socket.h)
7. 7
7Sockets IPv4 en Linux
Sockets IPv4
● Familia: AF_INET
● Tipos:
– SOCK_STREAM para TCP (ver man 7 tcp).
– SOCK_DGRAM para UDP (ver man 7 udp).
– SOCK_RAW para desarrollar nuevos protocolos o hacer uso
de funcionalidades internas de los existentes (ver man 7
raw).
● Ver man 7 ip
8. 8
8Sockets IPv4 en Linux
TCP vs UDP
● Orientado a conexión: TCP sí, UDP no.
● Longitud de mensajes: mayor en TCP que en
UDP.
● Gestión de errores:
– TCP: desde el protocolo. Mayor sobrecarga.
– UDP: externo al protocolo. Ej. reenvíos por timeout
(alarmas).
9. 9
9Sockets IPv4 en Linux
Sesiones
● Hay una (y sólo una) sesión entre dos IPs y dos puertos (uno en cada IP).
● Roles de cada IP para cada sesión: si al inicio de la sesión escucha es servidor
(el proceso está dormido hasta que atienda una petición); si envía es cliente.
● Ej. de combinaciones y casos particulares:
– Que una IP1 haga de servidor con una IP2 y de cliente con otra IP3
– Que una IP1 haga de servidor con una IP2 y de cliente con la misma IP2 por otro puerto.
– Que ambas IPs estén en un mismo equipo.
10. 10
10Sockets IPv4 en Linux
Puertos
● Listado de puertos y servicios estándares (“well-known”)
de capas por encima de 4 en /etc/services (ver anexos)
–
– No confundir con /etc/protocols
● Importante: byte order (ver más adelante).
● Para abrir un puerto < 1024 hay que tener privilegios de
root o CAP_NET_BIND_SERVICE. Ej:
$nc -l -p 1023
$Can't grab 0.0.0.0:1023 with bind : Permission denied
12. 12
12Sockets IPv4 en Linux
En general,
Envío y Recepción
Secuencias para
servidor/cliente TCP/UDP
s = socket
bind
listen
fd = accept
read
write
close (fd)
close (s)
s = socket
connect
write
read
close (s)
s = socket
bind
recvfrom
sendto
close (s)
s = socket
bind
sendto
recvfrom
close (s)
TCP
server
TCP
client
UDP
server
UDP
client
Estado:
listening
Opcional
En TCP hay 2 sockets en servidor; hay que cerrar ambos al final
connect connect
OpcionalOpcional
13. 13
13Sockets IPv4 en Linux
Modelos de Servidor
● Iterativo: un solo servidor atiende a un único cliente, y cuando
éste acaba se atiende a otro. Se puede acelerar multiplexando
las peticiones de clientes mediante:
– Funciones select(2) o poll(2).
– Señal SIGIO.
● Múltiples servidores o servidores concurrentes: un servidor hace
fork(2) para atender a cada cliente con un proceso separado.
Ej: openssh-server
14. 14
14Sockets IPv4 en Linux
Funciones C:
Ficheros include
● sys/socket.h
● sys/types.h: no es obligatorio según POSIX pero
es conveniente por compatibilidad ej. con BSD
15. 15
15Sockets IPv4 en Linux
Funciones C:
Tipos de datos
Se emplean descriptores de sockets (tipo int) semejantes a los descriptores de ficheros
struct sockaddr {
sa_family_t sin_family;
char sa_data[14]; /* contenido según el uso */
};
struct sockaddr_in {
sa_family_t sin_family; /* 16 bits, address family: AF_INET */
in_port_t sin_port; /* 16 bits, port in network byte order */
struct in_addr sin_addr; /* 32 bits, internet address */
};
struct in_addr {
uint32_t s_addr; /* address in network byte order */
};
16. 16
16Sockets IPv4 en Linux
Funciones C:
socket(2)
int socket (int domain, int type, int ip_protocol)
● Se usa para crear un socket, de tipo IPv4 o
cualquiera.
● Valor de ip_protocol:
– Uno de /etc/protocols
– Si sólo es posible un valor para la combinación de
dominio y tipo, se puede indicar 0.
17. 17
17Sockets IPv4 en Linux
Funciones C:
bind(2)
int bind (int sockfd, const
struct sockaddr_in *addr, socklen_t addrlen);
● Asocia el socket con una (o todas) dirección IP y un
puerto del equipo local.
● Necesario en servidor TCP y UDP. En el cliente UDP
es opcional si sólo envía pero no recibe.
● Si addr.sin_addr es INADDR_ANY hace que se use
cualquier interface de red.
18. 18
18Sockets IPv4 en Linux
Funciones C:
listen(2)
int listen(int sockfd, int backlog);
● Pone a un socket del servidor TCP en estado de
escucha tras el bind.
● backlog: relacionado con conexiones que puede
aceptar. Ver ref:
http://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/023/2333/2333s2.html
19. 19
19Sockets IPv4 en Linux
Funciones C:
accept(2)
int accept(int sockfd, struct sockaddr *addr, socklen_t
*addrlen);
● Obtiene un nuevo socket para recepción y transmisión en el servidor
TCP para la primera conexión pendiente (connect del lado cliente), a
partir de un socket en escucha.
● La llamada queda bloqueada hasta que haya una conexión.
● addr se rellena en la llamada con la información de la conexión
(dirección IP y nº de puerto en el servidor). Si es NULL no se hace
nada.
20. 20
20Sockets IPv4 en Linux
Funciones C:
connect(2)
int connect(int sockfd, const struct sockaddr
*addr, socklen_t addrlen);
● Conecta el socket indicado con una dirección y
puerto. Usos en:
– Cliente TCP. La llamada espera a que se complete la
conexión.
– Cliente o Servidor UDP: Necesaria si las funciones de envío
y recepción no especifican el otro extremo. La llamada
vuelve inmediatamente.
21. 21
21Sockets IPv4 en Linux
Funciones C:
Envío
● Sin indicar la dirección/puerto remoto (en UDP habría
que usar antes connect(2)):
– Funciones I/O estándar sin flags de sockets: write(2),
writev(2), sendfile(2).
– Funciones con flags de sockets: send(2).
● Indicando la dirección/puerto remoto:
– sendto(2).
– sendmsg(2): con estructuras específicas msghdr y iovec.
22. 22
22Sockets IPv4 en Linux
Funciones C:
Recepción
● Sin obtener la dirección/puerto remoto (en UDP
habría que usar antes connect(2)):
– Funciones I/O estándar sin flags de sockets:
read(2), readv(2).
– Funciones con flags de sockets: recv(2).
● Obteniendo la dirección/puerto remoto:
– recvfrom(2).
– recvmsg(2): con estructuras específicas msghdr y iovec.
23. 23
23Sockets IPv4 en Linux
Funciones C:
Bloqueos en envío y recepción
● Las funciones anteriores se quedan en espera
hasta enviar o recibir.
● Gestión de bloqueos y esperas mediante:
– Disponibilidad de datos: select(2) y poll(2).
– No espera: flag O_NONBLOCK mediante fcntl(2).
– Uso de la señal SIGIO, usando el flag O_ASYNC
mediante fcntl(2).
24. 24
24Sockets IPv4 en Linux
Funciones C:
Cierre
● int close(int fd);
Cierre en ambos sentidos.
● int shutdown(int sockfd, int how);
Cierre en uno o ambos sentidos.
25. 25
25Sockets IPv4 en Linux
Funciones C:
Otras funciones
● Opciones de sockets: getsockopt(2),
setsockopt(2). Ej. SO_REUSEADDR para evitar
problemas de TIME_OUT en socket TCP del lado
servidor tras el close.
● Dirección IP local del socket (útil si ej. el socket se
hereda): getsockname(2)
● Dirección IP remota del socket TCP:
getpeername(2)
26. 26
26Sockets IPv4 en Linux
Interface de consola:
netstat(1)
● Da información sobre:
– Sockets TCP, UDP, raw, Unix.
● Si escucha por * o 0.0.0.0 significa que escucha por todas las interfaces.
● Puede mostrar procesos, usuarios, nombres o números, funcionar en modo
continuo (-c),...
– Rutas
– Grupos multicast
– Interfaces
– Estadísticas sobre protocolos IP, ICMP, TCP, UDP, UDP lite,...
27. 27
27Sockets IPv4 en Linux
Interface de consola:
nc(1) o netcat(1)
● Establece conexiones TCP, UDP y Unix sockets, funcionando en
modos cliente o servidor.
● Muestra en stdout lo que recibe y envía lo que lee de stdin.
● En modo servidor termina cuando el cliente cierra la conexión
(no ej. con carácter EOF).
● Ejemplos de uso:
– Proxys TCP, http (socks)
– Clientes y servidores http, smtp,... basados en scripts de shell
28. 28
28Sockets IPv4 en Linux
Interface de consola:
nc(1) o netcat(1)
● Versiones: original (v1.10 de 1996) y GNU (v0.7.1 de
2004). Compatible con la original, con más
prestaciones ej. tunneling, y con licencia GPL.
● Es distinto de telnet, el cual:
– No puede estar en modo escucha.
– No funciona sobre UDP.
– No transfiere cualquier secuencia binaria porque algunas
se consideran como opciones de telnet y se eliminan.
29. 29
29Sockets IPv4 en Linux
Interface de consola:
nc(1) o netcat(1) – Ejemplos de uso
● Talk. Ej. en servidor:
nc -vvl -p puerto <fich_banner_inicial
● Envío de ficheros. Ej. con compresión y encriptación:
gzip -c fich | openssl enc -des | nc ip puerto
● Ejecutar comandos:
– Modo servidor: cuando alguien se conecta. Ej:
nc -l -p puerto -e comando
– Modo cliente: al hacer la conexión. Ej:
nc -e /bin/bash ip_srv puerto
● Escaneo de puertos. Ej:
nc -zvvw 2 ip 1-1024 2>&1 | grep open
30. 30
30Sockets IPv4 en Linux
Interface de consola:
nc(1) o netcat(1) – Ejemplos de uso
● Captura hexadecimal de comunicación. Ej:
nc -v -o captura servidor_mail 25
● Túneles y reenvío de puertos:
– TCP sobre UDP. Lo que se envíe a un puerto TCP va hacia otro equipo
sobre UDP:
mkfifo /tmp/f
nc -l -p p_tcp </tmp/f | nc -u ip p_udp >/tmp/f
– UDP sobre TCP. Lo que se envíe a un puerto UDP va hacia otro equipo
sobre TCP:
mkfifo /tmp/f
nc -l -u -p p_udp </tmp/f | nc ip p_tcp >/tmp/f
– Otros: TCP sobre TCP, UDP sobre UDP
31. 31
31Sockets IPv4 en Linux
Utilidades
● netcat6, socat
● netsed
● nmap
● tcpdump, wireshark
32. 32
32Sockets IPv4 en Linux
Interface procfs del kernel
● Algunas entradas son de sólo lectura y otras
permiten modificar límites.
● Otros ficheros:
– /proc/net/tcp, /proc/net/udp
– /proc/sys/net/ipv4/
● Se pueden configurar parámetros mediante
/etc/sysctl.conf y /etc/sysctl.d/*
● Más información en man 5 proc
34. 34
34Sockets IPv4 en Linux
Orden de bytes
● Aplica a valores binarios de direcciones de red y números de puertos
que se transmiten. Posibilidades:
– Según la red: Big endian (primero Most Significant Byte). Ej: 2.0.0.1 = 0x2001
– Según host, ej: en x86_64 es Little Endian (primero Least Significant Byte).
Ej: 2.0.0.1 = 0x1002
● A nivel de bytes, no de bits.
● Grupos de funciones para conversión de orden:
– byteorder(3): htonl(3), htons(3), ntohl(3), ntohs(3).
– endian(3): …
– Para direcciones de red: inet(3).
35. 35
35Sockets IPv4 en Linux
Direcciones IPv4:
Bits y Evolución
● Grupos de bits:
– De red:
● N bits más significativos.
● Máscara de red (en general, bits contiguos).
– De equipo.
● 16 – N bits menos significativos.
● Especiales:
– Todos los bits a 0 = dirección de la red.
– Todos los bits a 1 = dirección de broadcast.
36. 36
36Sockets IPv4 en Linux
Direcciones IPv4:
Bits y Evolución
● Evolución de la división de bits para red y
equipo:
– 8 bits para la red y 24 para el equipo.
– División en clases: unicast (A, B, C), multicast (D),
reservadas (E). Problema: si hay que gestionar más de
255 equipos pero una red B es excesiva.
– CIDR.
37. 37
37Sockets IPv4 en Linux
Direcciones IPv4:
Formatos y Tipos
● Formatos de notación:
– Números y puntos, ej. 192.168.2.13
– Binario; importante orden de bytes.
● Tipos:
– Públicas.
– Privadas. NAT.
– Multicast.
– Reservadas, ej. loopback, link-local para zeroconf (169.254.1.0),...
http://en.wikipedia.org/wiki/List_of_assigned_/8_IPv4_address_blocks
38. 38
38Sockets IPv4 en Linux
Direcciones IPv4:
Funciones C
● Grupo de funciones inet(3):
– Conversión entre notación de puntos o binaria: inet_aton (reemplaza
a inet_addr), inet_network, inet_ntoa.
– Separación partes de red y equipo: inet_makeaddr, inet_lnaof,
inet_netof
– Tipos usados para indicar el orden:
● De red: struct in_addr (único campo s_addr de 32 bits), menos en inet_addr
● De equipo: int o in_addr_t
● Extensiones para IPv6: inet_pton(3), inet_ntop(3)
39. 39
39Sockets IPv4 en Linux
Nombres de equipos,
protocolos y servicios
● Distinción:
– Nombres y direcciones de equipos.
– Nombres y números de protocolos:
● De capa de transporte o inferior: “protocolos”.
● Por encima de la capa de transporte: “servicios”.
● Especificación y orden de métodos para resolver nombres en fichero
/etc/nsswitch.conf:
– Nombres de equipos, de protocolos y de servicios, pero también otros (ej. Usuarios).
– Métodos: ficheros (ej. /etc/hosts), DNS y multicast DNS (para equipos), LDAP,
Winbind, base de datos (Berkeley, PostgreSQL, My SQL), antiguo NIS,...
40. 40
40Sockets IPv4 en Linux
Nombres de equipos
● Ficheros:
– Según el método:
● Si es por fichero: /etc/hosts
● Si es por DNS (en el cliente): /etc/resolv.conf
– El orden de ambos se puede indicar con
/etc/host.conf pero es preferible usar
/etc/nsswitch.conf por ser más moderno.
41. 41
41Sockets IPv4 en Linux
Nombres de equipos
● Funciones:
– Grupo gethostbyname(3):
● Usa una estructura hostent para gestionar nombres, alias de nombres y una o
varias direcciones.
● Usa /etc/nsswitch.conf y quizás /etc/hosts, /etc/resolv.conf,...
● Reemplazada por getaddrinfo(3).
– Funciones para cliente DNS (no /etc/hosts): grupo resolver(3).
– Nombre del equipo local: gethostname(2), sethostname(2).
42. 42
42Sockets IPv4 en Linux
Nombres de protocolos
● Fichero /etc/protocols.
● Funciones: getprotobyname(3), ...
44. 44
44Sockets IPv4 en Linux
Nombres de servicios
● Fichero /etc/services.Cada línea especifica:
– El nombre y los posibles alias.
– El número y si va sobre TCP, UDP, DDP,...
– Posibles alias.
● Funciones:
– getservbyname(3): a partir de un nombre de servicio, proporciona
su nº de puerto, protocolo y alias mediante una estructura servent
– ...
45. 45
45Sockets IPv4 en Linux
Nombres de equipos y de servicios
● Funciones que combinan ambas búsquedas:
– getaddrinfo(3): combina las búsquedas de nombres
de equipos y de servicios.
– getnameinfo(3): inversa de getaddrinfo(3), busca
nombre a partir de dirección.