summaryrefslogtreecommitdiff
path: root/vendor/github.com/pion/transport/vnet/chunk.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/pion/transport/vnet/chunk.go')
-rw-r--r--vendor/github.com/pion/transport/vnet/chunk.go283
1 files changed, 283 insertions, 0 deletions
diff --git a/vendor/github.com/pion/transport/vnet/chunk.go b/vendor/github.com/pion/transport/vnet/chunk.go
new file mode 100644
index 0000000..7a87a2f
--- /dev/null
+++ b/vendor/github.com/pion/transport/vnet/chunk.go
@@ -0,0 +1,283 @@
+package vnet
+
+import (
+ "fmt"
+ "net"
+ "strconv"
+ "strings"
+ "sync/atomic"
+ "time"
+)
+
+type tcpFlag uint8
+
+const (
+ tcpFIN tcpFlag = 0x01
+ tcpSYN tcpFlag = 0x02
+ tcpRST tcpFlag = 0x04
+ tcpPSH tcpFlag = 0x08
+ tcpACK tcpFlag = 0x10
+)
+
+func (f tcpFlag) String() string {
+ var sa []string
+ if f&tcpFIN != 0 {
+ sa = append(sa, "FIN")
+ }
+ if f&tcpSYN != 0 {
+ sa = append(sa, "SYN")
+ }
+ if f&tcpRST != 0 {
+ sa = append(sa, "RST")
+ }
+ if f&tcpPSH != 0 {
+ sa = append(sa, "PSH")
+ }
+ if f&tcpACK != 0 {
+ sa = append(sa, "ACK")
+ }
+
+ return strings.Join(sa, "-")
+}
+
+// Generate a base36-encoded unique tag
+// See: https://play.golang.org/p/0ZaAID1q-HN
+var assignChunkTag = func() func() string { //nolint:gochecknoglobals
+ var tagCtr uint64
+
+ return func() string {
+ n := atomic.AddUint64(&tagCtr, 1)
+ return strconv.FormatUint(n, 36)
+ }
+}()
+
+// Chunk represents a packet passed around in the vnet
+type Chunk interface {
+ setTimestamp() time.Time // used by router
+ getTimestamp() time.Time // used by router
+ getSourceIP() net.IP // used by router
+ getDestinationIP() net.IP // used by router
+ setSourceAddr(address string) error // used by nat
+ setDestinationAddr(address string) error // used by nat
+
+ SourceAddr() net.Addr
+ DestinationAddr() net.Addr
+ UserData() []byte
+ Tag() string
+ Clone() Chunk
+ Network() string // returns "udp" or "tcp"
+ String() string
+}
+
+type chunkIP struct {
+ timestamp time.Time
+ sourceIP net.IP
+ destinationIP net.IP
+ tag string
+}
+
+func (c *chunkIP) setTimestamp() time.Time {
+ c.timestamp = time.Now()
+ return c.timestamp
+}
+
+func (c *chunkIP) getTimestamp() time.Time {
+ return c.timestamp
+}
+
+func (c *chunkIP) getDestinationIP() net.IP {
+ return c.destinationIP
+}
+
+func (c *chunkIP) getSourceIP() net.IP {
+ return c.sourceIP
+}
+
+func (c *chunkIP) Tag() string {
+ return c.tag
+}
+
+type chunkUDP struct {
+ chunkIP
+ sourcePort int
+ destinationPort int
+ userData []byte
+}
+
+func newChunkUDP(srcAddr, dstAddr *net.UDPAddr) *chunkUDP {
+ return &chunkUDP{
+ chunkIP: chunkIP{
+ sourceIP: srcAddr.IP,
+ destinationIP: dstAddr.IP,
+ tag: assignChunkTag(),
+ },
+ sourcePort: srcAddr.Port,
+ destinationPort: dstAddr.Port,
+ }
+}
+
+func (c *chunkUDP) SourceAddr() net.Addr {
+ return &net.UDPAddr{
+ IP: c.sourceIP,
+ Port: c.sourcePort,
+ }
+}
+
+func (c *chunkUDP) DestinationAddr() net.Addr {
+ return &net.UDPAddr{
+ IP: c.destinationIP,
+ Port: c.destinationPort,
+ }
+}
+
+func (c *chunkUDP) UserData() []byte {
+ return c.userData
+}
+
+func (c *chunkUDP) Clone() Chunk {
+ var userData []byte
+ if c.userData != nil {
+ userData = make([]byte, len(c.userData))
+ copy(userData, c.userData)
+ }
+
+ return &chunkUDP{
+ chunkIP: chunkIP{
+ timestamp: c.timestamp,
+ sourceIP: c.sourceIP,
+ destinationIP: c.destinationIP,
+ tag: c.tag,
+ },
+ sourcePort: c.sourcePort,
+ destinationPort: c.destinationPort,
+ userData: userData,
+ }
+}
+
+func (c *chunkUDP) Network() string {
+ return udpString
+}
+
+func (c *chunkUDP) String() string {
+ src := c.SourceAddr()
+ dst := c.DestinationAddr()
+ return fmt.Sprintf("%s chunk %s %s => %s",
+ src.Network(),
+ c.tag,
+ src.String(),
+ dst.String(),
+ )
+}
+
+func (c *chunkUDP) setSourceAddr(address string) error {
+ addr, err := net.ResolveUDPAddr(udpString, address)
+ if err != nil {
+ return err
+ }
+ c.sourceIP = addr.IP
+ c.sourcePort = addr.Port
+ return nil
+}
+
+func (c *chunkUDP) setDestinationAddr(address string) error {
+ addr, err := net.ResolveUDPAddr(udpString, address)
+ if err != nil {
+ return err
+ }
+ c.destinationIP = addr.IP
+ c.destinationPort = addr.Port
+ return nil
+}
+
+type chunkTCP struct {
+ chunkIP
+ sourcePort int
+ destinationPort int
+ flags tcpFlag // control bits
+ userData []byte // only with PSH flag
+ // seq uint32 // always starts with 0
+ // ack uint32 // always starts with 0
+}
+
+func newChunkTCP(srcAddr, dstAddr *net.TCPAddr, flags tcpFlag) *chunkTCP {
+ return &chunkTCP{
+ chunkIP: chunkIP{
+ sourceIP: srcAddr.IP,
+ destinationIP: dstAddr.IP,
+ tag: assignChunkTag(),
+ },
+ sourcePort: srcAddr.Port,
+ destinationPort: dstAddr.Port,
+ flags: flags,
+ }
+}
+
+func (c *chunkTCP) SourceAddr() net.Addr {
+ return &net.TCPAddr{
+ IP: c.sourceIP,
+ Port: c.sourcePort,
+ }
+}
+
+func (c *chunkTCP) DestinationAddr() net.Addr {
+ return &net.TCPAddr{
+ IP: c.destinationIP,
+ Port: c.destinationPort,
+ }
+}
+
+func (c *chunkTCP) UserData() []byte {
+ return c.userData
+}
+
+func (c *chunkTCP) Clone() Chunk {
+ userData := make([]byte, len(c.userData))
+ copy(userData, c.userData)
+
+ return &chunkTCP{
+ chunkIP: chunkIP{
+ timestamp: c.timestamp,
+ sourceIP: c.sourceIP,
+ destinationIP: c.destinationIP,
+ },
+ sourcePort: c.sourcePort,
+ destinationPort: c.destinationPort,
+ userData: userData,
+ }
+}
+
+func (c *chunkTCP) Network() string {
+ return "tcp"
+}
+
+func (c *chunkTCP) String() string {
+ src := c.SourceAddr()
+ dst := c.DestinationAddr()
+ return fmt.Sprintf("%s %s chunk %s %s => %s",
+ src.Network(),
+ c.flags.String(),
+ c.tag,
+ src.String(),
+ dst.String(),
+ )
+}
+
+func (c *chunkTCP) setSourceAddr(address string) error {
+ addr, err := net.ResolveTCPAddr("tcp", address)
+ if err != nil {
+ return err
+ }
+ c.sourceIP = addr.IP
+ c.sourcePort = addr.Port
+ return nil
+}
+
+func (c *chunkTCP) setDestinationAddr(address string) error {
+ addr, err := net.ResolveTCPAddr("tcp", address)
+ if err != nil {
+ return err
+ }
+ c.destinationIP = addr.IP
+ c.destinationPort = addr.Port
+ return nil
+}