blob: 21f9399d3e233efaf51bd03ce45f0ae1ab62dfcc [file] [log] [blame]
Serge Bazanskide0330a2020-07-30 20:48:48 +02001package main
2
3import (
4 "context"
5 "net"
6 "strings"
7
8 "github.com/golang/glog"
9)
10
11type packetFrom struct {
12 addr net.Addr
13 data []byte
14}
15
16func (s *service) runProxy(ctx context.Context, updates chan *lockUpdate, laserAddr net.Addr, laserNet, clientNet net.PacketConn) {
17 glog.Infof("Proxy starting... (laser: %v, laser network: %v, client network: %v)", laserAddr, laserNet, clientNet)
18
19
20 pipe := func(conn net.PacketConn, C chan *packetFrom) {
21 for {
22 buf := make([]byte, 1500)
23 n, addr, err := conn.ReadFrom(buf)
24 if err != nil {
25 glog.Errorf("pipe failed: %v", err)
26 }
27 C <- &packetFrom{ addr, buf[:n] }
28 }
29 }
30
31 laserC := make(chan *packetFrom)
32 go pipe(laserNet, laserC)
33 clientC := make(chan *packetFrom)
34 go pipe(clientNet, clientC)
35
36 var allowedClient string
37 var curClient *net.Addr
38 for {
39 select {
40 case <-ctx.Done():
41 err := ctx.Err()
42 glog.Errorf("Proxy stopped: %v", err)
43 return
44 case u := <-updates:
45 allowedClient = u.addr
46 glog.Infof("New allowed client: %q", allowedClient)
47 case p := <-laserC:
48 s.lockCtrl <- &lockCtrl{
49 bump: &lockCtrlBump{},
50 }
51 if curClient == nil {
52 glog.Warningf("Packet from laser without client connected, dropping.")
53 break
54 }
55 clientNet.WriteTo(p.data, *curClient)
56 case p := <-clientC:
57 s.lockCtrl <- &lockCtrl{
58 bump: &lockCtrlBump{},
59 }
60 if strings.Split(p.addr.String(), ":")[0] == allowedClient {
61 curClient = &p.addr
62 laserNet.WriteTo(p.data, laserAddr)
63 } else {
64 glog.Infof("Rejecting packet from %s", p.addr.String())
65 }
66 }
67 }
68}
69