structs.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. // Copyright (C) 2016 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 https://mozilla.org/MPL/2.0/.
  6. package connections
  7. import (
  8. "context"
  9. "crypto/tls"
  10. "fmt"
  11. "io"
  12. "net"
  13. "net/url"
  14. "time"
  15. "github.com/syncthing/syncthing/lib/config"
  16. "github.com/syncthing/syncthing/lib/nat"
  17. "github.com/syncthing/syncthing/lib/protocol"
  18. "github.com/thejerf/suture/v4"
  19. )
  20. type tlsConn interface {
  21. io.ReadWriteCloser
  22. ConnectionState() tls.ConnectionState
  23. RemoteAddr() net.Addr
  24. SetDeadline(time.Time) error
  25. SetWriteDeadline(time.Time) error
  26. LocalAddr() net.Addr
  27. }
  28. // internalConn is the raw TLS connection plus some metadata on where it
  29. // came from (type, priority).
  30. type internalConn struct {
  31. tlsConn
  32. connType connType
  33. priority int
  34. }
  35. type connType int
  36. const (
  37. connTypeRelayClient connType = iota
  38. connTypeRelayServer
  39. connTypeTCPClient
  40. connTypeTCPServer
  41. connTypeQUICClient
  42. connTypeQUICServer
  43. )
  44. func (t connType) String() string {
  45. switch t {
  46. case connTypeRelayClient:
  47. return "relay-client"
  48. case connTypeRelayServer:
  49. return "relay-server"
  50. case connTypeTCPClient:
  51. return "tcp-client"
  52. case connTypeTCPServer:
  53. return "tcp-server"
  54. case connTypeQUICClient:
  55. return "quic-client"
  56. case connTypeQUICServer:
  57. return "quic-server"
  58. default:
  59. return "unknown-type"
  60. }
  61. }
  62. func (t connType) Transport() string {
  63. switch t {
  64. case connTypeRelayClient, connTypeRelayServer:
  65. return "relay"
  66. case connTypeTCPClient, connTypeTCPServer:
  67. return "tcp"
  68. case connTypeQUICClient, connTypeQUICServer:
  69. return "quic"
  70. default:
  71. return "unknown"
  72. }
  73. }
  74. func (c internalConn) Close() error {
  75. // *tls.Conn.Close() does more than it says on the tin. Specifically, it
  76. // sends a TLS alert message, which might block forever if the
  77. // connection is dead and we don't have a deadline set.
  78. _ = c.SetWriteDeadline(time.Now().Add(250 * time.Millisecond))
  79. return c.tlsConn.Close()
  80. }
  81. func (c internalConn) Type() string {
  82. return c.connType.String()
  83. }
  84. func (c internalConn) Priority() int {
  85. return c.priority
  86. }
  87. func (c internalConn) Crypto() string {
  88. cs := c.ConnectionState()
  89. return fmt.Sprintf("%s-%s", tlsVersionNames[cs.Version], tlsCipherSuiteNames[cs.CipherSuite])
  90. }
  91. func (c internalConn) Transport() string {
  92. transport := c.connType.Transport()
  93. host, _, err := net.SplitHostPort(c.LocalAddr().String())
  94. if err != nil {
  95. return transport
  96. }
  97. ip := net.ParseIP(host)
  98. if ip == nil {
  99. return transport
  100. }
  101. if ip.To4() != nil {
  102. return transport + "4"
  103. }
  104. return transport + "6"
  105. }
  106. func (c internalConn) String() string {
  107. return fmt.Sprintf("%s-%s/%s/%s", c.LocalAddr(), c.RemoteAddr(), c.Type(), c.Crypto())
  108. }
  109. type dialerFactory interface {
  110. New(config.OptionsConfiguration, *tls.Config) genericDialer
  111. Priority() int
  112. AlwaysWAN() bool
  113. Valid(config.Configuration) error
  114. String() string
  115. }
  116. type commonDialer struct {
  117. trafficClass int
  118. reconnectInterval time.Duration
  119. tlsCfg *tls.Config
  120. }
  121. func (d *commonDialer) RedialFrequency() time.Duration {
  122. return d.reconnectInterval
  123. }
  124. type genericDialer interface {
  125. Dial(context.Context, protocol.DeviceID, *url.URL) (internalConn, error)
  126. RedialFrequency() time.Duration
  127. }
  128. type listenerFactory interface {
  129. New(*url.URL, config.Wrapper, *tls.Config, chan internalConn, *nat.Service) genericListener
  130. Valid(config.Configuration) error
  131. }
  132. type ListenerAddresses struct {
  133. URI *url.URL
  134. WANAddresses []*url.URL
  135. LANAddresses []*url.URL
  136. }
  137. type genericListener interface {
  138. suture.Service
  139. URI() *url.URL
  140. // A given address can potentially be mutated by the listener.
  141. // For example we bind to tcp://0.0.0.0, but that for example might return
  142. // tcp://gateway1.ip and tcp://gateway2.ip as WAN addresses due to there
  143. // being multiple gateways, and us managing to get a UPnP mapping on both
  144. // and tcp://192.168.0.1 and tcp://10.0.0.1 due to there being multiple
  145. // network interfaces. (The later case for LAN addresses is made up just
  146. // to provide an example)
  147. WANAddresses() []*url.URL
  148. LANAddresses() []*url.URL
  149. Error() error
  150. OnAddressesChanged(func(ListenerAddresses))
  151. String() string
  152. Factory() listenerFactory
  153. NATType() string
  154. }
  155. type Model interface {
  156. protocol.Model
  157. AddConnection(conn protocol.Connection, hello protocol.Hello)
  158. Connection(remoteID protocol.DeviceID) (protocol.Connection, bool)
  159. OnHello(protocol.DeviceID, net.Addr, protocol.Hello) error
  160. GetHello(protocol.DeviceID) protocol.HelloIntf
  161. }
  162. type onAddressesChangedNotifier struct {
  163. callbacks []func(ListenerAddresses)
  164. }
  165. func (o *onAddressesChangedNotifier) OnAddressesChanged(callback func(ListenerAddresses)) {
  166. o.callbacks = append(o.callbacks, callback)
  167. }
  168. func (o *onAddressesChangedNotifier) notifyAddressesChanged(l genericListener) {
  169. o.notifyAddresses(ListenerAddresses{
  170. URI: l.URI(),
  171. WANAddresses: l.WANAddresses(),
  172. LANAddresses: l.LANAddresses(),
  173. })
  174. }
  175. func (o *onAddressesChangedNotifier) clearAddresses(l genericListener) {
  176. o.notifyAddresses(ListenerAddresses{
  177. URI: l.URI(),
  178. })
  179. }
  180. func (o *onAddressesChangedNotifier) notifyAddresses(l ListenerAddresses) {
  181. for _, callback := range o.callbacks {
  182. callback(l)
  183. }
  184. }
  185. type dialTarget struct {
  186. addr string
  187. dialer genericDialer
  188. priority int
  189. uri *url.URL
  190. deviceID protocol.DeviceID
  191. }
  192. func (t dialTarget) Dial(ctx context.Context) (internalConn, error) {
  193. l.Debugln("dialing", t.deviceID, t.uri, "prio", t.priority)
  194. return t.dialer.Dial(ctx, t.deviceID, t.uri)
  195. }