func listener(ctx context.Context, frameSize int, numStreams 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() }() rr := fnet.NewRoundRobin(frameSize) go func() { <-ctx.Done() rr.Close() }() for i := 0; i < numStreams; i++ { c, err := ln.Accept() if err != nil { fmt.Fprintf(os.Stderr, "ln.Accept(): %s\n", err.Error()) return err } fs := fnet.FromOrderedStream(c, frameSize) rr.AddConn(fs) } fc := fnet.FrameConn(rr) 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 dialer(ctx context.Context, frameSize int, numStreams int, addr string) error { rr := fnet.NewRoundRobin(frameSize) go func() { <-ctx.Done() rr.Close() }() for i := 0; i < numStreams; i++ { c, err := net.Dial("tcp", addr) if err != nil { fmt.Fprintf(os.Stderr, "net.Dial(%q): %s\n", addr, err.Error()) return err } fs := fnet.FromOrderedStream(c, frameSize) rr.AddConn(fs) } fc := fnet.FrameConn(rr) if err := clockprinter.Run(ctx, fc); err != nil { fmt.Errorf("clockprinter.Run: %s\n", err.Error()) } return nil }
func run(ctx context.Context, rendID *[32]byte, seed []byte, identifiable bool, numStreams int, udpSourceListen, udpDestinationSend string) 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, nil)) nodes = append(nodes, tr.Pick(weigh, nil)) } nodes = append(nodes, rendNode) rr := fnet.NewRoundRobin(nd.FRAMESIZE) defer rr.Close() 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[:]) if err != nil { return err } rr.AddConn(ndc) } udpFront, err := udp4rrtcp.Start(ctx, udpSourceListen, udpDestinationSend, rr) if err != nil { return err } defer udpFront.Stop() println("connected and running") <-ctx.Done() 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 }