Messages in this thread | | | Date | Fri, 12 Nov 1999 20:08:22 +0100 | From | Nicolas DE METZ-NOBLAT <> | Subject | Linux RedHat 6.x bug: IPv4/UDP bind() allocates same port number by default |
| |
[1.] IPv4/UDP bind() allocates same port number by default.
[2.] Full description of the problem/report:
When dynamically binding a new UDP socket to a port, the bind() system usually returns the same value, and this confuses remote UDP servers for a few minutes timeouts.
The reason is that the next eligible value used is the last allocated value (if freed) and not the next one.
Urgency: HIGH because may affect portability and interoperbility of applications using UDP protocol.
May need to be applied to older kernel versions.
[3.] Keywords: networking, ip, udp, bind :
[4.] Kernel version (from /proc/version): Linux version 2.2.12-20 (root@porky.devel.redhat.com) (gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)) #1 Mon Sep 27 10:40:35 EDT 1999
But apparently still present in kernel 2.3.27 looking at the source even if routine name changed in file linux/net/ipv4/udp.c
[5.] No OOPS message
[6.] Example:
------------------ begin example.c ------------------------
#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h>
struct sockaddr_in sin_from; struct sockaddr_in sin_read;
void test_socket(void) { int s; int p; int l;
if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { perror("socket"); exit(2); }
memset((char*)&sin_from, '\0', sizeof(sin_from)); sin_from.sin_family = AF_INET; sin_from.sin_addr.s_addr = htonl(INADDR_ANY); sin_from.sin_port = 0; if (bind(s, (struct sockaddr *)&sin_from, sizeof(sin_from)) < 0) { perror("bind"); exit(2); }
l = sizeof(sin_read); if (getsockname(s, &sin_read, &l) < 0) { perror("getsockname"); exit(2); }
p = ntohs(sin_read.sin_port); printf("Allocated port number = %d\n", p);
close(s); return; } main(int argc, char **argv) {
test_socket(); test_socket(); } ------------------ end example.c ------------------------
Output on Linux RedHat 6.1: Allocated port number = 1116 Allocated port number = 1116
Output on Solaris 2.6: Allocated port number = 44798 Allocated port number = 44799
Output on AIX 4.2.1: Allocated port number = 1151 Allocated port number = 1152
Output on LynxOS 2.5.1 (BSD 4.4 networking): Allocated port number = 3002 Allocated port number = 3003
Only Linux reports twice the same value and this explains other problems when using UDP protocol, like confused remote servers: I have some programs that run once without any problem, but if restarted without waiting for at least 2 minutes, the remote server just refuse the connection, because the port number and all other informations are identical to the previous connection.
[7.] Environment This is just RedHat 6.1 standard distribution (+ AFS 3.5 patch 2 from Transarc, but this is not relevant).
[7.1.] Software (add the output of the ver_linux script here)
-- Versions installed: (if some fields are empty or look -- unusual then possibly you have very old versions) Linux pspc7811 2.2.12-20 #1 Mon Sep 27 10:40:35 EDT 1999 i686 unknown Kernel modules 2.1.121 Gnu C egcs-2.91.66 Binutils 2.9.1.0.24 Linux C Library 2.1.2 Dynamic linker ldd (GNU libc) 2.1.2 Procps 2.0.4 Mount 2.9u Net-tools 1.53 Console-tools 1999.03.02 Sh-utils 2.0 Sh-utils Parker. Sh-utils Sh-utils Inc. Sh-utils NO Sh-utils PURPOSE. Modules Loaded nfs lockd sunrpc autofs libafs-2.2.10 eepro100 nls_iso8859-1 nls_cp437 vfat fat opl3 sb uart401 sound soundlow soundcore
[7.2.] Processor information (from /proc/cpuinfo):
processor : 0 vendor_id : GenuineIntel cpu family : 6 model : 5 model name : Pentium II (Deschutes) stepping : 2 cpu MHz : 300.688613 cache size : 512 KB fdiv_bug : no hlt_bug : no sep_bug : no f00f_bug : no coma_bug : no fpu : yes fpu_exception : yes cpuid level : 2 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 sep mtrr pge mca cmov pat pse36 mmx osfxsr bogomips : 299.83
[7.3.] Module information (from /proc/modules):
nfs 29656 2 (autoclean) lockd 30984 0 (autoclean) [nfs] sunrpc 52516 1 (autoclean) [nfs lockd] autofs 8964 3 (autoclean) libafs-2.2.10 353060 1 eepro100 12112 1 (autoclean) nls_iso8859-1 2020 1 (autoclean) nls_cp437 3548 1 (autoclean) vfat 9180 1 (autoclean) fat 30464 1 (autoclean) [vfat] opl3 11208 0 (unused) sb 33620 0 uart401 5968 0 [sb] sound 57240 0 [opl3 sb uart401] soundlow 300 0 [sound] soundcore 2372 6 [sb sound]
[7.4.] SCSI information (from /proc/scsi/scsi)
none
[X.] Other notes, patches, fixes, workarounds:
For kernel 2.2.12 in file /usr/src/linux/net/ipv4/udp.c, after line 171, in routine udp_v4_get_port(), a line udp_port_rover++; should be added once assigned a new value.
For kernel 2.3.27, this applies after line 173.
For kernel 2.2.5, the change is in routine udp_good_socknum() after line 225, add the line: start++;
Nicolas -- Nicolas de METZ-NOBLAT Phone: +41 22 76 72023 (direct) CERN - PS division +41 79 201 3070 CH-1211 Geneva 23 Fax: +41 22 76 79145 Switzerland mailto:Nicolas.de.Metz-Noblat@cern.ch
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |