git: accept: Save foreign address earlier, if protocol supports

看板DFBSD_commit作者時間14年前 (2011/12/28 02:04), 編輯推噓0(000)
留言0則, 0人參與, 最新討論串1/1
commit 88da6203404cc737cdbc49d09c95a3ea552ef7e3 Author: Sepherosa Ziehau <sephe@dragonflybsd.org> Date: Tue Nov 29 21:38:34 2011 +0800 accept: Save foreign address earlier, if protocol supports it - Add so_faddr into socket, which records the accepted socket's foreign address. If it is set, kern_accept() will use it directly instead of calling protocol specific method to extract the foreign address. - Add protocol specific method, pru_safefaddr, which will save the foreign address into socket.so_faddr if the necessary information is supplied. This protocol method will only be called in protocol thread. - Pass the foreign address to sonewconn() if possible, so the foreign address could be saved before the accepted socket is put onto the complete list. Currently only IPv4/TCP implemented pru_savefaddr This intends to address the following problems: - Calling pru_accept directly from user context is not MPSAFE, we always races the socket.so_pcb check->use against protocol thread clear/free socket.so_pcb, though the race window is too tiny to be hit. To make it mpsafe, we should dispatch pru_accept to protocol thread. If socket.so_faddr is set here, we are race against nothing and nothing expensive like put the current user thread into sleep will happen. However, if the socket is dropped when it still sits on the complete list, the error will not be timely delivered, i.e. accept(2) will not return error, but the later on read(2)/write(2) on the socket will deliver the error. - Calling pru_accept directly races against the inpcb.inp_f{addr,port} setting up in the protocol thread, since inpcb.inp_f{addr,port} is setup _after_ the accepted socket was put onto the complete list. user thread proto thread : : : accepted socket -> comp : (inpcb.inp_f{addr,port} are 0 here) comp -> socket : pru_accept : : setup inpcb.inp_f{addr,port} Returning of 0.0.0.0:0 from accept(2) was observed on heavily loaded web servers. Summary of changes: sys/kern/uipc_socket.c | 14 +++++++++++--- sys/kern/uipc_socket2.c | 16 +++++++++++++++- sys/kern/uipc_syscalls.c | 10 +++++++++- sys/netinet/in_pcb.c | 17 +++++++++++++++++ sys/netinet/in_pcb.h | 1 + sys/netinet/tcp_syncache.c | 25 +++++++++++++++++-------- sys/netinet/tcp_usrreq.c | 9 ++++++++- sys/sys/protosw.h | 7 +++++++ sys/sys/socketvar.h | 4 ++++ 9 files changed, 89 insertions(+), 14 deletions(-) http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/88da6203404cc737cdbc49d09c95a3ea552ef7e3 -- DragonFly BSD source repository
文章代碼(AID): #1E-WYlNw (DFBSD_commit)