]> git.lizzy.rs Git - mt.git/blob - cmd/proxy/proxy.go
d05010082718f5440d527d9067136d5c3233df8c
[mt.git] / cmd / proxy / proxy.go
1 /*
2 Proxy is a Minetest proxy server
3 supporting multiple concurrent connections.
4
5 Usage:
6         proxy dial:port listen:port
7 where dial:port is the server address
8 and listen:port is the address to listen on.
9 */
10 package main
11
12 import (
13         "errors"
14         "fmt"
15         "log"
16         "net"
17         "os"
18
19         "github.com/Minetest-j45/mt"
20 )
21
22 func main() {
23         if len(os.Args) != 3 {
24                 fmt.Fprintln(os.Stderr, "usage: proxy dial:port listen:port")
25                 os.Exit(1)
26         }
27
28         srvaddr, err := net.ResolveUDPAddr("udp", os.Args[1])
29         if err != nil {
30                 log.Fatal(err)
31         }
32
33         lc, err := net.ListenPacket("udp", os.Args[2])
34         if err != nil {
35                 log.Fatal(err)
36         }
37         defer lc.Close()
38
39         l := mt.Listen(lc)
40         for {
41                 clt, err := l.Accept()
42                 if err != nil {
43                         log.Print(err)
44                         continue
45                 }
46
47                 log.Print(clt.RemoteAddr().String() + " connected")
48
49                 conn, err := net.DialUDP("udp", nil, srvaddr)
50                 if err != nil {
51                         log.Print(err)
52                         continue
53                 }
54                 srv := mt.Connect(conn)
55
56                 go proxy(clt, srv)
57                 go proxy(srv, clt)
58         }
59 }
60
61 func proxy(src, dest mt.Peer) {
62         s := fmt.Sprint(src.ID(), " (", src.RemoteAddr(), "): ")
63
64         for {
65                 pkt, err := src.Recv()
66                 if err != nil {
67                         if errors.Is(err, net.ErrClosed) {
68                                 if err := src.WhyClosed(); err != nil {
69                                         log.Print(s, "disconnected: ", err)
70                                 } else {
71                                         log.Print(s, "disconnected")
72                                 }
73                                 break
74                         }
75
76                         log.Print(s, err)
77                         continue
78                 }
79
80                 if _, err := dest.Send(pkt); err != nil {
81                         log.Print(err)
82                 }
83         }
84
85         dest.Close()
86 }