Tcp Ecn Source Code

TCP ECN source code

TCP_ECN_OK is bit flag from linuxkernel's internal struct tcp_sock as (field ecn_flags). There are several bitflags in it (include/net/tcp.h file from linux kernel sources):

398 #define TCP_ECN_OK              1
399 #define TCP_ECN_QUEUE_CWR 2
400 #define TCP_ECN_DEMAND_CWR 4
401 #define TCP_ECN_SEEN 8

Expression tp->ecn_flags & TCP_ECN_OK is the logic test, is the TCP_ECN_OK still set or not.

Update: I think that TCP_ECN_OK bit is set when the tcp socket is open (if the current settings of sysctl enables ECN support in Linux), and it will stay set if the other side of socket supports ECN too.

As said in wikipedia http://en.wikipedia.org/wiki/Explicit_Congestion_Notification

ECN is an optional feature that is only used when both endpoints support it and are willing to use it.

... skip to Linux section

The Linux kernel supports three working modes of the ECN for TCP, as configured by value of the /proc/sys/net/ipv4/tcp_ecn variable, through the sysctl interface:[11 - tcp_ecn in Documentation/networking/ip-sysctl.txt]

  • 0 – disable ECN and neither initiate nor accept it
  • 1 – enable ECN when requested by incoming connections, and also request ECN on outgoing connection attempts
  • 2 – enable ECN when requested by incoming connections, but do not request ECN on outgoing connections. // DEFAULT in 3.14 //

The default value is 2, meaning that by default ECN is enabled when requested by incoming connections, but it is not requested on outgoing connections. Anyway, ECN is used by the Linux kernel only when both ends of the TCP connection indicate support for it.[11]

For example, when we send SYN in beginning of outgoing socket connection, and sysctl tcp_ecn is enabled for outgoing connections ("sysctl_tcp_ecn" flag is 1), we set ECE bit in tcp header and set TCP_ECN_OK. net/ipv4/tcp_output.c Line 315

315 /* Packet ECN state for a SYN.  */
316 static inline void TCP_ECN_send_syn(struct sock *sk, struct sk_buff *skb)
....
320 tp->ecn_flags = 0;
321 if (sock_net(sk)->ipv4.sysctl_tcp_ecn == 1) {
322 TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_ECE | TCPHDR_CWR;
323 tp->ecn_flags = TCP_ECN_OK;
324 }

Later, if the other side of connection have no support of ECN or it is disabled, we will unset TCP_ECN_OK flag.
net/ipv4/tcp_input.c Line 246

246 static inline void TCP_ECN_rcv_synack(struct tcp_sock *tp, const struct tcphdr *th)
247 {
248 if ((tp->ecn_flags & TCP_ECN_OK) && (!th->ece || th->cwr))
249 tp->ecn_flags &= ~TCP_ECN_OK;
250 }

For incoming connections, we unset TCP_ECN_OK, if in incoming SYN there was no ECE tcp header flag (read more about flags and ECN in RFC3168 "The Addition of Explicit Congestion Notification (ECN) to IP")

252 static inline void TCP_ECN_rcv_syn(struct tcp_sock *tp, const struct tcphdr *th)
253 {
254 if ((tp->ecn_flags & TCP_ECN_OK) && (!th->ece || !th->cwr))
255 tp->ecn_flags &= ~TCP_ECN_OK;
256 }

Set TCP ECN on a socket (C Linux)

Short answer: no and technically yes (but based on the question it won't help and I don't think it is yes to what you wanted to ask).

ECN is turned on by echoing 1 to /proc/sys/net/ipv4/tcp_ecn. See
ip_sysctl.txt. By default it should be 2 which enables ECN when the peer requests it, but does not initiate requests for it. To set this would require "privileges" and can't be done via a socket so the 1st answer is no.

Congestion algorithms may be set on a per socket basis and may involve ECN, trivially the default one does. So technically, yes. But even though the congestion algorithms may involve ECN, the code in tcp_input.c and tcp_output.c makes it clear that without the sysctl flag set, it won't use it, so it won't help.

See the very good information in this answer

TCP flags present in the header

Yeah they are part of the "reserved 6 bits" (res1 + res2). They are optional and are more or less resent addition (Stevens' book does not even mention them). Doff is 4 bits and specifies header length which is normally 20 bytes but can be longer if options like MSS is included.

what's the meaning for the TCP_NEW_SYN_RECV?

I've found this:

TCP_SYN_RECV state is currently used by fast open sockets.

Initial TCP requests (the pseudo sockets created when a SYN is received)
are not yet associated to a state. They are attached to their parent,
and the parent is in TCP_LISTEN state.

This commit adds TCP_NEW_SYN_RECV state, so that we can convert
TCP stack to a different schem gradually.

source, the author commit: http://git.kernel.org/linus/10feb428a504



Related Topics



Leave a reply



Submit