Module sock - Socket library

Socket library.

The occam socket library uses the blocking system call functionality within KRoC to allow socket operations to be performed asynchronously.

The interfaces in this module are wrappers around the POSIX sockets interface; see socket(2) and related manual pages for more information on their semantics. The wrappers are not complete; in particular, protocols other than IPv4 TCP and UDP are not currently supported.

It is sometimes useful to be able to terminate a blocking call before it finishes, or to ALT on its completion. To support this, some PROCs are provided in both "normal" and "ALTable" versions. The ALTable versions have two extra channel parameters which may be used to terminate the call.

To terminate a blocking call, the process running in parallel with the call sends a signal down the kill channel. It should then await a response from the response channel indicating the outcome of the kill:

  • -2: the call had completed normally before it received the kill signal
  • -1: the call had already finished, and the kill had no effect
  • 0: the call was terminated successfully
  • 1: the call was in the process of terminating, and the kill had no effect
  • 2: the call had started terminating, and the kill had no effect

When the call terminates normally, i.e. upon completion, a value of -2 is sent down the response channel. The process should indicate to the blocking call that it may terminate by sending a signal down the kill channel. The net result is that however the call terminates, a value should be expected from response, and a signal should be sent down kill.

A read from a socket, with a timeout, may be implemented thus:

CHAN OF BOOL kill:
 CHAN OF INT response:
 PAR
   --{{{  blocking call
   socket.altable.read (kill, response, sock, buffer, bytes, result)
   --}}}
   --{{{  wait for response or timeout
   TIMER tim:
   INT t:
   SEQ
     tim ? t
     ALT
       --{{{  incoming response for normal termination
       INT any:
       response ? any
         kill ! TRUE
       --}}}
       --{{{  timeout (after 1 second)
       tim ? AFTER (t PLUS 1000000)
         INT k.result:
         SEQ
           kill ! TRUE
           response ? k.result
           -- take action on k.result if necessary
       --}}}
   --}}}

To use this library:

#INCLUDE "sock.module"

Index

Declarations

socklib.inc:36Record SOCKET

DATA TYPE SOCKET

The information which is known about a socket.

For most purposes, the address family will be AF.INET for IPv4, the socket type will be either SOCK.STREAM for TCP or SOCK.DGRAM for UDP, and the protocol will be IPPROTO.TCP for TCP or IPPROTO.UDP for UDP.

This structure does not accurately reflect the true types of the two port and addr members. Ports are typically unsigned 16-bit numbers, while addresses are unsigned 32-bit numbers (for IPV4 at least). They are incorrect for ease of compatability with the corresponding structure in the C code; in addition, occam does not provide unsigned 16-bit or 32-bit types.

socklib.inc:38Variable fd

INT

File descriptor

socklib.inc:39Variable local.port

INT

Local port number

socklib.inc:40Variable remote.port

INT

Remote port number

socklib.inc:41Variable local.addr

INT

Local IPv4 address, in host order

socklib.inc:42Variable remote.addr

INT

Remote IPv4 address, in host order

socklib.inc:43Variable s.family

INT

Socket family (one of AF)

socklib.inc:44Variable s.type

INT

Socket type (one of SOCK)

socklib.inc:45Variable s.proto

INT

IP protocol (one of IPPROTO)

socklib.inc:46Variable error

INT

The error code of the last operation on this socket, if it failed

socklib.inc:50Group SOCK

Socket types

socklib.inc:53Constant SOCK.STREAM

VAL SOCK.STREAM

Stream sockets (like TCP)

socklib.inc:55Constant SOCK.DGRAM

VAL SOCK.DGRAM

Datagram sockets (like UDP)

socklib.inc:62Group AF

Address families

socklib.inc:68Constant AF.INET

VAL AF.INET

IPv4

socklib.inc:93Group PF

Protocol families

socklib.inc:99Constant PF.INET

VAL PF.INET

IPv4

socklib.inc:124Group IPPROTO

IP protocols

socklib.inc:132Constant IPPROTO.TCP

VAL IPPROTO.TCP

