title: setsockopt on "accepted" fd on Linux
body: <p>I have had a rather strange observation about behavior of setsockopt on Linux for SO_REUSEADDR. In one line: if I apply the sockopt to an fd returned by accept on a "listening socket" the socketoption is reflected on the port held by the listening socket.</p>
  
  <p>Ok some code.</p>
  
  <p>Server : Opens a socket, applies SO_REUSEADDR to be true. Accepts a connection and then applies SO_REUSEADDR to be false on the fd on the fd returned by accept.</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;arpa/inet.h&gt;
  #include &lt;string.h&gt;
  
  int main(void)
  {
          int s,  len;
          int sin_size;
          int reuse = 1;
          int ret;
          struct sockaddr_in my_addr;
  
          memset(&amp;my_addr, 0, sizeof(my_addr));
          my_addr.sin_family = AF_INET;
          my_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
          my_addr.sin_port = htons(33235);
  
          if( (s = socket(AF_INET, SOCK_STREAM, 0)) &lt; 0)
          {
                 printf("Socket Error\n");
                 return -1;
          }
  
          setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &amp;reuse, sizeof(int));
  
          if( bind(s, (struct sockaddr*)&amp;my_addr, sizeof(struct sockaddr))  &lt; 0)
          {
                 printf("Bind Error\n");
                 return -1;
          }
  
          listen(s, 6);
  
          reuse = 0;
          memset(&amp;my_addr, 0, sizeof(my_addr));
          while(1) {
             ret = accept(s, (struct sockaddr*)&amp;my_addr, &amp;len);
             if (ret&lt;0) {
                printf("Accept failed\n");
             } else {
                printf("Accepted a client setting reuse add to 0\n");
                setsockopt(ret, SOL_SOCKET, SO_REUSEADDR, &amp;reuse, sizeof(int));
             }
          }
  
          printf("Server exiting\n");
  
          return 0;
  }
  </code></pre>
  
  <p>Client : Client connects to the server, and doesn't do anything after that ensuring that the server socket stays in TIME_WAIT state. </p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;sys/socket.h&gt;
  #include &lt;sys/types.h&gt;
  #include &lt;arpa/inet.h&gt;
  #include &lt;string.h&gt;
  #include &lt;errno.h&gt;
  
  int main(void)
  {
          int s,  len;
          int sin_size;
          struct sockaddr_in my_addr;
  
          memset(&amp;my_addr, 0, sizeof(my_addr));
          my_addr.sin_family = AF_INET;
          my_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
          my_addr.sin_port = htons(33235);
  
          if( (s = socket(AF_INET, SOCK_STREAM, 0)) &lt; 0)
          {
                 printf("Socket Error\n");
                 return -1;
          }
  
          if (!connect(s,(struct sockaddr*)&amp;my_addr, sizeof(struct sockaddr)))
          {
             printf("Client Connected successfully\n");
          }
          else
          {
             printf("%s\n",strerror(errno));
          }
  
          while(1) sleep(1);
  
          return 0;
  }
  </code></pre>
  
  <p>Steps that I do reproduce the issue.</p>
  
  <ol>
  <li>Run server.</li>
  <li>Connect client.</li>
  <li>Kill and restart server. The server fails with Bind Failure</li>
  </ol>
  
  <p>I tested this on mac os. And the bind didn't fail. I have digged up all Posix specifications and none of them say that this code is undefined. </p>
  
  <p>Question:</p>
  
  <p>Can someone with more <em>experience</em> on this share their understanding of the issue?</p>