Skip to content

Commit 194f6f1

Browse files
committed
[feature] Auto-detect game-controller host
1 parent 5341742 commit 194f6f1

File tree

5 files changed

+119
-116
lines changed

5 files changed

+119
-116
lines changed

cmd/ssl-auto-ref-client/main.go

Lines changed: 19 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
11
package main
22

33
import (
4-
"crypto"
5-
"crypto/rand"
64
"crypto/rsa"
7-
"crypto/sha256"
8-
"crypto/x509"
9-
"encoding/pem"
105
"flag"
6+
"github.com/RoboCup-SSL/ssl-game-controller/internal/app/client"
117
"github.com/RoboCup-SSL/ssl-game-controller/pkg/refproto"
128
"github.com/RoboCup-SSL/ssl-go-tools/pkg/sslconn"
13-
"github.com/golang/protobuf/proto"
14-
"io/ioutil"
159
"log"
1610
"net"
1711
)
1812

13+
var udpAddress = flag.String("udpAddress", "224.5.23.1:10003", "The multicast address of ssl-game-controller")
14+
var autoDetectAddress = flag.Bool("autoDetectHost", true, "Automatically detect the game-controller host and replace it with the host given in address")
1915
var refBoxAddr = flag.String("address", "localhost:10007", "Address to connect to")
2016
var privateKeyLocation = flag.String("privateKey", "", "A private key to be used to sign messages")
2117
var clientIdentifier = flag.String("identifier", "test", "The identifier of the client")
@@ -30,47 +26,28 @@ type Client struct {
3026
func main() {
3127
flag.Parse()
3228

33-
loadPrivateKey()
29+
client.LoadPrivateKey(*privateKeyLocation)
30+
31+
if *autoDetectAddress {
32+
host := client.DetectHost(*udpAddress)
33+
if host != "" {
34+
log.Print("Detected game-controller host: ", host)
35+
*refBoxAddr = client.SetHost(*refBoxAddr, host)
36+
}
37+
}
3438

3539
conn, err := net.Dial("tcp", *refBoxAddr)
3640
if err != nil {
3741
log.Fatal("could not connect to game-controller at ", *refBoxAddr)
3842
}
3943
defer conn.Close()
4044
log.Printf("Connected to game-controller at %v", *refBoxAddr)
41-
client := Client{}
42-
client.conn = conn
43-
44-
client.register()
45-
client.sendGameEvent()
46-
client.sendAutoRefMessage("Hello World")
47-
}
45+
c := Client{}
46+
c.conn = conn
4847

49-
func loadPrivateKey() {
50-
if *privateKeyLocation != "" {
51-
privateKey = readPrivateKey()
52-
if privateKey != nil {
53-
log.Print("Found private key")
54-
} else {
55-
log.Print("No private key available")
56-
}
57-
}
58-
}
59-
60-
func readPrivateKey() *rsa.PrivateKey {
61-
b, err := ioutil.ReadFile(*privateKeyLocation)
62-
if err != nil {
63-
log.Fatal("Could not find private key at ", *privateKeyLocation)
64-
}
65-
p, _ := pem.Decode(b)
66-
if p.Type != "RSA PRIVATE KEY" {
67-
log.Fatal("Private key type is wrong: ", p.Type)
68-
}
69-
privateKey, err := x509.ParsePKCS1PrivateKey(p.Bytes)
70-
if err != nil {
71-
log.Fatal(err)
72-
}
73-
return privateKey
48+
c.register()
49+
c.sendGameEvent()
50+
c.sendAutoRefMessage("Hello World")
7451
}
7552

7653
func (c *Client) register() {
@@ -86,7 +63,7 @@ func (c *Client) register() {
8663
registration.Identifier = clientIdentifier
8764
if privateKey != nil {
8865
registration.Signature = &refproto.Signature{Token: controllerReply.NextToken, Pkcs1V15: []byte{}}
89-
registration.Signature.Pkcs1V15 = sign(privateKey, &registration)
66+
registration.Signature.Pkcs1V15 = client.Sign(privateKey, &registration)
9067
}
9168
log.Print("Sending registration")
9269
if err := sslconn.SendMessage(c.conn, &registration); err != nil {
@@ -136,7 +113,7 @@ func (c *Client) sendAutoRefMessage(msg string) {
136113
func (c *Client) sendRequest(request *refproto.AutoRefToControllerRequest) {
137114
if privateKey != nil {
138115
request.Signature = &refproto.Signature{Token: &c.token, Pkcs1V15: []byte{}}
139-
request.Signature.Pkcs1V15 = sign(privateKey, request)
116+
request.Signature.Pkcs1V15 = client.Sign(privateKey, request)
140117
}
141118

142119
log.Print("Sending ", request)
@@ -160,18 +137,3 @@ func (c *Client) sendRequest(request *refproto.AutoRefToControllerRequest) {
160137
c.token = ""
161138
}
162139
}
163-
164-
func sign(privateKey *rsa.PrivateKey, message proto.Message) []byte {
165-
messageBytes, err := proto.Marshal(message)
166-
if err != nil {
167-
log.Fatal(err)
168-
}
169-
hash := sha256.New()
170-
hash.Write(messageBytes)
171-
d := hash.Sum(nil)
172-
signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, d)
173-
if err != nil {
174-
log.Fatal(err)
175-
}
176-
return signature
177-
}

cmd/ssl-game-controller/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import (
88
"net/http"
99
)
1010

11-
var address = flag.String("address", "localhost:8081", "The address on which the UI and API is served, default: localhost:8081")
11+
var address = flag.String("address", "localhost:8081", "The address on which the UI and API is served")
1212

1313
func main() {
1414
flag.Parse()

cmd/ssl-ref-client/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414

1515
const maxDatagramSize = 8192
1616

17-
var refereeAddress = flag.String("address", "224.5.23.1:10003", "The multicast address of ssl-game-controller, default: 224.5.23.1:10003")
17+
var refereeAddress = flag.String("address", "224.5.23.1:10003", "The multicast address of ssl-game-controller")
1818
var fullScreen = flag.Bool("fullScreen", false, "Print the formatted message to the console, clearing the screen during print")
1919

2020
var history []refproto.Referee_Command

cmd/ssl-team-client/main.go

Lines changed: 19 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
11
package main
22

33
import (
4-
"crypto"
5-
"crypto/rand"
64
"crypto/rsa"
7-
"crypto/sha256"
8-
"crypto/x509"
9-
"encoding/pem"
105
"flag"
6+
"github.com/RoboCup-SSL/ssl-game-controller/internal/app/client"
117
"github.com/RoboCup-SSL/ssl-game-controller/pkg/refproto"
128
"github.com/RoboCup-SSL/ssl-go-tools/pkg/sslconn"
13-
"github.com/golang/protobuf/proto"
14-
"io/ioutil"
159
"log"
1610
"net"
1711
)
1812

13+
var udpAddress = flag.String("udpAddress", "224.5.23.1:10003", "The multicast address of ssl-game-controller")
14+
var autoDetectAddress = flag.Bool("autoDetectHost", true, "Automatically detect the game-controller host and replace it with the host given in address")
1915
var refBoxAddr = flag.String("address", "localhost:10008", "Address to connect to")
2016
var privateKeyLocation = flag.String("privateKey", "", "A private key to be used to sign messages")
2117
var teamName = flag.String("teamName", "Test Team", "The name of the team as it is sent by the referee")
@@ -30,50 +26,31 @@ type Client struct {
3026
func main() {
3127
flag.Parse()
3228

33-
loadPrivateKey()
29+
client.LoadPrivateKey(*privateKeyLocation)
30+
31+
if *autoDetectAddress {
32+
host := client.DetectHost(*udpAddress)
33+
if host != "" {
34+
log.Print("Detected game-controller host: ", host)
35+
*refBoxAddr = client.SetHost(*refBoxAddr, host)
36+
}
37+
}
3438

3539
conn, err := net.Dial("tcp", *refBoxAddr)
3640
if err != nil {
3741
log.Fatal("could not connect to game-controller at ", *refBoxAddr)
3842
}
3943
defer conn.Close()
4044
log.Printf("Connected to game-controller at %v", *refBoxAddr)
41-
client := Client{}
42-
client.conn = conn
45+
c := Client{}
46+
c.conn = conn
4347

44-
client.register()
45-
client.sendDesiredKeeper(3)
48+
c.register()
49+
c.sendDesiredKeeper(3)
4650

4751
for {
48-
client.ReplyToChoices()
49-
}
50-
}
51-
52-
func loadPrivateKey() {
53-
if *privateKeyLocation != "" {
54-
privateKey = readPrivateKey()
55-
if privateKey != nil {
56-
log.Print("Found private key")
57-
} else {
58-
log.Print("No private key available")
59-
}
60-
}
61-
}
62-
63-
func readPrivateKey() *rsa.PrivateKey {
64-
b, err := ioutil.ReadFile(*privateKeyLocation)
65-
if err != nil {
66-
log.Fatal("Could not find private key at ", *privateKeyLocation)
67-
}
68-
p, _ := pem.Decode(b)
69-
if p.Type != "RSA PRIVATE KEY" {
70-
log.Fatal("Private key type is wrong: ", p.Type)
52+
c.ReplyToChoices()
7153
}
72-
privateKey, err := x509.ParsePKCS1PrivateKey(p.Bytes)
73-
if err != nil {
74-
log.Fatal(err)
75-
}
76-
return privateKey
7754
}
7855

7956
func (c *Client) register() {
@@ -89,7 +66,7 @@ func (c *Client) register() {
8966
registration.TeamName = teamName
9067
if privateKey != nil {
9168
registration.Signature = &refproto.Signature{Token: controllerReply.NextToken, Pkcs1V15: []byte{}}
92-
registration.Signature.Pkcs1V15 = sign(privateKey, &registration)
69+
registration.Signature.Pkcs1V15 = client.Sign(privateKey, &registration)
9370
}
9471
log.Print("Sending registration")
9572
if err := sslconn.SendMessage(c.conn, &registration); err != nil {
@@ -137,7 +114,7 @@ func (c *Client) ReplyToChoices() {
137114
func (c *Client) sendRequest(request *refproto.TeamToControllerRequest) {
138115
if privateKey != nil {
139116
request.Signature = &refproto.Signature{Token: &c.token, Pkcs1V15: []byte{}}
140-
request.Signature.Pkcs1V15 = sign(privateKey, request)
117+
request.Signature.Pkcs1V15 = client.Sign(privateKey, request)
141118
}
142119

143120
log.Print("Sending ", request)
@@ -161,18 +138,3 @@ func (c *Client) sendRequest(request *refproto.TeamToControllerRequest) {
161138
c.token = ""
162139
}
163140
}
164-
165-
func sign(privateKey *rsa.PrivateKey, message proto.Message) []byte {
166-
messageBytes, err := proto.Marshal(message)
167-
if err != nil {
168-
log.Fatal(err)
169-
}
170-
hash := sha256.New()
171-
hash.Write(messageBytes)
172-
d := hash.Sum(nil)
173-
signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, d)
174-
if err != nil {
175-
log.Fatal(err)
176-
}
177-
return signature
178-
}

internal/app/client/client.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package client
2+
3+
import (
4+
"crypto"
5+
"crypto/rand"
6+
"crypto/rsa"
7+
"crypto/sha256"
8+
"crypto/x509"
9+
"encoding/pem"
10+
"github.com/golang/protobuf/proto"
11+
"io/ioutil"
12+
"log"
13+
"net"
14+
"strings"
15+
)
16+
17+
func DetectHost(address string) string {
18+
addr, err := net.ResolveUDPAddr("udp", address)
19+
if err != nil {
20+
log.Fatal(err)
21+
}
22+
conn, err := net.ListenMulticastUDP("udp", nil, addr)
23+
if err != nil {
24+
log.Fatal(err)
25+
}
26+
defer conn.Close()
27+
_, udpAddr, err := conn.ReadFromUDP([]byte{0})
28+
if err != nil {
29+
log.Fatal(err)
30+
}
31+
return udpAddr.IP.String()
32+
}
33+
34+
func SetHost(address string, host string) string {
35+
parts := strings.Split(address, ":")
36+
return host + ":" + parts[1]
37+
}
38+
39+
func LoadPrivateKey(privateKeyLocation string) {
40+
if privateKeyLocation != "" {
41+
privateKey := ReadPrivateKey(privateKeyLocation)
42+
if privateKey != nil {
43+
log.Print("Found private key")
44+
} else {
45+
log.Print("No private key available")
46+
}
47+
}
48+
}
49+
50+
func ReadPrivateKey(privateKeyLocation string) *rsa.PrivateKey {
51+
b, err := ioutil.ReadFile(privateKeyLocation)
52+
if err != nil {
53+
log.Fatal("Could not find private key at ", privateKeyLocation)
54+
}
55+
p, _ := pem.Decode(b)
56+
if p.Type != "RSA PRIVATE KEY" {
57+
log.Fatal("Private key type is wrong: ", p.Type)
58+
}
59+
privateKey, err := x509.ParsePKCS1PrivateKey(p.Bytes)
60+
if err != nil {
61+
log.Fatal(err)
62+
}
63+
return privateKey
64+
}
65+
66+
func Sign(privateKey *rsa.PrivateKey, message proto.Message) []byte {
67+
messageBytes, err := proto.Marshal(message)
68+
if err != nil {
69+
log.Fatal(err)
70+
}
71+
hash := sha256.New()
72+
hash.Write(messageBytes)
73+
d := hash.Sum(nil)
74+
signature, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, d)
75+
if err != nil {
76+
log.Fatal(err)
77+
}
78+
return signature
79+
}

0 commit comments

Comments
 (0)