forked from hswaw/hscloud
70 lines
1.5 KiB
Go
70 lines
1.5 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"net"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/golang/glog"
|
||
|
)
|
||
|
|
||
|
type packetFrom struct {
|
||
|
addr net.Addr
|
||
|
data []byte
|
||
|
}
|
||
|
|
||
|
func (s *service) runProxy(ctx context.Context, updates chan *lockUpdate, laserAddr net.Addr, laserNet, clientNet net.PacketConn) {
|
||
|
glog.Infof("Proxy starting... (laser: %v, laser network: %v, client network: %v)", laserAddr, laserNet, clientNet)
|
||
|
|
||
|
|
||
|
pipe := func(conn net.PacketConn, C chan *packetFrom) {
|
||
|
for {
|
||
|
buf := make([]byte, 1500)
|
||
|
n, addr, err := conn.ReadFrom(buf)
|
||
|
if err != nil {
|
||
|
glog.Errorf("pipe failed: %v", err)
|
||
|
}
|
||
|
C <- &packetFrom{ addr, buf[:n] }
|
||
|
}
|
||
|
}
|
||
|
|
||
|
laserC := make(chan *packetFrom)
|
||
|
go pipe(laserNet, laserC)
|
||
|
clientC := make(chan *packetFrom)
|
||
|
go pipe(clientNet, clientC)
|
||
|
|
||
|
var allowedClient string
|
||
|
var curClient *net.Addr
|
||
|
for {
|
||
|
select {
|
||
|
case <-ctx.Done():
|
||
|
err := ctx.Err()
|
||
|
glog.Errorf("Proxy stopped: %v", err)
|
||
|
return
|
||
|
case u := <-updates:
|
||
|
allowedClient = u.addr
|
||
|
glog.Infof("New allowed client: %q", allowedClient)
|
||
|
case p := <-laserC:
|
||
|
s.lockCtrl <- &lockCtrl{
|
||
|
bump: &lockCtrlBump{},
|
||
|
}
|
||
|
if curClient == nil {
|
||
|
glog.Warningf("Packet from laser without client connected, dropping.")
|
||
|
break
|
||
|
}
|
||
|
clientNet.WriteTo(p.data, *curClient)
|
||
|
case p := <-clientC:
|
||
|
s.lockCtrl <- &lockCtrl{
|
||
|
bump: &lockCtrlBump{},
|
||
|
}
|
||
|
if strings.Split(p.addr.String(), ":")[0] == allowedClient {
|
||
|
curClient = &p.addr
|
||
|
laserNet.WriteTo(p.data, laserAddr)
|
||
|
} else {
|
||
|
glog.Infof("Rejecting packet from %s", p.addr.String())
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|