niaucchi4

package
v0.11.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 10, 2019 License: GPL-3.0 Imports: 19 Imported by: 0

README

niaucchi4: the 3rd generation Geph obfuscation protocol

Architecture

Unlike previous iterations, niaucchi4 presents an unreliable transport to upper layers. This allows it to work around environments where TCP sessions are unreliable (mobile network switching etc), letting hours-long upper-layer sessions become practical. It can also use multiple UDP sessions, automatically converging on the best path.

[Authentication, encryption]
[        niaucchi4         ]
[  UDP  ][  UDP   ][  UDP  ]

Like previous versions, though, intermediate hosts are still identified by host:port and cookie.

Opening a tunnel

To open a new tunnel the client sends the intermediary a packet like the following from a fresh source port:

[32-byte nonce][encrypted pubkey || rhost:rport][arbitrary garbage]

The ed25519 pubkey can either be encrypted with chacha20-poly1305 or aes256-gcm. In either case the encryption nonce is null, the tag precedes the ciphertext, and the key is HMAC-SHA256(cookie, nonce).

The server should respond with a similar message. A shared secret sharedsec is derived.

Tunnel wire format

The tunnel wire format is simply RLP:

[body padding]

encrypted with HMAC-SHA256(sharedsec, "up") or "down" depending on the direction. Undecodeable packets should be silently discarded and can be used as padding.

An empty-padding packet is to be considered a ping packet, and should be returned to the sender unchanged. This allows measuring latency. Ping packets should be created at a randomly sampled size.

Rekeying

Every 2^16 packets we send, we rekey by setting sharedsec = SHA256(sharedsec) and recompute the sending key. This ensures that we can safely use AEADs with short nonces. When receivers get an undecryptable packet, they try to decode it with the "next" key too.

What does the intermediary do

The intermediary keeps a NAT-like table of incoming tunnels by host:port of the client, mapping them to tunnel state structures and outgoing UDP sockets. The tunnels are cleared only under memory pressure and should not be timed out unless absolutely necessary.

End-to-end wire format

The end-to-end format is simply a 64-bit sessid and then the body.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Dial

func Dial(addr string, cookie []byte) (conn *kcp.UDPSession, err error)

Dial dials KCP over obfs in one function.

Types

type Listener

type Listener struct {
	// contains filtered or unexported fields
}

Listener operates KCP over obfs. Standard caveats about KCP not having proper open and close signaling apply.

func Listen

func Listen(sock *ObfsSocket) *Listener

Listen creates a new listener.

func (*Listener) Accept

func (l *Listener) Accept() (c *kcp.UDPSession, err error)

Accept accepts a new connection.

type ObfsSocket

type ObfsSocket struct {
	// contains filtered or unexported fields
}

ObfsSocket represents an obfuscated PacketConn.

func ObfsListen

func ObfsListen(cookie []byte, wire net.PacketConn) *ObfsSocket

ObfsListen opens a new obfuscated PacketConn.

func (*ObfsSocket) Close

func (os *ObfsSocket) Close() error

func (*ObfsSocket) LocalAddr

func (os *ObfsSocket) LocalAddr() net.Addr

func (*ObfsSocket) ReadFrom

func (os *ObfsSocket) ReadFrom(p []byte) (n int, addr net.Addr, err error)

func (*ObfsSocket) SetDeadline

func (os *ObfsSocket) SetDeadline(t time.Time) error

func (*ObfsSocket) SetReadDeadline

func (os *ObfsSocket) SetReadDeadline(t time.Time) error

func (*ObfsSocket) SetWriteDeadline

func (os *ObfsSocket) SetWriteDeadline(t time.Time) error

func (*ObfsSocket) WriteTo

func (os *ObfsSocket) WriteTo(b []byte, addr net.Addr) (int, error)

type Wrapper

type Wrapper struct {
	// contains filtered or unexported fields
}

Wrapper is a PacketConn that can be hot-replaced by other PacketConns on I/O failure or manually. It squelches any errors bubbling up.

func Wrap

func Wrap(getConn func() net.PacketConn) *Wrapper

Wrap creates a new Wrapper instance.

func (*Wrapper) Close

func (w *Wrapper) Close() error

func (*Wrapper) LocalAddr

func (w *Wrapper) LocalAddr() net.Addr

func (*Wrapper) ReadFrom

func (w *Wrapper) ReadFrom(p []byte) (n int, addr net.Addr, err error)

func (*Wrapper) SetDeadline

func (w *Wrapper) SetDeadline(t time.Time) error

func (*Wrapper) SetReadDeadline

func (w *Wrapper) SetReadDeadline(t time.Time) error

func (*Wrapper) SetWriteDeadline

func (w *Wrapper) SetWriteDeadline(t time.Time) error

func (*Wrapper) WriteTo

func (w *Wrapper) WriteTo(b []byte, addr net.Addr) (int, error)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL