2023-06-27 01:24:19 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"encoding/json"
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
|
|
|
"net"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/libp2p/go-libp2p"
|
|
|
|
"github.com/libp2p/go-libp2p/core/crypto"
|
|
|
|
"github.com/libp2p/go-libp2p/core/peer"
|
|
|
|
"github.com/multiformats/go-multiaddr"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
runServer := flag.Bool("run-server", false, "Should run as server")
|
|
|
|
serverAddr := flag.String("server-address", "", "Server address")
|
|
|
|
transport := flag.String("transport", "tcp", "Transport to use")
|
|
|
|
uploadBytes := flag.Uint64("upload-bytes", 0, "Upload bytes")
|
|
|
|
downloadBytes := flag.Uint64("download-bytes", 0, "Download bytes")
|
|
|
|
flag.Parse()
|
|
|
|
|
|
|
|
host, port, err := net.SplitHostPort(*serverAddr)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
tcpMultiAddrStr := fmt.Sprintf("/ip4/%s/tcp/%s", host, port)
|
|
|
|
quicMultiAddrStr := fmt.Sprintf("/ip4/%s/udp/%s/quic-v1", host, port)
|
|
|
|
|
|
|
|
var opts []libp2p.Option
|
|
|
|
if *runServer {
|
|
|
|
opts = append(opts, libp2p.ListenAddrStrings(tcpMultiAddrStr, quicMultiAddrStr))
|
|
|
|
|
|
|
|
// Generate stable fake identity.
|
|
|
|
//
|
|
|
|
// Using a stable identity (i.e. peer ID) allows the client to
|
|
|
|
// connect to the server without a prior exchange of the
|
|
|
|
// server's peer ID.
|
|
|
|
priv, _, err := crypto.GenerateEd25519Key(&simpleReader{seed: 0})
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("failed to generate key: %s", err)
|
|
|
|
}
|
|
|
|
opts = append(opts, libp2p.Identity(priv))
|
|
|
|
}
|
|
|
|
|
|
|
|
h, err := libp2p.New(opts...)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("failed to instantiate libp2p: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
perf := NewPerfService(h)
|
|
|
|
if *runServer {
|
|
|
|
for _, a := range h.Addrs() {
|
|
|
|
fmt.Println(a.Encapsulate(multiaddr.StringCast("/p2p/" + h.ID().String())))
|
|
|
|
}
|
|
|
|
|
|
|
|
select {} // run forever, exit on interrupt
|
|
|
|
}
|
|
|
|
|
|
|
|
var multiAddrStr string
|
|
|
|
switch *transport {
|
|
|
|
case "tcp":
|
|
|
|
multiAddrStr = tcpMultiAddrStr
|
|
|
|
case "quic-v1":
|
|
|
|
multiAddrStr = quicMultiAddrStr
|
|
|
|
default:
|
|
|
|
fmt.Println("Invalid transport. Accepted values: 'tcp' or 'quic-v1'")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
// Peer ID corresponds to the above fake identity.
|
|
|
|
multiAddrStr = multiAddrStr + "/p2p/12D3KooWDpJ7As7BWAwRMfu1VU2WCqNjvq387JEYKDBj4kx6nXTN"
|
|
|
|
serverInfo, err := peer.AddrInfoFromString(multiAddrStr)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("failed to build address info: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
start := time.Now()
|
|
|
|
err = h.Connect(context.Background(), *serverInfo)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("failed to dial peer: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
err = perf.RunPerf(context.Background(), serverInfo.ID, uint64(*uploadBytes), uint64(*downloadBytes))
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("failed to execute perf: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
jsonB, err := json.Marshal(Result{
|
2023-10-25 11:24:08 +00:00
|
|
|
TimeSeconds: time.Since(start).Seconds(),
|
|
|
|
UploadBytes: *uploadBytes,
|
|
|
|
DownloadBytes: *downloadBytes,
|
|
|
|
Type: "final",
|
2023-06-27 01:24:19 +00:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
log.Fatalf("failed to marshal perf result: %s", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Println(string(jsonB))
|
|
|
|
}
|
|
|
|
|
|
|
|
type Result struct {
|
2023-10-25 11:24:08 +00:00
|
|
|
Type string `json:"type"`
|
|
|
|
TimeSeconds float64 `json:"timeSeconds"`
|
|
|
|
UploadBytes uint64 `json:"uploadBytes"`
|
|
|
|
DownloadBytes uint64 `json:"downloadBytes"`
|
2023-06-27 01:24:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type simpleReader struct {
|
|
|
|
seed uint8
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *simpleReader) Read(p []byte) (n int, err error) {
|
|
|
|
for i := range p {
|
|
|
|
p[i] = r.seed
|
|
|
|
}
|
|
|
|
return len(p), nil
|
|
|
|
}
|