package net import "net" type LuxChannelType uint const ( LuxChannelInterior = 0 LuxChannelExterior = 1 ) func (chType *LuxChannelType) String() string { switch *chType { case LuxChannelInterior: return "interior" case LuxChannelExterior: return "exterior" default: return "?" } } type LuxChannel struct { Type LuxChannelType Address *net.UDPAddr conn *net.UDPConn preconnected bool control chan bool } // bind udp socket to receive packets func NewLuxInboundChannel(udpStr string, chType LuxChannelType) (LuxChannel, error) { addr, err := net.ResolveUDPAddr("udp", udpStr) if err != nil { return LuxChannel{}, err } conn, err := net.ListenUDP("udp", addr) if err != nil { return LuxChannel{}, err } return LuxChannel{ Type: chType, Address: addr, conn: conn, preconnected: false, control: make(chan bool), }, nil } // udp socket to send datagrams func NewLuxOutboundChannel(udpStr string, chType LuxChannelType) (LuxChannel, error) { addr, err := net.ResolveUDPAddr("udp", udpStr) if err != nil { return LuxChannel{}, err } conn, err := net.DialUDP("udp", nil, addr) if err != nil { return LuxChannel{}, err } return LuxChannel{ Type: chType, Address: addr, conn: conn, preconnected: true, }, nil } const MAX_UDP_SIZE = 65535 func (ch *LuxChannel) Recv() (LuxDatagram, error) { buf := make([]byte, MAX_UDP_SIZE) len, addr, err := ch.conn.ReadFromUDP(buf) if err != nil { return LuxDatagram{}, err } return LuxDatagram{ Target: addr, Payload: buf[:len], Channel: ch, }, nil } func (ch *LuxChannel) Send(dgram LuxDatagram) error { if ch.preconnected { _, err := ch.conn.Write(dgram.Payload) return err } else { _, err := ch.conn.WriteToUDP(dgram.Payload, dgram.Target) return err } } func (ch *LuxChannel) Close() { ch.conn.Close() }