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