uipc_socket.c (191917) | uipc_socket.c (193272) |
---|---|
1/*- 2 * Copyright (c) 1982, 1986, 1988, 1990, 1993 3 * The Regents of the University of California. 4 * Copyright (c) 2004 The FreeBSD Foundation 5 * Copyright (c) 2004-2008 Robert N. M. Watson 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 81 unchanged lines hidden (view full) --- 90 * calls to explicitly manage socket references, soref(), and sorele(). 91 * Currently, these are generally required only when transitioning a socket 92 * from a listen queue to a file descriptor, in order to prevent garbage 93 * collection of the socket at an untimely moment. For a number of reasons, 94 * these interfaces are not preferred, and should be avoided. 95 */ 96 97#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1982, 1986, 1988, 1990, 1993 3 * The Regents of the University of California. 4 * Copyright (c) 2004 The FreeBSD Foundation 5 * Copyright (c) 2004-2008 Robert N. M. Watson 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 81 unchanged lines hidden (view full) --- 90 * calls to explicitly manage socket references, soref(), and sorele(). 91 * Currently, these are generally required only when transitioning a socket 92 * from a listen queue to a file descriptor, in order to prevent garbage 93 * collection of the socket at an untimely moment. For a number of reasons, 94 * these interfaces are not preferred, and should be avoided. 95 */ 96 97#include <sys/cdefs.h> |
98__FBSDID("$FreeBSD: head/sys/kern/uipc_socket.c 191917 2009-05-08 14:34:25Z zec $"); | 98__FBSDID("$FreeBSD: head/sys/kern/uipc_socket.c 193272 2009-06-01 21:17:03Z jhb $"); |
99 100#include "opt_inet.h" 101#include "opt_inet6.h" 102#include "opt_mac.h" 103#include "opt_zero.h" 104#include "opt_compat.h" 105 106#include <sys/param.h> --- 2942 unchanged lines hidden (view full) --- 3049 so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING); 3050 so->so_state |= SS_ISCONNECTING; 3051 SOCK_UNLOCK(so); 3052} 3053 3054void 3055soisconnected(struct socket *so) 3056{ | 99 100#include "opt_inet.h" 101#include "opt_inet6.h" 102#include "opt_mac.h" 103#include "opt_zero.h" 104#include "opt_compat.h" 105 106#include <sys/param.h> --- 2942 unchanged lines hidden (view full) --- 3049 so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING); 3050 so->so_state |= SS_ISCONNECTING; 3051 SOCK_UNLOCK(so); 3052} 3053 3054void 3055soisconnected(struct socket *so) 3056{ |
3057 struct socket *head; | 3057 struct socket *head; 3058 int ret; |
3058 | 3059 |
3060restart: |
|
3059 ACCEPT_LOCK(); 3060 SOCK_LOCK(so); 3061 so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING); 3062 so->so_state |= SS_ISCONNECTED; 3063 head = so->so_head; 3064 if (head != NULL && (so->so_qstate & SQ_INCOMP)) { 3065 if ((so->so_options & SO_ACCEPTFILTER) == 0) { 3066 SOCK_UNLOCK(so); 3067 TAILQ_REMOVE(&head->so_incomp, so, so_list); 3068 head->so_incqlen--; 3069 so->so_qstate &= ~SQ_INCOMP; 3070 TAILQ_INSERT_TAIL(&head->so_comp, so, so_list); 3071 head->so_qlen++; 3072 so->so_qstate |= SQ_COMP; 3073 ACCEPT_UNLOCK(); 3074 sorwakeup(head); 3075 wakeup_one(&head->so_timeo); 3076 } else { 3077 ACCEPT_UNLOCK(); | 3061 ACCEPT_LOCK(); 3062 SOCK_LOCK(so); 3063 so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING); 3064 so->so_state |= SS_ISCONNECTED; 3065 head = so->so_head; 3066 if (head != NULL && (so->so_qstate & SQ_INCOMP)) { 3067 if ((so->so_options & SO_ACCEPTFILTER) == 0) { 3068 SOCK_UNLOCK(so); 3069 TAILQ_REMOVE(&head->so_incomp, so, so_list); 3070 head->so_incqlen--; 3071 so->so_qstate &= ~SQ_INCOMP; 3072 TAILQ_INSERT_TAIL(&head->so_comp, so, so_list); 3073 head->so_qlen++; 3074 so->so_qstate |= SQ_COMP; 3075 ACCEPT_UNLOCK(); 3076 sorwakeup(head); 3077 wakeup_one(&head->so_timeo); 3078 } else { 3079 ACCEPT_UNLOCK(); |
3078 so->so_upcall = 3079 head->so_accf->so_accept_filter->accf_callback; 3080 so->so_upcallarg = head->so_accf->so_accept_filter_arg; 3081 so->so_rcv.sb_flags |= SB_UPCALL; | 3080 soupcall_set(so, SO_RCV, 3081 head->so_accf->so_accept_filter->accf_callback, 3082 head->so_accf->so_accept_filter_arg); |
3082 so->so_options &= ~SO_ACCEPTFILTER; | 3083 so->so_options &= ~SO_ACCEPTFILTER; |
3084 ret = head->so_accf->so_accept_filter->accf_callback(so, 3085 head->so_accf->so_accept_filter_arg, M_DONTWAIT); 3086 if (ret == SU_ISCONNECTED) 3087 soupcall_clear(so, SO_RCV); |
|
3083 SOCK_UNLOCK(so); | 3088 SOCK_UNLOCK(so); |
3084 so->so_upcall(so, so->so_upcallarg, M_DONTWAIT); | 3089 if (ret == SU_ISCONNECTED) 3090 goto restart; |
3085 } 3086 return; 3087 } 3088 SOCK_UNLOCK(so); 3089 ACCEPT_UNLOCK(); 3090 wakeup(&so->so_timeo); 3091 sorwakeup(so); 3092 sowwakeup(so); --- 48 unchanged lines hidden (view full) --- 3141 3142 sa2 = malloc(sa->sa_len, M_SONAME, mflags); 3143 if (sa2) 3144 bcopy(sa, sa2, sa->sa_len); 3145 return sa2; 3146} 3147 3148/* | 3091 } 3092 return; 3093 } 3094 SOCK_UNLOCK(so); 3095 ACCEPT_UNLOCK(); 3096 wakeup(&so->so_timeo); 3097 sorwakeup(so); 3098 sowwakeup(so); --- 48 unchanged lines hidden (view full) --- 3147 3148 sa2 = malloc(sa->sa_len, M_SONAME, mflags); 3149 if (sa2) 3150 bcopy(sa, sa2, sa->sa_len); 3151 return sa2; 3152} 3153 3154/* |
3155 * Register per-socket buffer upcalls. 3156 */ 3157void 3158soupcall_set(struct socket *so, int which, 3159 int (*func)(struct socket *, void *, int), void *arg) 3160{ 3161 struct sockbuf *sb; 3162 3163 switch (which) { 3164 case SO_RCV: 3165 sb = &so->so_rcv; 3166 break; 3167 case SO_SND: 3168 sb = &so->so_snd; 3169 break; 3170 default: 3171 panic("soupcall_set: bad which"); 3172 } 3173 SOCKBUF_LOCK_ASSERT(sb); 3174#if 0 3175 /* XXX: accf_http actually wants to do this on purpose. */ 3176 KASSERT(sb->sb_upcall == NULL, ("soupcall_set: overwriting upcall")); 3177#endif 3178 sb->sb_upcall = func; 3179 sb->sb_upcallarg = arg; 3180 sb->sb_flags |= SB_UPCALL; 3181} 3182 3183void 3184soupcall_clear(struct socket *so, int which) 3185{ 3186 struct sockbuf *sb; 3187 3188 switch (which) { 3189 case SO_RCV: 3190 sb = &so->so_rcv; 3191 break; 3192 case SO_SND: 3193 sb = &so->so_snd; 3194 break; 3195 default: 3196 panic("soupcall_clear: bad which"); 3197 } 3198 SOCKBUF_LOCK_ASSERT(sb); 3199 KASSERT(sb->sb_upcall != NULL, ("soupcall_clear: no upcall to clear")); 3200 sb->sb_upcall = NULL; 3201 sb->sb_upcallarg = NULL; 3202 sb->sb_flags &= ~SB_UPCALL; 3203} 3204 3205/* |
|
3149 * Create an external-format (``xsocket'') structure using the information in 3150 * the kernel-format socket structure pointed to by so. This is done to 3151 * reduce the spew of irrelevant information over this interface, to isolate 3152 * user code from changes in the kernel structure, and potentially to provide 3153 * information-hiding if we decide that some of this information should be 3154 * hidden from users. 3155 */ 3156void --- 162 unchanged lines hidden --- | 3206 * Create an external-format (``xsocket'') structure using the information in 3207 * the kernel-format socket structure pointed to by so. This is done to 3208 * reduce the spew of irrelevant information over this interface, to isolate 3209 * user code from changes in the kernel structure, and potentially to provide 3210 * information-hiding if we decide that some of this information should be 3211 * hidden from users. 3212 */ 3213void --- 162 unchanged lines hidden --- |