kern/71274: Frequent bind()/connect()'s assign same local ports to
different sockets
Dmitry Dvoinikov
dmitry at targeted.org
Wed Sep 1 23:10:20 PDT 2004
>Number: 71274
>Category: kern
>Synopsis: Frequent bind()/connect()'s assign same local ports to different sockets
>Confidential: no
>Severity: serious
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Thu Sep 02 06:10:20 GMT 2004
>Closed-Date:
>Last-Modified:
>Originator: Dmitry Dvoinikov
>Release: 4.10-RELEASE
>Organization:
-
>Environment:
FreeBSD 4.10-RELEASE FreeBSD 4.10-RELEASE #0: Tue May 25 22:47:12 GMT 2004 root at perseus.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC i386
>Description:
1. A program keeps looping forever creating TCP sockets and connecting them to some TCP server in a connect/send/recv/close fashion (sample uses HTTP server at localhost).
2. Each outgoing socket is assigned a local port number, either explicitly (with bind to zero port before connect) or implicitly (within connect).
3. After this program runs for a while, it happens that another port number assigned has just been used a few connects ago (and that used socket is probably not free, but is still alive in TIME_WAIT or some other near-terminal state). Therefore this second connect gets a port number which is not free, and therefore connect fails returning "Connection refused".
4. This is not a resource exhaustion problem, as netstat output shows only around a thousand sockets.
5. This is not a congestion problem, because the looping program is single-threaded and can't produce more than one connection at a time.
>How-To-Repeat:
Compile an run this program, having http server at localhost:80 (I used thttpd for it's lightweightness, but even http doesn't really matter of course, it's just any TCP server). Examine program's output for the following pattern:
bound to 2664
bound to 1267 <<<<< REPEATS
bound to 4646
bound to 3060
bound to 1374
bound to 4986
bound to 1267 <<<<< REPEATS
connect failed: Connection refused
------------------------------------------------
base64 encoded sample:
------------------------------------------------
begin-base64 644 test.c
I2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3NvY2tldC5oPgojaW5jbHVkZSA8
c3RkaW8uaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRl
IDxuZXRpbmV0L2luLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNp
bmNsdWRlIDxzeXMvcGFyYW0uaD4KCmNoYXIqIFJFUVVFU1QgPSAiR0VUIC8gSFRUUC8xLjBcclxu
XHJcbiI7CgppbnQgbWFpbigpCnsKCiAgICAgICAgaW50IHMsIHVudXNlZDsKICAgICAgICBzdHJ1
Y3Qgc29ja2FkZHJfaW4gYTsKICAgICAgICBjaGFyIGJ1ZlsxMDI0XTsKCiAgICAgICAgbWVtc2V0
KCZhLCAwLCBzaXplb2Yoc3RydWN0IHNvY2thZGRyX2luKSk7CiAgICAgICAgYS5zaW5fbGVuID0g
c2l6ZW9mKHN0cnVjdCBzb2NrYWRkcl9pbik7CiAgICAgICAgYS5zaW5fZmFtaWx5ID0gQUZfSU5F
VDsKICAgICAgICBhLnNpbl9hZGRyLnNfYWRkciA9IGh0b25sKDB4N2YwMDAwMDEpOwoKICAgICAg
ICB3aGlsZSAoMSkKICAgICAgICB7CgogICAgICAgICAgICAgICAgcyA9IHNvY2tldChQRl9JTkVU
LCBTT0NLX1NUUkVBTSwgMCk7CgkJaWYgKHMgPT0gLTEpCgkJewoJCQlmcHJpbnRmKHN0ZG91dCwg
InNvY2tldCBmYWlsZWQ6ICVzXG4iLCBzdHJlcnJvcihlcnJubykpOwoJCQljb250aW51ZTsKCQl9
CgogICAgICAgICAgICAgICAgYS5zaW5fcG9ydCA9IDA7CiAgICAgICAgICAgICAgICBpZiAoYmlu
ZChzLCAoc3RydWN0IHNvY2thZGRyKikmYSwgc2l6ZW9mKHN0cnVjdCBzb2NrYWRkcl9pbikpID09
IC0xKQoJCXsKCQkJY2xvc2Uocyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZwcmludGYoc3Rk
b3V0LCAiYmluZCBmYWlsZWQ6ICVzXG4iLCBzdHJlcnJvcihlcnJubykpOyAKICAgICAgICAgICAg
ICAgICAgICAgICAgY29udGludWU7CgkJfQoKICAgICAgICAgICAgICAgIHVudXNlZCA9IHNpemVv
ZihzdHJ1Y3Qgc29ja2FkZHJfaW4pOwogICAgICAgICAgICAgICAgaWYgKGdldHNvY2tuYW1lKHMs
IChzdHJ1Y3Qgc29ja2FkZHIqKSZhLCAmdW51c2VkKSA9PSAtMSkKCQl7CiAgICAgICAgICAgICAg
ICAgICAgICAgIGNsb3NlKHMpOwogICAgICAgICAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZG91
dCwgImdldHNvY2tuYW1lIGZhaWxlZDogJXNcbiIsIHN0cmVycm9yKGVycm5vKSk7ICAgICAgICAg
ICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsgCgkJfQoKICAgICAg
ICAgICAgICAgIGZwcmludGYoc3Rkb3V0LCAiYm91bmQgdG8gJWRcbiIsICh1bnNpZ25lZCBsb25n
KW50b2hzKGEuc2luX3BvcnQpKTsKCiAgICAgICAgICAgICAgICBhLnNpbl9wb3J0ID0gaHRvbnMo
ODApOwogICAgICAgICAgICAgICAgaWYgKGNvbm5lY3QocywgKHN0cnVjdCBzb2NrYWRkciopJmEs
IHNpemVvZihzdHJ1Y3Qgc29ja2FkZHJfaW4pKSA9PSAtMSkKICAgICAgICAgICAgICAgIHsKICAg
ICAgICAgICAgICAgICAgICAgICAgY2xvc2Uocyk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZw
cmludGYoc3Rkb3V0LCAiY29ubmVjdCBmYWlsZWQ6ICVzXG4iLCBzdHJlcnJvcihlcnJubykpOwog
ICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KCiAgICAg
ICAgICAgICAgICBzZW5kKHMsIFJFUVVFU1QsIHN0cmxlbihSRVFVRVNUKSwgMCk7CiAgICAgICAg
ICAgICAgICB3aGlsZSAocmVjdihzLCBidWYsIHNpemVvZihidWYpLCAwKSA+IDApIHsgfQogICAg
ICAgICAgICAgICAgY2xvc2Uocyk7CgogICAgICAgIH0KCn0KCg==
====
------------------------------------------------
plain (broken ?) sample:
------------------------------------------------
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <string.h>
#include <errno.h>
#include <sys/param.h>
char* REQUEST = "GET / HTTP/1.0\r\n\r\n";
int main()
{
int s, unused;
struct sockaddr_in a;
char buf[1024];
memset(&a, 0, sizeof(struct sockaddr_in));
a.sin_len = sizeof(struct sockaddr_in);
a.sin_family = AF_INET;
a.sin_addr.s_addr = htonl(0x7f000001);
while (1)
{
s = socket(PF_INET, SOCK_STREAM, 0);
if (s == -1)
{
fprintf(stdout, "socket failed: %s\n", strerror(errno));
continue;
}
a.sin_port = 0;
if (bind(s, (struct sockaddr*)&a, sizeof(struct sockaddr_in)) == -1)
{
close(s);
fprintf(stdout, "bind failed: %s\n", strerror(errno));
continue;
}
unused = sizeof(struct sockaddr_in);
if (getsockname(s, (struct sockaddr*)&a, &unused) == -1)
{
close(s);
fprintf(stdout, "getsockname failed: %s\n", strerror(errno));
continue;
}
fprintf(stdout, "bound to %d\n", (unsigned long)ntohs(a.sin_port));
a.sin_port = htons(80);
if (connect(s, (struct sockaddr*)&a, sizeof(struct sockaddr_in)) == -1)
{
close(s);
fprintf(stdout, "connect failed: %s\n", strerror(errno));
continue;
}
send(s, REQUEST, strlen(REQUEST), 0);
while (recv(s, buf, sizeof(buf), 0) > 0) { }
close(s);
}
}
------------------------------------------------
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list