1 /* 2 * Copyright (c) 2008-2017 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28 /*! 29 * @header kpi_socket.h 30 * This header defines an API for creating and interacting with sockets 31 * in the kernel. It is possible to create sockets in the kernel 32 * without an associated file descriptor. In some cases, a reference to 33 * the socket may be known while the file descriptor is not. These 34 * functions can be used for interacting with sockets in the kernel. 35 * The API is similar to the user space socket API. 36 */ 37 #ifndef __KPI_SOCKET__ 38 #define __KPI_SOCKET__ 39 40 #include <sys/types.h> 41 #include <sys/kernel_types.h> 42 #include <sys/socket.h> 43 #include <sys/ioccom.h> 44 45 #ifndef PRIVATE 46 #include <Availability.h> 47 #define __NKE_API_DEPRECATED __API_DEPRECATED("Network Kernel Extension KPI is deprecated", macos(10.4, 10.15)) 48 #else 49 #define __NKE_API_DEPRECATED 50 #endif /* PRIVATE */ 51 52 __BEGIN_DECLS 53 54 struct timeval; 55 56 /*! 57 * @typedef sock_upcall 58 * 59 * @discussion sock_upcall is used by a socket to notify an in kernel 60 * client that data is waiting. Instead of making blocking calls in 61 * the kernel, a client can specify an upcall which will be called 62 * when data is available or the socket is ready for sending. 63 * 64 * Calls to your upcall function are not serialized and may be 65 * called concurrently from multiple threads in the kernel. 66 * 67 * Your upcall function will be called: 68 * when there is data more than the low water mark for reading, 69 * or when there is space for a write, 70 * or when there is a connection to accept, 71 * or when a socket is connected, 72 * or when a socket is closed or disconnected 73 * 74 * @param so A reference to the socket that's ready. 75 * @param cookie The cookie passed in when the socket was created. 76 * @param waitf Indicates whether or not it's safe to block. 77 */ 78 typedef void (*sock_upcall)(socket_t so, void *cookie, int waitf); 79 80 #ifdef KERNEL_PRIVATE 81 /*! 82 * @typedef sock_evupcall 83 * 84 * @discussion sock_evupcall is used by a socket to notify an in kernel 85 * client when an event occurs. Instead of making blocking calls in 86 * the kernel, a client can specify an upcall which will be called 87 * when an event status is available. 88 * @param so A reference to the socket that's ready. 89 * @param cookie The cookie passed in when the socket was created. 90 * @param event Indicates the event as defined by SO_FILT_HINT_* 91 */ 92 typedef void (*sock_evupcall)(socket_t so, void *cookie, uint32_t event); 93 #endif /* KERNEL_PRIVATE */ 94 95 /*! 96 * @function sock_accept 97 * @discussion Accepts an incoming connection on a socket. See 'man 2 98 * accept' for more information. Allocating a socket in this manner 99 * creates a socket with no associated file descriptor. 100 * @param so The listening socket you'd like to accept a connection on. 101 * @param from A pointer to a socket address that will be filled in 102 * with the address the connection is from. 103 * @param fromlen Maximum length of from. 104 * @param flags Supports MSG_DONTWAIT and MSG_USEUPCALL. If 105 * MSG_DONTWAIT is set, accept will return EWOULDBLOCK if there are 106 * no connections ready to be accepted. If MSG_USEUPCALL is set, 107 * the created socket will use the same upcall function attached to 108 * the original socket. 109 * @param callback A notifier function to be called when an event 110 * occurs on the socket. This may be NULL. 111 * @param cookie A cookie passed directly to the callback. 112 * @param new_so Upon success, *new_so will be a reference to a new 113 * socket for tracking the connection. 114 * @result 0 on success otherwise the errno error. 115 */ 116 #ifdef KERNEL_PRIVATE 117 extern errno_t sock_accept_internal(socket_t so, struct sockaddr *__sized_by(fromlen) from, int fromlen, 118 int flags, sock_upcall callback, void *cookie, socket_t *new_so); 119 120 #define sock_accept(so, from, fromlen, flags, callback, cookie, new_so) \ 121 sock_accept_internal((so), (from), (fromlen), (flags), (callback), \ 122 (cookie), (new_so)) 123 #else 124 extern errno_t sock_accept(socket_t so, struct sockaddr *__sized_by(fromlen) from, int fromlen, 125 int flags, sock_upcall callback, void *cookie, socket_t *new_so) 126 __NKE_API_DEPRECATED; 127 #endif /* KERNEL_PRIVATE */ 128 129 /*! 130 * @function sock_bind 131 * @discussion Binds a socket to a specific address. See 'man 2 bind' 132 * for more information. 133 * @param so The socket to be bound. 134 * @param to The local address the socket should be bound to. 135 * @result 0 on success otherwise the errno error. 136 */ 137 extern errno_t sock_bind(socket_t so, const struct sockaddr *to) 138 __NKE_API_DEPRECATED; 139 140 /*! 141 * @function sock_connect 142 * @discussion Initiates a connection on the socket. See 'man 2 143 * connect' for more information. 144 * @param so The socket to be connect. 145 * @param to The remote address the socket should connect to. 146 * @param flags Flags for connecting. The only flag supported so far is 147 * MSG_DONTWAIT. MSG_DONTWAIT will perform a non-blocking connect. 148 * sock_connect will return immediately with EINPROGRESS. The 149 * upcall, if supplied, will be called when the connection is 150 * completed. 151 * @result 0 on success, EINPROGRESS for a non-blocking connect that 152 * has not completed, otherwise the errno error. 153 */ 154 extern errno_t sock_connect(socket_t so, const struct sockaddr *to, int flags) 155 __NKE_API_DEPRECATED; 156 157 #ifdef KERNEL_PRIVATE 158 /* 159 * This function was added to support NFS. NFS does something funny, 160 * setting a short timeout and checking to see if it should abort the 161 * connect every two seconds. Ideally, NFS would use the upcall to be 162 * notified when the connect is complete. 163 * 164 * If you feel you need to use this function, please contact us to 165 * explain why. 166 * 167 * @function sock_connectwait 168 * @discussion Allows a caller to wait on a socket connect. 169 * @param so The socket being connected. 170 * @param tv The amount of time to wait. 171 * @result 0 on success otherwise the errno error. EINPROGRESS will be 172 * returned if the connection did not complete in the timeout 173 * specified. 174 */ 175 extern errno_t sock_connectwait(socket_t so, const struct timeval *tv); 176 #endif /* KERNEL_PRIVATE */ 177 178 /*! 179 * @function sock_getpeername 180 * @discussion Retrieves the remote address of a connected socket. See 181 * 'man 2 getpeername'. 182 * @param so The socket. 183 * @param peername Storage for the peer name. 184 * @param peernamelen Length of storage for the peer name. 185 * @result 0 on success otherwise the errno error. 186 */ 187 extern errno_t sock_getpeername(socket_t so, struct sockaddr *__sized_by(peernamelen) peername, 188 int peernamelen) 189 __NKE_API_DEPRECATED; 190 191 /*! 192 * @function sock_getsockname 193 * @discussion Retrieves the local address of a socket. See 'man 2 194 * getsockname'. 195 * @param so The socket. 196 * @param sockname Storage for the local name. 197 * @param socknamelen Length of storage for the socket name. 198 * @result 0 on success otherwise the errno error. 199 */ 200 extern errno_t sock_getsockname(socket_t so, struct sockaddr *__sized_by(socknamelen) sockname, 201 int socknamelen) 202 __NKE_API_DEPRECATED; 203 204 /*! 205 * @function sock_getsockopt 206 * @discussion Retrieves a socket option. See 'man 2 getsockopt'. 207 * @param so The socket. 208 * @param level Level of the socket option. 209 * @param optname The option name. 210 * @param optval The option value. 211 * @param optlen The length of optval, returns the actual length. 212 * @result 0 on success otherwise the errno error. 213 */ 214 extern errno_t sock_getsockopt(socket_t so, int level, int optname, 215 void *optval, int *optlen) 216 __NKE_API_DEPRECATED; 217 218 /*! 219 * @function sock_ioctl 220 * @discussion Performs an ioctl operation on a socket. See 'man 2 ioctl'. 221 * @param so The socket. 222 * @param request The ioctl name. 223 * @param argp The argument. 224 * @result 0 on success otherwise the errno error. 225 */ 226 extern errno_t sock_ioctl(socket_t so, unsigned long request, void *__sized_by(IOCPARM_LEN(request)) argp) 227 __NKE_API_DEPRECATED; 228 229 /*! 230 * @function sock_setsockopt 231 * @discussion Sets a socket option. See 'man 2 setsockopt'. 232 * @param so The socket. 233 * @param level Level of the socket option. 234 * @param optname The option name. 235 * @param optval The option value. 236 * @param optlen The length of optval. 237 * @result 0 on success otherwise the errno error. 238 */ 239 extern errno_t sock_setsockopt(socket_t so, int level, int optname, 240 const void *optval, int optlen) 241 __NKE_API_DEPRECATED; 242 243 #ifdef KERNEL_PRIVATE 244 /* 245 * This function was added to support AFP setting the traffic class 246 * for a backup stream within a wireless LAN or over link-local address. 247 * 248 * If you feel you need to use this function, please contact us to 249 * explain why. 250 * 251 * @function sock_settclassopt 252 * @discussion Allows a caller to set the traffic class. 253 * @param so The socket. 254 * @param optval The option value. 255 * @param optlen The length of optval. 256 * @result 0 on success otherwise the errno error. 257 */ 258 extern errno_t sock_settclassopt(socket_t so, const void* optval, size_t optlen); 259 260 /* 261 * This function was added to support AFP getting the traffic class 262 * set on a stream. 263 * 264 * This is also a private API, please contact us if you need to use it. 265 * 266 * @function sockgettclassopt 267 * @discussion Allows a caller to get the traffic class. 268 * @param so The socket. 269 * @param optval The option value. 270 * @param optlen The length of optval, returns the actual length. 271 * @result 0 on success otherwise the errno error. 272 */ 273 extern errno_t sock_gettclassopt(socket_t so, void* optval, size_t* optlen); 274 275 #ifdef XNU_KERNEL_PRIVATE 276 extern void socket_set_traffic_mgt_flags_locked(socket_t so, u_int8_t flags); 277 extern void socket_clear_traffic_mgt_flags_locked(socket_t so, u_int8_t flags); 278 #endif /* XNU_KERNEL_PRIVATE */ 279 #ifdef BSD_KERNEL_PRIVATE 280 extern void socket_set_traffic_mgt_flags(socket_t so, u_int8_t flags); 281 extern void socket_clear_traffic_mgt_flags(socket_t so, u_int8_t flags); 282 extern errno_t socket_defunct(struct proc *, socket_t so, int); 283 extern errno_t sock_receive_internal(socket_t, struct msghdr *, mbuf_t *, 284 int, size_t *); 285 #endif /* BSD_KERNEL_PRIVATE */ 286 #endif /* KERNEL_PRIVATE */ 287 288 /*! 289 * @function sock_listen 290 * @discussion Indicate that the socket should start accepting incoming 291 * connections. See 'man 2 listen'. 292 * @param so The socket. 293 * @param backlog The maximum length of the queue of pending connections. 294 * @result 0 on success otherwise the errno error. 295 */ 296 extern errno_t sock_listen(socket_t so, int backlog) 297 __NKE_API_DEPRECATED; 298 299 /*! 300 * @function sock_receive 301 * @discussion Receive data from a socket. Similar to recvmsg. See 'man 302 * 2 recvmsg' for more information about receiving data. 303 * @param so The socket. 304 * @param msg The msg describing how the data should be received. 305 * @param flags See 'man 2 recvmsg'. 306 * @param recvdlen Number of bytes received, same as return value of 307 * userland recvmsg. 308 * @result 0 on success, EWOULDBLOCK if non-blocking and operation 309 * would cause the thread to block, otherwise the errno error. 310 */ 311 extern errno_t sock_receive(socket_t so, struct msghdr *msg, int flags, 312 size_t *recvdlen) 313 __NKE_API_DEPRECATED; 314 315 /*! 316 * @function sock_receivembuf 317 * @discussion Receive data from a socket. Similar to sock_receive 318 * though data is returned as a chain of mbufs. See 'man 2 recvmsg' 319 * for more information about receiving data. 320 * @param so The socket. 321 * @param msg The msg describing how the data should be received. May 322 * be NULL. The msg_iov is ignored. 323 * @param data Upon return *data will be a reference to an mbuf chain 324 * containing the data received. This eliminates copying the data 325 * out of the mbufs. Caller is responsible for freeing the mbufs. 326 * @param flags See 'man 2 recvmsg'. 327 * @param recvlen Maximum number of bytes to receive in the mbuf chain. 328 * Upon return, this value will be set to the number of bytes 329 * received, same as return value of userland recvmsg. 330 * @result 0 on success, EWOULDBLOCK if non-blocking and operation 331 * would cause the thread to block, otherwise the errno error. 332 */ 333 extern errno_t sock_receivembuf(socket_t so, struct msghdr *msg, mbuf_t *data, 334 int flags, size_t *recvlen) 335 __NKE_API_DEPRECATED; 336 337 /*! 338 * @function sock_send 339 * @discussion Send data on a socket. Similar to sendmsg. See 'man 2 340 * sendmsg' for more information about sending data. 341 * @param so The socket. 342 * @param msg The msg describing how the data should be sent. Any 343 * pointers must point to data in the kernel. 344 * @param flags See 'man 2 sendmsg'. 345 * @param sentlen The number of bytes sent. 346 * @result 0 on success, EWOULDBLOCK if non-blocking and operation 347 * would cause the thread to block, otherwise the errno error. 348 */ 349 extern errno_t sock_send(socket_t so, const struct msghdr *msg, int flags, 350 size_t *sentlen) 351 __NKE_API_DEPRECATED; 352 353 /*! 354 * @function sock_sendmbuf 355 * @discussion Send data in an mbuf on a socket. Similar to sock_send 356 * only the data to be sent is taken from the mbuf chain. 357 * @param so The socket. 358 * @param msg The msg describing how the data should be sent. The 359 * msg_iov is ignored. msg may be NULL. 360 * @param data The mbuf chain of data to send. 361 * @param flags See 'man 2 sendmsg'. 362 * @param sentlen The number of bytes sent. 363 * @result 0 on success, EWOULDBLOCK if non-blocking and operation 364 * would cause the thread to block, otherwise the errno error. 365 * Regardless of return value, the mbuf chain 'data' will be freed. 366 */ 367 extern errno_t sock_sendmbuf(socket_t so, const struct msghdr *msg, mbuf_t data, 368 int flags, size_t *sentlen) 369 __NKE_API_DEPRECATED; 370 371 #ifdef KERNEL_PRIVATE 372 /*! 373 * @function sock_sendmbuf_can_wait 374 * @discussion Variation of sock_sendmbuf that can wait for the send socket 375 * buffer to drain when it is full instead of returning EMSGSIZE. 376 * @param so The socket. 377 * @param msg The msg describing how the data should be sent. The 378 * msg_iov is ignored. msg may be NULL. 379 * @param data The mbuf chain of data to send. 380 * @param flags See 'man 2 sendmsg'. 381 * @param sentlen The number of bytes sent. 382 * @result 0 on success, EWOULDBLOCK if non-blocking and operation 383 * would cause the thread to block, otherwise the errno error. 384 * Regardless of return value, the mbuf chain 'data' will be freed. 385 */ 386 extern errno_t sock_sendmbuf_can_wait(socket_t so, const struct msghdr *msg, mbuf_t data, 387 int flags, size_t *sentlen); 388 #define HAS_SOCK_SENDMBUF_CAN_WAIT 1 389 390 #endif /* KERNEL_PRIVATE */ 391 392 /*! 393 * @function sock_shutdown 394 * @discussion Shutdown one or both directions of a connection. See 395 * 'man 2 shutdown' for more information. 396 * @param so The socket. 397 * @param how SHUT_RD - shutdown receive. 398 * SHUT_WR - shutdown send. 399 * SHUT_RDWR - shutdown both. 400 * @result 0 on success otherwise the errno error. 401 */ 402 extern errno_t sock_shutdown(socket_t so, int how) 403 __NKE_API_DEPRECATED; 404 405 /*! 406 * @function sock_socket 407 * @discussion Allocate a socket. Allocating a socket in this manner 408 * creates a socket with no associated file descriptor. For more 409 * information, see 'man 2 socket'. 410 * @param domain The socket domain (PF_INET, etc...). 411 * @param type The socket type (SOCK_STREAM, SOCK_DGRAM, etc...). 412 * @param protocol The socket protocol. 413 * @param callback A notifier function to be called when an event 414 * occurs on the socket. This may be NULL. 415 * @param cookie A cookie passed directly to the callback. 416 * @param new_so Upon success, a reference to the new socket. 417 * @result 0 on success otherwise the errno error. 418 */ 419 #ifdef KERNEL_PRIVATE 420 extern errno_t sock_socket_internal(int domain, int type, int protocol, 421 sock_upcall callback, void *cookie, socket_t *new_so); 422 423 #define sock_socket(domain, type, protocol, callback, cookie, new_so) \ 424 sock_socket_internal((domain), (type), (protocol), \ 425 (callback), (cookie), (new_so)) 426 #else 427 extern errno_t sock_socket(int domain, int type, int protocol, 428 sock_upcall callback, void *cookie, socket_t *new_so) 429 __NKE_API_DEPRECATED; 430 #endif /* KERNEL_PRIVATE */ 431 432 /*! 433 * @function sock_close 434 * @discussion Close the socket. 435 * @param so The socket to close. This should only ever be a socket 436 * created with sock_socket. Closing a socket created in user space 437 * using sock_close may leave a file descriptor pointing to the 438 * closed socket, resulting in undefined behavior. 439 */ 440 extern void sock_close(socket_t so) 441 __NKE_API_DEPRECATED; 442 443 /* 444 * @function sock_retain 445 * @discussion Prevents the socket from closing 446 * @param so The socket to close. Increment a retain count on the 447 * socket, preventing it from being closed when sock_close is 448 * called. This is used when a File Descriptor is passed (and 449 * closed) from userland and the kext wants to keep ownership of 450 * that socket. It is used in conjunction with 451 * sock_release(socket_t so). 452 */ 453 extern void sock_retain(socket_t so) 454 __NKE_API_DEPRECATED; 455 456 /* 457 * @function sock_release 458 * @discussion Decrement the retain count and close the socket if the 459 * retain count reaches zero. 460 * @param so The socket to release. This is used to release ownership 461 * on a socket acquired with sock_retain. When the last retain 462 * count is reached, this will call sock_close to close the socket. 463 */ 464 extern void sock_release(socket_t so) 465 __NKE_API_DEPRECATED; 466 467 /*! 468 * @function sock_setpriv 469 * @discussion Set the privileged bit in the socket. Allows for 470 * operations that require root privileges. 471 * @param so The socket on which to modify the SS_PRIV flag. 472 * @param on Indicate whether or not the SS_PRIV flag should be set. 473 * @result 0 on success otherwise the errno error. 474 */ 475 extern errno_t sock_setpriv(socket_t so, int on) 476 __NKE_API_DEPRECATED; 477 478 /*! 479 * @function sock_isconnected 480 * @discussion Returns whether or not the socket is connected. 481 * @param so The socket to check. 482 * @result 0 - socket is not connected. 1 - socket is connected. 483 */ 484 extern int sock_isconnected(socket_t so) 485 __NKE_API_DEPRECATED; 486 487 /*! 488 * @function sock_isnonblocking 489 * @discussion Returns whether or not the socket is non-blocking. In 490 * the context of this KPI, non-blocking means that functions to 491 * perform operations on a socket will not wait for completion. 492 * 493 * To enable or disable blocking, use the FIONBIO ioctl. The 494 * parameter is an int. If the int is zero, the socket will block. 495 * If the parameter is non-zero, the socket will not block. 496 * @result 0 - socket will block. 1 - socket will not block. 497 */ 498 extern int sock_isnonblocking(socket_t so) 499 __NKE_API_DEPRECATED; 500 501 /*! 502 * @function sock_gettype 503 * @discussion Retrieves information about the socket. This is the same 504 * information that was used to create the socket. If any of the 505 * parameters following so are NULL, that information is not 506 * retrieved. 507 * @param so The socket to check. 508 * @param domain The domain of the socket (PF_INET, ...). May be NULL. 509 * @param type The socket type (SOCK_STREAM, SOCK_DGRAM, ...). May be NULL. 510 * @param protocol The socket protocol. May be NULL. 511 * @result 0 on success otherwise the errno error. 512 */ 513 extern errno_t sock_gettype(socket_t so, int *domain, int *type, int *protocol) 514 __NKE_API_DEPRECATED; 515 516 #ifdef KERNEL_PRIVATE 517 /* 518 * @function sock_nointerrupt 519 * @discussion Disables interrupt on socket buffers (sets SB_NOINTR on 520 * send and receive socket buffers). 521 * @param so The socket to modify. 522 * @param on Indicate whether or not the SB_NOINTR flag should be set. 523 * @result 0 on success otherwise the errno error. 524 */ 525 extern errno_t sock_nointerrupt(socket_t so, int on); 526 527 /* 528 * @function sock_getlistener 529 * @discussion Retrieves the listening socket of a pre-accepted socket, 530 * i.e. a socket which is still in the incomplete/completed list. 531 * Once a socket has been accepted, the information pertaining 532 * to its listener is no longer available. Therefore, modules 533 * interested in finding out the listening socket should install 534 * the appropriate socket filter callback (sf_attach) which gets 535 * invoked prior to the socket being fully accepted, and call 536 * this routine at such a time to obtain the listener. Callers 537 * are guaranteed that the listener socket will not go away 538 * during the sf_attach callback, and therefore the value is 539 * safe to be used only in that callback context. Callers should 540 * therefore take note that the listening socket's lock will be 541 * held throughout the duration of the callback. 542 * @param so The pre-accepted socket. 543 * @result Non-NULL value which indicates the listening socket; otherwise, 544 * NULL if the socket is not in the incomplete/completed list 545 * of a listener. 546 */ 547 extern socket_t sock_getlistener(socket_t so); 548 549 /* 550 * @function sock_getaddr 551 * @discussion Retrieves the local or remote address of a socket. 552 * This is a composite of sock_getpeername and sock_getsockname, 553 * except that the allocated socket address is returned to the 554 * caller, and that the caller is reponsible for calling 555 * sock_freeaddr once finished with it. 556 * @param so The socket. 557 * @param psockname Pointer to the storage for the socket name. 558 * @param peername 0 for local address, and non-zero for peer address. 559 * @result 0 on success otherwise the errno error. 560 */ 561 extern errno_t sock_getaddr(socket_t so, struct sockaddr **psockname, 562 int peername); 563 564 /* 565 * @function sock_freeaddr 566 * @discussion Frees the socket address allocated by sock_getaddr. 567 * @param sockname The socket name to be freed. 568 */ 569 extern void sock_freeaddr(struct sockaddr *sockname); 570 571 /* 572 * @function sock_setupcall 573 * @discussion Set the notifier function to be called when an event 574 * occurs on the socket. This may be set to NULL to disable 575 * further notifications. Setting the function does not 576 * affect currently notifications about to be sent or being sent. 577 * Note: When this function is used on a socket passed from 578 * userspace it is crucial to call sock_retain() on the socket 579 * otherwise a callback could be dispatched on a closed socket 580 * and cause a crash. 581 * @param sock The socket. 582 * @param callback The notifier function 583 * @param context A cookie passed directly to the callback 584 */ 585 extern errno_t sock_setupcall(socket_t sock, sock_upcall callback, 586 void *context); 587 588 /* 589 * @function sock_setupcalls 590 * @discussion Set the notifier function to be called when an event 591 * occurs on the socket. This may be set to NULL to disable 592 * further notifications. Setting the function does not 593 * affect currently notifications about to be sent or being sent. 594 * Note: When this function is used on a socket passed from 595 * userspace it is crucial to call sock_retain() on the socket 596 * otherwise a callback could be dispatched on a closed socket 597 * and cause a crash. 598 * @param sock The socket. 599 * @param read_callback The read notifier function 600 * @param read_context A cookie passed directly to the read callback 601 * @param write_callback The write notifier function 602 * @param write_context A cookie passed directly to the write callback 603 */ 604 extern errno_t sock_setupcalls(socket_t sock, sock_upcall read_callback, 605 void *read_context, sock_upcall write_callback, void *write_context); 606 607 /* 608 * @function sock_setupcalls_locked 609 * @discussion The locked version of sock_setupcalls 610 * @param locked: When sets, indicates that the callbacks expect to be 611 * on a locked socket. Thus, no unlock is done prior to 612 * calling the callback. 613 */ 614 extern void sock_setupcalls_locked(socket_t sock, 615 sock_upcall rcallback, void *rcontext, 616 sock_upcall wcallback, void *wcontext, int locked); 617 618 /* 619 * @function sock_catchevents 620 * @discussion Set the notifier function to be called when an event 621 * occurs on the socket. This may be set to NULL to disable 622 * further notifications. Setting the function does not 623 * affect currently notifications about to be sent or being sent. 624 * @param sock The socket. 625 * @param event_callback The event notifier function 626 * @param event_context A cookie passed directly to the event callback 627 * @param event_mask One or more SO_FILT_HINT_* values OR'ed together, 628 * indicating the registered event(s). 629 */ 630 extern errno_t sock_catchevents(socket_t sock, sock_evupcall event_callback, 631 void *event_context, uint32_t event_mask); 632 633 extern void sock_catchevents_locked(socket_t sock, sock_evupcall ecallback, 634 void *econtext, uint32_t emask); 635 636 637 /* 638 * @function sock_iskernel 639 * @discussion Returns true if the socket was created by the kernel or 640 * is owned by the kernel. 641 * @param sock The socket. 642 * @result True if the kernel owns the socket. 643 */ 644 extern int sock_iskernel(socket_t); 645 #endif /* KERNEL_PRIVATE */ 646 647 __END_DECLS 648 #undef __NKE_API_DEPRECATED 649 #endif /* __KPI_SOCKET__ */ 650