Git Product home page Git Product logo

nat's People

Contributors

mdlayher avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

nat's Issues

nat/natpmp: add low-level Conn and Message APIs

Per the discussions with @danderson in #1, there is a need to enable sending/receiving NAT-PMP (and later PCP) messages over a single multiplexed UDP socket.

I think the best way to do this is to add a low-level Conn API (inspired by my NDP package) that looks something like so:

package natpmp

type Conn struct {
    // TODO: do or do not embed this directly to allow access to all deadline/raw byte I/O methods?
    net.PacketConn
}

func NewConn(pc net.PacketConn) (*Conn, error) {
    // Setup logic probably using x/net/ipv4. We still need to think about the multicast group case
    // where a NAT gateway can notify us of its new external IP.
}

type Message interface {
    Op() uint8
    encoding.BinaryMarshaler
    encoding.BinaryUnmarshaler
}

// All messages implement the Message interface.
type ExternalAddressRequest struct{}
type ExternalAddress struct{}
// other messages

// Marshaling to/from bytes while also dealing with message headers and I/O errors.
func ParseMessage(b []byte) (Message, error) {}
func MarshalMessage(m Message) ([]byte, error) {}

// Convenient APIs for dealing with Messages directly, while the underlying Conn also permits raw byte I/O
func (c *Conn) SendMessage(m Message, addr net.Addr) error {}
func (c *Conn) ReceiveMessage() (Message, net.Addr, error) {}

The existing Client can make use of this API in a very concise way and keep all the existing serialization and backoff/retry logic. It's unclear to me if any of that logic should live in Conn directly, but I'm leaning toward keeping it out.

For the Tailscale netcheck use case, it'd be easy to probe for NAT-PMP (and later PCP) using Conn.SendMessage, and then messages could be received using a raw Conn.ReadFrom combined with a call to ParseMessage.

Overall I think this approach provides significant flexibility while also allowing a nice low and high-level APIs. Thoughts, @danderson?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.