]> git.lizzy.rs Git - mt.git/blob - rudp/proxy/proxy.go
rudp: optimize and refactor
[mt.git] / rudp / proxy / proxy.go
1 /*
2 Proxy is a Minetest RUDP 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         "mt/rudp"
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 := rudp.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.Addr(), " connected")
48
49                 conn, err := net.DialUDP("udp", nil, srvaddr)
50                 if err != nil {
51                         log.Print(err)
52                         continue
53                 }
54                 srv := rudp.Connect(conn, conn.RemoteAddr())
55
56                 go proxy(clt, srv)
57                 go proxy(srv, clt)
58         }
59 }
60
61 func proxy(src, dest *rudp.Peer) {
62         for {
63                 pkt, err := src.Recv()
64                 if err != nil {
65                         if errors.Is(err, net.ErrClosed) {
66                                 msg := src.Addr().String() + " disconnected"
67                                 if src.TimedOut() {
68                                         msg += " (timed out)"
69                                 }
70                                 log.Print(msg)
71
72                                 break
73                         }
74
75                         log.Print(err)
76                         continue
77                 }
78
79                 if _, err := dest.Send(pkt); err != nil {
80                         log.Print(err)
81                 }
82         }
83
84         dest.SendDisco(0, true)
85         dest.Close()
86 }