100 lines
1.9 KiB
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()
|
|
}
|