OpenKODE Core extension: KD_ATX_socktype


NameATX_socktype
Name stringsKD_ATX_socktype
ContributorsTim Renouf
ContactsAntix Labs
StatusImplemented by Antix Labs
Version2
Number8
Dependencies Requires OpenKODE Core 1.0. This extension is written based on the wording of the OpenKODE Core 1.0 specification.

1. Overview

When drafting the Bluetooth extension, it became apparent that 20 Network sockets has some structural deficiencies when a new socket type needs to be added. The changes in this extension are intended to improve that situation, without changing any semantics of OpenKODE Core (other than defining a new type KDSockaddrAfInATX).

The changes fall into three areas:

  • Restructure of 20 Network sockets, consisting of a new section 20.2 Socket type and address families, which subsumes the old 20.3 Types, and a new section 20.3 TCP and UDP, which subsumes the old 20.2 Network connection.

  • Function changes to allow for the growth of KDSockaddr.

  • Function changes so that whether kdSocketListen is supported depends on the socket type.

2. Header file

This extension does not have an associated header file.

3. 20.2. Socket types and address families

This is a new section. (The text of the old 20.2 Network connection is subsumed into the new 20.3 TCP and UDP, below.)

Each socket type defined in OpenKODE core has some of the following characteristics:

If a socket type is connection based, then any communication is between two endpoints, one of which is the server (it calls kdSocketBind, kdSocketListen and kdSocketAccept), and the other is the client (it calls kdSocketConnect).

If a socket type is connectionless, then one device may send data to any other addressable device without connecting first.

If a socket type is reliable, then data sent arrives at its destination, uncorrupted and in order, otherwise an error is generated (although not necessarily by the function call that sent the lost data).

If a socket type is unreliable, then data sent does not necessarily arrive, or may arrive corrupted, or packets may arrive out of order. The application(s) must make their own arrangements to work round this.

If a socket type is stream oriented, then data is sent as a stream and the boundaries between different kdSocketSend or kdSocketSendTo calls are not preserved.

If a socket type is datagram oriented, then data is sent as a packet. The packet of data sent by a single kdSocketSend or kdSocketSendTo call is read as a single unit by a single kdSocketRecv or kdSocketRecvFrom call. If the receive call does not provide enough buffer space for the packet, then it is truncated and the truncated part is lost.

3.1. KDSockaddr

Struct type for socket address.

Synopsis

typedef struct KDSockaddr {
    KDuint16 family;
    union {
        KDSockaddrAfInATX sin;
    } data;
} KDSockaddr;

Description

This struct contains a socket address. The two top-level members are family, which specifies the address family, and data, which is a union where the union member in use depends on the address family.

See below for the address families supported by OpenKODE Core.

4. 20.3. TCP and UDP

This is a new section, which also subsumes the old 20.3 Types.

An OpenKODE Core implementation may support neither, one or both of TCP and UDP sockets. The socket type constants for use in kdSocketCreate are:

#define KD_SOCK_TCP 64
#define KD_SOCK_UDP 65

A TCP socket is connection based, reliable and stream oriented.

A UDP socket is connectionless, unreliable and datagram oriented.

Both TCP and UDP use the IP addressing family, and contribute the sin field (of the type KDSockaddrAfInATX defined here) to the KDSockaddr data union:

#define KD_AF_INET 70
typedef struct KDSockaddrAfInATX {
    KDuint16 port;
    KDuint32 address;
} KDSockaddrAfInATX;

For a KDSockaddr addr where addr.family is KD_AF_INET, the fields are set as follows:

addr.data.sin.port

Port number in network byte order

addr.data.sin.address

IP address in network byte order

Any special signficance attached to certain ranges of IP addresses is implementation specific. In particular, there is no guarantee that there is a loopback interface accessed with the IP address 127.0.0.1.

4.1. Network connection

If a name is looked up or a socket is created and used in such a way that the platform needs to establish a connection to a network that it is not permanently connected to (for example over the air), it is undefined at what point the connection is established.

4.2. Network connection implementation notes

It is recommended that the platform should not establish a connection that spends the user’s money any earlier than a call to kdNameLookup or a call to kdSocketConnect.

