dgrelay

package module
v0.0.0-...-6158d28 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2021 License: MIT Imports: 4 Imported by: 0

README

Datagram Relay

This is a small Go library that allows transparent (and supposedly performant) relays between a datagram-like file descriptor and a stream-like file descriptor. It also supports relays between two datagram-like or two stream-like file descriptors, but assuming that datagrams are being transported. It can be used with SEQPACKET type file descriptors too.

It's useful when you want to convert a UDP socket into a TCP socket, or transport TUN/TAP packets or frames over a TCP socket... it can be useful with VSOCK type sockets too... or to transport QUIC over TCP.

A datagram can't be larger than 65,536 bytes.

On the stream-side datagrams are prefixed by two-bytes that indicate the size of the datagram that follows, in big-endian order.

The relay can only forward in one direction when there is positive flow between the sides (source can be read and sink can be written), or if there are datagrams in the internal buffer and the sink side is ready to receive them. This is useful because you can use the kernel's flow control algorithms on the file descriptors (like in TCP, or UNIX sockets) to only relay when each side is ready, allowing you to use minimal system resources and achieve maximal throughput on the relayed link.

Note that the datagram socket must be both bound and connected as this library does not care about the source or destination of datagram file descriptors. Also, it goes without mention that the file descriptors must be non-blocking.

Example

dgrelay.Forward(
	context.Background(),
	&dgrelay.DatagramFD{
		FD: afd,
	},
	&dgrelay.StreamFD{
		FD: bfd,
	},
	8,    /* buffers */
	2048, /* buffer size */
)

License

Copyright © 2021 Stojan Dimitrovski. Some rights reserved.

Licensed under the MIT License. You can get a copy of it in LICENSE.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	EWOULDBLOCK = unix.EWOULDBLOCK
)

Functions

func Forward

func Forward(ctx context.Context, afd, bfd FD, buffers, bufferSize int) error

Types

type Buffer

type Buffer struct {
	ID   int
	Data []byte
	ROff int
	WOff int
}

func (*Buffer) Readsize

func (buf *Buffer) Readsize() int

func (*Buffer) Writesize

func (buf *Buffer) Writesize(size int)

type DatagramFD

type DatagramFD struct {
	FD int
}

func (*DatagramFD) Close

func (fd *DatagramFD) Close() error

func (*DatagramFD) Read

func (fd *DatagramFD) Read(queue *Queue) (int, error)

func (*DatagramFD) Unix

func (fd *DatagramFD) Unix() int

func (*DatagramFD) Write

func (fd *DatagramFD) Write(queue *Queue) (int, error)

type Direction

type Direction struct {
	RQueue *Queue
	WQueue *Queue

	A FD
	B FD

	CanRead  bool
	CanWrite bool
}

func NewDirection

func NewDirection(afd, bfd FD, buffers, size int) *Direction

func (*Direction) CanForward

func (d *Direction) CanForward() bool

func (*Direction) Forward

func (d *Direction) Forward(ctx context.Context) error

type FD

type FD interface {
	Unix() int

	Read(*Queue) (int, error)
	Write(*Queue) (int, error)

	Close() error
}

type Queue

type Queue struct {
	Buffers []*Buffer
	Head    int
	Tail    int
	Size    int
}

func NewQueue

func NewQueue(capacity int) *Queue

func (*Queue) Add

func (q *Queue) Add(buf *Buffer)

func (*Queue) Move

func (q *Queue) Move(n int, to *Queue)

func (*Queue) Peek

func (q *Queue) Peek(off int) *Buffer

func (*Queue) Pop

func (q *Queue) Pop(n int)

type StreamFD

type StreamFD struct {
	FD      int
	MinData int
}

func (*StreamFD) Close

func (fd *StreamFD) Close() error

func (*StreamFD) Read

func (fd *StreamFD) Read(queue *Queue) (int, error)

func (*StreamFD) Unix

func (fd *StreamFD) Unix() int

func (*StreamFD) Write

func (fd *StreamFD) Write(queue *Queue) (int, error)

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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