Networking Implementation

Networking Implementation


Document formatted by vherva at Fri Apr 24 11:23:45 1998 on the host schemestation. This document is produced by the SchemeStation project during the Tik-76.115 course.

1 Introduction

SCHEMESTATION is a network oriented operating system. This implies that the system has to provide the user processes (agents) communication facilities. As the current aim of the current project is to simulate the actual hardware on the top of a UNIX system, a natural choice is to simulate the network traffic on the top of the TCP/IP protocol stack. Network simulation could be done on the top of bare IP or even on the top of plain hardware (eg. Ethernet). We, however, see no point in doing this as the aim of this project is not to rewrite network software.

Thus, communication is simulated on the top of the TCP/IP stack, which provides the necessary reliability. (In a realistic system another, perhaps SCHEMESTATION-specific, protocol could be used.)

TCP provides a reliable stream-like connection; SCHEMESTATION uses transfer data in packets. This packet traffic is implemented on the top of TCP, so the simulation itself does not need to take care of acknowledging packets or similar stuff.

2 Addressing

Since every packet is sent, in principle, to an agent (not to a domain for example), addressing scheme needs to uniquely address agents. The networking system is however responsible for addressing only domains. The network system passes received packets to the messaging system [Messaging System Specification] that along with the addressing system [Addressing module specification] does then finer-grain addressing based on agent addresses.

Every packet contains a destination address. The address is a 128-bit domain address; the agent specifier is part of the payload of the packet, and the networking system does not need to be aware of it.

3 Communication between domains

Every SCHEMESTATION simulator may listen to its own TCP/IP port. The convention is however, that in a simulated multi-domain SCHEMESTATION environment there is one router that listens to a port (by default, 7000). Other domains connect to it and send all packets through this connection. For generality, however, every domain maintains a list of open connections, and search through it too see whether they are directly connected to the domain they need to send the packet to. If no such direct connection is found, the packet is sent to the router.

When the router is started, the listened port is bound and begun to listen with net_becomrouter() before calling the net_initialize() function. (The port number is passed as a command line argument to the network simulator.) If listening the port fails the function returns error.

Client domains call net_userouter() instead. The router to connect to is given as an argument.

When a domain wishes to send a packet to another domain, it first checks whether it should use a router. If no router is in the connections list, it searches for a direct connection (with net_findconnection) through the list of readily established connection if one is made to the desired destination. If one is found, the client puts the packet on the connection's list of packets to be send with net_deliverpacket. If no connection exists it establishes first a new connection to the destination with net_openconnection.

The event loop notifies the network module every time it is possible to send data over a connection by calling net_eloop_callback. The networking module then sends as many packets as possible with net_sendpacket and gives the control back to the caller.

The event loop also notifies the network module of arrived packets by calling net_eloop_callback. The network reads all available packets from the socket with net_recvpacket and for every completely received packet it calls the addressing system callback registered with net_registerpacketcallback. Packets can be partially received or sent, in which case processing them is completed when the event loop gives control back next time, or even later.

Opening a connection consists of calling net_openconnection that allocates the connection struct, adds it to the global connection list, opens the socket the the destination, and does handshake with net_doclienthandshake.

The server side (router) gets notification of opened connection from the event loop ( net_acceptcallback) and calls net_acceptconnection that allocates the connection struct, adds it to the global connection list, and does handshake with net_serverhandshake.

The handshake is done as follows: a client sends first a magic number, then protocol version number, and then its SSPP DomainAddress. The server replies with another magic number, protocol version number and its address. The client then sends an open connection control command, and at this point both ends agree on having a valid connection.

The parties can use control commands to, for example, close connections. If the data length is set zero, the packet includes a (network byte order) 2-octet control command a argument. These include opening a connection (0) and closing a connection (1). These command are handled by net_handlecontrol

4 The functions of module networking

File network-internal.h

