101 lines
2.6 KiB
Go
101 lines
2.6 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"bytes"
|
|
iroh "git.coopcloud.tech/decentral1se/iroh-go"
|
|
|
|
"gomod.cblgh.org/iroh-tracker/util"
|
|
"gomod.cblgh.org/iroh-tracker/proto"
|
|
)
|
|
|
|
var (
|
|
alpn = util.GetALPN(proto.VERSION)
|
|
trackerEndpointID string
|
|
readkey string
|
|
topic string
|
|
)
|
|
|
|
func parseFlags() {
|
|
flag.StringVar(&readkey, "readkey", "client-hello-there-iroh-tracker", "iroh tracker read key")
|
|
flag.StringVar(&trackerEndpointID, "endpoint", "", "endpoint id of peer")
|
|
flag.StringVar(&topic, "topic", "test-topic", "topic to announce & query on")
|
|
flag.Parse()
|
|
}
|
|
|
|
func ClientHello() []byte {
|
|
return []byte(fmt.Sprintf("V%d/CLIENT/HELLO/%x", proto.VERSION, util.TwiceHashedKey(readkey)))
|
|
}
|
|
|
|
func ClientPut() []byte {
|
|
// NOTE: twice hashed topic
|
|
return []byte(fmt.Sprintf("V%d/CLIENT/PUT/%x", proto.VERSION, util.TwiceHashedKey(topic)))
|
|
}
|
|
|
|
func ClientGet() []byte {
|
|
// NOTE: twice hashed topic
|
|
return []byte(fmt.Sprintf("V%d/CLIENT/GET/%x", proto.VERSION, util.TwiceHashedKey(topic)))
|
|
}
|
|
|
|
func start(e *iroh.Endpoint, id string, done chan struct{}) {
|
|
remote, err := iroh.EndpointIdFromString(id)
|
|
util.Check(err)
|
|
|
|
addr := iroh.NewEndpointAddr(remote, nil, nil)
|
|
conn, err := e.Connect(addr, alpn)
|
|
util.Check(err)
|
|
|
|
// from docs:
|
|
// "The peer that calls open_bi must write to its SendStream before the peer Connection is able to accept the stream
|
|
// using accept_bi()"
|
|
// https://docs.rs/iroh/latest/iroh/endpoint/struct.Connection.html#method.accept_bi
|
|
stream, err := conn.OpenBi()
|
|
util.Check(err)
|
|
|
|
responseCh := make(chan []byte)
|
|
processClosure := func(incoming []byte) ([]byte, bool) {
|
|
if bytes.Equal(incoming, []byte("HELLO:welcome")) {
|
|
fmt.Println("welcome OK!")
|
|
return ClientPut(), true
|
|
}
|
|
if bytes.Equal(incoming, []byte("PUT:OK")) {
|
|
fmt.Println("PUT OK!")
|
|
return ClientGet(), true
|
|
}
|
|
if endpointList, exists := bytes.CutPrefix(incoming, []byte("GET:")); exists {
|
|
// endpoints := bytes.Split(endpointList, []byte(","))
|
|
fmt.Printf("GET:%s\n", string(endpointList))
|
|
// we got what we came for
|
|
close(done)
|
|
return nil, false
|
|
}
|
|
return nil, false
|
|
}
|
|
go util.HandleReading(stream.Recv(), processClosure, responseCh, done)
|
|
go util.SendResponses(stream.Send(), responseCh, done)
|
|
|
|
// open bidi stream with client hello message
|
|
responseCh <- ClientHello()
|
|
|
|
util.Check(err)
|
|
}
|
|
|
|
func main() {
|
|
parseFlags()
|
|
|
|
preset := iroh.PresetN0()
|
|
opts := iroh.EndpointOptions{
|
|
Preset: &preset,
|
|
Alpns: &[][]byte{alpn},
|
|
}
|
|
|
|
clientEndpoint, err := iroh.EndpointBind(opts)
|
|
util.Check(err)
|
|
|
|
done := make(chan struct{})
|
|
go func() { start(clientEndpoint, trackerEndpointID, done) }()
|
|
|
|
<-done
|
|
}
|