Thank you guys, your tips were really helpful!

Here's the solution I came up with for reading the ECN bits:
After setting the IP_RECVTOS options
syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_RECVTOS, 1)
one can read packets from the socket using
n, oobn, flags, addr, err := conn.ReadMsgUDP(b, oob)
oob now contains all the control messages, which can be parsed using
ctrlMsgs, err := syscall.ParseSocketControlMessage(oob[:oobn])
The ECN bits can now be extracted by searching for the IP_TOS control 
message:
for _, ctrlMsg := range ctrlMsgs {
    if ctrlMsg.Header.Type == syscall.IP_TOS {
        ecn := ctrlMsg.Data[0] & 0x3
    }
}

This code works, it's just a bit unfortunate that parsing the control 
messages causes quite a few allocations, especially as this is code that's 
run per packet. One would have to benchmark the performance impact of this. 
For accessing the ECN bits it's probably not too hard to write a 
specialized parser that doesn't allocate at all.
On Thursday, August 6, 2020 at 11:52:46 PM UTC+7 david....@gmail.com wrote:

> On Thu, Aug 6, 2020 at 10:02 AM Uli Kunitz <uli.k...@gmail.com> wrote:
>
>> Reading is possible with IP_RECVTOS on Linux but requires the use of 
>> recvmsg, because the TOS field is provided as ancillary data. This wouldn't 
>> be very portable though. Raw sockets with IP_HDRINCL are a better option if 
>> portability is a concern.
>
> Keep in mind that raw sockets are privileged under Linux. (the process 
> must have CAP_NET_RAW either by being root, or some other mechanism)
> That vastly limits the usefulness of a QUIC implementation.
>
>>
>> On Wednesday, August 5, 2020 at 11:33:41 PM UTC+2 ma...@acln.ro wrote:
>>
>>> ECN bits are represented in the TOS field. I think you can use 
>>> setsockopt with the IP_TOS option to set the TOS field on a socket. See 
>>> ip(7). On the Go side, use the SyscallConn method on your UDPConn, then 
>>> call setsockopt using the Control method. Something like this (untested): 
>>> https://play.golang.org/p/6_R-zlBSibv
>>>
>>> On Wed, Aug 5, 2020 at 9:30 PM <marten...@gmail.com> wrote:
>>>
>>>> I'm working on a Go implementation of the QUIC protocol (
>>>> https://github.com/lucas-clemente/quic-go). QUIC specifies how to use 
>>>> ECN (Explicit Congestion Notification) to detect and respond to congestion 
>>>> in the network (see 
>>>> https://tools.ietf.org/html/draft-ietf-quic-transport-29#section-13.4 for 
>>>> details on that).
>>>>
>>>> As far as I can see, there's no way to read (and write) the ECN bits 
>>>> from the IP header, unless I use a raw socket, which would be a suboptimal 
>>>> solution for many reasons.
>>>> The closest I could get to extracting information from the IP header 
>>>> was by using *UDPConn.ReadFromUDP* and then using *golang.org/x/net/ipv4 
>>>> <http://golang.org/x/net/ipv4>* to parse the *oob* bytes into an 
>>>> *ipv4.ControlMessage* (or equivalently for IPv6). This at least gives 
>>>> me access to the TTL field. It seems like this approach is insufficient to 
>>>> get access to the ECN bits though.
>>>>
>>>> Can anyone help me with this?
>>>>
>>>> -- 
>>>> You received this message because you are subscribed to the Google 
>>>> Groups "golang-nuts" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>> an email to golang-nuts...@googlegroups.com.
>>>> To view this discussion on the web visit 
>>>> https://groups.google.com/d/msgid/golang-nuts/3c96ecc4-e507-48d1-a912-9e3caf6ecd11o%40googlegroups.com
>>>>  
>>>> <https://groups.google.com/d/msgid/golang-nuts/3c96ecc4-e507-48d1-a912-9e3caf6ecd11o%40googlegroups.com?utm_medium=email&utm_source=footer>
>>>> .
>>>>
>>>
>>>
>>> -- 
>>> Andrei Călin
>>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golang-nuts...@googlegroups.com.
>>
> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/fe7cd943-cbb2-4530-a71a-d0b72100fb67n%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/golang-nuts/fe7cd943-cbb2-4530-a71a-d0b72100fb67n%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/c5483506-2b69-44aa-9b03-537f1b217c4an%40googlegroups.com.

Reply via email to