C-functions:

  • NetConnectionStatus net_acceptconnection(IN int fd, INOUT Connection **conn)
    Description: Accepts a connection that is made to the port we listen. Calls handshake routine, and if the connection is ok, adds it in the global list with net_netconnection(). Returns NET_CONNECTION_OK on success, NET_CONNECTION_TCPFAIL if call to accept() or setsockopt() fails, or NET_CONNECTION_NONSSPPPEER if handshake fails.

  • NetConnectionStatus net_closeconnection(IN DomainAddress *addr, IN Bool closed)
    Description: Closes the connection to addr if argumentclosed is true, the is assumed closed and no attempt to reclose it not made. If the fd is open, notifies the peer with a NET_CONTROL_CLOSE control coand. Returns NET_OK on success.

  • void net_connectcallbk(IN EventLoopIONotification notification, IN void *context)
    Description: Called by the event loop, when the network-listen fd gets a connection. Esentially calls net_acceptconnection();

  • void net_delete_packets(PacketListNode *n)
    Description: Delete the packetlist N and all packets contained.

  • NetConnectionStatus net_doclienthandshake(INOUT Connection *conn)
    Description: Does a serverside handshake on a just established Connection conn. This includes receiving a magic number, protocol version, and our local SSPP-address. A similar reply is sent to the client, and after that a NET_CONTROL_OPEN control coand is expected from the client. If the handshake fails due to incompatible protocol or whatever, NET_CONNECTION_NONSSPPPEER is returned. Otherwise returns NET_CONNECTION_OK.

  • NetConnectionStatus net_doserverhandshake(INOUT Connection* conn)
    Description: Does a clientside handshake on a just established Connection conn. This includes sending a magic number, protocol version, and our local SSPP-address. A similar reply is the received from the server, and after that a NET_CONTROL_OPEN control coand is sent. If the handshake fails due to incompatible protocol or whatever, NET_CONNECTION_NONSSPPPEER is returned. Otherwise returns NET_CONNECTION_OK.

  • NetStatus net_dropconnection(IN Connection *connection)
    Description: Close the connection connection and remove if from the connections table.

  • void net_eloop_callback(IN EventLoopIONotification notification, IN void *context)
    Description: Called when any of the connections either eget new stuff to be read, or becomes free to be written. Calls net_sendpacket() and/or net_recvpacket() respectively.

  • NetConnectionStatus net_findconnection(IN DomainAddress *addr, OUT Connection **connection)
    Description: Browser through the connection list and checks whether a connection to addr exists. If so pointer to it is returned. Return NET_CONNECTION_OK on success, NET_CONNECTION_INVALIDADDRESS, if the connection is not found.

  • void net_get_tcpip_addr(IN DomainAddress *addr, OUT struct in_addr *ip, OUT unsigned short *port)
    Description: Extracts the ip-address and tcp-port from a SSPP-DomainAddress addr.

  • NetStatus net_getconnection(IN DomainAddress *addr, OUT Connection **conn)
    Description: Finds out if there is a readily opened connection to DomainAddress addr, and returns it. If no Such Conneection is found, one is established and pointer to it is returned. If establishing connection fails, NET_TCPFAIL is returned, otherwise the return value is set to NET_OK.

  • NetStatus net_handlecontrol(IN Connection *connection)
    Description: Receives a control coand (a SSPP-packet with datalen field set to zero) from fd and acts accordingly. Return NET_OK if coand is understoodand completed, NET_FATAL, if coand was understood, but not completed and NET_CONTROLERR, if the control coand was not understood.

  • NetSndStatus net_makessppaddress(IN char* hostname, IN unsigned long ipaddr, IN unsigned short tcpport, OUT DomainAddress *addr)
    Description: Makes an SSP DomainAddress out of an IP-address / TCP-port pair. The ip-address is put in the beginning of the SSPP address, and the unsigned short (network byteorder) port number id put in the octets 4 and 5. The rest (10 octets) are padded with zero. An SSPP DomainAddress made like this is handy to use in the UNIX-process simulation of SchemeStation. This is however only a convention. Returns NET_SND_COMPELE on success or NET_SND_INVALIDADDRESS if the address is invalid.

  • NetConnectionStatus net_newconnection(IN int fd, IN DomainAddress *address, INOUT Connection **)
    Description: Prepares a new Connection struct, and adds it in the global connection list. Return NET_CONNECTION_OK on success.

  • NetConnectionStatus net_openconnection(IN DomainAddress *addr, OUT Connection **connection)
    Description: If we have no router to rely on, and we have to send a packet to a domain we haven't contacted before, net_openconnection() is called by net_findconnection(). It tries to open a socket to the addr, and if this succeeds, creates a new Connection entry in the network's connection list, and return NET_CONNECTIONOK. Otherwise returns NET_CONNECTIONTCPFAIL

  • NetConnectionStatus net_protoconnection(IN int fd, OUT Connection **conn)
    Description:

  • void net_set_event_loop_reqs(Connection *connection)
    Description:

  • read(fd, buf, len)
    Description:

  • write(fd, buf, len)
    Description:


