net.TCPConn equivalent for setsockopt

213 views
Skip to first unread message

Dan Kortschak

unread,
Sep 30, 2018, 9:42:46 PM9/30/18
to golang-nuts
I have been translating some C socket networking code (not my main area
of expertise) and there is something that I don't see a way to do with
net.TCPConn.

The original code sets a revc timeout using

```
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
```

Short of messing around with the fd and using syscall.SetsockoptTimeval
(or unix.SetsockoptTimeval) which seems like overkill, is there a
sensible way to do this or is it omitted because it is not a useful
thing to do?

thanks
Dan

robert engels

unread,
Sep 30, 2018, 10:04:22 PM9/30/18
to Dan Kortschak, golang-nuts
use conn SetReadDeadline()
> --
> 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.
> For more options, visit https://groups.google.com/d/optout.

robert engels

unread,
Sep 30, 2018, 10:05:23 PM9/30/18
to Dan Kortschak, golang-nuts
But you need to set it on every call because it is an absolute time.

robert engels

unread,
Sep 30, 2018, 10:06:44 PM9/30/18
to Dan Kortschak, golang-nuts

Dan Kortschak

unread,
Sep 30, 2018, 10:09:59 PM9/30/18
to robert engels, golang-nuts
Yeah, I looked at that. It doesn't look like a good solution.

On Sun, 2018-09-30 at 21:03 -0500, robert engels wrote:
> use conn SetReadDeadline()
>
> >
> > On Sep 30, 2018, at 8:41 PM, Dan Kortschak <dan.kortschak@adelaide.

Ian Lance Taylor

unread,
Oct 1, 2018, 3:01:49 PM10/1/18
to Dan Kortschak, golang-nuts
As you know, Go's net package uses deadlines rather than timeouts. We
made this choice because timeouts are inherently ambiguous when
reading more than 1 byte from a TCP connection: does the timeout refer
to reading all the requested data, or does it refer to reading a
single byte, or does it refer to the amount of time between each byte
that arrives? And in the modern era this has to be considered in the
context of slowloris attacks. Rather than try to sort out what people
might want, we just use a deadline, which is always clear.

The best approach for your case is going to be to figure out what the
code you are porting actually wants.

Ian

robert engels

unread,
Oct 1, 2018, 4:54:07 PM10/1/18
to Ian Lance Taylor, Dan Kortschak, golang-nuts
That brings up a problem I have with the way godoc is generated/provided.

If you go to the TCPConn SetReadDeadline function, it states “implements the Conn SetReadDeadline method”, with no way of referencing the documentation for Conn.SetReadDeadline, in fact, no way of even getting to the Conn interface… who knows what Conn is ??? Assume it is a Conn returned by Dial? How do you determine this?

Furthermore, it is not completely specified, meaning if the read timeout occurs, and some data was read, is it discarded? will it be returned with the next read (if any)? Doesn’t say...

Maybe I am looking at it wrong, but I think Go’s “simplicity” cannot be extended to the specifications, especially when dealing with low-level networking, api, etc. It makes it very difficult to use, and be able to guarantee it will work the same on all platforms - hurting the portability.

Ian Lance Taylor

unread,
Oct 1, 2018, 6:00:31 PM10/1/18
to robert engels, Dan Kortschak, golang-nuts
On Mon, Oct 1, 2018 at 1:53 PM, robert engels <ren...@ix.netcom.com> wrote:
>
> If you go to the TCPConn SetReadDeadline function, it states “implements the Conn SetReadDeadline method”, with no way of referencing the documentation for Conn.SetReadDeadline, in fact, no way of even getting to the Conn interface… who knows what Conn is ??? Assume it is a Conn returned by Dial? How do you determine this?

You're right, that is kind of useless. Would you mind filing an issue
about that? It should be fixed one way or another.


> Furthermore, it is not completely specified, meaning if the read timeout occurs, and some data was read, is it discarded? will it be returned with the next read (if any)? Doesn’t say...

The behavior of the standard Read method when an error occurs is
documented by the io.Reader interface.


> Maybe I am looking at it wrong, but I think Go’s “simplicity” cannot be extended to the specifications, especially when dealing with low-level networking, api, etc. It makes it very difficult to use, and be able to guarantee it will work the same on all platforms - hurting the portability.

I'm not really sure what you're thinking of here.

Ian

Dan Kortschak

unread,
Oct 1, 2018, 6:08:19 PM10/1/18
to Ian Lance Taylor, golang-nuts
Thanks, Ian.

Yes, I think that is doable.

Dan

robert engels

unread,
Oct 1, 2018, 7:00:54 PM10/1/18
to Ian Lance Taylor, Dan Kortschak, golang-nuts
On Oct 1, 2018, at 4:59 PM, Ian Lance Taylor <ia...@golang.org> wrote:

