main.go 3.6 KB

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