TCP

socklib.inc:136Constant IPPROTO.UDP

VAL IPPROTO.UDP

UDP

socklib.inc:157Group IPPORT

Well-known TCP and UDP ports

socklib.inc:187Group INADDR

IPv4 addresses

socklib.inc:190Constant INADDR.ANY

VAL INADDR.ANY

Any IPv4 address, when binding

socklib.inc:192Constant INADDR.BROADCAST

VAL INADDR.BROADCAST

Broadcast to all reachable hosts

socklib.inc:195Constant INADDR.LOOPBACK

VAL INADDR.LOOPBACK

The local machine, via the loopback interface

socklib.inc:202Group OPTION

Boolean values for socket.setsockopt

socklib.inc:205Constant OPTION.OFF

VAL OPTION.OFF

Boolean option turned off

socklib.inc:207Constant OPTION.ON

VAL OPTION.ON

Boolean option turned on

socklib.inc:210Group SOL

Option levels for socket.setsockopt

socklib.inc:214Constant SOL.SOCKET

VAL SOL.SOCKET

Options for sockets of all protocols

socklib.inc:216Constant SOL.TCP

VAL SOL.TCP

Options for TCP sockets

socklib.inc:218Constant SOL.UDP

VAL SOL.UDP

Options for UDP sockets

socklib.inc:234Group SO

Generic options for socket.setsockopt

socklib.inc:237Constant SO.DEBUG

VAL SO.DEBUG

Enable debug tracing

socklib.inc:239Constant SO.REUSEADDR

VAL SO.REUSEADDR

Allow addresses to be reused when binding

socklib.inc:241Constant SO.TYPE

VAL SO.TYPE

Get socket type

socklib.inc:243Constant SO.ERROR

VAL SO.ERROR

Get pending error and clear

socklib.inc:245Constant SO.DONTROUTE

VAL SO.DONTROUTE

Bypass routing table lookup

socklib.inc:247Constant SO.BROADCAST

VAL SO.BROADCAST

Allow transmission to broadcast addresses

socklib.inc:249Constant SO.SNDBUF

VAL SO.SNDBUF

Send buffer size

socklib.inc:251Constant SO.RCVBUF

VAL SO.RCVBUF

Receive buffer size

socklib.inc:253Constant SO.KEEPALIVE

VAL SO.KEEPALIVE

Send keep-alive messages periodically

socklib.inc:255Constant SO.OOBINLINE

VAL SO.OOBINLINE

Leave received out-of-band data inline

socklib.inc:263Constant SO.RCVLOWAT

VAL SO.RCVLOWAT

Receive buffer low-water mark

socklib.inc:265Constant SO.SNDLOWAT

VAL SO.SNDLOWAT

Send buffer low-water mark

socklib.inc:270Group TCP

TCP-related options for socket.setsockopt

socklib.inc:273Constant TCP.NODELAY

VAL TCP.NODELAY