File network-packet.h

C-functions:

  • void net_addresstoasc(char *str, int base, DomainAddress *addr)
    Description: Formats the DomainAddress in the caller allocated char array pointed by str. If base is 10, notation "ip.ip.ip.ip tcp-port x.x x.x.x.x" is used, otherwise a hexadesimal notation is used.

  • Bool net_cmpraddr(IN DomainAddress *a, IN DomainAddress *b)
    Description: Compares two DomainAddresses. True is returned on match, False otherwise.

  • NetSndStatus net_deliverpacket(IN Packet *pckt, IN DomainAddress *addr)
    Description: Adds the packet to the appropriate connections packetstosend list. If no connection to the desired peer exists, establishes one. Return NET_SND_COMPLETE on success, NET_SND_INVALIDADDRESS if the address was invalid.

  • void net_destroypacket(Packet *packet)
    Description: Delete packet and its contents.

  • NetRcvStatus net_getrecpaddr(IN Packet *pckt, OUT DomainAddress *addr)
    Description: Extracts the recipients address from the packet, and returns NET_RCV_COMPLETE.

  • void net_packettoasc(char *str, Packet *packet, Bool includedata, int maxlen)
    Description: Formats a packet in the caller allocated char array pointed by str. If include data is set, the packet data is dumped along with packet header. never uses more than maxlen chars.

  • NetRcvStatus net_recvpacket(struct Connection *connection)
    Description: Receives as any packets from connection as possible. When (non-blocking) reading socket fails, gives control back to caller and sets the progrptr of the last packet to the number of bytes read of that packet. Returns either NET_RCV_COMPLETE if all was sent and NET_RCV_PARTIALLYSENT otherwise. If socket fails, NET_RCV_SOCKETSENDFAILED is returned.

  • NetSndStatus net_sendpacket(struct Connection *)
    Description: Send as many packet from the connections packetstosend list as the socket accepts. When writing becomes impossible, gives control back to the caller, and sets the progrptr of the last packet to the number of bytes sent of that packet. Returns either NET_SND_COMPLETE if all was sent and NET_SND_PARTIALLYSENT otherwise. If socket fails, NET_SND_SOCKETSENDFAILED is returned.


File network.h

