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
Profiling Arbitrary Cuda Applications
Caputre Opengl Window in X11 with Fast Framerate - Possible
Logging Memory Access Footprint
How to Invoke Any Kernel Function
How Event Packet Header Is Getiing in Hci_Send_Req API Implementation
User Time Larger Than Real Time
How to Get CPU Serial Under Linux Without Root Permissions
Library Path Order for Alternate Glibc Dynamic Linker (Ld.So)
Can't Install The Caret Package in R (In My Linux Machine)
Install Python 32 Bit on 64 Bit Linux
Disable CPU Caches (L1/L2) on Armv8-A Linux
Goroutine in Io Wait State for Long Time
How Does Linux Kernel Prevents The Bios System Calls
Install Ssh Server on Embedded Device
Compiling and Linking a 32 Bit Application on Debian 64 Bit