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 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{ |
3057 struct socket *head; 3058 int ret; |
3059 |
3060restart: |
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(); |
3080 soupcall_set(so, SO_RCV, 3081 head->so_accf->so_accept_filter->accf_callback, 3082 head->so_accf->so_accept_filter_arg); |
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); |
3088 SOCK_UNLOCK(so); |
3089 if (ret == SU_ISCONNECTED) 3090 goto restart; |
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/* |
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 --- |