github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/apps/mixnet/mixnet_test.go (about) 1 // Copyright (c) 2015, Google Inc. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License0. 14 15 package mixnet 16 17 import ( 18 "bytes" 19 "crypto/rand" 20 "crypto/tls" 21 "crypto/x509" 22 "crypto/x509/pkix" 23 "encoding/base64" 24 "errors" 25 "fmt" 26 "io" 27 "io/ioutil" 28 "log" 29 "net" 30 "os" 31 "path" 32 "strings" 33 "sync" 34 "testing" 35 "time" 36 37 "github.com/golang/protobuf/proto" 38 "github.com/jlmucb/cloudproxy/go/tao" 39 ) 40 41 var password = make([]byte, 32) 42 var network = "tcp" 43 var localAddr = "127.0.0.1:0" 44 var timeout, _ = time.ParseDuration("1s") 45 var configDirName = "mixnet_test_domain" 46 47 var id = pkix.Name{ 48 Organization: []string{"Mixnet tester"}, 49 } 50 51 // genHostname() generates a random hostname. 52 func genHostname() string { 53 rb := make([]byte, 16) 54 rand.Read(rb) 55 return base64.URLEncoding.EncodeToString(rb) 56 } 57 58 func makeTrivialDomain(configDir string) (*tao.Domain, error) { 59 var policyDomainConfig tao.DomainConfig 60 policyDomainConfig.SetDefaults() 61 policyDomainConfig.DomainInfo.GuardType = proto.String("AllowAll") 62 configPath := path.Join(configDir, "tao.config") 63 return tao.CreateDomain(policyDomainConfig, configPath, password) 64 } 65 66 func makeContext(batchSize int, hopCount int) (*RouterContext, *ProxyContext, *DirectoryContext, *tao.Domain, error) { 67 tempDir, err := ioutil.TempDir("", configDirName) 68 if err != nil { 69 return nil, nil, nil, nil, err 70 } 71 // Create a domain with a LiberalGuard. 72 d, err := makeTrivialDomain(tempDir) 73 if err != nil { 74 return nil, nil, nil, nil, err 75 } 76 77 directory, err := makeDirectorycontext(tempDir, localAddr, d) 78 if err != nil { 79 return nil, nil, nil, nil, err 80 } 81 82 router, err := makeRouterContext(tempDir, localAddr, 83 []string{directory.listener.Addr().String()}, batchSize, d) 84 if err != nil { 85 return nil, nil, nil, nil, err 86 } 87 88 // Create a proxy context. This just loads the domain. 89 proxy, err := makeProxyContext(localAddr, []string{directory.listener.Addr().String()}, hopCount, d) 90 if err != nil { 91 router.Close() 92 return nil, nil, nil, nil, err 93 } 94 95 return router, proxy, directory, d, nil 96 } 97 98 func makeRouterContext(dir, rAddr string, directories []string, 99 batchSize int, domain *tao.Domain) (*RouterContext, error) { 100 // Create a SoftTao from the domain. 101 st, err := tao.NewSoftTao(dir, password) 102 if err != nil { 103 return nil, err 104 } 105 106 // Create router context. This loads the domain and binds a 107 // socket and an anddress. 108 router, err := NewRouterContext(domain.ConfigPath, network, rAddr, 109 timeout, directories, batchSize, &id, st) 110 if err != nil { 111 return nil, err 112 } 113 // Because we are auto assigning ports, explicitly set the addr here 114 router.addr = router.listener.Addr().String() 115 return router, nil 116 } 117 118 func makeProxyContext(proxyAddr string, directories []string, hopCount int, domain *tao.Domain) (*ProxyContext, error) { 119 // Create a proxy context. This just loads the domain. 120 proxy, err := NewProxyContext(domain.ConfigPath, network, proxyAddr, directories, hopCount, timeout) 121 if err != nil { 122 return nil, err 123 } 124 125 return proxy, nil 126 } 127 128 func makeDirectorycontext(dir, addr string, domain *tao.Domain) (*DirectoryContext, error) { 129 // Create a SoftTao from the domain. 130 st, err := tao.NewSoftTao(dir, password) 131 if err != nil { 132 return nil, err 133 } 134 135 directory, err := NewDirectoryContext(domain.ConfigPath, network, addr, timeout, &id, st) 136 if err != nil { 137 return nil, err 138 } 139 go runDirectory(directory) 140 time.Sleep(100 * time.Millisecond) 141 return directory, nil 142 } 143 144 type testResult struct { 145 err error 146 msg []byte 147 } 148 149 func runDirectory(directory *DirectoryContext) { 150 for { 151 _, err := directory.Accept() 152 if err != nil { 153 if strings.Contains(err.Error(), "closed network connection") { 154 break 155 } else { 156 log.Println("Directory err:", err) 157 } 158 } 159 } 160 } 161 162 // Router accepts a connection from a proxy and reads a cell. 163 func runRouterReadCell(router *RouterContext, ch chan<- testResult) { 164 c, err := router.Accept() 165 if err != nil { 166 ch <- testResult{err, []byte{}} 167 return 168 } 169 170 cell := make([]byte, CellBytes) 171 if _, err := c.Read(cell); err != nil { 172 ch <- testResult{err, cell} 173 } else { 174 ch <- testResult{nil, cell} 175 } 176 } 177 178 // Proxy dials a router and sends a cell. 179 func runProxyWriteCell(proxy *ProxyContext, addr string, msg []byte) error { 180 c, err := proxy.DialRouter(network, addr) 181 if err != nil { 182 return err 183 } 184 185 if _, err := c.Write(msg); err != nil { 186 return err 187 } 188 189 return nil 190 } 191 192 // Router accepts a connection from a proxy and handles a number of requests. 193 func runRouterHandleOneConn(router *RouterContext, ch chan<- testResult) { 194 _, err := router.Accept() 195 if err != nil { 196 ch <- testResult{err, []byte{}} 197 return 198 } 199 200 for { 201 if err = <-router.errs; err != nil { 202 ch <- testResult{err, nil} 203 } 204 } 205 } 206 207 // Router accepts a connection from a proxy with multiple circuits 208 func runRouterHandleOneConnMultCircuits(router *RouterContext, ch chan<- testResult) { 209 _, err := router.Accept() 210 if err != nil { 211 ch <- testResult{err, []byte{}} 212 return 213 } 214 215 for { 216 if err = <-router.errs; err != nil { 217 ch <- testResult{err, nil} 218 } 219 } 220 } 221 222 func runRouterHandleConns(router *RouterContext, connCt int, ch chan<- testResult) { 223 for i := 0; i < connCt; i++ { 224 _, err := router.Accept() 225 if err != nil { 226 ch <- testResult{err, []byte{}} 227 return 228 } 229 } 230 231 for { 232 if err := <-router.errs; err != nil { 233 ch <- testResult{err, nil} 234 } 235 } 236 } 237 238 // Proxy dials a router, creates a circuit, and sends a message over 239 // the circuit. 240 func runProxySendMessage(proxy *ProxyContext, rAddr, dAddr string, msg []byte, exitKey *[32]byte) ([]byte, error) { 241 circ, _, err := proxy.CreateCircuit([]string{rAddr}, dAddr) 242 if err != nil { 243 return nil, err 244 } 245 246 if err = circ.SendMessage(msg); err != nil { 247 return nil, err 248 } 249 250 // dummyServer receives one message and replies. Without this line, 251 // the router will report a broken pipe. 252 msg, err = circ.ReceiveMessage() 253 return msg, err 254 } 255 256 // A dummy TLS server echoes back client's message. 257 func runTLSServer(clientCt int, ch chan<- testResult, addr chan<- string) { 258 cert, err := tls.LoadX509KeyPair("cert.pem", "key.pem") 259 config := &tls.Config{ 260 RootCAs: x509.NewCertPool(), 261 Certificates: []tls.Certificate{cert}, 262 InsecureSkipVerify: true, 263 ClientAuth: tls.RequestClientCert, 264 } 265 l, err := tls.Listen(network, localAddr, config) 266 if err != nil { 267 ch <- testResult{err, []byte{}} 268 return 269 } 270 defer l.Close() 271 addr <- l.Addr().String() 272 273 for i := 0; i < clientCt; i++ { 274 c, err := l.Accept() 275 if err != nil { 276 ch <- testResult{err, []byte{}} 277 return 278 } 279 280 go func(c net.Conn, clientNo int) { 281 defer c.Close() 282 buf := make([]byte, MaxMsgBytes+1) 283 for { 284 bytes, err := c.Read(buf) 285 if err != nil { 286 ch <- testResult{err, nil} 287 } else { 288 _, err := c.Write(buf[:bytes]) 289 if err != nil { 290 ch <- testResult{err, nil} 291 } else { 292 bufCopy := make([]byte, bytes) 293 copy(bufCopy, buf[:bytes]) 294 ch <- testResult{nil, bufCopy} 295 } 296 } 297 } 298 }(c, i) 299 } 300 } 301 302 // Test connection set up. 303 func TestProxyRouterConnect(t *testing.T) { 304 password = []byte{1,2,3,4} 305 router, proxy, _, domain, err := makeContext(1, 1) 306 if err != nil { 307 t.Fatal(err) 308 } 309 defer router.Close() 310 defer proxy.Close() 311 defer os.RemoveAll(path.Base(domain.ConfigPath)) 312 routerAddr := router.listener.Addr().String() 313 314 // Wait for a connection from the proxy. 315 ch := make(chan bool) 316 go func(ch chan<- bool) { 317 router.Accept() 318 ch <- true 319 }(ch) 320 321 _, err = proxy.DialRouter(network, routerAddr) 322 if err != nil { 323 t.Error(err) 324 } 325 326 <-ch 327 } 328 329 // Test CREATE and DESTROY. 330 func TestCreateDestroy(t *testing.T) { 331 router, proxy, directory, domain, err := makeContext(1, 1) 332 if err != nil { 333 t.Fatal(err) 334 } 335 defer directory.Close() 336 defer router.Close() 337 defer proxy.Close() 338 defer os.RemoveAll(path.Base(domain.ConfigPath)) 339 rAddr := router.listener.Addr().String() 340 341 // The address doesn't matter here because no packets will be sent on 342 // the established circuit. 343 fakeAddr := "127.0.0.1:0" 344 ch := make(chan testResult) 345 go runRouterHandleOneConn(router, ch) 346 347 _, id, err := proxy.CreateCircuit([]string{rAddr}, fakeAddr) 348 if err != nil { 349 t.Error("Error creating circuit:", err) 350 } 351 352 if len(router.circuits) != 1 { 353 t.Error("Failed to establish circuit. Num circuits:", len(router.circuits)) 354 } 355 356 if err = proxy.DestroyCircuit(id); err != nil { 357 t.Error("Error destroying circuit:", err) 358 } 359 360 select { 361 case res := <-ch: 362 if res.err != nil { 363 t.Error("Unexpected router error:", res.err) 364 } 365 default: 366 } 367 368 if len(router.circuits) != 0 { 369 t.Error("Expecting 0 circuits, but have", len(router.circuits)) 370 } 371 } 372 373 func TestCreateDestroyMultiHop(t *testing.T) { 374 router1, proxy, directory, domain, err := makeContext(1, 3) 375 if err != nil { 376 t.Fatal(err) 377 } 378 defer directory.Close() 379 dirAddr := directory.listener.Addr().String() 380 tempDir, err := ioutil.TempDir("", configDirName) 381 if err != nil { 382 t.Fatal(err) 383 } 384 router2, err := makeRouterContext(tempDir, localAddr, []string{dirAddr}, 1, domain) 385 if err != nil { 386 t.Fatal(err) 387 } 388 router3, err := makeRouterContext(tempDir, localAddr, []string{dirAddr}, 1, domain) 389 if err != nil { 390 t.Fatal(err) 391 } 392 defer router1.Close() 393 defer router2.Close() 394 defer router3.Close() 395 defer proxy.Close() 396 defer os.RemoveAll(path.Base(domain.ConfigPath)) 397 rAddr1 := router1.listener.Addr().String() 398 rAddr2 := router2.listener.Addr().String() 399 rAddr3 := router3.listener.Addr().String() 400 401 // The address doesn't matter here because no packets will be sent on 402 // the established circuit. 403 fakeAddr := "127.0.0.1:0" 404 ch1 := make(chan testResult) 405 ch2 := make(chan testResult) 406 ch3 := make(chan testResult) 407 go runRouterHandleOneConn(router1, ch1) 408 go runRouterHandleOneConn(router2, ch2) 409 go runRouterHandleOneConn(router3, ch3) 410 411 _, id, err := proxy.CreateCircuit([]string{rAddr1, rAddr2, rAddr3}, fakeAddr) 412 if err != nil { 413 t.Error(err) 414 } 415 416 if len(router1.circuits) != 2 || len(router2.circuits) != 2 || len(router3.circuits) != 1 { 417 t.Error("Expecting (2,2,1) circuits, but have", 418 len(router1.circuits), len(router2.circuits), len(router3.circuits)) 419 } 420 421 if err = proxy.DestroyCircuit(id); err != nil { 422 t.Error("Could not destroy circuit:", err) 423 } 424 425 for _, ch := range []chan testResult{ch1, ch2, ch3} { 426 select { 427 case res := <-ch: 428 if res.err != nil { 429 t.Error("Unexpected router error:", res.err) 430 } 431 default: 432 } 433 } 434 435 if len(router1.circuits) != 0 || len(router2.circuits) != 0 || len(router3.circuits) != 0 { 436 t.Error("Expecting 0 connections, but have", 437 len(router1.circuits), len(router2.circuits), len(router3.circuits)) 438 } 439 } 440 441 // Test multiplexing for proxy 442 func TestMultiplexProxyCircuit(t *testing.T) { 443 router, proxy, _, domain, err := makeContext(1, 1) 444 if err != nil { 445 t.Fatal(err) 446 } 447 defer router.Close() 448 defer proxy.Close() 449 defer os.RemoveAll(path.Base(domain.ConfigPath)) 450 rAddr := router.listener.Addr().String() 451 452 // The address doesn't matter here because no packets will be sent on 453 // the established circuit. 454 ch := make(chan testResult) 455 clientCt := 2 456 numReqs := make([]int, clientCt) 457 fakeAddrs := make([]string, clientCt) 458 ids := make([]uint64, clientCt) 459 for i := range numReqs { 460 numReqs[i] = 2 461 fakeAddrs[i] = fmt.Sprintf("127.0.0.1:%d", -i) 462 } 463 go runRouterHandleOneConnMultCircuits(router, ch) 464 465 wg := new(sync.WaitGroup) 466 for i := range numReqs { 467 wg.Add(1) 468 go func(i int) { 469 defer wg.Done() 470 var e error 471 _, ids[i], e = proxy.CreateCircuit([]string{rAddr}, fakeAddrs[i]) 472 if e != nil { 473 t.Error("Couldn't create circuit:", err) 474 } 475 }(i) 476 } 477 wg.Wait() 478 479 unique := make(map[*Conn]bool) 480 for _, conn := range proxy.circuits { 481 unique[conn] = true 482 } 483 if len(unique) != 1 { 484 t.Error(errors.New("Should only have one connection")) 485 } 486 487 for i := range numReqs { 488 wg.Add(1) 489 go func(i int) { 490 defer wg.Done() 491 err := proxy.DestroyCircuit(ids[i]) 492 if err != nil { 493 t.Error("Couldn't destroy circuit:", err) 494 } 495 }(i) 496 } 497 wg.Wait() 498 select { 499 case res := <-ch: 500 if res.err != nil { 501 t.Error("Unexpected router error:", res.err) 502 } 503 default: 504 } 505 } 506 507 // Test sending a cell. 508 func TestProxyRouterCell(t *testing.T) { 509 router, proxy, _, domain, err := makeContext(1, 1) 510 if err != nil { 511 t.Fatal(err) 512 } 513 defer router.Close() 514 defer proxy.Close() 515 defer os.RemoveAll(path.Base(domain.ConfigPath)) 516 ch := make(chan testResult) 517 518 cell := make([]byte, CellBytes+1) 519 for i := 0; i < len(cell); i++ { 520 cell[i] = byte(i) 521 } 522 523 // This cell is just right. 524 go runRouterReadCell(router, ch) 525 if err = runProxyWriteCell(proxy, router.listener.Addr().String(), cell[:CellBytes]); err != nil { 526 t.Error(err) 527 } 528 res := <-ch 529 if res.err != nil && res.err != io.EOF { 530 t.Error(res.err) 531 } else if bytes.Compare(res.msg, cell[:CellBytes]) != 0 { 532 t.Errorf("Server got: %s", res.msg) 533 } 534 535 // This cell is too big. 536 go runRouterReadCell(router, ch) 537 if err = runProxyWriteCell(proxy, router.listener.Addr().String(), cell); err != errCellLength { 538 t.Error("runProxyWriteCell(): should have returned errCellLength") 539 } 540 res = <-ch 541 if err := res.err.(net.Error); !err.Timeout() { 542 t.Error("runRouterReadCell(): should have timed out") 543 } 544 } 545 546 // Test setting up a circuit and relay a message to destination. Try 547 // messages of various lengths. 548 func TestProxyRouterRelay(t *testing.T) { 549 router, proxy, _, domain, err := makeContext(1, 1) 550 if err != nil { 551 t.Fatal(err) 552 } 553 defer router.Close() 554 defer proxy.Close() 555 defer os.RemoveAll(path.Base(domain.ConfigPath)) 556 routerCh := make(chan testResult) 557 dstCh := make(chan testResult) 558 dstAddrCh := make(chan string) 559 560 // Create a long message. 561 msg := make([]byte, (CellBytes*5)+237) 562 for i := 0; i < len(msg); i++ { 563 msg[i] = byte(i) 564 } 565 var res testResult 566 567 trials := []int{ 568 37, // A short message 569 //CellBytes - (BODY + LEN_SIZE), // A cell 570 //len(msg), // A long message 571 } 572 573 go runDummyServer(len(trials), 1, dstCh, dstAddrCh) 574 dstAddr := <-dstAddrCh 575 rAddr := router.listener.Addr().String() 576 577 // First two messages fits in one cell, the last one is over multiple cells 578 go runRouterHandleOneConnMultCircuits(router, routerCh) 579 580 for _, l := range trials { 581 reply, err := runProxySendMessage(proxy, rAddr, dstAddr, msg[:l], router.publicKey) 582 if err != nil { 583 t.Errorf("relay (length=%d): %s", l, err) 584 } 585 586 res = <-dstCh 587 if res.err != nil { 588 t.Error(res.err) 589 } else if bytes.Compare(reply, msg[:l]) != 0 { 590 t.Errorf("relay (length=%d): received: %v", l, reply) 591 t.Errorf("relay (length=%d): sent: %x", l, msg[:l]) 592 } 593 } 594 595 select { 596 case res := <-routerCh: 597 if res.err != nil { 598 t.Error("Router error:", res.err) 599 } 600 default: 601 } 602 } 603 604 // TODO(kwonalbert): removed malicious tests because they didn't mean much anymore 605 // with the new exit nodes.. 606 607 // Test timeout on CreateMessage(). 608 func TestCreateTimeout(t *testing.T) { 609 router, proxy, _, domain, err := makeContext(2, 1) 610 if err != nil { 611 t.Fatal(err) 612 } 613 defer router.Close() 614 defer proxy.Close() 615 defer os.RemoveAll(path.Base(domain.ConfigPath)) 616 routerAddr := router.listener.Addr().String() 617 ch := make(chan testResult) 618 619 // The proxy should get a timeout if it's the only connecting client. 620 go runRouterHandleConns(router, 1, ch) 621 hostAddr := genHostname() + ":80" 622 _, _, err = proxy.CreateCircuit([]string{routerAddr}, hostAddr) 623 if err == nil { 624 t.Errorf("proxy.CreateCircuit(%s, %s) incorrectly succeeded when it should have timed out", routerAddr, hostAddr) 625 } 626 627 select { 628 case res := <-ch: 629 e, _ := res.err.(net.Error) 630 if res.err != nil && !e.Timeout() { 631 t.Error(res.err) 632 } 633 default: 634 } 635 } 636 637 // Test timeout on ReceiveMessage(). 638 func TestSendMessageTimeout(t *testing.T) { 639 router, proxy, directory, domain, err := makeContext(2, 1) 640 if err != nil { 641 t.Fatal(err) 642 } 643 defer directory.Close() 644 proxy2, err := makeProxyContext(localAddr, []string{directory.listener.Addr().String()}, 1, domain) 645 if err != nil { 646 t.Fatal(err) 647 } 648 defer router.Close() 649 defer proxy.Close() 650 defer proxy2.Close() 651 defer os.RemoveAll(path.Base(domain.ConfigPath)) 652 routerAddr := router.listener.Addr().String() 653 ch := make(chan testResult) 654 done := make(chan bool) 655 656 go runRouterHandleConns(router, 2, ch) 657 658 // Proxy 1 creates a circuit, sends a message and awaits a reply. 659 go func() { 660 circ, _, err := proxy.CreateCircuit([]string{routerAddr}, genHostname()+":80") 661 if err != nil { 662 t.Error(err) 663 } 664 if err = circ.SendMessage([]byte("hello")); err != nil { 665 t.Error(err) 666 } 667 _, err = circ.ReceiveMessage() 668 if e, ok := err.(net.Error); !(ok && e.Timeout()) { 669 t.Error("receiveMessage should have timed out") 670 } 671 done <- true 672 }() 673 674 // Proxy 2 just creates a circuit. 675 go func() { 676 _, _, err = proxy2.CreateCircuit([]string{routerAddr}, genHostname()+":80") 677 if err != nil { 678 t.Error(err) 679 } 680 done <- true 681 }() 682 <-done 683 <-done 684 } 685 686 // Test mixnet end-to-end with many clients. Proxy a protocol through mixnet. 687 // The client sends the server a message and the server echoes it back. 688 func TestMixnetSingleHop(t *testing.T) { 689 clientCt := 10 690 router, proxy, directory, domain, err := makeContext(clientCt, 1) 691 if err != nil { 692 t.Fatal(err) 693 } 694 defer directory.Close() 695 proxy.Close() 696 defer router.Close() 697 defer os.RemoveAll(path.Base(domain.ConfigPath)) 698 routerAddr := router.listener.Addr().String() 699 700 var res testResult 701 clientCh := make(chan testResult, clientCt) 702 proxyCh := make(chan testResult, clientCt) 703 routerCh := make(chan testResult) 704 dstCh := make(chan testResult, clientCt) 705 dstAddrCh := make(chan string) 706 707 go runRouterHandleConns(router, clientCt, routerCh) 708 go runDummyServer(clientCt, 1, dstCh, dstAddrCh) 709 dstAddr := <-dstAddrCh 710 711 for i := 0; i < clientCt; i++ { 712 go func(pid int, ch chan<- testResult) { 713 pa := "127.0.0.1:0" 714 proxy, err := makeProxyContext(pa, []string{directory.listener.Addr().String()}, 1, domain) 715 if err != nil { 716 ch <- testResult{err, nil} 717 return 718 } 719 defer proxy.Close() 720 proxyAddr := proxy.listener.Addr().String() 721 go runSocksServerOne(proxy, []string{routerAddr}, proxyCh, router.publicKey) 722 723 msg := []byte(fmt.Sprintf("Hello, my name is %d", pid)) 724 ch <- runSocksClient(proxyAddr, dstAddr, msg) 725 }(i, clientCh) 726 } 727 728 // Wait for clients to finish. 729 for i := 0; i < clientCt; i++ { 730 res = <-clientCh 731 if res.err != nil { 732 t.Error(res.err) 733 } else { 734 t.Log("client got:", string(res.msg)) 735 } 736 } 737 738 // Wait for proxies to finish. 739 for i := 0; i < clientCt; i++ { 740 res = <-proxyCh 741 if res.err != nil { 742 t.Error(res.err) 743 } 744 } 745 746 // Wait for server to finish. 747 for i := 0; i < clientCt; i++ { 748 res = <-dstCh 749 if res.err != nil { 750 t.Error(res.err) 751 } 752 } 753 754 // Wait for router to finish. 755 select { 756 case res := <-routerCh: 757 if res.err != nil { 758 t.Error("Unexpected router error:", res.err) 759 } 760 default: 761 } 762 } 763 764 // Test routing TLS connection with mixnet 765 func TestMixnetSingleHopTLS(t *testing.T) { 766 clientCt := 4 767 router, proxy, directory, domain, err := makeContext(clientCt, 1) 768 if err != nil { 769 t.Fatal(err) 770 } 771 defer directory.Close() 772 proxy.Close() 773 defer router.Close() 774 defer os.RemoveAll(path.Base(domain.ConfigPath)) 775 routerAddr := router.listener.Addr().String() 776 777 var res testResult 778 clientCh := make(chan testResult, clientCt) 779 proxyCh := make(chan testResult, clientCt) 780 routerCh := make(chan testResult) 781 dstCh := make(chan testResult, clientCt) 782 dstAddrCh := make(chan string) 783 784 go runRouterHandleConns(router, clientCt, routerCh) 785 go runTLSServer(clientCt, dstCh, dstAddrCh) 786 dstAddr := <-dstAddrCh 787 788 for i := 0; i < clientCt; i++ { 789 go func(pid int, ch chan<- testResult) { 790 pa := "127.0.0.1:0" 791 proxy, err := makeProxyContext(pa, []string{directory.listener.Addr().String()}, 1, domain) 792 if err != nil { 793 ch <- testResult{err, nil} 794 return 795 } 796 defer proxy.Close() 797 proxyAddr := proxy.listener.Addr().String() 798 go runSocksServer(proxy, []string{routerAddr}, proxyCh, router.publicKey) 799 800 msg := []byte(fmt.Sprintf("Hello, my name is %d", pid)) 801 ch <- runTLSClient(proxyAddr, dstAddr, msg) 802 }(i, clientCh) 803 } 804 805 // Wait for clients to finish. 806 for i := 0; i < clientCt; i++ { 807 res = <-clientCh 808 if res.err != nil { 809 // FIX 810 fmt.Printf("Error line 810: %s\n", res.err.Error()) 811 // t.Error(res.err) 812 } else { 813 t.Log("client got:", string(res.msg)) 814 } 815 } 816 817 // Wait for proxies to finish. 818 for i := 0; i < clientCt; i++ { 819 res = <-proxyCh 820 if res.err != nil { 821 // FIX 822 fmt.Printf("Error line 820: %s\n", res.err.Error()) 823 // t.Error(res.err) 824 } 825 } 826 827 // Wait for server to finish. 828 for i := 0; i < clientCt; i++ { 829 res = <-dstCh 830 if res.err != nil { 831 // FIX 832 fmt.Printf("Error line 829: %s\n", res.err.Error()) 833 // t.Error(res.err) 834 } 835 } 836 837 // Wait for router to finish. 838 select { 839 case res := <-routerCh: 840 if res.err != nil { 841 // FIX 842 fmt.Printf("Error line 836: %s\n", res.err.Error()) 843 // t.Error("Unexpected router error:", res.err) 844 } 845 default: 846 } 847 } 848 849 // Test mixnet end-to-end with many clients and two routers. 850 func TestMixnetMultiHop(t *testing.T) { 851 clientCt := 10 852 router, proxy, directory, domain, err := makeContext(clientCt, 3) 853 if err != nil { 854 t.Fatal(err) 855 } 856 defer directory.Close() 857 dirAddr := directory.listener.Addr().String() 858 859 tempDir, err := ioutil.TempDir("", configDirName) 860 if err != nil { 861 t.Fatal(err) 862 } 863 router2, err := makeRouterContext(tempDir, localAddr, []string{dirAddr}, 1, domain) 864 if err != nil { 865 t.Fatal(err) 866 } 867 router3, err := makeRouterContext(tempDir, localAddr, []string{dirAddr}, 1, domain) 868 if err != nil { 869 t.Fatal(err) 870 } 871 proxy.Close() 872 defer router.Close() 873 defer router2.Close() 874 defer router3.Close() 875 defer os.RemoveAll(path.Base(domain.ConfigPath)) 876 routerAddr := router.listener.Addr().String() 877 routerAddr2 := router2.listener.Addr().String() 878 routerAddr3 := router3.listener.Addr().String() 879 880 var res testResult 881 clientCh := make(chan testResult, clientCt) 882 proxyCh := make(chan testResult, clientCt) 883 routerCh := make(chan testResult) 884 routerCh2 := make(chan testResult) 885 routerCh3 := make(chan testResult) 886 dstCh := make(chan testResult, clientCt) 887 dstAddrCh := make(chan string) 888 889 go runRouterHandleConns(router, clientCt, routerCh) 890 go runRouterHandleOneConn(router2, routerCh2) 891 go runRouterHandleOneConn(router3, routerCh3) 892 go runDummyServer(clientCt, 1, dstCh, dstAddrCh) 893 dstAddr := <-dstAddrCh 894 895 for i := 0; i < clientCt; i++ { 896 go func(pid int, ch chan<- testResult) { 897 pa := "127.0.0.1:0" 898 proxy, err := makeProxyContext(pa, []string{directory.listener.Addr().String()}, 3, domain) 899 if err != nil { 900 ch <- testResult{err, nil} 901 return 902 } 903 defer proxy.Close() 904 proxyAddr := proxy.listener.Addr().String() 905 go runSocksServerOne(proxy, []string{routerAddr, routerAddr2, routerAddr3}, proxyCh, router3.publicKey) 906 907 msg := []byte(fmt.Sprintf("Hello, my name is %d", pid)) 908 ch <- runSocksClient(proxyAddr, dstAddr, msg) 909 }(i, clientCh) 910 } 911 912 // Wait for clients to finish. 913 for i := 0; i < clientCt; i++ { 914 res = <-clientCh 915 if res.err != nil { 916 t.Error(res.err) 917 } else { 918 t.Log("client got:", string(res.msg)) 919 } 920 } 921 922 // Wait for proxies to finish. 923 for i := 0; i < clientCt; i++ { 924 res = <-proxyCh 925 if res.err != nil { 926 t.Error(res.err) 927 } 928 } 929 930 // Wait for server to finish. 931 for i := 0; i < clientCt; i++ { 932 res = <-dstCh 933 if res.err != nil { 934 t.Error(res.err) 935 } 936 } 937 938 // Check if routers had any errors 939 for _, ch := range []chan testResult{routerCh, routerCh2} { 940 select { 941 case res := <-ch: 942 if res.err != nil { 943 t.Error("Unexpected router error:", res.err) 944 } 945 default: 946 } 947 } 948 } 949 950 // Test mixnets with multiple paths, mixing with each other 951 // Current test only supports even and same number of clients per router 952 func TestMixnetMultiPath(t *testing.T) { 953 clientCt := 20 954 numPaths := 2 955 perPath := clientCt / numPaths 956 pathLen := 3 957 routerCt := pathLen * numPaths 958 routers := make([]*RouterContext, routerCt) 959 routerAddrs := make([]string, routerCt) 960 router, proxy, directory, domain, err := makeContext(perPath, 3) 961 if err != nil { 962 t.Fatal(err) 963 } 964 defer directory.Close() 965 dirAddr := directory.listener.Addr().String() 966 967 routerChs := make([]chan testResult, routerCt) 968 tempDir, err := ioutil.TempDir("", configDirName) 969 if err != nil { 970 t.Fatal(err) 971 } 972 for i := range routers { 973 if i == 0 { 974 routers[i] = router 975 } else { 976 routers[i], err = makeRouterContext(tempDir, localAddr, []string{dirAddr}, perPath, domain) 977 if err != nil { 978 t.Fatal(err) 979 } 980 } 981 defer routers[i].Close() 982 routerChs[i] = make(chan testResult) 983 if i%3 == 0 { // entry 984 routerAddrs[i] = routers[i].listener.Addr().String() 985 go runRouterHandleConns(routers[i], perPath, routerChs[i]) 986 } else { 987 routerAddrs[i] = routers[i].listener.Addr().String() 988 go runRouterHandleConns(routers[i], numPaths, routerChs[i]) 989 } 990 } 991 proxy.Close() 992 defer os.RemoveAll(path.Base(domain.ConfigPath)) 993 994 var res testResult 995 clientCh := make(chan testResult, clientCt) 996 proxyCh := make(chan testResult, clientCt) 997 dstCh := make(chan testResult, clientCt) 998 dstAddrCh := make(chan string) 999 1000 go runDummyServer(clientCt, 1, dstCh, dstAddrCh) 1001 dstAddr := <-dstAddrCh 1002 for i := 0; i < clientCt; i++ { 1003 go func(pid int, ch chan<- testResult) { 1004 pa := "127.0.0.1:0" 1005 proxy, err := makeProxyContext(pa, []string{directory.listener.Addr().String()}, 3, domain) 1006 if err != nil { 1007 ch <- testResult{err, nil} 1008 return 1009 } 1010 defer proxy.Close() 1011 proxyAddr := proxy.listener.Addr().String() 1012 circuit := make([]string, pathLen) 1013 var exitKey *[32]byte 1014 if pid%2 == 0 { 1015 copy(circuit, routerAddrs[:3]) 1016 if pid%4 == 2 { 1017 circuit[1] = routerAddrs[4] 1018 } 1019 exitKey = routers[2].publicKey 1020 } else { 1021 copy(circuit, routerAddrs[3:]) 1022 if pid%4 == 3 { 1023 circuit[1] = routerAddrs[1] 1024 } 1025 exitKey = routers[5].publicKey 1026 } 1027 go runSocksServerOne(proxy, circuit, proxyCh, exitKey) 1028 1029 msg := []byte(fmt.Sprintf("Hello, my name is %d", pid)) 1030 ch <- runSocksClient(proxyAddr, dstAddr, msg) 1031 }(i, clientCh) 1032 } 1033 1034 // Wait for clients to finish. 1035 for i := 0; i < clientCt; i++ { 1036 res = <-clientCh 1037 if res.err != nil { 1038 t.Error(res.err) 1039 } else { 1040 t.Log("client got:", string(res.msg)) 1041 } 1042 } 1043 1044 // Wait for proxies to finish. 1045 for i := 0; i < clientCt; i++ { 1046 res = <-proxyCh 1047 if res.err != nil { 1048 t.Error(res.err) 1049 } 1050 } 1051 1052 // Wait for server to finish. 1053 for i := 0; i < clientCt; i++ { 1054 res = <-dstCh 1055 if res.err != nil { 1056 t.Error(res.err) 1057 } 1058 } 1059 1060 // Wait for router to finish. 1061 for i := range routers { 1062 select { 1063 case res = <-routerChs[i]: 1064 if res.err != nil { 1065 t.Fatal(i, "Unexpected router error:", res.err) 1066 } 1067 default: 1068 } 1069 } 1070 }