1 | |
1 | |
2 | /* |
2 | /* |
3 | * static char *rcsid_sockets_c = |
3 | * static char *rcsid_sockets_c = |
4 | * "$Id: lowlevel.c,v 1.2 2006/05/21 23:46:39 root Exp $"; |
4 | * "$Id: lowlevel.c,v 1.5 2006/06/16 10:15:22 root Exp $"; |
5 | */ |
5 | */ |
6 | |
6 | |
7 | /* |
7 | /* |
8 | CrossFire, A Multiplayer game for X-windows |
8 | CrossFire, A Multiplayer game for X-windows |
9 | |
9 | |
… | |
… | |
44 | |
44 | |
45 | #ifdef __linux__ |
45 | #ifdef __linux__ |
46 | # include <sys/types.h> |
46 | # include <sys/types.h> |
47 | # include <sys/socket.h> |
47 | # include <sys/socket.h> |
48 | # include <netinet/in.h> |
48 | # include <netinet/in.h> |
|
|
49 | # define TCP_HZ 1000 // sorry... |
49 | # include <netinet/tcp.h> |
50 | # include <netinet/tcp.h> |
50 | #endif |
51 | #endif |
51 | |
52 | |
|
|
53 | // use a really low timeout, as it doesn't cost any bandwidth, and you can |
|
|
54 | // easily die in 20 seconds... |
|
|
55 | #define SOCKET_TIMEOUT1 10 |
|
|
56 | #define SOCKET_TIMEOUT2 20 |
|
|
57 | |
52 | void Socket_Flush (NewSocket *ns) |
58 | void Socket_Flush (NewSocket *ns) |
53 | { |
59 | { |
54 | #ifdef __linux__ |
60 | #ifdef __linux__ |
|
|
61 | // check time of last ack, and, if too old, kill connection |
|
|
62 | struct tcp_info tcpi; |
|
|
63 | socklen_t len = sizeof (tcpi); |
|
|
64 | |
|
|
65 | if (!getsockopt (ns->fd, IPPROTO_TCP, TCP_INFO, &tcpi, &len) && len == sizeof (tcpi)) |
|
|
66 | { |
|
|
67 | unsigned int diff = tcpi.tcpi_last_ack_recv - tcpi.tcpi_last_data_sent; |
|
|
68 | |
|
|
69 | if (tcpi.tcpi_unacked |
|
|
70 | && SOCKET_TIMEOUT1 * TCP_HZ < diff && diff < 0x80000000UL // ack delayed for 20s |
|
|
71 | && SOCKET_TIMEOUT2 * TCP_HZ < tcpi.tcpi_last_data_sent) // no data sent for 10s |
|
|
72 | { |
|
|
73 | LOG (llevDebug, "Connection on fd %d closed due to ack timeout (%u/%u/%u)\n", ns->fd, |
|
|
74 | (unsigned)tcpi.tcpi_last_ack_recv, (unsigned)tcpi.tcpi_last_data_sent, (unsigned)tcpi.tcpi_unacked); |
|
|
75 | ns->status = Ns_Dead; |
|
|
76 | } |
|
|
77 | } |
|
|
78 | |
55 | int val; |
79 | int val; |
56 | val = 0; setsockopt (ns->fd, IPPROTO_TCP, TCP_CORK, &val, sizeof (val)); |
80 | val = 0; setsockopt (ns->fd, IPPROTO_TCP, TCP_CORK, &val, sizeof (val)); |
57 | val = 1; setsockopt (ns->fd, IPPROTO_TCP, TCP_CORK, &val, sizeof (val)); |
81 | val = 1; setsockopt (ns->fd, IPPROTO_TCP, TCP_CORK, &val, sizeof (val)); |
58 | #endif |
82 | #endif |
59 | } |
83 | } |