niaucchi4

package
v0.12.1 Latest Latest
Warning

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

Go to latest
Published: Dec 13, 2019 License: GPL-3.0 Imports: 20 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 DialKCP added in v0.12.0

func DialKCP(addr string, cookie []byte) (conn net.Conn, err error)

DialKCP dials KCP over obfs in one function.

Types

type KCPListener added in v0.12.0

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

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

func ListenKCP added in v0.12.0

func ListenKCP(sock *ObfsSocket) *KCPListener

ListenKCP creates a new listener.

func (*KCPListener) Accept added in v0.12.0

func (l *KCPListener) 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 ObfsStream added in v0.12.0

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

func NewObfsStream added in v0.12.0

func NewObfsStream(wire net.Conn, key []byte, isServ bool) *ObfsStream

func (*ObfsStream) Close added in v0.12.0

func (os *ObfsStream) Close() error

func (*ObfsStream) LocalAddr added in v0.12.0

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

func (*ObfsStream) Read added in v0.12.0

func (os *ObfsStream) Read(p []byte) (n int, err error)

func (*ObfsStream) RemoteAddr added in v0.12.0

func (os *ObfsStream) RemoteAddr() net.Addr

func (*ObfsStream) SetDeadline added in v0.12.0

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

func (*ObfsStream) SetReadDeadline added in v0.12.0

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

func (*ObfsStream) SetWriteDeadline added in v0.12.0

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

func (*ObfsStream) Write added in v0.12.0

func (os *ObfsStream) Write(p []byte) (n int, err 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