Disable Nagle algorithm (don't delay small packets)

socklib.inc:276Constant TCP.CORK

VAL TCP.CORK

While set, pause sending of partial frames

socklib.inc:279Constant TCP.KEEPINTVL

VAL TCP.KEEPINTVL

Seconds between keep-alive messages

socklib.inc:284Constant TCP.DEFER.ACCEPT

VAL TCP.DEFER.ACCEPT

Defer accept until data arrives

socklib.inc:290Group MSG

Flag constants for socket.sendto and socket.recvfrom

socklib.inc:310Group SHUT

Mode constants for socket.shutdown

socklib.inc:313Constant SHUT.RD

VAL SHUT.RD

Disallow further receives

socklib.inc:315Constant SHUT.WR

VAL SHUT.WR

Disallow further sends

socklib.inc:317Constant SHUT.RDWR

VAL SHUT.RDWR

Disallow further sends and receives

socklib.occ:181Process socket.create

PROC socket.create (RESULT SOCKET sock, VAL INT domain, VAL INT type, VAL INT protocol)

Create a socket. If the socket is successfully created, a valid file descriptor will be in the fd field of the returned socket, otherwise it will contain -1. Example:

SOCKET sock:
 SEQ
   create.socket (sock, PF.INET, SOCK.STREAM, IPPROTO.TCP)
   IF
     sock[fd] = -1
       SEQ
         -- failed to create the socket
         STOP
     TRUE
       SKIP

Parameters:

RESULT SOCKET sock The returned socket
VAL INT domain Address family (one of AF)
VAL INT type Socket type (one of SOCK)
VAL INT protocol IP protocol (one of IPPROTO)

socklib.occ:194Process socket.close

PROC socket.close (SOCKET sock)

Close a socket. No result is provided. The socket is shut down before being closed to cause the return of any parallel readers/writers.

Parameters:

SOCKET sock The socket to close

socklib.occ:213Process socket.read

PROC socket.read (SOCKET sock, []BYTE buffer, VAL INT count, INT result)

Read from a socket. Read as much data as is currently available from a socket into a buffer.

Parameters:

SOCKET sock Socket to read from
[]BYTE buffer Buffer to write data to
VAL INT count The maximum amount of data to read
INT result -1 on error, 0 on end-of-file (remote connection closed), otherwise the number of bytes read into buffer (which may be less than count)

socklib.occ:230Process socket.fullread

PROC socket.fullread (SOCKET sock, []BYTE buffer, VAL INT count, INT result)

Read a fixed number of bytes from a socket. Read exactly count bytes from a socket into a buffer. This is equivalent to repeatedly calling socket.read until the requested number of bytes have been read.

Parameters:

SOCKET sock Socket to read from
[]BYTE buffer Buffer to write data to
VAL INT count The amount of data to read
INT result -1 on error, 0 on end-of-file (remote connection closed), otherwise the number of bytes read into buffer

socklib.occ:243Process socket.write

PROC socket.write (SOCKET sock, VAL []BYTE buffer, INT result)

Write to a socket. Write as much data as possible from the buffer to the socket.

Parameters:

SOCKET sock Socket to write to
VAL []BYTE buffer Buffer to read from
INT result -1 on error, otherwise the number of bytes written (which may be less than the length of buffer)

socklib.occ:258Process socket.fullwrite

PROC socket.fullwrite (SOCKET sock, VAL []BYTE buffer, INT result)

Write a fixed number of bytes to a socket. Write the entirety of buffer to a socket. This is equivalent to repeatedly calling socket.write until the entire buffer has been written.

Parameters:

SOCKET sock Socket to write to
VAL []BYTE buffer Buffer to read from
INT result -1 on error, otherwise the number of bytes written

socklib.occ:277Process socket.write.addr

PROC socket.write.addr (SOCKET sock, VAL INT addr, size, INT result)

Write data from memory to a socket (unsafe). Similar to socket.write, but reading data directly from the given memory address.

As this operation accesses memory directly, it is inherently unsafe, and should not be used in most occam programs.

Deprecated: do not use in new code.

Parameters:

SOCKET sock Socket to write to
VAL INT addr Memory address to read from
VAL INT size Maximum number of bytes to write
INT result -1 on error, otherwise the number of bytes written (which may be less than size)

socklib.occ:296Process socket.fullwrite.addr

PROC socket.fullwrite.addr (SOCKET sock, VAL INT addr, size, INT result)

Write a fixed amount of data from memory to a socket (unsafe). Similar to socket.fullwrite, but reading data directly from the given memory address.

As this operation accesses memory directly, it is inherently unsafe, and should not be used in most occam programs.

Deprecated: do not use in new code.

Parameters:

SOCKET sock Socket to write to
VAL INT addr Memory address to read from
VAL INT size Number of bytes to write
INT result -1 on error, otherwise the number of bytes written

socklib.occ:308Process socket.connect

PROC socket.connect (SOCKET sock, INT result)

Connect a socket. Attempt to make a connection to the remote port specified in sock.

Parameters:

SOCKET sock Socket to connect
INT result -1 if an error occured, 0 otherwise

socklib.occ:326Process socket.listen

PROC socket.listen (SOCKET sock, VAL INT backlog, INT result)

Make a socket listen for incoming connections. The socket should have already been bound to a host/port combination using socket.bind. After this, socket.accept can be used to accept incoming connections.

Parameters:

SOCKET sock Socket to listen
VAL INT backlog The number of incoming connections that may be queued by the kernel while the program is not accepting them; most operating systems impose arbitrary limits on this, so changing it will have little effect
INT result -1 if an error occured, otherwise the file descriptor of the accepted socket

socklib.occ:340Process socket.bind

PROC socket.bind (SOCKET sock, INT result)

Bind a socket to a local address. Set the local address of a socket from the fields in sock. sock[local.addr] should be a valid address for one of the host's interfaces, or the constant INADDR.ANY to specify all interfaces.

Parameters:

SOCKET sock Socket to bind
INT result -1 if an error occured, 0 otherwise

socklib.occ:355Process socket.accept

PROC socket.accept (SOCKET sock, SOCKET client, INT result)

Accept an incoming connection on a listening socket. The socket must already have had socket.bind and socket.listen called on it successfully. The returned socket client is the newly-accepted connection; its fields are filled in with the details of the new connection.

Parameters:

SOCKET sock Socket to accept a connection from
SOCKET client New socket for the accepted connection
INT result -1 if an error occured, 0 otherwise

socklib.occ:374Process socket.sendto

PROC socket.sendto (SOCKET sock, VAL []BYTE message, VAL INT flags, INT result)

Send a datagram message through a socket. This is used to send messages over connectionless protocols like UDP. The destination host and port are specified in the sock record; the host can be specified as INADDR.BROADCAST to broadcast to all hosts on the local network, provided the SO.BROADCAST option has been set on the socket.

Parameters:

SOCKET sock Socket to send datagram from
VAL []BYTE message Message to send
VAL INT flags Bitwise or of MSG flags (normally either 0 or )
INT result -1 if an error occured, otherwise the number of bytes sent

socklib.occ:392Process socket.recvfrom

PROC socket.recvfrom (SOCKET sock, []BYTE message, VAL INT flags, INT result)

Receive a datagram from a socket. This is used to receive messages over connectionless protocols like UDP. The socket must have been bound to a local address. The host and port from which the message was received are filled in in the sock record.

Parameters:

SOCKET sock Socket to receive datagram from
[]BYTE message Buffer for the received datagram
VAL INT flags Bitwise or of MSG flags (normally either 0 or )
INT result -1 if an error occurred, otherwise the number of bytes received

socklib.occ:408Process socket.setsockopt

PROC socket.setsockopt (SOCKET sock, VAL INT level, VAL INT option, VAL INT value, INT result)

Set a socket option. This only supports options with integer arguments, such as SO.BROADCAST and SO.REUSEADDR.

Parameters:

SOCKET sock Socket to set options upon
VAL INT level Option level (one of SOL)
VAL INT option Option to set (protocol-dependent; usually one of SO or TCP)
VAL INT value New value for the option
INT result -1 if an error occured, 0 otherwise

socklib.occ:424Process socket.getsockopt

PROC socket.getsockopt (SOCKET sock, VAL INT level, VAL INT option, INT value, INT result)

Get a socket option. This only supports options with integer arguments, such as SO.BROADCAST and SO.REUSEADDR.

Parameters:

SOCKET sock Socket to get options from
VAL INT level Option level (one of SOL)
VAL INT option Option to get (protocol-dependent; usually one of SO or TCP)
INT value The current value of the option
INT result -1 if an error occured, 0 otherwise

socklib.occ:441Process socket.error

PROC socket.error (SOCKET sock, []BYTE buffer, INT length)

Get last error as a string. This returns a human-readable string describing the last error that occurred upon sock.

The "not connected" error (ENOTCONN) can come as a result of attempting to use a SOCKET where the fd field is set to -1.

Parameters:

SOCKET sock Socket to get error from
[]BYTE buffer Buffer to write error string into
INT length The length of the string returned

socklib.occ:454Process socket.shutdown

PROC socket.shutdown (SOCKET sock, VAL INT how, INT result)

Close a socket in one or both directions. This is like socket.close, but allows the socket to be closed only in one direction as well.

Parameters:

SOCKET sock Socket to close
VAL INT how Direction(s) to close the socket in (one of SHUT)
INT result -1 if an error occured, 0 otherwise

socklib.occ:466Process socket.getsockname

PROC socket.getsockname (SOCKET sock, RESULT INT result)

Get the local address of a connected socket. This fills in the local.addr and local.port fields of the given SOCKET.

Parameters:

SOCKET sock Socket to get local address of
RESULT INT result -1 if an error occured, 0 otherwise

socklib.occ:478Process socket.getpeername

PROC socket.getpeername (SOCKET sock, RESULT INT result)

Get the remote address of a connected socket. This fills in the remote.addr and remote.port fields of the given SOCKET.

Parameters:

SOCKET sock Socket to get remote address of
RESULT INT result -1 if an error occured, 0 otherwise

socklib.occ:489Process socket.gethostname

PROC socket.gethostname (RESULT []BYTE name, RESULT INT result)

Get the hostname of the local machine.

Parameters:

RESULT []BYTE name Buffer to return the name in
RESULT INT result -1 if an error occurred, otherwise the length of the result in name

socklib.occ:500Process socket.sethostname

PROC socket.sethostname (VAL []BYTE name, RESULT INT result)

Set the hostname of the local machine. This typically requires superuser privileges.

Parameters:

VAL []BYTE name The new hostname
RESULT INT result -1 if an error occured, 0 otherwise

socklib.occ:513Process socket.getdomainname

PROC socket.getdomainname (RESULT []BYTE name, RESULT INT result)

Get the NIS domain name of the local machine. Note that this is not the DNS domain name; on the vast majority of modern machines this will be unset.

Parameters:

RESULT []BYTE name Buffer to return the name in
RESULT INT result -1 if an error occurred, otherwise the length of the result in name

socklib.occ:525Process socket.setdomainname

PROC socket.setdomainname (VAL []BYTE name, RESULT INT result)

Set the NIS domain name of the local machine. This typically requires superuser privileges. Note that this is not the DNS domain name.

Parameters:

VAL []BYTE name The new domain name
RESULT INT result -1 if an error occured, 0 otherwise

socklib.occ:535Process socket.altable.connect

PROC socket.altable.connect (CHAN OF BOOL kill, CHAN OF INT response, SOCKET sock, INT result)

ALTable version of socket.connect.

socklib.occ:567Process socket.altable.read

PROC socket.altable.read (CHAN OF BOOL kill, CHAN OF INT response, SOCKET sock, []BYTE buffer, VAL INT count, INT result)

ALTable version of socket.read.

socklib.occ:599Process socket.altable.fullread

PROC socket.altable.fullread (CHAN OF BOOL kill, CHAN OF INT response, SOCKET sock, []BYTE buffer, VAL INT count, INT result)

ALTable version of socket.fullread.

socklib.occ:631Process socket.altable.write

PROC socket.altable.write (CHAN OF BOOL kill, CHAN OF INT response, SOCKET sock, VAL []BYTE buffer, INT result)

ALTable version of socket.write.

socklib.occ:663Process socket.altable.fullwrite

PROC socket.altable.fullwrite (CHAN OF BOOL kill, CHAN OF INT response, SOCKET sock, VAL []BYTE buffer, INT result)

ALTable version of socket.fullwrite.

socklib.occ:695Process socket.altable.accept

PROC socket.altable.accept (CHAN OF BOOL kill, CHAN OF INT response, SOCKET sock, SOCKET client, INT result)

ALTable version of socket.accept.

socklib.occ:727Process socket.altable.recvfrom

PROC socket.altable.recvfrom (CHAN OF BOOL kill, CHAN OF INT response, SOCKET sock, []BYTE message, VAL INT flags, INT result)

ALTable version of socket.recvfrom.

socklib.occ:770Process socket.addr.of.host

PROC socket.addr.of.host (VAL []BYTE hostname, INT addr, INT result)

Find the address of a host given its name. This returns the address of the requested host; when there are several, it will pick an arbitrary one.

Parameters:

VAL []BYTE hostname Hostname to look up; this can either be a DNS-style name, or an IPv4 address in decimal dot notation
INT addr The address found
INT result -1 if an error occured (such as the hostname not being resolvable), 0 otherwise

socklib.occ:785Process socket.addrs.of.host

PROC socket.addrs.of.host (VAL []BYTE hostname, RESULT []INT addrs, RESULT INT result)

Find all the addresses of a host given its name. Like socket.addr.of.host, but this will find all the addresses rather than just the first.

Parameters:

VAL []BYTE hostname Hostname to look up; this can either be a DNS-style name, or an IPv4 address in decimal dot notation
RESULT []INT addrs The addresses found
RESULT INT result -1 if an error occured (such as the hostname not being resolvable), otherwise the number of addresses returned

socklib.occ:801Process socket.naddrs.of.host

PROC socket.naddrs.of.host (VAL []BYTE hostname, RESULT INT result)

Find the number of addresses of a host given its name. This finds out how many addresses a host has, so it can be used before socket.addrs.of.host -- but bear in mind that the resolver's response might change between the two calls, so the result of this call should only be used as a hint.

Parameters:

VAL []BYTE hostname Hostname to look up; this can either be a DNS-style name, or an IPv4 address in decimal dot notation
RESULT INT result -1 if an error occured (such as the hostname not being resolvable), otherwise the number of addresses

socklib.occ:814Process socket.host.of.addr

PROC socket.host.of.addr (VAL INT addr, []BYTE hostname, INT length, INT result)

Find the name of a host given its address. This returns the hostname associated with the given address.

Parameters:

VAL INT addr The address to look up
[]BYTE hostname Buffer to write the hostname into
INT length Length of the returned hostname
INT result -1 if an error occured, 0 otherwise

socklib.occ:826Process socket.ip.of.addr

PROC socket.ip.of.addr (VAL INT addr, []BYTE ip.addr, INT length, INT result)

Format an IPv4 address as a dotted-decimal string.

Parameters:

VAL INT addr The address to format
[]BYTE ip.addr Buffer to write the decimal address into
INT length Length of the result
INT result -1 if an error occured, 0 otherwise

socklib.occ:838Process socket.create.tcp

PROC socket.create.tcp (SOCKET sock)

Create a TCP socket. On failure, sock[fd] will be set to -1.

Parameters:

SOCKET sock The newly-created socket

socklib.occ:848Process socket.create.udp

PROC socket.create.udp (SOCKET sock)

Create a UDP socket. On failure, sock[fd] will be set to -1.

Parameters:

SOCKET sock The newly-created socket

socklib.occ:860Process socket.create.connect.tcp

PROC socket.create.connect.tcp (SOCKET sock, VAL INT addr, VAL INT port, INT result)

Create a TCP socket and connect it.

Parameters:

SOCKET sock The newly-created socket
VAL INT addr IPv4 address to connect to
VAL INT port Port to connect to
INT result -1 if an error occured, 0 otherwise

socklib.occ:888Process socket.create.listen.tcp

PROC socket.create.listen.tcp (SOCKET sock, VAL INT addr, VAL INT port, INT result)

Create a TCP socket and make it listen on a local port. The socket is set to listen with a backlog of 32 connections by default; you can use socket.listen to change the backlog if necessary.

Parameters:

SOCKET sock The newly-created socket
VAL INT addr IPv4 address to listen on
VAL INT port Port to listen on
INT result -1 if an error occured, 0 otherwise

socklib.occ:919Process socket.create.listen.udp

PROC socket.create.listen.udp (SOCKET sock, VAL INT addr, VAL INT port, INT result)

Create a UDP socket and bind it to a local port.

Parameters:

SOCKET sock The newly-created socket
VAL INT addr IPv4 address to bind to
VAL INT port Port to bind to
INT result -1 if an error occured, 0 otherwise