structs.go 5.3 KB

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