derp.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. // Package derp implements the Designated Encrypted Relay for Packets (DERP)
  4. // protocol.
  5. //
  6. // DERP routes packets to clients using curve25519 keys as addresses.
  7. //
  8. // DERP is used by Tailscale nodes to proxy encrypted WireGuard
  9. // packets through the Tailscale cloud servers when a direct path
  10. // cannot be found or opened. DERP is a last resort. Both sides
  11. // between very aggressive NATs, firewalls, no IPv6, etc? Well, DERP.
  12. package derp
  13. import (
  14. "bufio"
  15. "encoding/binary"
  16. "errors"
  17. "fmt"
  18. "io"
  19. "net"
  20. "time"
  21. )
  22. // MaxPacketSize is the maximum size of a packet sent over DERP.
  23. // (This only includes the data bytes visible to magicsock, not
  24. // including its on-wire framing overhead)
  25. const MaxPacketSize = 64 << 10
  26. // Magic is the DERP Magic number, sent in the frameServerKey frame
  27. // upon initial connection.
  28. const Magic = "DERP🔑" // 8 bytes: 0x44 45 52 50 f0 9f 94 91
  29. const (
  30. NonceLen = 24
  31. FrameHeaderLen = 1 + 4 // frameType byte + 4 byte length
  32. KeyLen = 32
  33. MaxInfoLen = 1 << 20
  34. )
  35. // KeepAlive is the minimum frequency at which the DERP server sends
  36. // keep alive frames. The server adds some jitter, so this timing is not
  37. // exact, but 2x this value can be considered a missed keep alive.
  38. const KeepAlive = 60 * time.Second
  39. // ProtocolVersion is bumped whenever there's a wire-incompatible change.
  40. // - version 1 (zero on wire): consistent box headers, in use by employee dev nodes a bit
  41. // - version 2: received packets have src addrs in frameRecvPacket at beginning
  42. const ProtocolVersion = 2
  43. // FrameType is the one byte frame type at the beginning of the frame
  44. // header. The second field is a big-endian uint32 describing the
  45. // length of the remaining frame (not including the initial 5 bytes).
  46. type FrameType byte
  47. /*
  48. Protocol flow:
  49. Login:
  50. * client connects
  51. * server sends frameServerKey
  52. * client sends frameClientInfo
  53. * server sends frameServerInfo
  54. Steady state:
  55. * server occasionally sends frameKeepAlive (or framePing)
  56. * client responds to any framePing with a framePong
  57. * client sends frameSendPacket
  58. * server then sends frameRecvPacket to recipient
  59. */
  60. const (
  61. FrameServerKey = FrameType(0x01) // 8B magic + 32B public key + (0+ bytes future use)
  62. FrameClientInfo = FrameType(0x02) // 32B pub key + 24B nonce + naclbox(json)
  63. FrameServerInfo = FrameType(0x03) // 24B nonce + naclbox(json)
  64. FrameSendPacket = FrameType(0x04) // 32B dest pub key + packet bytes
  65. FrameForwardPacket = FrameType(0x0a) // 32B src pub key + 32B dst pub key + packet bytes
  66. FrameRecvPacket = FrameType(0x05) // v0/1: packet bytes, v2: 32B src pub key + packet bytes
  67. FrameKeepAlive = FrameType(0x06) // no payload, no-op (to be replaced with ping/pong)
  68. FrameNotePreferred = FrameType(0x07) // 1 byte payload: 0x01 or 0x00 for whether this is client's home node
  69. // framePeerGone is sent from server to client to signal that
  70. // a previous sender is no longer connected. That is, if A
  71. // sent to B, and then if A disconnects, the server sends
  72. // framePeerGone to B so B can forget that a reverse path
  73. // exists on that connection to get back to A. It is also sent
  74. // if A tries to send a CallMeMaybe to B and the server has no
  75. // record of B
  76. FramePeerGone = FrameType(0x08) // 32B pub key of peer that's gone + 1 byte reason
  77. // framePeerPresent is like framePeerGone, but for other members of the DERP
  78. // region when they're meshed up together.
  79. //
  80. // The message is at least 32 bytes (the public key of the peer that's
  81. // connected). If there are at least 18 bytes remaining after that, it's the
  82. // 16 byte IP + 2 byte BE uint16 port of the client. If there's another byte
  83. // remaining after that, it's a PeerPresentFlags byte.
  84. // While current servers send 41 bytes, old servers will send fewer, and newer
  85. // servers might send more.
  86. FramePeerPresent = FrameType(0x09)
  87. // frameWatchConns is how one DERP node in a regional mesh
  88. // subscribes to the others in the region.
  89. // There's no payload. If the sender doesn't have permission, the connection
  90. // is closed. Otherwise, the client is initially flooded with
  91. // framePeerPresent for all connected nodes, and then a stream of
  92. // framePeerPresent & framePeerGone has peers connect and disconnect.
  93. FrameWatchConns = FrameType(0x10)
  94. // frameClosePeer is a privileged frame type (requires the
  95. // mesh key for now) that closes the provided peer's
  96. // connection. (To be used for cluster load balancing
  97. // purposes, when clients end up on a non-ideal node)
  98. FrameClosePeer = FrameType(0x11) // 32B pub key of peer to close.
  99. FramePing = FrameType(0x12) // 8 byte ping payload, to be echoed back in framePong
  100. FramePong = FrameType(0x13) // 8 byte payload, the contents of the ping being replied to
  101. // frameHealth is sent from server to client to tell the client
  102. // if their connection is unhealthy somehow. Currently the only unhealthy state
  103. // is whether the connection is detected as a duplicate.
  104. // The entire frame body is the text of the error message. An empty message
  105. // clears the error state.
  106. FrameHealth = FrameType(0x14)
  107. // frameRestarting is sent from server to client for the
  108. // server to declare that it's restarting. Payload is two big
  109. // endian uint32 durations in milliseconds: when to reconnect,
  110. // and how long to try total. See ServerRestartingMessage docs for
  111. // more details on how the client should interpret them.
  112. FrameRestarting = FrameType(0x15)
  113. )
  114. // PeerGoneReasonType is a one byte reason code explaining why a
  115. // server does not have a path to the requested destination.
  116. type PeerGoneReasonType byte
  117. const (
  118. PeerGoneReasonDisconnected = PeerGoneReasonType(0x00) // is only sent when a peer disconnects from this server
  119. PeerGoneReasonNotHere = PeerGoneReasonType(0x01) // server doesn't know about this peer
  120. PeerGoneReasonMeshConnBroke = PeerGoneReasonType(0xf0) // invented by Client.RunWatchConnectionLoop on disconnect; not sent on the wire
  121. )
  122. // PeerPresentFlags is an optional byte of bit flags sent after a framePeerPresent message.
  123. //
  124. // For a modern server, the value should always be non-zero. If the value is zero,
  125. // that means the server doesn't support this field.
  126. type PeerPresentFlags byte
  127. // PeerPresentFlags bits.
  128. const (
  129. PeerPresentIsRegular = 1 << 0
  130. PeerPresentIsMeshPeer = 1 << 1
  131. PeerPresentIsProber = 1 << 2
  132. PeerPresentNotIdeal = 1 << 3 // client said derp server is not its Region.Nodes[0] ideal node
  133. )
  134. // IdealNodeHeader is the HTTP request header sent on DERP HTTP client requests
  135. // to indicate that they're connecting to their ideal (Region.Nodes[0]) node.
  136. // The HTTP header value is the name of the node they wish they were connected
  137. // to. This is an optional header.
  138. const IdealNodeHeader = "Ideal-Node"
  139. // FastStartHeader is the header (with value "1") that signals to the HTTP
  140. // server that the DERP HTTP client does not want the HTTP 101 response
  141. // headers and it will begin writing & reading the DERP protocol immediately
  142. // following its HTTP request.
  143. const FastStartHeader = "Derp-Fast-Start"
  144. var bin = binary.BigEndian
  145. func writeUint32(bw *bufio.Writer, v uint32) error {
  146. var b [4]byte
  147. bin.PutUint32(b[:], v)
  148. // Writing a byte at a time is a bit silly,
  149. // but it causes b not to escape,
  150. // which more than pays for the silliness.
  151. for _, c := range &b {
  152. err := bw.WriteByte(c)
  153. if err != nil {
  154. return err
  155. }
  156. }
  157. return nil
  158. }
  159. func readUint32(br *bufio.Reader) (uint32, error) {
  160. var b [4]byte
  161. // Reading a byte at a time is a bit silly,
  162. // but it causes b not to escape,
  163. // which more than pays for the silliness.
  164. for i := range &b {
  165. c, err := br.ReadByte()
  166. if err != nil {
  167. return 0, err
  168. }
  169. b[i] = c
  170. }
  171. return bin.Uint32(b[:]), nil
  172. }
  173. // ReadFrameTypeHeader reads a frame header from br and
  174. // verifies that the frame type matches wantType.
  175. //
  176. // If it does, it returns the frame length (not including
  177. // the 5 byte header) and a nil error.
  178. //
  179. // If it doesn't, it returns an error and a zero length.
  180. func ReadFrameTypeHeader(br *bufio.Reader, wantType FrameType) (frameLen uint32, err error) {
  181. gotType, frameLen, err := ReadFrameHeader(br)
  182. if err == nil && wantType != gotType {
  183. err = fmt.Errorf("bad frame type 0x%X, want 0x%X", gotType, wantType)
  184. }
  185. return frameLen, err
  186. }
  187. // ReadFrameHeader reads the header of a DERP frame,
  188. // reading 5 bytes from br.
  189. func ReadFrameHeader(br *bufio.Reader) (t FrameType, frameLen uint32, err error) {
  190. tb, err := br.ReadByte()
  191. if err != nil {
  192. return 0, 0, err
  193. }
  194. frameLen, err = readUint32(br)
  195. if err != nil {
  196. return 0, 0, err
  197. }
  198. return FrameType(tb), frameLen, nil
  199. }
  200. // readFrame reads a frame header and then reads its payload into
  201. // b[:frameLen].
  202. //
  203. // If the frame header length is greater than maxSize, readFrame returns
  204. // an error after reading the frame header.
  205. //
  206. // If the frame is less than maxSize but greater than len(b), len(b)
  207. // bytes are read, err will be io.ErrShortBuffer, and frameLen and t
  208. // will both be set. That is, callers need to explicitly handle when
  209. // they get more data than expected.
  210. func readFrame(br *bufio.Reader, maxSize uint32, b []byte) (t FrameType, frameLen uint32, err error) {
  211. t, frameLen, err = ReadFrameHeader(br)
  212. if err != nil {
  213. return 0, 0, err
  214. }
  215. if frameLen > maxSize {
  216. return 0, 0, fmt.Errorf("frame header size %d exceeds reader limit of %d", frameLen, maxSize)
  217. }
  218. n, err := io.ReadFull(br, b[:min(frameLen, uint32(len(b)))])
  219. if err != nil {
  220. return 0, 0, err
  221. }
  222. remain := frameLen - uint32(n)
  223. if remain > 0 {
  224. if _, err := io.CopyN(io.Discard, br, int64(remain)); err != nil {
  225. return 0, 0, err
  226. }
  227. err = io.ErrShortBuffer
  228. }
  229. return t, frameLen, err
  230. }
  231. // WriteFrameHeader writes a frame header to bw.
  232. //
  233. // The frame header is 5 bytes: a one byte frame type
  234. // followed by a big-endian uint32 length of the
  235. // remaining frame (not including the 5 byte header).
  236. //
  237. // It does not flush bw.
  238. func WriteFrameHeader(bw *bufio.Writer, t FrameType, frameLen uint32) error {
  239. if err := bw.WriteByte(byte(t)); err != nil {
  240. return err
  241. }
  242. return writeUint32(bw, frameLen)
  243. }
  244. // WriteFrame writes a complete frame & flushes it.
  245. func WriteFrame(bw *bufio.Writer, t FrameType, b []byte) error {
  246. if len(b) > 10<<20 {
  247. return errors.New("unreasonably large frame write")
  248. }
  249. if err := WriteFrameHeader(bw, t, uint32(len(b))); err != nil {
  250. return err
  251. }
  252. if _, err := bw.Write(b); err != nil {
  253. return err
  254. }
  255. return bw.Flush()
  256. }
  257. // Conn is the subset of the underlying net.Conn the DERP Server needs.
  258. // It is a defined type so that non-net connections can be used.
  259. type Conn interface {
  260. io.WriteCloser
  261. LocalAddr() net.Addr
  262. // The *Deadline methods follow the semantics of net.Conn.
  263. SetDeadline(time.Time) error
  264. SetReadDeadline(time.Time) error
  265. SetWriteDeadline(time.Time) error
  266. }
  267. // ServerInfo is the message sent from the server to clients during
  268. // the connection setup.
  269. type ServerInfo struct {
  270. Version int `json:"version,omitempty"`
  271. TokenBucketBytesPerSecond int `json:",omitempty"`
  272. TokenBucketBytesBurst int `json:",omitempty"`
  273. }