Where the underlying OS demands connection before the socket is created, the implementation could allow creation of the OpenKODE Core socket handle without creating an OS socket, and then asynchronously establish the network connection when the application calls kdSocketConnect. The implementation does not then create the OS socket until the network connection has been established, and the OpenKODE Core KD_EVENT_SOCKET_CONNECT_COMPLETE event is not generated until the network connection is established, the socket has been created, and the socket has been connected.

5. Function changes to allow for the growth of KDSockaddr

Adding a new socket type could cause KDSockaddr to grow in size. This could cause problems for any vendor wanting to provide binary backwards compatibility between versions of its implementation.

To allow a vendor to implement binary backwards compatibility, changes need to be made to the definition of how much of the KDSockaddr struct needs to be readable or writable in any OpenKODE Core function that takes a KDSockaddr pointer as a parameter.

Therefore this extension specifies the following changes:

5.1. KDSockaddr reading functions: kdSocketSendTo

For 20.4.10. kdSocketSendTo, this phrase at the end of the Description subsection:

or addr is not KD_NULL and does not point to a readable location of type KDSockaddr, then undefined behavior results.

is changed to

then undefined behavior results. If addr is not KD_NULL and does not point to a location of type KDSockaddr, readable for at least the length required such that the data union element(s) for socket type(s) that use the address family specified in the family field can be read, then undefined behavior results.

5.2. Other KDSockaddr reading functions

For each of the following functions: 20.4.5. kdSocketBind, 20.4.7. kdSocketConnect, this phrase at the end of the Description subsection:

or addr does not point to a readable location of type KDSockaddr, then undefined behavior results.

is changed to

then undefined behavior results. If addr does not point to a location of type KDSockaddr, readable for at least the length required such that the data union element(s) for socket type(s) that use the address family specified in the family field can be read, then undefined behavior results.

5.3. KDSockaddr writing functions: kdSocketRecvFrom

For 20.4.11. kdSocketRecvFrom, this phrase at the end of the Description subsection:

or addr is not KD_NULL and does not point to a writable location of type KDSockaddr, then undefined behavior results.

is changed to

then undefined behavior results. If addr is not KD_NULL and does not point to a location of type KDSockaddr, writable for at least the length required such that the data union element for the socket type of socket can be written, then undefined behavior results.

5.4. Other KDSockaddr writing functions

For each of the following functions: 20.4.6. kdSocketGetName, 20.4.9. kdSocketAccept, this phrase at the end of the Description subsection:

or addr does not point to a writable location of type KDSockaddr, then undefined behavior results.

is changed to

then undefined behavior results. If addr does not point to a location of type KDSockaddr, writable for at least the length required such that the data union element for the socket type of socket can be written, then undefined behavior results.

6. Other function changes

6.1. kdSocketListen not implemented for some socket types

kdSocketListen defines that an implementation is allowed not to support kdSocketListen, even if the rest of socket functionality is supported. In this case kdSocketListen gives an error of KD_ENOSYS.

This definition does not fit well with multiple socket types. Instead, whether it is allowed not to support socket listening should be specified per socket type.

To that end, the following changes are made:

In 20.4.8. kdSocketListen, Description subsection, remove the paragraph:

It is allowed for an OpenKODE Core implementation to support the rest of the socket API but not kdSocketListen. In that case, kdSocketListen always fails with an error of KD_ENOSYS.

In 20.4.8. kdSocketListen, Errors subsection, change the description for KD_ENOSYS to:

The socket is of a connection-based type, but this implementation does not support listening for it.

In the new 20.2.1. TCP and UDP section resulting from the earlier changes in this extension specification, add to the end of the “A TCP socket...” paragraph:

Being connection based, a TCP socket does support listening, however it is allowed for an OpenKODE Core implementation not to support TCP socket listening. In this case, using a TCP socket in kdSocketListen gives the error KD_ENOSYS.

7. Revision history

7.1. Version 2, 2008-11-17

  • Fixed erroneous types in KDSockaddrAfInATX, and some other typos.

7.2. Version 1, 2008-10-16

  • First draft.