main.go 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902
  1. // dnstt-server is the server end of a DNS tunnel.
  2. //
  3. // Usage:
  4. // dnstt-server -gen-key [-privkey-file PRIVKEYFILE] [-pubkey-file PUBKEYFILE]
  5. // dnstt-server -udp ADDR [-privkey PRIVKEY|-privkey-file PRIVKEYFILE] DOMAIN UPSTREAMADDR
  6. //
  7. // Example:
  8. // dnstt-server -gen-key -privkey-file server.key -pubkey-file server.pub
  9. // dnstt-server -udp :53 -privkey-file server.key t.example.com 127.0.0.1:8000
  10. //
  11. // To generate a persistent server private key, first run with the -gen-key
  12. // option. By default the generated private and public keys are printed to
  13. // standard output. To save them to files instead, use the -privkey-file and
  14. // -pubkey-file options.
  15. // dnstt-server -gen-key
  16. // dnstt-server -gen-key -privkey-file server.key -pubkey-file server.pub
  17. //
  18. // You can give the server's private key as a file or as a hex string.
  19. // -privkey-file server.key
  20. // -privkey 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
  21. //
  22. // The -udp option controls the address that will listen for incoming DNS
  23. // queries.
  24. //
  25. // The -mtu option controls the maximum size of response UDP payloads.
  26. // Queries that do not advertise requester support for responses of at least
  27. // this size at least this size will be responded to with a FORMERR. The default
  28. // value is maxUDPPayload.
  29. //
  30. // DOMAIN is the root of the DNS zone reserved for the tunnel. See README for
  31. // instructions on setting it up.
  32. //
  33. // UPSTREAMADDR is the TCP address to which incoming tunnelled streams will be
  34. // forwarded.
  35. package main
  36. import (
  37. "bytes"
  38. "encoding/base32"
  39. "encoding/binary"
  40. "flag"
  41. "fmt"
  42. "io"
  43. "io/ioutil"
  44. "log"
  45. "net"
  46. "os"
  47. "sync"
  48. "time"
  49. "github.com/xtaci/kcp-go/v5"
  50. "github.com/xtaci/smux"
  51. "www.bamsoftware.com/git/dnstt.git/dns"
  52. "www.bamsoftware.com/git/dnstt.git/noise"
  53. "www.bamsoftware.com/git/dnstt.git/turbotunnel"
  54. )
  55. const (
  56. // smux streams will be closed after this much time without receiving data.
  57. idleTimeout = 10 * time.Minute
  58. // How to set the TTL field in Answer resource records.
  59. responseTTL = 60
  60. // How long we may wait for downstream data before sending an empty
  61. // response. If another query comes in while we are waiting, we'll send
  62. // an empty response anyway and restart the delay timer for the next
  63. // response.
  64. //
  65. // This number should be less than 2 seconds, which in 2019 was reported
  66. // to be the query timeout of the Quad9 DoH server.
  67. // https://dnsencryption.info/imc19-doe.html Section 4.2, Finding 2.4
  68. maxResponseDelay = 1 * time.Second
  69. )
  70. var (
  71. // We don't send UDP payloads larger than this, in an attempt to avoid
  72. // network-layer fragmentation. 1280 is the minimum IPv6 MTU, 40 bytes
  73. // is the size of an IPv6 header (though without any extension headers),
  74. // and 8 bytes is the size of a UDP header.
  75. //
  76. // Control this value with the -mtu command-line option.
  77. //
  78. // https://dnsflagday.net/2020/#message-size-considerations
  79. // "An EDNS buffer size of 1232 bytes will avoid fragmentation on nearly
  80. // all current networks."
  81. //
  82. // On 2020-04-19, the Quad9 resolver was seen to have a UDP payload size
  83. // of 1232. Cloudflare's was 1452, and Google's was 4096.
  84. maxUDPPayload = 1280 - 40 - 8
  85. )
  86. // base32Encoding is a base32 encoding without padding.
  87. var base32Encoding = base32.StdEncoding.WithPadding(base32.NoPadding)
  88. // generateKeypair generates a private key and the corresponding public key. If
  89. // privkeyFilename and pubkeyFilename are respectively empty, it prints the
  90. // corresponding key to standard output; otherwise it saves the key to the given
  91. // file name. The private key is saved with mode 0400 and the public key is
  92. // saved with 0666 (before umask). In case of any error, it attempts to delete
  93. // any files it has created before returning.
  94. func generateKeypair(privkeyFilename, pubkeyFilename string) (err error) {
  95. // Filenames to delete in case of error (avoid leaving partially written
  96. // files).
  97. var toDelete []string
  98. defer func() {
  99. for _, filename := range toDelete {
  100. fmt.Fprintf(os.Stderr, "deleting partially written file %s\n", filename)
  101. if closeErr := os.Remove(filename); closeErr != nil {
  102. fmt.Fprintf(os.Stderr, "cannot remove %s: %v\n", filename, closeErr)
  103. if err == nil {
  104. err = closeErr
  105. }
  106. }
  107. }
  108. }()
  109. privkey, pubkey, err := noise.GenerateKeypair()
  110. if err != nil {
  111. return err
  112. }
  113. if privkeyFilename != "" {
  114. // Save the privkey to a file.
  115. f, err := os.OpenFile(privkeyFilename, os.O_RDWR|os.O_CREATE, 0400)
  116. if err != nil {
  117. return err
  118. }
  119. toDelete = append(toDelete, privkeyFilename)
  120. err = noise.WriteKey(f, privkey)
  121. if err2 := f.Close(); err == nil {
  122. err = err2
  123. }
  124. if err != nil {
  125. return err
  126. }
  127. }
  128. if pubkeyFilename != "" {
  129. // Save the pubkey to a file.
  130. f, err := os.Create(pubkeyFilename)
  131. if err != nil {
  132. return err
  133. }
  134. toDelete = append(toDelete, pubkeyFilename)
  135. err = noise.WriteKey(f, pubkey)
  136. if err2 := f.Close(); err == nil {
  137. err = err2
  138. }
  139. if err != nil {
  140. return err
  141. }
  142. }
  143. // All good, allow the written files to remain.
  144. toDelete = nil
  145. if privkeyFilename != "" {
  146. fmt.Printf("privkey written to %s\n", privkeyFilename)
  147. } else {
  148. fmt.Printf("privkey %x\n", privkey)
  149. }
  150. if pubkeyFilename != "" {
  151. fmt.Printf("pubkey written to %s\n", pubkeyFilename)
  152. } else {
  153. fmt.Printf("pubkey %x\n", pubkey)
  154. }
  155. return nil
  156. }
  157. // readKeyFromFile reads a key from a named file.
  158. func readKeyFromFile(filename string) ([]byte, error) {
  159. f, err := os.Open(filename)
  160. if err != nil {
  161. return nil, err
  162. }
  163. defer f.Close()
  164. return noise.ReadKey(f)
  165. }
  166. // handleStream bidirectionally connects a client stream with a TCP socket
  167. // addressed by upstream.
  168. func handleStream(stream *smux.Stream, upstream *net.TCPAddr, conv uint32) error {
  169. conn, err := net.DialTCP("tcp", nil, upstream)
  170. if err != nil {
  171. return fmt.Errorf("stream %08x:%d connect upstream: %v", conv, stream.ID(), err)
  172. }
  173. defer conn.Close()
  174. var wg sync.WaitGroup
  175. wg.Add(2)
  176. go func() {
  177. defer wg.Done()
  178. _, err := io.Copy(stream, conn)
  179. if err == io.EOF {
  180. // smux Stream.Write may return io.EOF.
  181. err = nil
  182. }
  183. if err != nil {
  184. log.Printf("stream %08x:%d copy stream←upstream: %v\n", conv, stream.ID(), err)
  185. }
  186. conn.CloseRead()
  187. stream.Close()
  188. }()
  189. go func() {
  190. defer wg.Done()
  191. _, err := io.Copy(conn, stream)
  192. if err == io.EOF {
  193. // smux Stream.WriteTo may return io.EOF.
  194. err = nil
  195. }
  196. if err != nil && err != io.ErrClosedPipe {
  197. log.Printf("stream %08x:%d copy upstream←stream: %v\n", conv, stream.ID(), err)
  198. }
  199. conn.CloseWrite()
  200. }()
  201. wg.Wait()
  202. return nil
  203. }
  204. // acceptStreams wraps a KCP session in a Noise channel and an smux.Session,
  205. // then awaits smux streams. It passes each stream to handleStream.
  206. func acceptStreams(conn *kcp.UDPSession, privkey, pubkey []byte, upstream *net.TCPAddr) error {
  207. // Put a Noise channel on top of the KCP conn.
  208. rw, err := noise.NewServer(conn, privkey, pubkey)
  209. if err != nil {
  210. return err
  211. }
  212. // Put an smux session on top of the encrypted Noise channel.
  213. smuxConfig := smux.DefaultConfig()
  214. smuxConfig.Version = 2
  215. smuxConfig.KeepAliveTimeout = idleTimeout
  216. sess, err := smux.Server(rw, smuxConfig)
  217. if err != nil {
  218. return err
  219. }
  220. defer sess.Close()
  221. for {
  222. stream, err := sess.AcceptStream()
  223. if err != nil {
  224. if err, ok := err.(net.Error); ok && err.Temporary() {
  225. continue
  226. }
  227. return err
  228. }
  229. log.Printf("begin stream %08x:%d", conn.GetConv(), stream.ID())
  230. go func() {
  231. defer func() {
  232. log.Printf("end stream %08x:%d", conn.GetConv(), stream.ID())
  233. stream.Close()
  234. }()
  235. err := handleStream(stream, upstream, conn.GetConv())
  236. if err != nil {
  237. log.Printf("stream %08x:%d handleStream: %v\n", conn.GetConv(), stream.ID(), err)
  238. }
  239. }()
  240. }
  241. }
  242. // acceptSessions listens for incoming KCP connections and passes them to
  243. // acceptStreams.
  244. func acceptSessions(ln *kcp.Listener, privkey, pubkey []byte, mtu int, upstream *net.TCPAddr) error {
  245. for {
  246. conn, err := ln.AcceptKCP()
  247. if err != nil {
  248. if err, ok := err.(net.Error); ok && err.Temporary() {
  249. continue
  250. }
  251. return err
  252. }
  253. log.Printf("begin session %08x", conn.GetConv())
  254. // Permit coalescing the payloads of consecutive sends.
  255. conn.SetStreamMode(true)
  256. // Disable the dynamic congestion window (limit only by the
  257. // maximum of local and remote static windows).
  258. conn.SetNoDelay(
  259. 0, // default nodelay
  260. 0, // default interval
  261. 0, // default resend
  262. 1, // nc=1 => congestion window off
  263. )
  264. if rc := conn.SetMtu(mtu); !rc {
  265. panic(rc)
  266. }
  267. go func() {
  268. defer func() {
  269. log.Printf("end session %08x", conn.GetConv())
  270. conn.Close()
  271. }()
  272. err := acceptStreams(conn, privkey, pubkey, upstream)
  273. if err != nil {
  274. log.Printf("session %08x acceptStreams: %v\n", conn.GetConv(), err)
  275. }
  276. }()
  277. }
  278. }
  279. // nextPacket reads the next length-prefixed packet from r, ignoring padding. It
  280. // returns a nil error only when a packet was read successfully. It returns
  281. // io.EOF only when there were 0 bytes remaining to read from r. It returns
  282. // io.ErrUnexpectedEOF when EOF occurs in the middle of an encoded packet.
  283. //
  284. // The prefixing scheme is as follows. A length prefix L < 0xe0 means a data
  285. // packet of L bytes. A length prefix L >= 0xe0 means padding of L - 0xe0 bytes
  286. // (not counting the length of the length prefix itself).
  287. func nextPacket(r *bytes.Reader) ([]byte, error) {
  288. // Convert io.EOF to io.ErrUnexpectedEOF.
  289. eof := func(err error) error {
  290. if err == io.EOF {
  291. err = io.ErrUnexpectedEOF
  292. }
  293. return err
  294. }
  295. for {
  296. prefix, err := r.ReadByte()
  297. if err != nil {
  298. // We may return a real io.EOF only here.
  299. return nil, err
  300. }
  301. if prefix >= 224 {
  302. paddingLen := prefix - 224
  303. _, err := io.CopyN(ioutil.Discard, r, int64(paddingLen))
  304. if err != nil {
  305. return nil, eof(err)
  306. }
  307. } else {
  308. p := make([]byte, int(prefix))
  309. _, err = io.ReadFull(r, p)
  310. return p, eof(err)
  311. }
  312. }
  313. }
  314. // responseFor constructs a response dns.Message that is appropriate for query.
  315. // Along with the dns.Message, it returns the query's decoded data payload. If
  316. // the returned dns.Message is nil, it means that there should be no response to
  317. // this query. If the returned dns.Message has an Rcode() of dns.RcodeNoError,
  318. // the message is a candidate for for carrying downstream data in a TXT record.
  319. func responseFor(query *dns.Message, domain dns.Name) (*dns.Message, []byte) {
  320. resp := &dns.Message{
  321. ID: query.ID,
  322. Flags: 0x8000, // QR = 1, RCODE = no error
  323. Question: query.Question,
  324. }
  325. if query.Flags&0x8000 != 0 {
  326. // QR != 0, this is not a query. Don't even send a response.
  327. return nil, nil
  328. }
  329. // Check for EDNS(0) support. Include our own OPT RR only if we receive
  330. // one from the requester.
  331. // https://tools.ietf.org/html/rfc6891#section-6.1.1
  332. // "Lack of presence of an OPT record in a request MUST be taken as an
  333. // indication that the requester does not implement any part of this
  334. // specification and that the responder MUST NOT include an OPT record
  335. // in its response."
  336. payloadSize := 0
  337. for _, rr := range query.Additional {
  338. if rr.Type != dns.RRTypeOPT {
  339. continue
  340. }
  341. if len(resp.Additional) != 0 {
  342. // https://tools.ietf.org/html/rfc6891#section-6.1.1
  343. // "If a query message with more than one OPT RR is
  344. // received, a FORMERR (RCODE=1) MUST be returned."
  345. resp.Flags |= dns.RcodeFormatError
  346. log.Printf("FORMERR: more than one OPT RR")
  347. return resp, nil
  348. }
  349. resp.Additional = append(resp.Additional, dns.RR{
  350. Name: dns.Name{},
  351. Type: dns.RRTypeOPT,
  352. Class: 4096, // responder's UDP payload size
  353. TTL: 0,
  354. Data: []byte{},
  355. })
  356. additional := &resp.Additional[0]
  357. version := (rr.TTL >> 16) & 0xff
  358. if version != 0 {
  359. // https://tools.ietf.org/html/rfc6891#section-6.1.1
  360. // "If a responder does not implement the VERSION level
  361. // of the request, then it MUST respond with
  362. // RCODE=BADVERS."
  363. resp.Flags |= dns.ExtendedRcodeBadVers & 0xf
  364. additional.TTL = (dns.ExtendedRcodeBadVers >> 4) << 24
  365. log.Printf("BADVERS: EDNS version %d != 0", version)
  366. return resp, nil
  367. }
  368. payloadSize = int(rr.Class)
  369. }
  370. if payloadSize < 512 {
  371. // https://tools.ietf.org/html/rfc6891#section-6.1.1 "Values
  372. // lower than 512 MUST be treated as equal to 512."
  373. payloadSize = 512
  374. }
  375. // We will return RcodeFormatError if payloadSize is too small, but
  376. // first, check the name in order to set the AA bit properly.
  377. // There must be exactly one question.
  378. if len(query.Question) != 1 {
  379. resp.Flags |= dns.RcodeFormatError
  380. log.Printf("FORMERR: too few or too many questions (%d)", len(query.Question))
  381. return resp, nil
  382. }
  383. question := query.Question[0]
  384. // Check the name to see if it ends in our chosen domain, and extract
  385. // all that comes before the domain if it does. If it does not, we will
  386. // return RcodeNameError below, but prefer to return RcodeFormatError
  387. // for payload size if that applies as well.
  388. prefix, ok := question.Name.TrimSuffix(domain)
  389. if !ok {
  390. // Not a name we are authoritative for.
  391. resp.Flags |= dns.RcodeNameError
  392. log.Printf("NXDOMAIN: not authoritative for %s", question.Name)
  393. return resp, nil
  394. }
  395. resp.Flags |= 0x0400 // AA = 1
  396. if query.Opcode() != 0 {
  397. // We don't support OPCODE != QUERY.
  398. resp.Flags |= dns.RcodeNotImplemented
  399. log.Printf("NOTIMPL: unrecognized OPCODE %d", query.Opcode())
  400. return resp, nil
  401. }
  402. if question.Type != dns.RRTypeTXT {
  403. // We only support QTYPE == TXT.
  404. resp.Flags |= dns.RcodeNameError
  405. // No log message here; it's common for recursive resolvers to
  406. // send NS or A queries when the client only asked for a TXT. I
  407. // suspect this is related to QNAME minimization, but I'm not
  408. // sure. https://tools.ietf.org/html/rfc7816
  409. // log.Printf("NXDOMAIN: QTYPE %d != TXT", question.Type)
  410. return resp, nil
  411. }
  412. encoded := bytes.ToUpper(bytes.Join(prefix, nil))
  413. payload := make([]byte, base32Encoding.DecodedLen(len(encoded)))
  414. n, err := base32Encoding.Decode(payload, encoded)
  415. if err != nil {
  416. // Base32 error, make like the name doesn't exist.
  417. resp.Flags |= dns.RcodeNameError
  418. log.Printf("NXDOMAIN: base32 decoding: %v", err)
  419. return resp, nil
  420. }
  421. payload = payload[:n]
  422. // We require clients to support EDNS(0) with a minimum payload size;
  423. // otherwise we would have to set a small KCP MTU (only around 200
  424. // bytes). https://tools.ietf.org/html/rfc6891#section-7 "If there is a
  425. // problem with processing the OPT record itself, such as an option
  426. // value that is badly formatted or that includes out-of-range values, a
  427. // FORMERR MUST be returned."
  428. if payloadSize < maxUDPPayload {
  429. resp.Flags |= dns.RcodeFormatError
  430. log.Printf("FORMERR: requester payload size %d is too small (minimum %d)", payloadSize, maxUDPPayload)
  431. return resp, nil
  432. }
  433. return resp, payload
  434. }
  435. // record represents a DNS message appropriate for a response to a previously
  436. // received query, along with metadata necessary for sending the response.
  437. // recvLoop sends instances of record to sendLoop via a channel. sendLoop
  438. // receives instances of record and may fill in the message's Answer section
  439. // before sending it.
  440. type record struct {
  441. Resp *dns.Message
  442. Addr net.Addr
  443. ClientID turbotunnel.ClientID
  444. }
  445. // recvLoop repeatedly calls dnsConn.ReadFrom, extracts the packets contained in
  446. // the incoming DNS queries, and puts them on ttConn's incoming queue. Whenever
  447. // a query calls for a response, constructs a partial response and passes it to
  448. // sendLoop over ch.
  449. func recvLoop(domain dns.Name, dnsConn net.PacketConn, ttConn *turbotunnel.QueuePacketConn, ch chan<- *record) error {
  450. for {
  451. var buf [4096]byte
  452. n, addr, err := dnsConn.ReadFrom(buf[:])
  453. if err != nil {
  454. if err, ok := err.(net.Error); ok && err.Temporary() {
  455. log.Printf("ReadFrom temporary error: %v", err)
  456. continue
  457. }
  458. return err
  459. }
  460. // Got a UDP packet. Try to parse it as a DNS message.
  461. query, err := dns.MessageFromWireFormat(buf[:n])
  462. if err != nil {
  463. log.Printf("cannot parse DNS query: %v", err)
  464. continue
  465. }
  466. resp, payload := responseFor(&query, domain)
  467. // Extract the ClientID from the payload.
  468. var clientID turbotunnel.ClientID
  469. n = copy(clientID[:], payload)
  470. payload = payload[n:]
  471. if n == len(clientID) {
  472. // Discard padding and pull out the packets contained in
  473. // the payload.
  474. r := bytes.NewReader(payload)
  475. for {
  476. p, err := nextPacket(r)
  477. if err != nil {
  478. break
  479. }
  480. // Feed the incoming packet to KCP.
  481. ttConn.QueueIncoming(p, clientID)
  482. }
  483. } else {
  484. // Payload is not long enough to contain a ClientID.
  485. if resp != nil && resp.Rcode() == dns.RcodeNoError {
  486. resp.Flags |= dns.RcodeNameError
  487. log.Printf("NXDOMAIN: %d bytes are too short to contain a ClientID", n)
  488. }
  489. }
  490. // If a response is called for, pass it to sendLoop via the channel.
  491. if resp != nil {
  492. select {
  493. case ch <- &record{resp, addr, clientID}:
  494. default:
  495. }
  496. }
  497. }
  498. }
  499. // sendLoop repeatedly receives records from ch. Those that represent an error
  500. // response, it sends on the network immediately. Those that represent a
  501. // response capable of carrying data, it packs full of as many packets as will
  502. // fit while keeping the total size under maxEncodedPayload, then sends it.
  503. func sendLoop(dnsConn net.PacketConn, ttConn *turbotunnel.QueuePacketConn, ch <-chan *record, maxEncodedPayload int) error {
  504. var nextRec *record
  505. for {
  506. rec := nextRec
  507. nextRec = nil
  508. if rec == nil {
  509. var ok bool
  510. rec, ok = <-ch
  511. if !ok {
  512. break
  513. }
  514. }
  515. if rec.Resp.Rcode() == dns.RcodeNoError && len(rec.Resp.Question) == 1 {
  516. // If it's a non-error response, we can fill the Answer
  517. // section with downstream packets.
  518. // Any changes to how responses are built need to happen
  519. // also in computeMaxEncodedPayload.
  520. rec.Resp.Answer = []dns.RR{
  521. {
  522. Name: rec.Resp.Question[0].Name,
  523. Type: rec.Resp.Question[0].Type,
  524. Class: rec.Resp.Question[0].Class,
  525. TTL: responseTTL,
  526. Data: nil, // will be filled in below
  527. },
  528. }
  529. var payload bytes.Buffer
  530. limit := maxEncodedPayload
  531. // We loop and bundle as many packets from OutgoingQueue
  532. // into the response as will fit. Any packet that would
  533. // overflow the capacity of the DNS response, we stash
  534. // to be bundled into a future response.
  535. timer := time.NewTimer(maxResponseDelay)
  536. loop:
  537. for {
  538. var p []byte
  539. select {
  540. // Check the nextRec, timer, and stash cases
  541. // before considering the OutgoingQueue case.
  542. // Only if all these cases fail do we enter the
  543. // default arm, where they are checked again in
  544. // addition to OutgoingQueue.
  545. case nextRec = <-ch:
  546. // If there's another response waiting
  547. // to be sent, wait no longer for a
  548. // payload for this one.
  549. break loop
  550. case <-timer.C:
  551. break loop
  552. case p = <-ttConn.Unstash(rec.ClientID):
  553. default:
  554. select {
  555. case nextRec = <-ch:
  556. break loop
  557. case <-timer.C:
  558. break loop
  559. case p = <-ttConn.Unstash(rec.ClientID):
  560. case p = <-ttConn.OutgoingQueue(rec.ClientID):
  561. }
  562. }
  563. // We wait for the first packet in a bundle
  564. // only. The second and later packets must be
  565. // immediately available or they will be omitted
  566. // from this bundle.
  567. timer.Reset(0)
  568. limit -= 2 + len(p)
  569. if payload.Len() == 0 {
  570. // No packet length check for the first
  571. // packet; if it's too large, we allow
  572. // it to be truncated and dropped by the
  573. // receiver.
  574. } else if limit < 0 {
  575. // Stash this packet to send in the next
  576. // response.
  577. ttConn.Stash(p, rec.ClientID)
  578. break loop
  579. }
  580. if int(uint16(len(p))) != len(p) {
  581. panic(len(p))
  582. }
  583. binary.Write(&payload, binary.BigEndian, uint16(len(p)))
  584. payload.Write(p)
  585. }
  586. timer.Stop()
  587. rec.Resp.Answer[0].Data = dns.EncodeRDataTXT(payload.Bytes())
  588. }
  589. buf, err := rec.Resp.WireFormat()
  590. if err != nil {
  591. log.Printf("resp WireFormat: %v", err)
  592. continue
  593. }
  594. // Truncate if necessary.
  595. // https://tools.ietf.org/html/rfc1035#section-4.1.1
  596. if len(buf) > maxUDPPayload {
  597. log.Printf("truncating response of %d bytes to max of %d", len(buf), maxUDPPayload)
  598. buf = buf[:maxUDPPayload]
  599. buf[2] |= 0x02 // TC = 1
  600. }
  601. // Now we actually send the message as a UDP packet.
  602. _, err = dnsConn.WriteTo(buf, rec.Addr)
  603. if err != nil {
  604. if err, ok := err.(net.Error); ok && err.Temporary() {
  605. log.Printf("WriteTo temporary error: %v", err)
  606. continue
  607. }
  608. return err
  609. }
  610. }
  611. return nil
  612. }
  613. // computeMaxEncodedPayload computes the maximum amount of downstream TXT RR
  614. // data that keep the overall response size less than maxUDPPayload, in the
  615. // worst case when the response answers a query that has a maximum-length name
  616. // in its Question section. Returns 0 in the case that no amount of data makes
  617. // the overall response size small enough.
  618. //
  619. // This function needs to be kept in sync with sendLoop with regard to how it
  620. // builds candidate responses.
  621. func computeMaxEncodedPayload(limit int) int {
  622. // 64+64+64+62 octets, needs to be base32-decodable.
  623. maxLengthName, err := dns.NewName([][]byte{
  624. []byte("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"),
  625. []byte("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"),
  626. []byte("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"),
  627. []byte("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"),
  628. })
  629. if err != nil {
  630. panic(err)
  631. }
  632. if len(maxLengthName.String())+2 != 255 {
  633. panic(fmt.Sprintf("max-length name is %d octets, should be %d %s",
  634. len(maxLengthName.String())+2, 255, maxLengthName))
  635. }
  636. queryLimit := uint16(limit)
  637. if int(queryLimit) != limit {
  638. queryLimit = 0xffff
  639. }
  640. query := &dns.Message{
  641. Question: []dns.Question{
  642. {
  643. Name: maxLengthName,
  644. Type: dns.RRTypeTXT,
  645. Class: dns.RRTypeTXT,
  646. },
  647. },
  648. // EDNS(0)
  649. Additional: []dns.RR{
  650. {
  651. Name: dns.Name{},
  652. Type: dns.RRTypeOPT,
  653. Class: queryLimit, // requester's UDP payload size
  654. TTL: 0, // extended RCODE and flags
  655. Data: []byte{},
  656. },
  657. },
  658. }
  659. resp, _ := responseFor(query, dns.Name([][]byte{}))
  660. // As in sendLoop.
  661. resp.Answer = []dns.RR{
  662. {
  663. Name: query.Question[0].Name,
  664. Type: query.Question[0].Type,
  665. Class: query.Question[0].Class,
  666. TTL: responseTTL,
  667. Data: nil, // will be filled in below
  668. },
  669. }
  670. // Binary search to find the maximum payload length that does not result
  671. // in a wire-format message whose length exceeds the limit.
  672. low := 0
  673. high := 32768
  674. for low+1 < high {
  675. mid := (low + high) / 2
  676. resp.Answer[0].Data = dns.EncodeRDataTXT(make([]byte, mid))
  677. buf, err := resp.WireFormat()
  678. if err != nil {
  679. panic(err)
  680. }
  681. if len(buf) <= limit {
  682. low = mid
  683. } else {
  684. high = mid
  685. }
  686. }
  687. return low
  688. }
  689. func run(privkey, pubkey []byte, domain dns.Name, upstream net.Addr, dnsConn net.PacketConn) error {
  690. defer dnsConn.Close()
  691. log.Printf("pubkey %x", pubkey)
  692. // We have a variable amount of room in which to encode downstream
  693. // packets in each response, because each response must contain the
  694. // query's Question section, which is of variable length. But we cannot
  695. // give dynamic packet size limits to KCP; the best we can do is set a
  696. // global maximum which no packet will exceed. We choose that maximum to
  697. // keep the UDP payload size under maxUDPPayload, even in the worst case
  698. // of a maximum-length name in the query's Question section.
  699. maxEncodedPayload := computeMaxEncodedPayload(maxUDPPayload)
  700. // 2 bytes accounts for a packet length prefix.
  701. mtu := maxEncodedPayload - 2
  702. if mtu < 80 {
  703. if mtu < 0 {
  704. mtu = 0
  705. }
  706. return fmt.Errorf("maximum UDP payload size of %d leaves only %d bytes for payload", maxUDPPayload, mtu)
  707. }
  708. log.Printf("effective MTU %d\n", mtu)
  709. // Start up the virtual PacketConn for turbotunnel.
  710. ttConn := turbotunnel.NewQueuePacketConn(turbotunnel.DummyAddr{}, idleTimeout*2)
  711. ln, err := kcp.ServeConn(nil, 0, 0, ttConn)
  712. if err != nil {
  713. return fmt.Errorf("opening KCP listener: %v", err)
  714. }
  715. defer ln.Close()
  716. go func() {
  717. err := acceptSessions(ln, privkey, pubkey, mtu, upstream.(*net.TCPAddr))
  718. if err != nil {
  719. log.Printf("acceptSessions: %v\n", err)
  720. }
  721. }()
  722. ch := make(chan *record, 100)
  723. defer close(ch)
  724. // We could run multiple copies of sendLoop; that would allow more time
  725. // for each response to collect downstream data before being evicted by
  726. // another response that needs to be sent.
  727. go func() {
  728. err := sendLoop(dnsConn, ttConn, ch, maxEncodedPayload)
  729. if err != nil {
  730. log.Printf("sendLoop: %v", err)
  731. }
  732. }()
  733. return recvLoop(domain, dnsConn, ttConn, ch)
  734. }
  735. func main() {
  736. var genKey bool
  737. var privkeyFilename string
  738. var privkeyString string
  739. var pubkeyFilename string
  740. var udpAddr string
  741. flag.Usage = func() {
  742. fmt.Fprintf(flag.CommandLine.Output(), `Usage:
  743. %[1]s -gen-key -privkey-file PRIVKEYFILE -pubkey-file PUBKEYFILE
  744. %[1]s -udp ADDR -privkey-file PRIVKEYFILE DOMAIN UPSTREAMADDR
  745. Example:
  746. %[1]s -gen-key -privkey-file server.key -pubkey-file server.pub
  747. %[1]s -udp :53 -privkey-file server.key t.example.com 127.0.0.1:8000
  748. `, os.Args[0])
  749. flag.PrintDefaults()
  750. }
  751. flag.BoolVar(&genKey, "gen-key", false, "generate a server keypair; print to stdout or save to files")
  752. flag.IntVar(&maxUDPPayload, "mtu", maxUDPPayload, "maximum size of DNS responses")
  753. flag.StringVar(&privkeyString, "privkey", "", fmt.Sprintf("server private key (%d hex digits)", noise.KeyLen*2))
  754. flag.StringVar(&privkeyFilename, "privkey-file", "", "read server private key from file (with -gen-key, write to file)")
  755. flag.StringVar(&pubkeyFilename, "pubkey-file", "", "with -gen-key, write server public key to file")
  756. flag.StringVar(&udpAddr, "udp", "", "UDP address to listen on (required)")
  757. flag.Parse()
  758. log.SetFlags(log.LstdFlags | log.LUTC)
  759. if genKey {
  760. // -gen-key mode.
  761. if flag.NArg() != 0 || privkeyString != "" || udpAddr != "" {
  762. flag.Usage()
  763. os.Exit(1)
  764. }
  765. if err := generateKeypair(privkeyFilename, pubkeyFilename); err != nil {
  766. fmt.Fprintf(os.Stderr, "cannot generate keypair: %v\n", err)
  767. os.Exit(1)
  768. }
  769. } else {
  770. // Ordinary server mode.
  771. if flag.NArg() != 2 {
  772. flag.Usage()
  773. os.Exit(1)
  774. }
  775. domain, err := dns.ParseName(flag.Arg(0))
  776. if err != nil {
  777. fmt.Fprintf(os.Stderr, "invalid domain %+q: %v\n", flag.Arg(0), err)
  778. os.Exit(1)
  779. }
  780. upstream, err := net.ResolveTCPAddr("tcp", flag.Arg(1))
  781. if err != nil {
  782. fmt.Fprintf(os.Stderr, "cannot resolve %+q: %v\n", flag.Arg(1), err)
  783. os.Exit(1)
  784. }
  785. if udpAddr == "" {
  786. fmt.Fprintf(os.Stderr, "the -udp option is required\n")
  787. os.Exit(1)
  788. }
  789. dnsConn, err := net.ListenPacket("udp", udpAddr)
  790. if err != nil {
  791. fmt.Fprintf(os.Stderr, "opening UDP listener: %v\n", err)
  792. os.Exit(1)
  793. }
  794. if pubkeyFilename != "" {
  795. fmt.Fprintf(os.Stderr, "-pubkey-file may only be used with -gen-key\n")
  796. os.Exit(1)
  797. }
  798. var privkey []byte
  799. if privkeyFilename != "" && privkeyString != "" {
  800. fmt.Fprintf(os.Stderr, "only one of -privkey and -privkey-file may be used\n")
  801. os.Exit(1)
  802. } else if privkeyFilename != "" {
  803. var err error
  804. privkey, err = readKeyFromFile(privkeyFilename)
  805. if err != nil {
  806. fmt.Fprintf(os.Stderr, "cannot read privkey from file: %v\n", err)
  807. os.Exit(1)
  808. }
  809. } else if privkeyString != "" {
  810. var err error
  811. privkey, err = noise.DecodeKey(privkeyString)
  812. if err != nil {
  813. fmt.Fprintf(os.Stderr, "privkey format error: %v\n", err)
  814. os.Exit(1)
  815. }
  816. }
  817. if len(privkey) == 0 {
  818. log.Println("generating a temporary one-time keypair")
  819. log.Println("use the -privkey or -privkey-file option for a persistent server keypair")
  820. var err error
  821. privkey, _, err = noise.GenerateKeypair()
  822. if err != nil {
  823. fmt.Fprintln(os.Stderr, err)
  824. os.Exit(1)
  825. }
  826. }
  827. pubkey := noise.PubkeyFromPrivkey(privkey)
  828. err = run(privkey, pubkey, domain, upstream, dnsConn)
  829. if err != nil {
  830. log.Fatal(err)
  831. }
  832. }
  833. }