C-functions:

  • NetStatus net_becomerouter(IN unsigned short tcp_port_to_listen)
    Description: This is meant to be called just after net_initialize(). Finds out the DNS name and the IP-address of the UNIX-system, and begins listening a TCP-port, whose number is taken from the coand line options (actually the field .port in a Network structure). Return NET_OK on success, NET_ADDRESSFAIL, if unable to get the local address, NET_TCPFAIL, if establishing the listening socket fails, and NET_FATAL on other failures.

  • NetStatus net_get_info(OUT NetStatusInfo **ptr)
    Description: Return useful information about the current network status and statistics. The structure returned is allocated internally in the network module and may not be freed or modified by external procedures. Subsequent calls to this function may modify the contents of the structure. The pointer returned by this function is valid until next call but not necessarily longer.

  • NetStatus net_gethostaddress(OUT DomainAddress *addr)
    Description: Gets the SSPP DomainAddress of the local domain. Return NET_OK;

  • NetStatus net_initialize(void)
    Description: Initializes the network. Call this before any other networking functions. After this, one would typically call net_registerpacketcallback() and net_becomerouter() or net_userouter(). The host address must have been set using net_sethostaddress() before calling this function!

  • NetConnectionStatus net_open_connection(IN char *hostname, IN unsigned long ipaddr, IN unsigned short tcpport)
    Description:

  • NetStatus net_registerpacketcallback(IN NetPacketCallback callback, IN void *context)
    Description: Register the callback function to be called whenever network fetches a full packet. The callback function gets a NetPacketInfo-struct as an argument. The dynamically allocated data field as well as the dynamically allocated structure itself must be freed by the receiver of the callback. The context context is passed in the NetPacketInfo struct's .context field. Returns NET_OK.

  • NetStatus net_send(IN DomainAddress *addr, IN int size, IN uchar* data)
    Description: Sends the -long message (in bytes) to DomainAddress . Does not free any memory the arguments hold. Essentially gathers a Packet from the arguments and passes it to net_deliverpacket(). The memory area that contains the packet data may be modified after this function returns; a copy of the packet is made internally if needed. This applies to the DomainAddress ADDR also. Return NET_OK if succeeded, NET_FAILED if the packet cannot be delivered (SIZE <= 0 or address unknown and no suitable routers known).

  • NetStatus net_sethostaddress(IN DomainAddress *addr)
    Description: Set the domain address of the current simulator process. The domain address may not be changed after net_initialize() has been called; set the domain address before doing that. Returns NET_OK in any case, though that is a bit misleading. Do not call this function after having called net_initialize().

  • NetStatus net_shutdown(INOUT void)
    Description: Network shutdown. Closes all the connections (and notifies the peer also), and unregisters the fd:s to event loop. Event loop is not aborted. If mode is NET_SERVER begins to listen a tcp-port Return NET_OK.

  • NetStatus net_userouter(DomainAddress *address)
    Description: Specifies the router to be used. Meant to be called after net_initialize(). Return NET_FAILED if no connection could be established to the router, NET_OK on success.


File network-packet.h

C-functions:

  • void net_addresstoasc(char *str, int base, DomainAddress *addr)
    Description: Formats the DomainAddress in the caller allocated char array pointed by str. If base is 10, notation "ip.ip.ip.ip tcp-port x.x x.x.x.x" is used, otherwise a hexadesimal notation is used.

  • Bool net_cmpraddr(IN DomainAddress *a, IN DomainAddress *b)
    Description: Compares two DomainAddresses. True is returned on match, False otherwise.

  • NetSndStatus net_deliverpacket(IN Packet *pckt, IN DomainAddress *addr)
    Description: Adds the packet to the appropriate connections packetstosend list. If no connection to the desired peer exists, establishes one. Return NET_SND_COMPLETE on success, NET_SND_INVALIDADDRESS if the address was invalid.

  • void net_destroypacket(Packet *packet)
    Description: Delete packet and its contents.

  • NetRcvStatus net_getrecpaddr(IN Packet *pckt, OUT DomainAddress *addr)
    Description: Extracts the recipients address from the packet, and returns NET_RCV_COMPLETE.

  • void net_packettoasc(char *str, Packet *packet, Bool includedata, int maxlen)
    Description: Formats a packet in the caller allocated char array pointed by str. If include data is set, the packet data is dumped along with packet header. never uses more than maxlen chars.

  • NetRcvStatus net_recvpacket(struct Connection *connection)
    Description: Receives as any packets from connection as possible. When (non-blocking) reading socket fails, gives control back to caller and sets the progrptr of the last packet to the number of bytes read of that packet. Returns either NET_RCV_COMPLETE if all was sent and NET_RCV_PARTIALLYSENT otherwise. If socket fails, NET_RCV_SOCKETSENDFAILED is returned.

  • NetSndStatus net_sendpacket(struct Connection *)
    Description: Send as many packet from the connections packetstosend list as the socket accepts. When writing becomes impossible, gives control back to the caller, and sets the progrptr of the last packet to the number of bytes sent of that packet. Returns either NET_SND_COMPLETE if all was sent and NET_SND_PARTIALLYSENT otherwise. If socket fails, NET_SND_SOCKETSENDFAILED is returned.


© SchemeStation project 1997-1998 [Back to the document index]