X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/378393581903b274cb7a4d18e0d978071a6b592d..c18c124eaa464aaaa5549e99e5a70fc9cbb50944:/bsd/sys/kpi_socket.h?ds=sidebyside diff --git a/bsd/sys/kpi_socket.h b/bsd/sys/kpi_socket.h index 13c56414f..8a8f186b3 100644 --- a/bsd/sys/kpi_socket.h +++ b/bsd/sys/kpi_socket.h @@ -1,23 +1,29 @@ /* - * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2008-2012 Apple Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ - * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /*! @header kpi_socket.h @@ -33,27 +39,50 @@ #include #include +#include + +__BEGIN_DECLS struct timeval; /*! @typedef sock_upcall - + @discussion sock_upcall is used by a socket to notify an in kernel client that data is waiting. Instead of making blocking calls in the kernel, a client can specify an upcall which will be called when data is available or the socket is ready for sending. - + Calls to your upcall function are not serialized and may be called concurrently from multiple threads in the kernel. - - Your upcall function will be called when: - + + Your upcall function will be called: + when there is data more than the low water mark for reading, + or when there is space for a write, + or when there is a connection to accept, + or when a socket is connected, + or when a socket is closed or disconnected + @param so A reference to the socket that's ready. @param cookie The cookie passed in when the socket was created. @param waitf Indicates whether or not it's safe to block. */ -typedef void (*sock_upcall)(socket_t so, void* cookie, int waitf); +typedef void (*sock_upcall)(socket_t so, void *cookie, int waitf); + +#ifdef KERNEL_PRIVATE +/*! + @typedef sock_evupcall + + @discussion sock_evupcall is used by a socket to notify an in kernel + client when an event occurs. Instead of making blocking calls in + the kernel, a client can specify an upcall which will be called + when an event status is available. + @param so A reference to the socket that's ready. + @param cookie The cookie passed in when the socket was created. + @param int Indicates the event as defined by SO_FILT_HINT_* +*/ +typedef void (*sock_evupcall)(socket_t so, void *cookie, u_int32_t event); +#endif /* KERNEL_PRIVATE */ /*! @function sock_accept @@ -76,9 +105,8 @@ typedef void (*sock_upcall)(socket_t so, void* cookie, int waitf); socket for tracking the connection. @result 0 on success otherwise the errno error. */ -errno_t sock_accept(socket_t so, struct sockaddr *from, int fromlen, - int flags, sock_upcall callback, void* cookie, - socket_t *new_so); +extern errno_t sock_accept(socket_t so, struct sockaddr *from, int fromlen, + int flags, sock_upcall callback, void *cookie, socket_t *new_so); /*! @function sock_bind @@ -88,7 +116,7 @@ errno_t sock_accept(socket_t so, struct sockaddr *from, int fromlen, @param to The local address the socket should be bound to. @result 0 on success otherwise the errno error. */ -errno_t sock_bind(socket_t so, const struct sockaddr *to); +extern errno_t sock_bind(socket_t so, const struct sockaddr *to); /*! @function sock_connect @@ -104,18 +132,18 @@ errno_t sock_bind(socket_t so, const struct sockaddr *to); @result 0 on success, EINPROGRESS for a non-blocking connect that has not completed, otherwise the errno error. */ -errno_t sock_connect(socket_t so, const struct sockaddr *to, int flags); +extern errno_t sock_connect(socket_t so, const struct sockaddr *to, int flags); #ifdef KERNEL_PRIVATE -/*! +/* This function was added to support NFS. NFS does something funny, setting a short timeout and checking to see if it should abort the connect every two seconds. Ideally, NFS would use the upcall to be notified when the connect is complete. - + If you feel you need to use this function, please contact us to explain why. - + @function sock_connectwait @discussion Allows a caller to wait on a socket connect. @param so The socket being connected. @@ -124,8 +152,8 @@ errno_t sock_connect(socket_t so, const struct sockaddr *to, int flags); returned if the connection did not complete in the timeout specified. */ -errno_t sock_connectwait(socket_t so, const struct timeval *tv); -#endif KERNEL_PRIVATE +extern errno_t sock_connectwait(socket_t so, const struct timeval *tv); +#endif /* KERNEL_PRIVATE */ /*! @function sock_getpeername @@ -136,7 +164,8 @@ errno_t sock_connectwait(socket_t so, const struct timeval *tv); @param peernamelen Length of storage for the peer name. @result 0 on success otherwise the errno error. */ -errno_t sock_getpeername(socket_t so, struct sockaddr *peername, int peernamelen); +extern errno_t sock_getpeername(socket_t so, struct sockaddr *peername, + int peernamelen); /*! @function sock_getsockname @@ -147,7 +176,8 @@ errno_t sock_getpeername(socket_t so, struct sockaddr *peername, int peernamelen @param socknamelen Length of storage for the socket name. @result 0 on success otherwise the errno error. */ -errno_t sock_getsockname(socket_t so, struct sockaddr *sockname, int socknamelen); +extern errno_t sock_getsockname(socket_t so, struct sockaddr *sockname, + int socknamelen); /*! @function sock_getsockopt @@ -159,7 +189,8 @@ errno_t sock_getsockname(socket_t so, struct sockaddr *sockname, int socknamelen @param optlen The length of optval, returns the actual length. @result 0 on success otherwise the errno error. */ -errno_t sock_getsockopt(socket_t so, int level, int optname, void *optval, int *optlen); +extern errno_t sock_getsockopt(socket_t so, int level, int optname, + void *optval, int *optlen); /*! @function sock_ioctl @@ -169,7 +200,7 @@ errno_t sock_getsockopt(socket_t so, int level, int optname, void *optval, int * @param argp The argument. @result 0 on success otherwise the errno error. */ -errno_t sock_ioctl(socket_t so, unsigned long request, void *argp); +extern errno_t sock_ioctl(socket_t so, unsigned long request, void *argp); /*! @function sock_setsockopt @@ -181,7 +212,53 @@ errno_t sock_ioctl(socket_t so, unsigned long request, void *argp); @param optlen The length of optval. @result 0 on success otherwise the errno error. */ -errno_t sock_setsockopt(socket_t so, int level, int optname, const void *optval, int optlen); +extern errno_t sock_setsockopt(socket_t so, int level, int optname, + const void *optval, int optlen); + +#ifdef KERNEL_PRIVATE +/* + This function was added to support AFP setting the traffic class + for a backup stream within a wireless LAN or over link-local address. + + If you feel you need to use this function, please contact us to + explain why. + + @function sock_settclassopt + @discussion Allows a caller to set the traffic class. + @param so The socket. + @param optval The option value. + @param optlen The length of optval. + @result 0 on success otherwise the errno error. + */ +extern errno_t sock_settclassopt(socket_t so, const void* optval, size_t optlen); + +/* + This function was added to support AFP getting the traffic class + set on a stream. + + This is also a private API, please contact us if you need to use it. + + @function sockgettclassopt + @discussion Allows a caller to get the traffic class. + @param so The socket. + @param optval The option value. + @param optlen The length of optval, returns the actual length. + @result 0 on success otherwise the errno error. +*/ +extern errno_t sock_gettclassopt(socket_t so, void* optval, size_t* optlen); + +#ifdef XNU_KERNEL_PRIVATE +extern void socket_set_traffic_mgt_flags_locked(socket_t so, u_int32_t flags); +extern void socket_clear_traffic_mgt_flags_locked(socket_t so, u_int32_t flags); +#endif /* XNU_KERNEL_PRIVATE */ +#ifdef BSD_KERNEL_PRIVATE +extern void socket_set_traffic_mgt_flags(socket_t so, u_int32_t flags); +extern void socket_clear_traffic_mgt_flags(socket_t so, u_int32_t flags); +extern errno_t socket_defunct(struct proc *, socket_t so, int); +extern errno_t sock_receive_internal(socket_t, struct msghdr *, mbuf_t *, + int, size_t *); +#endif /* BSD_KERNEL_PRIVATE */ +#endif /* KERNEL_PRIVATE */ /*! @function sock_listen @@ -191,7 +268,7 @@ errno_t sock_setsockopt(socket_t so, int level, int optname, const void *optval, @param backlog The maximum length of the queue of pending connections. @result 0 on success otherwise the errno error. */ -errno_t sock_listen(socket_t so, int backlog); +extern errno_t sock_listen(socket_t so, int backlog); /*! @function sock_receive @@ -205,7 +282,8 @@ errno_t sock_listen(socket_t so, int backlog); @result 0 on success, EWOULDBLOCK if non-blocking and operation would cause the thread to block, otherwise the errno error. */ -errno_t sock_receive(socket_t so, struct msghdr *msg, int flags, size_t *recvdlen); +extern errno_t sock_receive(socket_t so, struct msghdr *msg, int flags, + size_t *recvdlen); /*! @function sock_receivembuf @@ -225,7 +303,8 @@ errno_t sock_receive(socket_t so, struct msghdr *msg, int flags, size_t *recvdle @result 0 on success, EWOULDBLOCK if non-blocking and operation would cause the thread to block, otherwise the errno error. */ -errno_t sock_receivembuf(socket_t so, struct msghdr *msg, mbuf_t *data, int flags, size_t *recvlen); +extern errno_t sock_receivembuf(socket_t so, struct msghdr *msg, mbuf_t *data, + int flags, size_t *recvlen); /*! @function sock_send @@ -239,7 +318,8 @@ errno_t sock_receivembuf(socket_t so, struct msghdr *msg, mbuf_t *data, int flag @result 0 on success, EWOULDBLOCK if non-blocking and operation would cause the thread to block, otherwise the errno error. */ -errno_t sock_send(socket_t so, const struct msghdr *msg, int flags, size_t *sentlen); +extern errno_t sock_send(socket_t so, const struct msghdr *msg, int flags, + size_t *sentlen); /*! @function sock_sendmbuf @@ -255,17 +335,20 @@ errno_t sock_send(socket_t so, const struct msghdr *msg, int flags, size_t *sent would cause the thread to block, otherwise the errno error. Regardless of return value, the mbuf chain 'data' will be freed. */ -errno_t sock_sendmbuf(socket_t so, const struct msghdr *msg, mbuf_t data, int flags, size_t *sentlen); +extern errno_t sock_sendmbuf(socket_t so, const struct msghdr *msg, mbuf_t data, + int flags, size_t *sentlen); /*! @function sock_shutdown @discussion Shutdown one or both directions of a connection. See 'man 2 shutdown' for more information. @param so The socket. - @param how SHUT_RD - shutdown receive. SHUT_WR - shutdown send. SHUT_RDWR - shutdown both. + @param how SHUT_RD - shutdown receive. + SHUT_WR - shutdown send. + SHUT_RDWR - shutdown both. @result 0 on success otherwise the errno error. */ -errno_t sock_shutdown(socket_t so, int how); +extern errno_t sock_shutdown(socket_t so, int how); /*! @function sock_socket @@ -281,20 +364,21 @@ errno_t sock_shutdown(socket_t so, int how); @param new_so Upon success, a reference to the new socket. @result 0 on success otherwise the errno error. */ -errno_t sock_socket(int domain, int type, int protocol, sock_upcall callback, - void* cookie, socket_t *new_so); +extern errno_t sock_socket(int domain, int type, int protocol, + sock_upcall callback, void *cookie, socket_t *new_so); /*! @function sock_close @discussion Close the socket. @param so The socket to close. This should only ever be a socket created with sock_socket. Closing a socket created in user space - using sock_close may leave a file descriptor pointing to the closed - socket, resulting in undefined behavior. + using sock_close may leave a file descriptor pointing to the + closed socket, resulting in undefined behavior. */ -void sock_close(socket_t so); +extern void sock_close(socket_t so); -/*! +#ifdef KERNEL_PRIVATE +/* @function sock_retain @discussion Prevents the socket from closing @param so The socket to close. Increment a retain count on the @@ -304,9 +388,9 @@ void sock_close(socket_t so); that socket. It is used in conjunction with sock_release(socket_t so). */ -void sock_retain(socket_t so); +extern void sock_retain(socket_t so); -/*! +/* @function sock_release @discussion Decrement the retain count and close the socket if the retain count reaches zero. @@ -314,7 +398,8 @@ void sock_retain(socket_t so); on a socket acquired with sock_retain. When the last retain count is reached, this will call sock_close to close the socket. */ -void sock_release(socket_t so); +extern void sock_release(socket_t so); +#endif /* KERNEL_PRIVATE */ /*! @function sock_setpriv @@ -324,7 +409,7 @@ void sock_release(socket_t so); @param on Indicate whether or not the SS_PRIV flag should be set. @result 0 on success otherwise the errno error. */ -errno_t sock_setpriv(socket_t so, int on); +extern errno_t sock_setpriv(socket_t so, int on); /*! @function sock_isconnected @@ -332,20 +417,20 @@ errno_t sock_setpriv(socket_t so, int on); @param so The socket to check. @result 0 - socket is not connected. 1 - socket is connected. */ -int sock_isconnected(socket_t so); +extern int sock_isconnected(socket_t so); /*! @function sock_isnonblocking @discussion Returns whether or not the socket is non-blocking. In the context of this KPI, non-blocking means that functions to perform operations on a socket will not wait for completion. - + To enable or disable blocking, use the FIONBIO ioctl. The parameter is an int. If the int is zero, the socket will block. If the parameter is non-zero, the socket will not block. @result 0 - socket will block. 1 - socket will not block. */ -int sock_isnonblocking(socket_t so); +extern int sock_isnonblocking(socket_t so); /*! @function sock_gettype @@ -354,15 +439,15 @@ int sock_isnonblocking(socket_t so); parameters following so are NULL, that information is not retrieved. @param so The socket to check. - @param domain The domain of the socket (PF_INET, etc...). May be NULL. - @param type The socket type (SOCK_STREAM, SOCK_DGRAM, etc...). May be NULL. + @param domain The domain of the socket (PF_INET, ...). May be NULL. + @param type The socket type (SOCK_STREAM, SOCK_DGRAM, ...). May be NULL. @param protocol The socket protocol. May be NULL. @result 0 on success otherwise the errno error. */ -errno_t sock_gettype(socket_t so, int *domain, int *type, int *protocol); +extern errno_t sock_gettype(socket_t so, int *domain, int *type, int *protocol); #ifdef KERNEL_PRIVATE -/*! +/* @function sock_nointerrupt @discussion Disables interrupt on socket buffers (sets SB_NOINTR on send and receive socket buffers). @@ -370,6 +455,111 @@ errno_t sock_gettype(socket_t so, int *domain, int *type, int *protocol); @param on Indicate whether or not the SB_NOINTR flag should be set. @result 0 on success otherwise the errno error. */ -errno_t sock_nointerrupt(socket_t so, int on); -#endif KERNEL_PRIVATE -#endif __KPI_SOCKET__ +extern errno_t sock_nointerrupt(socket_t so, int on); + +/* + @function sock_getlistener + @discussion Retrieves the listening socket of a pre-accepted socket, + i.e. a socket which is still in the incomplete/completed list. + Once a socket has been accepted, the information pertaining + to its listener is no longer available. Therefore, modules + interested in finding out the listening socket should install + the appropriate socket filter callback (sf_attach) which gets + invoked prior to the socket being fully accepted, and call + this routine at such a time to obtain the listener. Callers + are guaranteed that the listener socket will not go away + during the sf_attach callback, and therefore the value is + safe to be used only in that callback context. Callers should + therefore take note that the listening socket's lock will be + held throughout the duration of the callback. + @param so The pre-accepted socket. + @result Non-NULL value which indicates the listening socket; otherwise, + NULL if the socket is not in the incomplete/completed list + of a listener. + */ +extern socket_t sock_getlistener(socket_t so); + +/* + @function sock_getaddr + @discussion Retrieves the local or remote address of a socket. + This is a composite of sock_getpeername and sock_getsockname, + except that the allocated socket address is returned to the + caller, and that the caller is reponsible for calling + sock_freeaddr once finished with it. + @param so The socket. + @param psockname Pointer to the storage for the socket name. + @param peername 0 for local address, and non-zero for peer address. + @result 0 on success otherwise the errno error. + */ +extern errno_t sock_getaddr(socket_t so, struct sockaddr **psockname, + int peername); + +/* + @function sock_freeaddr + @discussion Frees the socket address allocated by sock_getaddr. + @param sockname The socket name to be freed. + */ +extern void sock_freeaddr(struct sockaddr *sockname); + +/* + @function sock_setupcall + @discussion Set the notifier function to be called when an event + occurs on the socket. This may be set to NULL to disable + further notifications. Setting the function does not + affect currently notifications about to be sent or being sent. + Note: When this function is used on a socket passed from + userspace it is crucial to call sock_retain() on the socket + otherwise a callback could be dispatched on a closed socket + and cause a crash. + @param sock The socket. + @param callback The notifier function + @param context A cookie passed directly to the callback +*/ +extern errno_t sock_setupcall(socket_t sock, sock_upcall callback, + void *context); + +/* + @function sock_setupcalls + @discussion Set the notifier function to be called when an event + occurs on the socket. This may be set to NULL to disable + further notifications. Setting the function does not + affect currently notifications about to be sent or being sent. + Note: When this function is used on a socket passed from + userspace it is crucial to call sock_retain() on the socket + otherwise a callback could be dispatched on a closed socket + and cause a crash. + @param sock The socket. + @param read_callback The read notifier function + @param read_context A cookie passed directly to the read callback + @param write_callback The write notifier function + @param write_context A cookie passed directly to the write callback +*/ +extern errno_t sock_setupcalls(socket_t sock, sock_upcall read_callback, + void *read_context, sock_upcall write_callback, void *write_context); + +/* + @function sock_catchevents + @discussion Set the notifier function to be called when an event + occurs on the socket. This may be set to NULL to disable + further notifications. Setting the function does not + affect currently notifications about to be sent or being sent. + @param sock The socket. + @param event_callback The event notifier function + @param event_context A cookie passed directly to the event callback + @param event_mask One or more SO_FILT_HINT_* values OR'ed together, + indicating the registered event(s). +*/ +extern errno_t sock_catchevents(socket_t sock, sock_evupcall event_callback, + void *event_context, u_int32_t event_mask); +/* + @function sock_iskernel + @discussion Returns true if the socket was created by the kernel or + is owned by the kernel. + @param sock The socket. + @result True if the kernel owns the socket. +*/ +extern int sock_iskernel(socket_t); +#endif /* KERNEL_PRIVATE */ + +__END_DECLS +#endif /* __KPI_SOCKET__ */