Log-in |

Please Note: Kernel Sockets is now part of Project Volo

The mercurial gate listed below only contains the original prototype. Please use the Volo gate to obtain the latest release.

<http://www.opensolaris.org/os/project/volo/>

Introduction

The goal of this project is to develop an interface for creating sockets within kernel modules.

Trying things out

Getting the source

You can obtain the source code for this project using Mercurial. The repository is:

    ssh://anon@hg.opensolaris.org/hg/kernel-sockets/ksocket

WARNING

This is work in progress, and the current interface is not stable, and the code is not fully tested. Therefore, it is very likely that there are bugs, some of which that could cause your system to crash

A guide on how to use Mercurial is available at:
<http://www.opensolaris.org/os/community/tools/scm/hg_help/>

Building the source

Detailed information on how to build ON is available at <http://www.opensolaris.org/os/community/on/devref_toc/>

Use the 20070312 closed bins.

Using Kernel Sockets

Please read the design document first! Some types have changed, but the document still gives an overview of what to expect from the interface.

Basic Interface

If you have done some network programming with sockets before, then the kernel socket interface should look very familiar (that was at least the goal!)

The basic interface is currently composed of the following functions:
    

 int ksock_socket(ksocket_t *s, int domain, int type, int protocol) 
 int ksock_bind(ksocket_t s, const struct sockaddr *addr, socklen_t addrlen) 
 int ksock_listen(ksocket_t s, int backlog) 
 int ksock_accept(ksocket_t s, ksocket_t ns, struct sockaddr addr, socklen_t *addrlen) 
 int ksock_connect(ksocket_t s, const struct sockaddr *addr, socklen_t addrlen) 
 int ksock_send(ksocket_t s, void msg, size_t msgsize, int flags, size_t sent) 
 int ksock_recv(ksocket_t s, void msg, size_t msgsize, int flags, size_t recvd) 
 int ksock_shutdown(ksocket_t s, int how) 
 int ksock_close(ksocket_t s) 
int ksock_setsockopt(ksocket_t s, int level, int optname, const void *optval, int optlen) 
 int ksock_getsockopt(ksocket_t s, int level, int optname, void optval, int optlen) 
 int ksock_getpeername(ksocket_t s, struct sockaddr addr, socklen_t addrlen) 
 int ksock_getsockname(ksocket_t s, struct sockaddr addr, socklen_t addrlen) 
 int ksock_ioctl(ksocket_t s, int cmd, intptr_t arg) 

All of the above functions return a result code that indicates whether the operation was successful. If an error was encountered, then the errno is returned, otherwise 0 is returned. Some userland socket functions (e.g., socket() and send()) return information other than error/success, and the kernel socket variant of those functions take an additional value-return argument.

For example, creating a new TCP socket would be done as follows:

    ksocket~_t s;
    int error;
    ...
    if ((error = ksock~_socket(&s, AF~_INET, SOCK~_STREAM, 0)) != 0)
            goto fail;

By default, kernel socket operations are blocking, however, that behavior
can be controlled using ksock_ioctl() (i.e, ksock~_ioctl(s, FIONBIO, &onoff)) Similarly, SIOCATMARK can be used to query about out of band data. However, there are several ioctls that are not allowed, specifically SIOCSPGRP, SIOCGPGRP and FIOASYNC. In addition, no STREAMs specific ioctls are supported (such as I_POP and I_PUSH)

Event Notification

As mentioned in the previous section, kernel sockets can be made non-blocking by using ksock_ioctl(), however, there is no select() or poll() functions that can be used to determine whether an event has take place. Instead, event notification is done asynchronously via a callback interface.

There are six events currently defined:

    /*
     \* Callback: connected
     \* Occurs:
     \*     When the socket have reached a connected state.
     \* Arguments:
     \*     s:        kernel socket the event occurred on
     \*     arg:      user supplied argument
     \*/
    typedef void (//ksock~_connected~_callback~_t)(ksocket~_t s, void //arg);  
    /\*
     \* Callback: disconnected
     \* Occurs:
     \*     When the socket have been disconnected.
     \* Arguments:
     \*     s:        kernel socket the event occurred on
     \*     arg:      user supplied argument
     \*     reason:   indication why the socket was disconnected.
     \*               0: Normal shutdown sequence; >0: errno (ie., ECONNRESET);
     \*               <0: Unknown reason
     \*/
    typedef void (//ksock~_disconnected~_callback~_t)(ksocket~_t s, void //arg, int reason);
    /\*
     \* Callback: newconn
     \* Occurs:
     \*     When a new connection has been added to the accept queue.
     \* Arguments:
     \*     s:        kernel socket the event occurred on
     \*     arg:      user supplied argument
     \*/
    typedef void (//ksock~_newconn~_callback~_t)(ksocket~_t s, void //arg);
    /\*
     \* Callback: recv
     \* Occurs:
     \*     When data has arrived or an event has occurred that affects the
     \*     ability to receive data.
     \* Arguments:
     \*     s:        kernel socket the event occurred on
     \*     arg:      user supplied argument
     \*     msglen:   0: end-of-file reached; >0: # bytes received; <0: unknown event
     \*/
    typedef void (//ksock~_recv~_callback~_t)(ksocket~_t s, void //arg, ssize_t msglen);
    /\*
     \* Callback: xmit
     \* Occurs:
     \*     When send buffers have been freed up so that new data can be
     \*     transmitted, or an event has occurred that affects the ability
     \*     to transmit data.
     \* Arguments:
     \*     s:        kernel socket the event occurred on
     \*     arg:      user supplied argument
     \*     freebuf:  0: unable to send more data; >0: # bytes that can be sent
     \*               without blocking; <0: unknown event
     \*/
    typedef void (//ksock~_xmit~_callback~_t)(ksocket~_t s, void //arg, ssize_t freebuf);
    /\*
     \* Callback: exception
     \* Occurs:
     \*     When there is an exception event (i.e. TCP urgent data has arrived)
     \* Arguments:
     \*     s:        kernel socket the event occurred on
     \*     arg:      user supplied argument
     \*     msglen:   transport specific event
     \*/
    typedef void (//ksock~_exception~_callback~_t)(ksocket~_t s, void //arg, uint32_t event);

Enabling callbacks for a specific socket would be done as follows:

    #include <sys/ksocket.h>
    ...
    ksock~_callbacks~_t xxx~_callbacks = {
        xxx~_connected,
        xxx~_disconnected,
        xxx~_newconn,
        xxx~_recv,
        xxx~_xmit,
        xxx~_exception
    };
    ...
    void foo(void)
    {
        ksocket~_t s;
        xxx~_data~_t *dp;        
        ...
        ksock~_callbacks(s, &xxx~_callbacks, dp);
        ...
    }

It is not required to have a callback for each event, leaving it as NULL will
disable the specific event. Also, disabling callbacks is done by passing in NULL to ksock_callbacks(). Callbacks will automatically be disabled when a socket is being closed (i.e., by using ksock_close()).

The amount of work done in a callback function should be limited, and it is specifically not allowed to use kernel socket functions. If heavy processing is needed, or if kernel socket functions need to be called (e.g., ksock_recv()), then another thread should be dispatched.

last modified by admin on 2009/10/26 12:14
Collectives
Project

Project kernel-sockets Pages

© Sun Microsystems Inc. 2009
XWiki Enterprise 1.8.2.19075 - Documentation
Terms Of Use | Privacy | Trademarks | Copyright Policy | Site Guidelines | Site map | Help
Your use of this web site or any of its content or software indicates your agreement to be bound by these Terms of Use.