networking - netcat linux
Extraño comportamiento de netcat con UDP (3)
Cuando nc
está escuchando un socket UDP, ''se bloquea'' en el puerto de origen y la IP de origen del primer paquete que recibe. Mira este rastro:
socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP) = 3
setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(3, {sa_family=AF_INET, sin_port=htons(10000), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
recvfrom(3, "f/n", 2048, MSG_PEEK, {sa_family=AF_INET, sin_port=htons(52832), sin_addr=inet_addr("127.0.0.1")}, [16]) = 2
connect(3, {sa_family=AF_INET, sin_port=htons(52832), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
Aquí puede ver que creó un socket UDP, lo configuró para la reutilización de direcciones y lo vinculó al puerto 10,000. Tan pronto como recibió su primer datagrama (desde el puerto 52,832), emitió una llamada al sistema de conexión ''conectándolo'' al 127.0.0.1:52,832. Para UDP, una connect
rechaza todos los paquetes que no coinciden con la IP y el puerto en la connect
.
Noté un comportamiento extraño al trabajar con netcat y UDP. Comienzo una instancia (instancia 1) de netcat que escucha en un puerto UDP:
nc -lu -p 10000
Así que lanzo otra instancia de netcat (instancia 2) y trato de enviar datagramas a mi proceso:
nc -u 127.0.0.1 10000
Veo los datagramas. Pero si cierro la instancia 2 y reinicio netcat nuevamente (instancia 3):
nc -u 127.0.0.1 10000
No puedo ver datagramas en la terminal de la instancia 1. Obstinadamente, el sistema operativo asigna un puerto fuente UDP diferente en la instancia 3 respecto a la instancia 2 y el problema está ahí: si utilizo el mismo puerto fuente de la instancia 2 (ejemplo 50000):
nc -u -p 50000 127.0.0.1 10000
de nuevo, la instancia 1 de netcat recibe los datagramas. UDP es un protocolo de menos conexión, entonces, ¿por qué? ¿Es este un comportamiento estándar de netcat?
Después de haber renunciado a netcat en mi versión del sistema operativo, esto es bastante corto y hace el trabajo:
#!/usr/bin/ruby
# Receive UDP packets bound for a port and output them
require ''socket''
require ''yaml''
unless ARGV.count == 2
puts "Usage: #{$0} listen_ip port_number"
exit(1)
end
listen_ip = ARGV[0]
port = ARGV[1].to_i
u1 = UDPSocket.new
u1.bind(listen_ip, port)
while true
mesg, addr = u1.recvfrom(100000)
puts mesg
end
Use la opción -k
:
nc -l -u -k 0.0.0.0 10000
- -k significa keep-alive, que netcat sigue escuchando después de cada conexión
- -u significa UDP
- -l escuchando en el puerto 10000