lux/net/lux_channel.go

100 lines
1.9 KiB
Go

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()
}