Bug 798 - Client-side TCP fast open fails (Linux)
Client-side TCP fast open fails (Linux)
Status: RESOLVED FIXED
Product: unbound
Classification: Unclassified
Component: server
unspecified
All Linux
: P5 normal
Assigned To: unbound team
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2016-07-18 15:07 CEST by Daisuke HIGASHI
Modified: 2016-07-18 15:54 CEST (History)
2 users (show)

See Also:


Attachments
TFO client-side bug fix patch (593 bytes, application/octet-stream)
2016-07-18 15:07 CEST, Daisuke HIGASHI
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Daisuke HIGASHI 2016-07-18 15:07:42 CEST
Created attachment 342 [details]
TFO client-side bug fix patch

Unbound (client-side TFO enabled, and configured to use TCP upstream only)
returns SERVFAIL after several query processing:

  $ dig -p 1053 @::1 unbound.net +short
  185.49.140.10

  $ dig -p 1053 @::1 isc.org +short
  149.20.64.69

  $ dig -p 1053 @::1 www.google.com
  ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 19985
  ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

  ;; OPT PSEUDOSECTION:
  ; EDNS: version: 0, flags:; udp: 4096
  ;; QUESTION SECTION:
  ;www.google.com.			IN	A
  
  $ dig -p 1053 @::1 www.yahoo.co.jp | grep status
  ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 24417

  $ dig -p 1053 @::1 www.amazon.com | grep status
  ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 15558
  ....

## configure option
  ./configure --enable-tfo-client --enable-tfo-server

## unbound.conf
  server:
        username: ""
        chroot: ""
        port: 1053
        tcp-upstream: yes   # use TCP only
        outgoing-num-tcp: 100


  According to "strace ./unbound -d", Unbound writev()s to outgoing TCP socket (fd=12) without preceding sendto() or connect() (and gets EPIPE). It seems that c->tcp_do_fastopen have to be set to 1 to do sendto() whenever outgoing TFO socket is created. A fix patch is attached.

  recvfrom(3, "<*\1 \0\1\0\0\0\0\0\1\3www\6google\3com\0\0\1\0\1"..., 65552, 0, {sa_family=AF_INET6, sin6_port=htons(54523), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 43
  socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) = 12
  fcntl(12, F_GETFL)                      = 0x2 (flags O_RDWR)
  fcntl(12, F_SETFL, O_RDWR|O_NONBLOCK)   = 0
  recvfrom(3, 0x1655e70, 65552, 0, 0x7ffcb2540bd8, 0x7ffcb2540c58) = -1 EAGAIN (Resource temporarily unavailable)
  select(14, [3 4 5 6 7 8 10], [12], NULL, {30, 0}) = 1 (out [12], left {29, 999995})
  getsockopt(12, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
  writev(12, [{"\0+", 2}, {"\275A\1\0\0\1\0\0\0\0\0\1\3www\6google\3com\0\0\1\0\1"..., 43}], 2) = -1 EPIPE (Broken pipe) ******
  --- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=12367, si_uid=1000} ---
  close(12)                               = 0
Comment 1 Wouter Wijngaards 2016-07-18 15:54:55 CEST
Hi Daisuke,

Fixed, thank you.

Best regards, Wouter