This is the mail archive of the ecos-discuss@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Socket leak when accept() is aborted by TCP RST?


On 2010-07-28, Grant Edwards <grant.b.edwards@gmail.com> wrote:
> On 2010-07-28, Andrew Lunn <andrew@lunn.ch> wrote:

>>> Where should the socket be freed?  In bsd_accept() where it is removed
>>> from the queue?  Or in socket.cxx when the fd/fp are freed?
>>
>> I would say in bsd_accept(). However, it would be good to find the
>> FreeBSD code equivalent of this code and see where it frees the
>> socket.
>
> I'm not sure, but I think it was done by the call to fdrop() that's
> #if'ed out with a // FIXME comment in the eCos version:
>
>      1  //==========================================================================
>      2  //
>      3  //      src/sys/kern/sockio.c
>   [...]
>    289  static int 
>    290  bsd_accept(cyg_file *fp, cyg_file *new_fp,
>    291             struct sockaddr *name, socklen_t *anamelen)
>    292  {
>   [...]
>    413  noconnection:
>    414  
>    415  #if 0 // FIXME
>    416          /*
>    417           * close the new descriptor, assuming someone hasn't ripped it
>    418           * out from under us.
>    419           */
>    420          if (error) {
>    421                  if (fdp->fd_ofiles[fd] == nfp) {
>    422                          fdp->fd_ofiles[fd] = NULL;
>    423                          fdrop(nfp, p);
>    424                  }
>    425          }
>    426          splx(s);
>    427  
>    428          /*
>    429           * Release explicitly held references before returning.
>    430           */
>    431  done:
>    432          if (nfp != NULL)
>    433                  fdrop(nfp, p);
>    434          fdrop(lfp, p);
>    435          return (error);
>    436      m_freem(nam);
>    437  #else
>    438   done:
>    439      splx(s);
>    440      if (sa)
>    441          FREE(sa, M_SONAME);
>    442  #endif
>    443      
>    444      return (error);
>    445  }
>
> In recent versions of FreeBSD, the fdrop() call appears to have been
> replace by a call to fdclose() which in turn calls fdrop().
>    
> I'm 90% convinced that it should be done before the done: label at
> line 438, but I haven't yet figured out how to do it.  Neither
> sofree(so) nor soclose(so) seem to have any effect.  Perhaps there's a
> reference count somewhere I have to decrement?

setting the SS_NOFDREF so_state flag before calling sofree() seems to
work.

Is there some reason we need to keep the above code that's elided by
the #if 0?

While looking at the rest of that same function, I noticed another
block of #if'ed out code with a // FIXME comment.

Does anybody know what it is that needs fixing below?

   334	    /*
   335	     * At this point we know that there is at least one connection
   336	     * ready to be accepted. Remove it from the queue prior to
   337	     * allocating the file descriptor for it since falloc() may
   338	     * block allowing another process to accept the connection
   339	     * instead.
   340	     */
   341	    so = TAILQ_FIRST(&head->so_comp);
   342	    TAILQ_REMOVE(&head->so_comp, so, so_list);
   343	    head->so_qlen--;
   344	
   345	#if 0 // FIXME
   346	    fflag = lfp->f_flag;
   347	    error = falloc(p, &nfp, &fd);
   348	    if (error) {
   349	        /*
   350	         * Probably ran out of file descriptors. Put the
   351	         * unaccepted connection back onto the queue and
   352	         * do another wakeup so some other process might
   353	         * have a chance at it.
   354	         */
   355	        TAILQ_INSERT_HEAD(&head->so_comp, so, so_list);
   356	        head->so_qlen++;
   357	        wakeup_one(&head->so_timeo);
   358	        splx(s);
   359	        goto done;
   360	    }
   361	    fhold(nfp);
   362	    p->p_retval[0] = fd;
   363	
   364	    /* connection has been removed from the listen queue */
   365	    KNOTE(&head->so_rcv.sb_sel.si_note, 0);
   366	#endif
   367	
   368	    so->so_state &= ~SS_COMP;
   369	    so->so_head = NULL;

-- 
Grant Edwards               grant.b.edwards        Yow! I have seen these EGG
                                  at               EXTENDERS in my Supermarket
                              gmail.com            ... I have read the
                                                   INSTRUCTIONS ...


-- 
Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos
and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]