Files

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
}