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.4.8 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)
- void net_set_event_loop_reqs(Connection *connection)
- read(fd, buf, len)
- write(fd, buf, len)
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)
-
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. |
|