client_test.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. // Copyright (C) 2014 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at http://mozilla.org/MPL/2.0/.
  6. package discover
  7. import (
  8. "fmt"
  9. "net"
  10. "time"
  11. "testing"
  12. "github.com/syncthing/protocol"
  13. "github.com/syncthing/syncthing/lib/sync"
  14. )
  15. var device protocol.DeviceID
  16. func init() {
  17. device, _ = protocol.DeviceIDFromString("P56IOI7-MZJNU2Y-IQGDREY-DM2MGTI-MGL3BXN-PQ6W5BM-TBBZ4TJ-XZWICQ2")
  18. }
  19. type FakeAnnouncer struct {
  20. pkt Announce
  21. }
  22. func (f *FakeAnnouncer) Announcement() Announce {
  23. return f.pkt
  24. }
  25. func TestUDP4Success(t *testing.T) {
  26. conn, err := net.ListenUDP("udp4", nil)
  27. if err != nil {
  28. t.Fatal(err)
  29. }
  30. port := conn.LocalAddr().(*net.UDPAddr).Port
  31. address := fmt.Sprintf("udp4://127.0.0.1:%d", port)
  32. pkt := Announce{
  33. Magic: AnnouncementMagic,
  34. This: Device{
  35. device[:],
  36. []string{"tcp://123.123.123.123:1234"},
  37. nil,
  38. },
  39. }
  40. ann := &FakeAnnouncer{
  41. pkt: pkt,
  42. }
  43. client, err := New(address, ann)
  44. if err != nil {
  45. t.Fatal(err)
  46. }
  47. udpclient := client.(*UDPClient)
  48. if udpclient.errorRetryInterval != DefaultErrorRetryInternval {
  49. t.Fatal("Incorrect retry interval")
  50. }
  51. if udpclient.listenAddress.IP != nil || udpclient.listenAddress.Port != 0 {
  52. t.Fatal("Wrong listen IP or port", udpclient.listenAddress)
  53. }
  54. if client.Address() != address {
  55. t.Fatal("Incorrect address")
  56. }
  57. buf := make([]byte, 2048)
  58. // First announcement
  59. conn.SetDeadline(time.Now().Add(time.Millisecond * 100))
  60. _, err = conn.Read(buf)
  61. if err != nil {
  62. t.Fatal(err)
  63. }
  64. // Announcement verification
  65. conn.SetDeadline(time.Now().Add(time.Millisecond * 1100))
  66. _, addr, err := conn.ReadFromUDP(buf)
  67. if err != nil {
  68. t.Fatal(err)
  69. }
  70. // Reply to it.
  71. _, err = conn.WriteToUDP(pkt.MustMarshalXDR(), addr)
  72. if err != nil {
  73. t.Fatal(err)
  74. }
  75. // We should get nothing else
  76. conn.SetDeadline(time.Now().Add(time.Millisecond * 100))
  77. _, err = conn.Read(buf)
  78. if err == nil {
  79. t.Fatal("Expected error")
  80. }
  81. // Status should be ok
  82. if !client.StatusOK() {
  83. t.Fatal("Wrong status")
  84. }
  85. // Do a lookup in a separate routine
  86. addrs := []string{}
  87. wg := sync.NewWaitGroup()
  88. wg.Add(1)
  89. go func() {
  90. pkt, err := client.Lookup(device)
  91. if err == nil {
  92. for _, addr := range pkt.This.Addresses {
  93. addrs = append(addrs, addr)
  94. }
  95. }
  96. wg.Done()
  97. }()
  98. // Receive the lookup and reply
  99. conn.SetDeadline(time.Now().Add(time.Millisecond * 100))
  100. _, addr, err = conn.ReadFromUDP(buf)
  101. if err != nil {
  102. t.Fatal(err)
  103. }
  104. conn.WriteToUDP(pkt.MustMarshalXDR(), addr)
  105. // Wait for the lookup to arrive, verify that the number of answers is correct
  106. wg.Wait()
  107. if len(addrs) != 1 || addrs[0] != "tcp://123.123.123.123:1234" {
  108. t.Fatal("Wrong number of answers")
  109. }
  110. client.Stop()
  111. }
  112. func TestUDP4Failure(t *testing.T) {
  113. conn, err := net.ListenUDP("udp4", nil)
  114. if err != nil {
  115. t.Fatal(err)
  116. }
  117. port := conn.LocalAddr().(*net.UDPAddr).Port
  118. address := fmt.Sprintf("udp4://127.0.0.1:%d/?listenaddress=127.0.0.1&retry=5", port)
  119. pkt := Announce{
  120. Magic: AnnouncementMagic,
  121. This: Device{
  122. device[:],
  123. []string{"tcp://123.123.123.123:1234"},
  124. nil,
  125. },
  126. }
  127. ann := &FakeAnnouncer{
  128. pkt: pkt,
  129. }
  130. client, err := New(address, ann)
  131. if err != nil {
  132. t.Fatal(err)
  133. }
  134. udpclient := client.(*UDPClient)
  135. if udpclient.errorRetryInterval != time.Second*5 {
  136. t.Fatal("Incorrect retry interval")
  137. }
  138. if !udpclient.listenAddress.IP.Equal(net.IPv4(127, 0, 0, 1)) || udpclient.listenAddress.Port != 0 {
  139. t.Fatal("Wrong listen IP or port", udpclient.listenAddress)
  140. }
  141. if client.Address() != address {
  142. t.Fatal("Incorrect address")
  143. }
  144. buf := make([]byte, 2048)
  145. // First announcement
  146. conn.SetDeadline(time.Now().Add(time.Millisecond * 100))
  147. _, err = conn.Read(buf)
  148. if err != nil {
  149. t.Fatal(err)
  150. }
  151. // Announcement verification
  152. conn.SetDeadline(time.Now().Add(time.Millisecond * 1100))
  153. _, _, err = conn.ReadFromUDP(buf)
  154. if err != nil {
  155. t.Fatal(err)
  156. }
  157. // Don't reply
  158. // We should get nothing else
  159. conn.SetDeadline(time.Now().Add(time.Millisecond * 100))
  160. _, err = conn.Read(buf)
  161. if err == nil {
  162. t.Fatal("Expected error")
  163. }
  164. // Status should be failure
  165. if client.StatusOK() {
  166. t.Fatal("Wrong status")
  167. }
  168. // Do a lookup in a separate routine
  169. addrs := []string{}
  170. wg := sync.NewWaitGroup()
  171. wg.Add(1)
  172. go func() {
  173. pkt, err := client.Lookup(device)
  174. if err == nil {
  175. for _, addr := range pkt.This.Addresses {
  176. addrs = append(addrs, addr)
  177. }
  178. }
  179. wg.Done()
  180. }()
  181. // Receive the lookup and don't reply
  182. conn.SetDeadline(time.Now().Add(time.Millisecond * 100))
  183. _, _, err = conn.ReadFromUDP(buf)
  184. if err != nil {
  185. t.Fatal(err)
  186. }
  187. // Wait for the lookup to timeout, verify that the number of answers is none
  188. wg.Wait()
  189. if len(addrs) != 0 {
  190. t.Fatal("Wrong number of answers")
  191. }
  192. client.Stop()
  193. }