III.1.3.2-Different functions involved

Tierra uses two sets of functions, one to send datagram, one to receive and process them. These sets are of course interdependent.
This section first deals with the functions sending messages, then with the receiving function, and last with the functions processing messages previously received.

a) Sending a genome: NEject()

NEject() is called whenever a creature wants to emigrate. For this beta version of Tierra, it is called at random, with a low probability, every time a creature attempts to spawn a daughter.

Here is the prototype of the function:

void NEject(I32s gen,I32s siz);

The parameters for this function are gen, the address of the genome in the soup, and siz, the size of the genome.

This function copies the genome in a message, and sends it to a remote node. In this beta version of Tierra, the destination address is chosen at random in the mapfile.

Create buffer
Put EMIGRATETAG in buffer
Put genome (siz octets from the gen address onward) in buffer
Choose index in mapfile at random
Open mapfile
Get index-th line in mapfile
Extract address information
Fill in destination address for socket with data above
Send buffer contents on socket
Close mapfile

b) Sending an address: Addr_send()

Addr_send() is called once at startup, and is used by Tierra to broadcast to other nodes its ability to communicate and its address.

I32s Addr_send()

The return value gives some status information.

This function sends the local address (association {IP address; protocol port}) and name, in the same format as a mapfile line, to every known node.
It goes through the following loop until it has gone through the whole mapfile:

Create buffer
Put SENDADDRTAG in buffer
Put local name and address under mapfile format in buffer
Open mapfile (for reading)
While not end of mapfile
    Get next line in the map file
    Extract address information (IP address and protocol port)
    Fill in destination address for socket with data above
    Send buffer contents on socket
Close mapfile

c) Sending a tping request: TPing_send()

TPing_send() is called by the decode function associated to a specific instruction in the assembler code of the creatures (tpingsnd() in instruct.c). It sends a tping request to a node whose index in the mapfile is specified by the creature.

I32s TPing_send(I32u index,ComAddr *cell_addr);

The parameters are index (index for an IP address in the mapfile) and cell_addr, a ComAddr structure containing the address of the creature sending the tping. The return value gives some status information.

The outline of the code is the following:

Create buffer
Put TPINGREQTAG in buffer
Put cell_addr in buffer
Open mapfile
Get index-th line in mapfile
Extract destination address (IP address and port number)
Fill in destination address for socket with above data
Send buffer content
Close mapfile

d) Receiving messages: NetRecvFunc()

This function is called at every turn of the life() loop (cf. III.1.1). It checks whether there is an incoming message waiting on the socket. If there is one, it processes the message and returns. If there is no message waiting, NetRecvFunc() returns without blocking.

I16s NetRecvFunc();

The return value indicates the return status of the function. The outline of the code follows:

Create buffer
Read on socket
If no incoming datagram (this is possible because the socket
                         option was set to non-blocking)
    Return
Else
    Put incoming data in buffer
    Check message tag
    Case tag is EMIGRATETAG
        Call Inject()
    Case tag is SENDADDRTAG
        Call Addr_recv()
    Case tag is TPINGREQTAG
        Call TPing_reply()
    Case tag is TPINGREPTAG
        Call TPing_recv()

e) Processing a genome: Inject()

This function is called from NetRecvFunc() when a message carrying a genome is received. It puts the received genome in the local soup.
This function is used to inject in the soup genomes from varied origins (network, genebanker, other soup...). This explains the apparition of some of the parameters.

void Inject(g, size, sad, tol, disk, rrpi)
FpInst g; /* pointer to genome */
I32s size; /* size of genome */
I32s sad; /* suggested address for placement */
I32s tol; /* tolerance placement of genome */
I32s disk; /* 1 = this genome comes from the disk */
float *rrpi; /* reap rand prop for injection */

This function receives the address and size of the incoming genome (g and size parameters), which is presently located in a receiving buffer.
An address in the soup can be suggested for grafting the new genome in the soup, through the sad and tol parameters.

f) Processing an address: Addr_recv()

This function is called from NetRecvFunc() when an address message arrives. It copies the received address in the local mapfile, if this address was not already known.

I32s Addr_recvI8s *address);

This function receives as parameter the string (in mapfile format) received in the datagram. It returns an exit status.

The outline of the code for this function follows:

Extract IP address and port number from string
Open mapfile
While not end of mapfile
    Get next line in the mapfile
    Extract address information
    Compare with IP address and port number from string
    If similar
        Return
Write string at end of mapfile (reached only if no match in mapfile)
Close mapfile

g) Processing a tping request & sending a reply: TPing_reply()

This function is called by NetRecvFunc() when it receives a tping request. It processes the request, and sends back the data required.

I32s TPing_reply(ComAddr *cell_addr);

The only parameter needed by this function is the address of the creature which sent the request. The return value is an exit status.

The outline of the code for this function follows.

Create buffer
Put TPINGREPTAG in buffer
Put local IP address and port number in buffer
Put *cell_addr in buffer
Put SoupSize, NumCells, Speed in buffer
Extract IP address and port number from cell_addr
Fill in destination address for socket with above data
Send buffer contents

h) Processing a tping reply: TPing_recv()

This function is called by NetRecvFunc() upon receiving a tping reply message. It puts the tping information in the I/O buffer associated with the destination creature.

I32s TPing_recv(I8s *buffer);

This function receives the data field received on the socket (minus the tag) in its buffer parameter. It returns an exit status value.

The outline of the code follows:

Extract destination creature from buffer
Put SoupSize, NumCells, Speed in IO buffer for cell
Put source address in IO buffer for cell