$30 off During Our Annual Pro Sale. View Details »

HTTP Server on random available port in Go

HTTP Server on random available port in Go

Imagine you want to start an HTTP server without specifying the port. For example, a temporary server for testing. How do you do that?

The answer is straightforward. Specify the port number to 0 like:

l, err := net.Listen("tcp", ":0")

It’s an easy rule provided by the net package, but do you understand how Go binds a random port allocation. I’ll give you a clear understanding of what Go does inside the net package.

The presentation contains the following topics.

net, net/http packages
File descriptor
TCP, UDP
System calls
I think this presentation will give audiences not only a knowledge of Go, but also one of system calls.

Kazuki Higashiguchi

March 24, 2022
Tweet

More Decks by Kazuki Higashiguchi

Other Decks in Technology

Transcript

  1. HTTP Server on random
    available port in Go
    Kazuki Higashiguchi
    March 31, 2022 @ Conf42: Golang 2022

    View Slide

  2. About Me
    Kazuki Higashiguchi
    Backend Engineer at Autify.
    No-code AI-powered software testing automation
    platform
    Follow @hgsgtk on Twitter

    View Slide

  3. Autify Solution
    No code unlocks automation
    at scale
    AI automatically maintenance
    test scripts

    View Slide

  4. Autify for Web / for Mobile
    We are taking demo requests https://autify.com/
    Autify for Web Autify for Mobile

    View Slide

  5. Available ports
    HTTP server on a random available port
    50123
    60012 45342 ?????
    go run main.go
    No port specified
    HTTP
    server
    ?????
    Port: ?????
    Bind & Listen

    View Slide

  6. Implementation using Go
    using port: 57645
    using port: 57473
    using port: 57464

    View Slide

  7. net.Listen
    "If the port in the address parameter is empty or "0", as in
    "127.0.0.1:" or "[::1]:0", a port number is automatically
    chosen”
    https://pkg.go.dev/net#Listen

    View Slide

  8. net/http/httptest invokes net.Listen with “0”
    net/http/httptest/server.go
    https://cs.opensource.google/go/go/+/refs/tags/go1.18:src/net/http/httptest/server.go;drc=refs%2Ftags%2Fgo1.18;l=60

    View Slide

  9. Dive into the
    standard libraries
    https://unsplash.com/photos/AN2SypyyOnA

    View Slide

  10. Signature: “network”

    View Slide

  11. View Slide

  12. 1: net.Listen -> net.ListenConfig.Listen
    https://cs.opensource.google/go/go/+/refs/tags/go1.18:src/net/dial.go;l=710
    net/ipsock.go

    View Slide

  13. 2. net.ListenConfig.Listen -> net.DefaultResolver
    https://cs.opensource.google/go/go/+/refs/tags/go1.18:src/net/dial.go;l=625
    DefaultResolver resolves the network IP
    address
    net/dial.go

    View Slide

  14. 3. net.DefaultResolver -> net.LookupPort
    LookupPort looks up the port for the given network
    e.g. LookupPort(“127.0.0.1”, “0”) -> returned port: 0
    net/ipsock.go
    https://cs.opensource.google/go/go/+/refs/tags/go1.18:src/net/ipsock.go;l=260;drc=refs%2Ftags%2Fgo1.18

    View Slide

  15. 4: net.ListenConfig.Listen -> sysListener.listenTCP
    https://cs.opensource.google/go/go/+/refs/tags/go1.18:src/net/dial.go;l=639;drc=refs%2Ftags%2Fgo1.18
    net/dial.go

    View Slide

  16. 5: sysListener.listenTCP -> internalsocket
    https://cs.opensource.google/go/go/+/refs/tags/go1.18:src/net/tcpsock_posix.go;l=167;drc=refs%2Ftags%2Fgo1.18
    net/tcpsocket_posix.go
    Return a network
    file descriptor

    View Slide

  17. socket type: SOCK_STREAM
    Network type Socket type Description
    “tcp”
    (Transmission Control
    Protocol)
    SOCK_STREAM Stream-oriented
    Sequenced, reliable, two-way, connection-base byte streams.
    “unix”
    (Unix domain sockets)
    “udp”
    (User Datagram Protocol)
    SOCK_DGRAM Datagram-oriented.
    Connectionless, unreliable messages
    “unixgram”
    “unixpacket” SOCK_SEQPACKET Datagram-oriented.
    Sequenced, reliable, two-way, connection-base byte streams.

    View Slide

  18. 6: internalsocket -> net.listenStream
    https://cs.opensource.google/go/go/+/refs/tags/go1.18:src/net/sock_posix.g
    o;l=56;drc=refs%2Ftags%2Fgo1.18
    net/sock_posix.go

    View Slide

  19. 7: execute three system calls
    https://cs.opensource.google/go/go/+/refs/tag
    s/go1.18:src/net/sock_posix.go;drc=refs%2Ftag
    s%2Fgo1.18;l=175
    net/sock_posix.go

    View Slide

  20. bind, listen, getsockname
    Bind
    Listen
    Getsockname
    Assign the socket address to the socket referred to by
    the file descriptor
    Mark the socket as a passive socket
    Return the current socket address

    View Slide

  21. Bind to an ephemeral port
    Bind
    Ephemeral port
    (Dynamic port)
    HTTP
    server
    Port: 54563
    Bind
    Choose one from ephemeral ports

    View Slide

  22. Specification of bind
    OS When a port number is zero Port range
    Linux Attempt to bind to an
    ephemeral port
    (Basically) 49152 - 65535
    Windows Assign a unique port from the
    dynamic client port range
    (On Windows Vista and later)
    49152 - 65535
    (Windows Server 2003 and earlier)
    1025 - 5000
    IANA defines the port range is 49152 - 65535

    View Slide

  23. Key consideration
    1. Confirm the “bind” specification
    2. Check your infrastructure can use an ephemeral port
    3. Check the range of ephemeral port

    View Slide

  24. Thank you
    See more detail in the article on dev,to.

    View Slide