explicit connection confirmation
Subsystems (4)
RFC PATCH 1/1 explicit connection confirmation
(please CC on replies, I am not on this list)
Hi,
This patch gives userland the ability to decide whether to react with an incoming TCP SYN with a SYN-ACK or a RST. It was hacked up after Linux Kongress 2001 and has been sitting on my patch pile since april this year or something.
The basic idea is this:
- Put the listening TCP socket in TCP_CONFIRM_CONNECT mode.
- Sockets returned from accept() on this socket after this will be sockets in the SYN_RECV state instead of the ESTABLISHED state (unless syncookies had to be used). By writing to the socket, you cause a SYN-ACK to be sent, and by immediately closing the socket you cause a RST to be sent.
There are two issues left, AFAICS:
- SYN_RECV sockets currently don't time out for some reason
- it deadlocks instantly on SMP
It's against 2.4.18. Could someone have a look at it please? I unfortunately haven't had any time at all lately, so I would be really happy if someone else could take this over. (Well, I can dream, can't I?)
cheers,
Lennert
include/linux/tcp.h renamed from include/linux/tcp.h.orig +1 -0
@@ -127,6 +127,7 @@#define TCP_WINDOW_CLAMP 10/* Bound advertised window */ #define TCP_INFO 11/* Information about this connection. */ #define TCP_QUICKACK 12/* Block/reenable quick acks */ +#define TCP_CONFIRM_CONNECT 13/* Let user control connection acceptance */ #define TCPI_OPT_TIMESTAMPS 1#define TCPI_OPT_SACK 2
include/net/sock.h renamed from include/net/sock.h.orig +6 -0
@@ -302,6 +302,7 @@__u8 reordering;/* Packet reordering metric. */ __u8 queue_shrunk;/* Write queue has been shrunk recently.*/ __u8 defer_accept;/* User waits for some data after accept() */ +__u8 confirm_connect;/* User wants control over conn. acceptance */ /* RTT measurement */ __u8 backoff;/* backoff */
@@ -411,6 +412,11 @@struct open_request *accept_queue;struct open_request *accept_queue_tail; +/* Our corresponding open_request if this socket is unconfirmed +* (i.e. if we haven't sent SYN-ACK or RST yet) +*/ +struct open_request *unconfirmed_openreq; +int write_pending;/* A write to socket waits to start. */ unsigned int keepalive_time;/* time before keep alive takes place */
include/net/tcp.h renamed from include/net/tcp.h.orig +14 -1
@@ -505,7 +505,8 @@ sack_ok : 1, wscale_ok : 1, ecn_ok : 1, - acked : 1; + acked : 1, + unconfirmed : 1;/* The following two fields can be easily recomputed I think -AK */ __u32 window_clamp;/* window clamp at creation time */ __u32 rcv_wnd;/* rcv_wnd offered first time */
@@ -533,6 +534,17 @@tcp_openreq_fastfree (req); } +static inline int tcp_is_unconfirmed (struct tcp_opt *tp) +{ +struct open_request *req; + + req = tp->unconfirmed_openreq; +if (req !=NULL && req->unconfirmed) +return 1 ; + +return 0 ; +} +#if defined(CONFIG_IPV6 ) || defined(CONFIG_IPV6_MODULE )#define TCP_INET_FAMILY (fam) ((fam) == AF_INET)#else
@@ -1661,6 +1673,7 @@ req->acked =0 ; req->ecn_ok =0 ; req->rmt_port = skb->h.th->source; + req->unconfirmed =0 ; }#define TCP_MEM_QUANTUM ((int)PAGE_SIZE)
net/ipv4/tcp.c renamed from net/ipv4/tcp.c.orig +39 -5
109 lines not on this page · raw message
net/ipv4/tcp_input.c renamed from net/ipv4/tcp_input.c.orig +5 -0
@@ -3749,6 +3749,11 @@switch (sk->state) {case TCP_SYN_RECV :if (acceptable) { +if (tp->unconfirmed_openreq !=NULL ) { +tcp_openreq_free (tp->unconfirmed_openreq); + tp->unconfirmed_openreq =NULL ; + } + tp->copied_seq = tp->rcv_nxt;mb ();tcp_set_state (sk,TCP_ESTABLISHED );
net/ipv4/tcp_minisocks.c renamed from net/ipv4/tcp_minisocks.c.orig +10 -2
@@ -696,6 +696,7 @@tcp_init_wl (newtp, req->snt_isn, req->rcv_isn); newtp->retransmits =0 ; + newtp->confirm_connect =0 ; newtp->backoff =0 ; newtp->srtt =0 ; newtp->mdev =TCP_TIMEOUT_INIT ;
@@ -839,7 +840,8 @@* Enforce "SYN-ACK" according to figure 8, figure 6 * of RFC793, fixed by RFC1122. */ - req->class->rtx_syn_ack (sk, req,NULL ); +if (!req->unconfirmed) + req->class->rtx_syn_ack (sk, req,NULL );return NULL ; }
@@ -864,7 +866,7 @@if (paws_reject || !tcp_in_window (TCP_SKB_CB (skb)->seq,TCP_SKB_CB (skb)->end_seq, req->rcv_isn+1 , req->rcv_isn+1 +req->rcv_wnd)) {/* Out of window: send ACK and drop. */ -if (!(flg &TCP_FLAG_RST )) +if (!req->unconfirmed && !(flg &TCP_FLAG_RST )) req->class->send_ack (skb, req);if (paws_reject)NET_INC_STATS_BH (PAWSEstabRejected);
@@ -907,6 +909,12 @@return NULL ; } +/* @@@ If we are in SYN_RECV and haven't confirmed/rejected +* the connection yet, this ACK is acking a never-sent packet. +*/ +if (tcp_is_unconfirmed (tp)) +return NULL ; +/* OK, ACK is valid, create big socket and * feed this segment to it. It will repeat all * the tests. THIS SEGMENT MUST MOVE SOCKET TO
net/ipv4/tcp_ipv4.c renamed from net/ipv4/tcp_ipv4.c.orig +26 -1
@@ -1270,12 +1270,14 @@int tcp_v4_conn_request (struct sock *sk,struct sk_buff *skb) { +struct tcp_opt *master_tp = &(sk->tp_pinfo.af_tcp);struct tcp_opt tp;struct open_request *req;__u32 saddr = skb->nh.iph->saddr;__u32 daddr = skb->nh.iph->daddr;__u32 isn =TCP_SKB_CB (skb)->when;struct dst_entry *dst =NULL ; +int dont_confirm =0 ;#ifdef CONFIG_SYN_COOKIES int want_cookie =0 ;#else
@@ -1312,6 +1314,9 @@if (req ==NULL ) goto drop; +if (!want_cookie && master_tp->confirm_connect) + dont_confirm =1 ; +tcp_clear_options (&tp); tp.mss_clamp =536 ; tp.user_mss = sk->tp_pinfo.af_tcp.user_mss;
@@ -1396,11 +1401,31 @@ } req->snt_isn = isn; -if (tcp_v4_send_synack (sk, req, dst)) +if (!dont_confirm &&tcp_v4_send_synack (sk, req, dst)) goto drop_and_free;if (want_cookie) {tcp_openreq_free (req); + }else if (dont_confirm) { +struct sock *child; +__u8 rcv_wscale; + + req->window_clamp = dst?dst->window:0 ; +tcp_select_initial_window (tcp_full_space (sk), req->mss, + &req->rcv_wnd, &req->window_clamp, +0 , &rcv_wscale); + req->rcv_wscale = rcv_wscale; + + child =tcp_v4_syn_recv_sock (sk, skb, req,NULL ); +if (child !=NULL ) { + req->unconfirmed =1 ; + child->tp_pinfo.af_tcp.unconfirmed_openreq = req; +tcp_acceptq_queue (sk, req, child); + sk->data_ready (sk,0 ); +sock_put (child); + }else { +tcp_openreq_free (req); + } }else {tcp_v4_synq_add (sk, req); }
net/ipv4/tcp_timer.c renamed from net/ipv4/tcp_timer.c.orig +2 -1
@@ -512,7 +512,8 @@if ((long )(now - req->expires) >=0 ) {if ((req->retrans < thresh || (req->acked && req->retrans < max_retries)) - && !req->class->rtx_syn_ack (sk, req,NULL )) { + && (req->unconfirmed || + !req->class->rtx_syn_ack (sk, req,NULL ))) {unsigned long timeo;if (req->retrans++ ==0 )
net/ipv4/af_inet.c renamed from net/ipv4/af_inet.c.orig +1 -1
@@ -693,7 +693,7 @@lock_sock (sk2); -BUG_TRAP ((1 <<sk2->state)&(TCPF_ESTABLISHED |TCPF_CLOSE_WAIT |TCPF_CLOSE )); +BUG_TRAP ((1 <<sk2->state)&(TCPF_SYN_RECV |TCPF_ESTABLISHED |TCPF_CLOSE_WAIT |TCPF_CLOSE ));sock_graft (sk2, newsock);
Quoted 5 lines · Lennert Buytenhek
- Sockets returned from
accept()on this socket after this will be sockets in theSYN_RECVstate instead of the ESTABLISHED state (unless syncookies had to be used). By writing to the socket, you cause a SYN-ACK to be sent, and by immediately closing the socket you cause a RST to be sent.
And reading, like a webserver would do? I think this approach smells, btw - doesn't this mean that processes will now be woken up on receiving a SYN instead of after completion of the handshake?
Would make a synflood all the more interesting..
Regards,
bert
Signature · 2 lines
http://www.PowerDNS.com Versatile DNS Software & Services http://lartc.org Linux Advanced Routing & Traffic Control HOWTO
Quoted 7 lines · bert hubert
Quoted 5 lines
- Sockets returned from
accept()on this socket after this will be sockets in theSYN_RECVstate instead of the ESTABLISHED state (unless syncookies had to be used). By writing to the socket, you cause a SYN-ACK to be sent, and by immediately closing the socket you cause a RST to be sent.And reading, like a webserver would do?
Will do nothing, but this can easily be changed.
I remind you of the fact that this option has to be explicitly enabled on a listening socket, so that apps have to be adapted to use the new interface anyway.
Quoted 3 lines
I think this approach smells, btw - doesn't this mean that processes will now be woken up on receiving a SYN instead of after completion of the handshake?
Yes, it does mean this. You are free to suggest alternatives.
Quoted 1 line
Would make a synflood all the more interesting..
In case of a synflood, the TCP stack will fall back to sending syncookies as it normally does.
cheers,
Lennert
Could you not have used netfilter for this? You have the app sending controls to add netfilter policies and delete them when not needed.
cheers,
jamal
Hi,
netfilter, yeah, sure, 'could have', but please.
'Make it a netfilter module' is generally what people say when they are confronted with a feature they don't like.
There was a thread about this in private mail round April this year, in which some good points were raised.
- From the kernel point of view, doing it in netfilter would require more state tracking and access to the socket hashes and would be uglier.
- From the application writer's point of view, doing it via a socket option is much more intuitive, since this flag is really a socket property, than doing it via some extra API which would make it way too difficult/complex to use in existing apps.
It's worth noting that selective TCP connection acceptance was also intended to be implemented as a socket option by the original BSD developers. See http://www.kohala.com/start/vanj.94jun27.txt
(link thanks to Marc Boucher).
Quoted 1 line
From the accept(2) man page on Red Hat Linux (again thanks to Marc
Boucher):
For certain protocols which require an explicit confirmation, such as DECNet, accept can be thought of as merely dequeuing the next connec-
tion request and not implying confirmation. Confirmation can be
implied by a normal read or write on the new file descriptor, and rejection can be implied by closing the new socket. Currently only DEC- Net has these semantics on Linux.
cheers,
Lennert
Quoted 9 lines · jamal
Could you not have used netfilter for this? You have the app sending controls to add netfilter policies and delete them when not needed.
cheers,
jamal
Quoted 3 lines · Lennert Buytenhek
Hi,
netfilter, yeah, sure, 'could have', but please.
apology if i sounded like one of those adolescent netfilter dangerous fools who show up with "mama, look what i can do with a packet now that ive read netfilter docs"
Quoted 3 lines
'Make it a netfilter module' is generally what people say when they are confronted with a feature they don't like.
My angle was to avoid being intrusive to the tcp code. you might get a fish sent to you in .nl in an armani suit;->
Quoted 4 lines
There was a thread about this in private mail round April this year, in which some good points were raised.
There are some good points; however, whats the app for this feature?
cheers,
jamal
Quoted 4 lines · jamal
Quoted 2 lines
There was a thread about this in private mail round April this year, in which some good points were raised.
There are some good points; however, whats the app for this feature?
This came up a long time ago on bugtraq in a discussion how to easily prevent certain IP addresses from DoSsing your TCP daemon. Right now, userspace is always forced to complete the threeway handshake, and can only then close the socket.
Even rather small amounts of SYN packets can thus easily saturate a server which has decided to handle only 100 connections AND has decided to ignore a certain IP address. Some inetd superservers contain code to ratelimit IP addresses which sadly is not as effective from userspace as it could be with the ability to RST a connection immediately.
It also allows userspace to simulate that a service isn't even there, without root capabilities.
Regards,
bert
Signature · 2 lines
http://www.PowerDNS.com Versatile DNS Software & Services http://lartc.org Linux Advanced Routing & Traffic Control HOWTO
it would also be useful for transparent proxying. presently all connections diverted to a proxy are immediately accepted, regardless of whether the second connection (proxy->real destination) succeeds or not.
Quoted 29 lines · bert hubert
Quoted 4 lines · jamal
Quoted 2 lines
There was a thread about this in private mail round April this year, in which some good points were raised.
There are some good points; however, whats the app for this feature?
This came up a long time ago on bugtraq in a discussion how to easily prevent certain IP addresses from DoSsing your TCP daemon. Right now, userspace is always forced to complete the threeway handshake, and can only then close the socket.
Even rather small amounts of SYN packets can thus easily saturate a server which has decided to handle only 100 connections AND has decided to ignore a certain IP address. Some inetd superservers contain code to ratelimit IP addresses which sadly is not as effective from userspace as it could be with the ability to RST a connection immediately.
It also allows userspace to simulate that a service isn't even there, without root capabilities.
Regards,
bert
Signature · 2 lines
http://www.PowerDNS.com Versatile DNS Software & Services http://lartc.org Linux Advanced Routing & Traffic Control HOWTO
Quoted 5 lines · jamal
Quoted 1 line
netfilter, yeah, sure, 'could have', but please.
apology if i sounded like one of those adolescent netfilter dangerous fools who show up with "mama, look what i can do with a packet now that ive read netfilter docs"
No, you don't sound such, sorry for reacting the way i did.
Quoted 5 lines
Quoted 2 lines
'Make it a netfilter module' is generally what people say when they are confronted with a feature they don't like.
My angle was to avoid being intrusive to the tcp code. you might get a fish sent to you in .nl in an armani suit;->
Sorry but I don't like fish nor armani suits :-)
Quoted 4 lines
Quoted 2 lines
There was a thread about this in private mail round April this year, in which some good points were raised.
There are some good points; however, whats the app for this feature?
My specific application is a proxy application that replaces the in-kernel IP masquerading functionality, using a wildcard REDIRECT rule plus SO_ORIGINAL_DST. The main reason I'm doing it in userspace is because downstream bandwidth limiting becomes a whole lot easier this way than doing it in-kernel -- it would need complicated state tracking and nonobvious window field manipulations if done there.
The applications that Bert and Marc named sound sane too. There's just a whole lot of things this thing can be used for.
cheers,
Lennert
Quoted 5 lines · Lennert Buytenhek
Quoted 3 lines
I think this approach smells, btw - doesn't this mean that processes will now be woken up on receiving a SYN instead of after completion of the handshake?
Yes, it does mean this. You are free to suggest alternatives.
I like having this ability - I dislike offering it to an unsuspecting userspace.
Quoted 4 lines
Quoted 1 line
Would make a synflood all the more interesting..
In case of a synflood, the TCP stack will fall back to sending syncookies as it normally does.
Yes, but in your setup, a spoofable SYN packet will spawn a process for many daemons, unless they are modified to first try to read/write to the socket (which might block!) before forking/pthread_create()ing.
Regards,
bert
Signature · 2 lines
http://www.PowerDNS.com Versatile DNS Software & Services http://lartc.org Linux Advanced Routing & Traffic Control HOWTO
Quoted 8 lines · bert hubert
Quoted 5 lines
Quoted 3 lines
I think this approach smells, btw - doesn't this mean that processes will now be woken up on receiving a SYN instead of after completion of the handshake?
Yes, it does mean this. You are free to suggest alternatives.
I like having this ability - I dislike offering it to an unsuspecting userspace.
Userspace needs to turn on the option first, so your 'unsuspecting' does not apply.
Quoted 8 lines
Quoted 4 lines
Quoted 1 line
Would make a synflood all the more interesting..
In case of a synflood, the TCP stack will fall back to sending syncookies as it normally does.
Yes, but in your setup, a spoofable SYN packet will spawn a process for many daemons, unless they are modified to first try to read/write to the socket (which might block!) before forking/pthread_create()ing.
Again, if the app decides to turn on TCP_CONFIRM_CONNECT, then it's up to the app to deal with it properly. There are very good reasons for not turning on TCP_CONFIRM_CONNECT by default, which is why it is not on by default, and why grafting a setsockopt onto every daemon there is out there is definitely not a good idea.
cheers,
Lennert
Quoted 5 lines · Lennert Buytenhek
Quoted 2 lines
I like having this ability - I dislike offering it to an unsuspecting userspace.
Userspace needs to turn on the option first, so your 'unsuspecting' does not apply.
Ah ok, I thought 'TCP_CONFIRM_CONNECT' was a TCP connection state like SYN_RECV.
Quoted 5 lines
Again, if the app decides to turn on
TCP_CONFIRM_CONNECT, then it's up to the app to deal with it properly. There are very good reasons for not turning onTCP_CONFIRM_CONNECTby default, which is why it is not on by default, and why grafting a setsockopt onto every daemon there is out there is definitely not a good idea.
Exactly. Ok, cool.
Regards,
bert
Signature · 2 lines
http://www.PowerDNS.com Versatile DNS Software & Services http://lartc.org Linux Advanced Routing & Traffic Control HOWTO
RFC PATCH 1/1 explicit connection confirmation
In reply to Lennert BuytenhekHi,
Below is the original email I sent to netdev about nine months ago announcing selective connection acceptance support for TCP sockets. I have forward-ported the 2.4.18 patch to 2.6.0-test2, included below. No functional changes have been made.
Could someone have a look at it?
cheers,
Lennert
Quoted 21 lines · buytenh
(please CC on replies, I am not on this list)
Hi,
This patch gives userland the ability to decide whether to react with an incoming TCP SYN with a SYN-ACK or a RST. It was hacked up after Linux Kongress 2001 and has been sitting on my patch pile since april this year or something.
The basic idea is this:
- Put the listening TCP socket inTCP_CONFIRM_CONNECTmode.
- Sockets returned fromaccept()on this socket after this will be sockets in theSYN_RECVstate instead of the ESTABLISHED state (unless syncookies had to be used). By writing to the socket, you cause a SYN-ACK to be sent, and by immediately closing the socket you cause a RST to be sent.There are two issues left, AFAICS:
-SYN_RECVsockets currently don't time out for some reason
- it deadlocks instantly on SMP
Quoted 9 lines
It's against 2.4.18. Could someone have a look at it please? I unfortunately haven't had any time at all lately, so I would be really happy if someone else could take this over. (Well, I can dream, can't I?)
cheers,
Lennert
include/linux/tcp.h renamed from include/linux/tcp.h.orig +7 -0
@@ -127,6 +127,7 @@#define TCP_WINDOW_CLAMP 10/* Bound advertised window */ #define TCP_INFO 11/* Information about this connection. */ #define TCP_QUICKACK 12/* Block/reenable quick acks */ +#define TCP_CONFIRM_CONNECT 13/* Let user control connection acceptance */ #define TCPI_OPT_TIMESTAMPS 1#define TCPI_OPT_SACK 2
@@ -257,6 +258,7 @@__u8 reordering;/* Packet reordering metric. */ __u8 queue_shrunk;/* Write queue has been shrunk recently.*/ __u8 defer_accept;/* User waits for some data after accept() */ +__u8 confirm_connect;/* User wants control over conn. acceptance */ /* RTT measurement */ __u8 backoff;/* backoff */
@@ -364,6 +366,11 @@struct open_request *accept_queue;struct open_request *accept_queue_tail; +/* Our corresponding open_request if this socket is unconfirmed +* (i.e. if we haven't sent SYN-ACK or RST yet) +*/ +struct open_request *unconfirmed_openreq; +int write_pending;/* A write to socket waits to start. */ unsigned int keepalive_time;/* time before keep alive takes place */
include/net/tcp.h renamed from include/net/tcp.h.orig +14 -1
@@ -591,7 +591,8 @@ sack_ok : 1, wscale_ok : 1, ecn_ok : 1, - acked : 1; + acked : 1, + unconfirmed : 1;/* The following two fields can be easily recomputed I think -AK */ __u32 window_clamp;/* window clamp at creation time */ __u32 rcv_wnd;/* rcv_wnd offered first time */
@@ -619,6 +620,17 @@tcp_openreq_fastfree (req); } +static inline int tcp_is_unconfirmed (struct tcp_opt *tp) +{ +struct open_request *req; + + req = tp->unconfirmed_openreq; +if (req !=NULL && req->unconfirmed) +return 1 ; + +return 0 ; +} +#if defined(CONFIG_IPV6 ) || defined(CONFIG_IPV6_MODULE )#define TCP_INET_FAMILY (fam) ((fam) == AF_INET)#else
@@ -1762,6 +1774,7 @@ req->acked =0 ; req->ecn_ok =0 ; req->rmt_port = skb->h.th->source; + req->unconfirmed =0 ; }#define TCP_MEM_QUANTUM ((int)PAGE_SIZE)
net/ipv4/af_inet.c renamed from net/ipv4/af_inet.c.orig +2 -2
@@ -685,8 +685,8 @@lock_sock (sk2); -BUG_TRAP ((1 << sk2->sk_state) & - (TCPF_ESTABLISHED |TCPF_CLOSE_WAIT |TCPF_CLOSE )); +BUG_TRAP ((1 << sk2->sk_state) & (TCPF_SYN_RECV |TCPF_ESTABLISHED | +TCPF_CLOSE_WAIT |TCPF_CLOSE ));sock_graft (sk2, newsock);
net/ipv4/tcp.c renamed from net/ipv4/tcp.c.orig +39 -5
109 lines not on this page · raw message
net/ipv4/tcp_input.c renamed from net/ipv4/tcp_input.c.orig +5 -0
@@ -3938,6 +3938,11 @@switch (sk->sk_state) {case TCP_SYN_RECV :if (acceptable) { +if (tp->unconfirmed_openreq !=NULL ) { +tcp_openreq_free (tp->unconfirmed_openreq); + tp->unconfirmed_openreq =NULL ; + } + tp->copied_seq = tp->rcv_nxt;mb ();tcp_set_state (sk,TCP_ESTABLISHED );
net/ipv4/tcp_ipv4.c renamed from net/ipv4/tcp_ipv4.c.orig +26 -1
@@ -1403,12 +1403,14 @@int tcp_v4_conn_request (struct sock *sk,struct sk_buff *skb) { +struct tcp_opt *master_tp =tcp_sk (sk);struct tcp_opt tp;struct open_request *req;__u32 saddr = skb->nh.iph->saddr;__u32 daddr = skb->nh.iph->daddr;__u32 isn =TCP_SKB_CB (skb)->when;struct dst_entry *dst =NULL ; +int dont_confirm =0 ;#ifdef CONFIG_SYN_COOKIES int want_cookie =0 ;#else
@@ -1445,6 +1447,9 @@if (!req) goto drop; +if (!want_cookie && master_tp->confirm_connect) + dont_confirm =1 ; +tcp_clear_options (&tp); tp.mss_clamp =536 ; tp.user_mss =tcp_sk (sk)->user_mss;
@@ -1533,11 +1538,31 @@ } req->snt_isn = isn; -if (tcp_v4_send_synack (sk, req, dst)) +if (!dont_confirm &&tcp_v4_send_synack (sk, req, dst)) goto drop_and_free;if (want_cookie) {tcp_openreq_free (req); + }else if (dont_confirm) { +struct sock *child; +__u8 rcv_wscale; + + req->window_clamp = dst ?dst_metric (dst,RTAX_WINDOW ) :0 ; +tcp_select_initial_window (tcp_full_space (sk), req->mss, + &req->rcv_wnd, &req->window_clamp, +0 , &rcv_wscale); + req->rcv_wscale = rcv_wscale; + + child =tcp_v4_syn_recv_sock (sk, skb, req,NULL ); +if (child !=NULL ) { + req->unconfirmed =1 ; +tcp_sk (child)->unconfirmed_openreq = req; +tcp_acceptq_queue (sk, req, child); + sk->sk_data_ready (sk,0 ); +sock_put (child); + }else { +tcp_openreq_free (req); + } }else {tcp_v4_synq_add (sk, req); }
net/ipv4/tcp_minisocks.c renamed from net/ipv4/tcp_minisocks.c.orig +10 -2
@@ -732,6 +732,7 @@tcp_init_wl (newtp, req->snt_isn, req->rcv_isn); newtp->retransmits =0 ; + newtp->confirm_connect =0 ; newtp->backoff =0 ; newtp->srtt =0 ; newtp->mdev =TCP_TIMEOUT_INIT ;
@@ -884,7 +885,8 @@* Enforce "SYN-ACK" according to figure 8, figure 6 * of RFC793, fixed by RFC1122. */ - req->class->rtx_syn_ack (sk, req,NULL ); +if (!req->unconfirmed) + req->class->rtx_syn_ack (sk, req,NULL );return NULL ; }
@@ -955,7 +957,7 @@if (paws_reject || !tcp_in_window (TCP_SKB_CB (skb)->seq,TCP_SKB_CB (skb)->end_seq, req->rcv_isn+1 , req->rcv_isn+1 +req->rcv_wnd)) {/* Out of window: send ACK and drop. */ -if (!(flg &TCP_FLAG_RST )) +if (!req->unconfirmed && !(flg &TCP_FLAG_RST )) req->class->send_ack (skb, req);if (paws_reject)NET_INC_STATS_BH (PAWSEstabRejected);
@@ -991,6 +993,12 @@return NULL ; } +/* @@@ If we are in SYN_RECV and haven't confirmed/rejected +* the connection yet, this ACK is acking a never-sent packet. +*/ +if (tcp_is_unconfirmed (tp)) +return NULL ; +/* OK, ACK is valid, create big socket and * feed this segment to it. It will repeat all * the tests. THIS SEGMENT MUST MOVE SOCKET TO
net/ipv4/tcp_timer.c renamed from net/ipv4/tcp_timer.c.orig +2 -1
@@ -519,7 +519,8 @@if (time_after_eq (now, req->expires)) {if ((req->retrans < thresh || (req->acked && req->retrans < max_retries)) - && !req->class->rtx_syn_ack (sk, req,NULL )) { + && (req->unconfirmed || + !req->class->rtx_syn_ack (sk, req,NULL ))) {unsigned long timeo;if (req->retrans++ ==0 )
Quoted 6 lines · Lennert Buytenhek
Hi,
Below is the original email I sent to netdev about nine months ago announcing selective connection acceptance support for TCP sockets. I have forward-ported the 2.4.18 patch to 2.6.0-test2, included below. No functional changes have been made.
That is great! Thanks for not forgetting about this issue.
I think this feature would really be great to develop _really_ transparent proxies.
Quoted 1 line
Could someone have a look at it?
I'm not a core networking guy, but it looks fine to me.
Dave, Andi, Alexey, James: Would this be a candidate for kernel inclusion at some point?
Quoted 1 line
Lennert
Signature · 3 lines
- Harald Welte <[email protected]> http://www.gnumonks.org/ ============================================================================ Programming is like sex: One mistake and you have to support it your lifetime