On Mon, Oct 1, 2018 at 1:53 PM, robert engels <ren...@ix.netcom.com> wrote:

If you go to the TCPConn SetReadDeadline function, it states “implements the Conn SetReadDeadline method”, with no way of referencing the documentation for Conn.SetReadDeadline, in fact, no way of even getting to the Conn interface… who knows what Conn is ??? Assume it is a Conn returned by Dial? How do you determine this?

You're right, that is kind of useless.  Would you mind filing an issue
about that?  It should be fixed one way or another.


I will do so.



Furthermore, it is not completely specified, meaning if the read timeout occurs, and some data was read, is it discarded? will it be returned with the next read (if any)? Doesn’t say...

The behavior of the standard Read method when an error occurs is
documented by the io.Reader interface.


But that is kind of the problem, without an ‘implements’ keyword, I would think that the documentation needs to be specify exactly what interfaces it “implements”. How do I KNOW that the read on on UDP connection is intended to be an io.Reader ? It may be “self evident” for the “stdlib” interfaces, or the de-facto expected behavior, but it gets far trickier when the interface is not a standard one.

If Go doesn’t have (or want), “implements”, there needs to be a way for the documentation to declare the ‘implemented’ interfaces as expected by the author.

For example, here is the documentation for UDPConn:

UDPConn is the implementation of the Conn and PacketConn interfaces for UDP network connections.

type UDPConn struct {
        // contains filtered or unexported fields
}
Again, which Conn, and which PacketConn, and if I have a Conn, and look at the (net.Conn) interface (below) it doesn’t state the Read method functions according to the io.Reader interface anywhere that I can determine...

// Read reads data from the connection.
// Read can be made to time out and return an Error with Timeout() == true
// after a fixed time limit; see SetDeadline and SetReadDeadline.
Read(b []byte) (n int, err error)


Maybe I am looking at it wrong, but I think Go’s “simplicity” cannot be extended to the specifications, especially when dealing with low-level networking, api, etc. It makes it very difficult to use, and be able to guarantee it will work the same on all platforms - hurting the portability.

I'm not really sure what you're thinking of here.

Pretty much inline with the previous sentiment. I just got done writing the LRMP protocol project, and I’ve done a LOT of networking code in many languages and platforms, and doing it in Go was more of a pain than I think it should of been. The documentation is just not ‘linked/reference’ in a way that is needed when you have dynamic interfaces. For example, similar problems with PacketConn - there are multiple PacketConn interfaces and it is nearly impossible to figure out “what is what” by reading the documentation. It often just states return a PacketConn, without a link to the specific PacketConn . To further the example, if you work with ipv4.PacketConn, is it a net.PacketConn? No way to know / see the hierarchy with out coding it and looking for errors…. Very inefficient.


Ian

robert engels

unread,
Oct 1, 2018, 11:02:58 PM10/1/18
to Ian Lance Taylor, Dan Kortschak, golang-nuts
I’v been thinking about what I said below, and I think it is a real problem. It might not affect a lot of people because it only comes into play with complex object hierarchies and multiple implementations - but this is exactly what networking layers/libraries are.

Without “implements” the documentation needs to specify either 1) the exact interface method the method are adhering to, or 2) if they don’t adhere to an interface they need to specify the exact constraints/operations of the method behavior.

To reiterate the example, there is net.Conn.Read(), but nowhere I can see that says this method adheres to the contract for io.Reader.Read(), or in anyway links back to the specification interface.

I can’t be the only person that has encountered this, so maybe I am approaching it wrong? or there is some other facility I am not aware of ?

Thanks for the help.

Agniva De Sarker

unread,
Oct 2, 2018, 12:36:46 AM10/2/18
to golang-nuts


On Tuesday, 2 October 2018 04:30:54 UTC+5:30, Robert Engels wrote:

On Oct 1, 2018, at 4:59 PM, Ian Lance Taylor <ia...@golang.org> wrote:

On Mon, Oct 1, 2018 at 1:53 PM, robert engels <ren...@ix.netcom.com> wrote:

If you go to the TCPConn SetReadDeadline function, it states “implements the Conn SetReadDeadline method”, with no way of referencing the documentation for Conn.SetReadDeadline, in fact, no way of even getting to the Conn interface… who knows what Conn is ??? Assume it is a Conn returned by Dial? How do you determine this?

You're right, that is kind of useless.  Would you mind filing an issue
about that?  It should be fixed one way or another.


I will do so.


robert engels

unread,
Oct 2, 2018, 12:50:15 AM10/2/18
to Agniva De Sarker, golang-nuts
Great, maybe I can find some time and contribute back… I think it would go a long way towards working with complex hierarchy systems easier.

Reply all
Reply to author
Forward
0 new messages