func listener(ctx context.Context, frameSize int, addr string) error { ln, err := net.Listen("tcp", addr) if err != nil { fmt.Fprintf(os.Stderr, "net.Listen(%q): %s\n", addr, err.Error()) return err } go func() { <-ctx.Done() ln.Close() }() c, err := ln.Accept() if err != nil { fmt.Fprintf(os.Stderr, "ln.Accept(): %s\n", err.Error()) return err } fc := fnet.FromOrderedStream(c, frameSize) go func() { <-ctx.Done() fc.Close() }() if err = clockstation.Run(ctx, fc, time.Tick(50*time.Millisecond)); err != nil { return fmt.Errorf("clockstation.Run: %s\n", err.Error()) } return nil }
func run(ctx context.Context, rendID *[32]byte, seed []byte, identifiable bool, numStreams int, rnd *mathrand.Rand) error { tr, err := torch.New(ctx, proxy.FromEnvironment()) if err != nil { return err } defer tr.Stop() rendNode := tr.WithDirectory(func(dir *directory.Directory) interface{} { shortInfos := make([]*directory.ShortNodeInfo, 0, len(dir.Routers)) for _, n := range dir.Routers { if n.Fast && n.Running && n.Stable && n.Valid && (n.Port == 443 || n.Port == 80) { shortInfos = append(shortInfos, n.ShortNodeInfo) } } rendShort := nd.Pick(shortInfos, rendID) for _, r := range dir.Routers { if r.ShortNodeInfo == rendShort { return r } } panic("unreachable") }).(*directory.NodeInfo) // when we talk to a website over TOR, the website knows what the third hop // is. Therefore our converstion partner may as well. nodes := make([]*directory.NodeInfo, 0, 3) if !identifiable { nodes = append(nodes, tr.Pick(weigh, rnd)) nodes = append(nodes, tr.Pick(weigh, rnd)) } nodes = append(nodes, rendNode) rr := fnet.NewRoundRobin(nd.FRAMESIZE) defer rr.Close() fmt.Println("plan:") for _, n := range nodes { fmt.Printf("%d\n", n.IP) } sending := false for i := 0; i < numStreams; i++ { seed_i := sha256.Sum256(append(append([]byte{}, seed...), byte(i))) tc1, c1, err := torch.BuildCircuit(ctx, proxy.FromEnvironment(), nodes) if err != nil { return err } defer tc1.Close() tc2, c2, err := torch.BuildCircuit(ctx, proxy.FromEnvironment(), nodes) if err != nil { return err } defer tc2.Close() ndc, err := nd.Handshake(ctx, c1, c2, seed_i[:]) // Arbitrarily choose one of the sides of the TOR connection to be the sender of the test data // By choosing the first ndc.bit if i == 0 { sending = ndc.Bit } if err != nil { return err } rr.AddConn(ndc) } println("connected and running") if sending { if err = clockstation.Run(ctx, rr, time.Tick(50*time.Millisecond)); err != nil { return fmt.Errorf("clockstation.Run: %s\n", err.Error()) } } else { if err = clockprinter.Run(ctx, rr); err != nil { fmt.Errorf("clockprinter.Run: %s\n", err.Error()) } } return nil <-ctx.Done() return nil }