main.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. // Copyright (C) 2015 Audrius Butkevicius and Contributors (see the CONTRIBUTORS file).
  2. package main
  3. import (
  4. "bufio"
  5. "context"
  6. "crypto/tls"
  7. "flag"
  8. "log"
  9. "net"
  10. "net/url"
  11. "os"
  12. "path/filepath"
  13. "time"
  14. syncthingprotocol "github.com/syncthing/syncthing/lib/protocol"
  15. "github.com/syncthing/syncthing/lib/relay/client"
  16. "github.com/syncthing/syncthing/lib/relay/protocol"
  17. )
  18. func main() {
  19. ctx := context.Background()
  20. log.SetOutput(os.Stdout)
  21. log.SetFlags(log.LstdFlags | log.Lshortfile)
  22. var connect, relay, dir string
  23. var join, test bool
  24. flag.StringVar(&connect, "connect", "", "Device ID to which to connect to")
  25. flag.BoolVar(&join, "join", false, "Join relay")
  26. flag.BoolVar(&test, "test", false, "Generic relay test")
  27. flag.StringVar(&relay, "relay", "relay://127.0.0.1:22067", "Relay address")
  28. flag.StringVar(&dir, "keys", ".", "Directory where cert.pem and key.pem is stored")
  29. flag.Parse()
  30. certFile, keyFile := filepath.Join(dir, "cert.pem"), filepath.Join(dir, "key.pem")
  31. cert, err := tls.LoadX509KeyPair(certFile, keyFile)
  32. if err != nil {
  33. log.Fatalln("Failed to load X509 key pair:", err)
  34. }
  35. id := syncthingprotocol.NewDeviceID(cert.Certificate[0])
  36. log.Println("ID:", id)
  37. uri, err := url.Parse(relay)
  38. if err != nil {
  39. log.Fatal(err)
  40. }
  41. stdin := make(chan string)
  42. go stdinReader(stdin)
  43. if join {
  44. log.Println("Creating client")
  45. relay, err := client.NewClient(uri, []tls.Certificate{cert}, nil, 10*time.Second)
  46. if err != nil {
  47. log.Fatal(err)
  48. }
  49. log.Println("Created client")
  50. go relay.Serve()
  51. recv := make(chan protocol.SessionInvitation)
  52. go func() {
  53. log.Println("Starting invitation receiver")
  54. for invite := range relay.Invitations() {
  55. select {
  56. case recv <- invite:
  57. log.Println("Received invitation", invite)
  58. default:
  59. log.Println("Discarding invitation", invite)
  60. }
  61. }
  62. }()
  63. for {
  64. conn, err := client.JoinSession(ctx, <-recv)
  65. if err != nil {
  66. log.Fatalln("Failed to join", err)
  67. }
  68. log.Println("Joined", conn.RemoteAddr(), conn.LocalAddr())
  69. connectToStdio(stdin, conn)
  70. log.Println("Finished", conn.RemoteAddr(), conn.LocalAddr())
  71. }
  72. } else if connect != "" {
  73. id, err := syncthingprotocol.DeviceIDFromString(connect)
  74. if err != nil {
  75. log.Fatal(err)
  76. }
  77. invite, err := client.GetInvitationFromRelay(ctx, uri, id, []tls.Certificate{cert}, 10*time.Second)
  78. if err != nil {
  79. log.Fatal(err)
  80. }
  81. log.Println("Received invitation", invite)
  82. conn, err := client.JoinSession(ctx, invite)
  83. if err != nil {
  84. log.Fatalln("Failed to join", err)
  85. }
  86. log.Println("Joined", conn.RemoteAddr(), conn.LocalAddr())
  87. connectToStdio(stdin, conn)
  88. log.Println("Finished", conn.RemoteAddr(), conn.LocalAddr())
  89. } else if test {
  90. if err := client.TestRelay(ctx, uri, []tls.Certificate{cert}, time.Second, 2*time.Second, 4); err == nil {
  91. log.Println("OK")
  92. } else {
  93. log.Println("FAIL:", err)
  94. }
  95. } else {
  96. log.Fatal("Requires either join or connect")
  97. }
  98. }
  99. func stdinReader(c chan<- string) {
  100. scanner := bufio.NewScanner(os.Stdin)
  101. for scanner.Scan() {
  102. c <- scanner.Text()
  103. c <- "\n"
  104. }
  105. }
  106. func connectToStdio(stdin <-chan string, conn net.Conn) {
  107. go func() {
  108. }()
  109. buf := make([]byte, 1024)
  110. for {
  111. conn.SetReadDeadline(time.Now().Add(time.Millisecond))
  112. n, err := conn.Read(buf[0:])
  113. if err != nil {
  114. nerr, ok := err.(net.Error)
  115. if !ok || !nerr.Timeout() {
  116. log.Println(err)
  117. return
  118. }
  119. }
  120. os.Stdout.Write(buf[:n])
  121. select {
  122. case msg := <-stdin:
  123. _, err := conn.Write([]byte(msg))
  124. if err != nil {
  125. return
  126. }
  127. default:
  128. }
  129. }
  130. }