-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 91a63c8
Showing
6 changed files
with
295 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
name: Go | ||
|
||
on: | ||
push: | ||
branches: [ "master" ] | ||
pull_request: | ||
branches: [ "master" ] | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- name: Set up Go | ||
uses: actions/setup-go@v4 | ||
with: | ||
go-version: '1.22' | ||
|
||
- name: Build | ||
run: go build -v ./... | ||
|
||
test: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- name: Set up Go | ||
uses: actions/setup-go@v4 | ||
with: | ||
go-version: '1.22' | ||
|
||
- name: Test | ||
run: go test -v ./... | ||
|
||
format: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- name: Set up Go | ||
uses: actions/setup-go@v4 | ||
with: | ||
go-version: '1.22' | ||
|
||
- name: Format | ||
run: diff -u <(echo -n) <(gofmt -d ./) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
teeworlds_client | ||
teeworlds | ||
proxy | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
# teeworlds proxy | ||
|
||
WORK IN PROGRESS | ||
|
||
## run the proxy | ||
|
||
``` | ||
go build | ||
./proxy -H 127.0.0.1 -P 8303 -p 8333 | ||
``` | ||
|
||
Start a teeworlds 0.7 server on port 8303 on your machine. | ||
Connect to 8333 with your 0.7 client and you will be proxied to the 8303 server. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
module github.com/teeworlds-go/proxy | ||
|
||
go 1.22.3 | ||
|
||
require github.com/teeworlds-go/teeworlds v0.0.0-20240621015046-db550ce86fda | ||
|
||
require github.com/teeworlds-go/huffman v1.0.0 // indirect |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
github.com/teeworlds-go/huffman v1.0.0 h1:XSNMNAJZb+njNrPACsxcDrrLDXTGjZZt35FqLAuHi4I= | ||
github.com/teeworlds-go/huffman v1.0.0/go.mod h1:kjaXpL6C6xL7CM+tWPNYjdEgVZB2GumKhx7rCDdXArU= | ||
github.com/teeworlds-go/teeworlds v0.0.0-20240621015046-db550ce86fda h1:Ho08Zo5Co+t5VfX4wVqiEDHxxDD3F+52AYne/Gs7oj0= | ||
github.com/teeworlds-go/teeworlds v0.0.0-20240621015046-db550ce86fda/go.mod h1:aKhyLQAZ0cXv3e6ivNMiolKLbycQlDTIq9Yldn7klWM= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,219 @@ | ||
// Implementation of a UDP proxy | ||
|
||
package main | ||
|
||
import ( | ||
"flag" | ||
"fmt" | ||
"log" | ||
"net" | ||
"os" | ||
"strings" | ||
"sync" | ||
|
||
"github.com/teeworlds-go/teeworlds/messages7" | ||
"github.com/teeworlds-go/teeworlds/network7" | ||
"github.com/teeworlds-go/teeworlds/protocol7" | ||
) | ||
|
||
// Information maintained for each client/server connection | ||
type Connection struct { | ||
ClientAddr *net.UDPAddr // Address of the client | ||
ServerConn *net.UDPConn // UDP connection to server | ||
} | ||
|
||
// Generate a new connection by opening a UDP connection to the server | ||
func NewConnection(srvAddr, cliAddr *net.UDPAddr) *Connection { | ||
conn := new(Connection) | ||
conn.ClientAddr = cliAddr | ||
srvudp, err := net.DialUDP("udp", nil, srvAddr) | ||
if checkreport(1, err) { | ||
return nil | ||
} | ||
conn.ServerConn = srvudp | ||
return conn | ||
} | ||
|
||
// Global state | ||
// Connection used by clients as the proxy server | ||
var ProxyConn *net.UDPConn | ||
|
||
// Address of server | ||
var ServerAddr *net.UDPAddr | ||
|
||
// Mapping from client addresses (as host:port) to connection | ||
var ClientDict map[string]*Connection = make(map[string]*Connection) | ||
|
||
// Mutex used to serialize access to the dictionary | ||
var dmutex *sync.Mutex = new(sync.Mutex) | ||
|
||
func setup(hostport string, port int) bool { | ||
// Set up Proxy | ||
saddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf(":%d", port)) | ||
if checkreport(1, err) { | ||
return false | ||
} | ||
pudp, err := net.ListenUDP("udp", saddr) | ||
if checkreport(1, err) { | ||
return false | ||
} | ||
ProxyConn = pudp | ||
Vlogf(2, "Proxy serving on port %d\n", port) | ||
|
||
// Get server address | ||
srvaddr, err := net.ResolveUDPAddr("udp", hostport) | ||
if checkreport(1, err) { | ||
return false | ||
} | ||
ServerAddr = srvaddr | ||
Vlogf(2, "Connected to server at %s\n", hostport) | ||
return true | ||
} | ||
|
||
func dlock() { | ||
dmutex.Lock() | ||
} | ||
|
||
func dunlock() { | ||
dmutex.Unlock() | ||
} | ||
|
||
// Go routine which manages connection from server to single client | ||
func RunConnection(conn *Connection, twconn *protocol7.Connection) { | ||
var buffer [1500]byte | ||
for { | ||
// Read from server | ||
n, err := conn.ServerConn.Read(buffer[0:]) | ||
if checkreport(1, err) { | ||
continue | ||
} | ||
|
||
srvMsg := buffer[0:n] | ||
result, err := twconn.OnPacket(srvMsg) | ||
if err != nil { | ||
panic(err) | ||
} | ||
// example of inspecting incoming trafic | ||
for i, msg := range result.Packet.Messages { | ||
if msg.MsgId() == network7.MsgGameSvChat { | ||
var chat *messages7.SvChat | ||
var ok bool | ||
if chat, ok = result.Packet.Messages[i].(*messages7.SvChat); ok { | ||
fmt.Printf("got chat msg: %s\n", chat.Message) | ||
chat.Message = "capitalism." | ||
|
||
// modify chat if this was a proxy | ||
result.Packet.Messages[i] = chat | ||
|
||
srvMsg = result.Packet.Pack(twconn) | ||
} | ||
} | ||
} | ||
|
||
// Relay it to client | ||
_, err = ProxyConn.WriteToUDP(srvMsg, conn.ClientAddr) | ||
if checkreport(1, err) { | ||
continue | ||
} | ||
Vlogf(3, "Relayed '%x' from server to %s.\n", | ||
buffer[0:n], conn.ClientAddr.String()) | ||
} | ||
} | ||
|
||
// Routine to handle inputs to Proxy port | ||
func RunProxy() { | ||
var buffer [1500]byte | ||
for { | ||
n, cliaddr, err := ProxyConn.ReadFromUDP(buffer[0:]) | ||
if checkreport(1, err) { | ||
continue | ||
} | ||
Vlogf(3, "Read '%x' from client %s\n", | ||
buffer[0:n], cliaddr.String()) | ||
saddr := cliaddr.String() | ||
dlock() | ||
conn, found := ClientDict[saddr] | ||
if !found { | ||
conn = NewConnection(ServerAddr, cliaddr) | ||
if conn == nil { | ||
dunlock() | ||
continue | ||
} | ||
ClientDict[saddr] = conn | ||
dunlock() | ||
Vlogf(2, "Created new connection for client %s\n", saddr) | ||
|
||
twconn := &protocol7.Connection{ | ||
ClientToken: [4]byte{0x01, 0x02, 0x03, 0x04}, | ||
ServerToken: [4]byte{0xff, 0xff, 0xff, 0xff}, | ||
Ack: 0, | ||
Players: make([]protocol7.Player, network7.MaxClients), | ||
} | ||
|
||
// Fire up routine to manage new connection | ||
go RunConnection(conn, twconn) | ||
} else { | ||
Vlogf(5, "Found connection for client %s\n", saddr) | ||
dunlock() | ||
} | ||
// Relay to server | ||
_, err = conn.ServerConn.Write(buffer[0:n]) | ||
if checkreport(1, err) { | ||
continue | ||
} | ||
} | ||
} | ||
|
||
var verbosity int = 6 | ||
|
||
// Log result if verbosity level high enough | ||
func Vlogf(level int, format string, v ...interface{}) { | ||
if level <= verbosity { | ||
log.Printf(format, v...) | ||
} | ||
} | ||
|
||
// Handle errors | ||
func checkreport(level int, err error) bool { | ||
if err == nil { | ||
return false | ||
} | ||
Vlogf(level, "Error: %s", err.Error()) | ||
return true | ||
} | ||
|
||
func main() { | ||
var ihelp *bool = flag.Bool("h", false, "Show help information") | ||
var ipport *int = flag.Int("p", 8333, "Proxy port") | ||
var isport *int = flag.Int("P", 8303, "Server port") | ||
var ishost *string = flag.String("H", "localhost", "Server address") | ||
var iverb *int = flag.Int("v", 1, "Verbosity (0-6)") | ||
// var idrop *float64 = flag.Float64("d", 0.0, "Packet drop rate") | ||
flag.Parse() | ||
verbosity = *iverb | ||
if *ihelp { | ||
flag.Usage() | ||
os.Exit(0) | ||
} | ||
if flag.NArg() > 0 { | ||
ok := true | ||
fields := strings.Split(flag.Arg(0), ":") | ||
ok = ok && len(fields) == 2 | ||
if ok { | ||
*ishost = fields[0] | ||
n, err := fmt.Sscanf(fields[1], "%d", isport) | ||
ok = ok && n == 1 && err == nil | ||
} | ||
if !ok { | ||
flag.Usage() | ||
os.Exit(0) | ||
} | ||
} | ||
hostport := fmt.Sprintf("%s:%d", *ishost, *isport) | ||
Vlogf(3, "Proxy port = %d, Server address = %s\n", | ||
*ipport, hostport) | ||
if setup(hostport, *ipport) { | ||
RunProxy() | ||
} | ||
os.Exit(0) | ||
} |