-
Notifications
You must be signed in to change notification settings - Fork 39
Application API
#############################################################################
#############################################################################
-
- Introduction
-
- API Walkthrough
- 2.1 Server-side operations
- 2.2 Client-side operations
-
- API Specification
- 3.1 rina_open
- 3.2 rina_register
- 3.3 rina_unregister
- 3.4 rina_register_wait
- 3.5 rina_flow_accept
- 3.6 rina_flow_respond
- 3.7 rina_flow_alloc
- 3.8 rina_flow_alloc_wait
- 3.9 rina_flow_spec_default
-
- Running and configuring IRATI
- 4.1 Loading the kernel modules
- 4.2 The configuration files
- 4.3 Running the IPC Manager Daemon
-
- Tutorials
-
- Overview of the software components
#############################################################################
############################################################################# Since existing network applications are written using the socket API, it comes natural to design a C RINA API which closely resembles the socket API, provided that the differences in the naming and addressing scheme and the QoS support are taken into account. The socket API is currently defined by the POSIX.1-2008 standard; for this reason the API presented in this section will be referred to as a POSIX-like API for RINA. The advantages of a C POSIX-like API include the following:
- POSIX standards are universally accepted and widely known, so that it would be easy for developers to catch up with the RINA API and write applications.
- It would be easy to port existing network applications to RINA, starting from the definition of a simple mapping between socket API calls and RINA API calls.
- File descriptors are used as universal handlers to interact with the API; this makes it possible to reuse standard system calls (e.g. read, write, close, ...), and synchronisation mechanism (e.g. select, poll, ...).
- The C language is widely used for mission-critical network applications, and a C API can also be used directly by C++ programs.
This C POSIX-like API was originally designed for the rlite RINA implementation.
#############################################################################
############################################################################# A convenient way to introduce the API is to show how a simple application would use the client-side and server-side API calls. This also eases the comparison with sockets, where a similar walkthrough is often presented. Note that in this context the term client simply refers to the initiator of the flow allocation procedure, while the term server refers to the other peer. The discussion here, in other words, does not imply that the client/server paradigm must be applied; the walkthrough is more general, being valid also for other distributed application paradigms (e.g. peer-to-peer).
The workflow presented in this subsection, depicted in figure 1, refers to the case of blocking operation, that is the API calls may block waiting for asynchronous events; moreover, for the sake of exposition, we assume that the operations do not fail. Non-blocking operations and errors are however covered by the API specification (section 2.2) and the examples (section 2.4).
############################################################################# The first operation needed by the server, (1) in figure 1, is rina_open, which takes no arguments and returns a listening file descriptor (an integer, as usual) to be used for subsequent server-side calls. This file descriptor is the handler for an instance of a RINA control device which acts as a receiver for incoming flow allocation requests.
At (2), the server calls rina_register to register a name with the RINA control device, specifying the associated listening file descriptor (lfd), the name of the DIF to register to (dif) and the name to be registered (appl). The DIF argument is optional and advisory: the API implementation may choose to ignore it, and use some namespace management strategy to decide into which DIF the name should be registered.
After a successful registration, the server can receive flow allocation requests, by calling rina_flow_accept on the listening file descriptor (3). Since the listening file descriptor was not put in non-blocking mode, this call will block until a flow request arrives. When this happens, the function returns a new file descriptor (cfd), the name of the remote application (src) and the QoS granted to the flow. The returned file descriptor is an handler for an instance of a RINA I/O device, to be used for data I/O.
At this point (4), the flow allocation is complete, and the server can exchange SDUs with the client, using the write and read blocking calls or working in non-blocking mode (possibly mutliplexing with other I/O devices, sockets, etc.) by means of poll or select. This I/O phase is completely analogous to the I/O exchange that happens with TCP or UDP sockets, only the QoS may be different.
Once the I/O session ends, the server can close the flow, triggering flow deallocation, using the close system call (5). The server can then decide whether to terminate or accept another flow allocation request (3).
############################################################################# Client operation is straightforward; the client calls rina_flow_alloc (1) to issue a flow allocation request, passing as arguments the name of the DIF that is asked to support the flow (dif), the name of the client (src, i.e. the source application name), the name of the destination application (dst, i.e. the server name) and the required QoS parameters for the flow (qos). The call will block until the flow allocation completes successfully, returning an file descriptor (fd) to be used for data I/O.
At this point the client can exchange SDUs with the server (2), using the I/O file descriptor either in blocking or not blocking mode, similarly to what is possible to do with sockets. When the I/O session terminates, the client can deallocate the flow with the close system call.
#############################################################################
############################################################################# In the following, the API calls are listed and documented in depth. Some general considerations:
-
Names (e.g. for applications and DIFs) are specified using C strings. Application names are composed of four components: process name, process instance, entity name and entity instance. Only process name is mandatory. The API mandates a standard separator to allow application developers to provide these 4 pieces of information using a single string. This separator is the '|' character, which cannot be used as part of the process name, instance, entity name or instance. Some examples of valid app names:
- traffic.generator
- traffic.generator|23
- traffic.generator||perf
- traffic.generator|23|perf
- traffic.generator|23|perf|12
-
The API functions typically return 0 or a positive value on success. On error, -1 is returned with the errno variable set accordingly to the specific error.
############################################################################# int rina_open(void)
This function opens a RINA control device that can be used to register/unregister names, and manage incoming flow allocation requests. On success, it returns a file descriptor that can be later passed to rina_register(), rina_unregister(), rina_flow_accept(), and rina_flow_respond().
On error -1 is returned with errno set properly. Applications typically call this function as a first step to implement server-side functionalities.
############################################################################# int rina_register(int fd, const char *dif, const char *appl, int flags)
This function registers the application name appl to a DIF in the system. After a successful registration, flow allocation requests can be received on fd by means of rina_flow_accept(). If dif is not NULL, the system may register the application to dif. However, the dif argument is only advisory and the implementation is free to ignore it. If dif is NULL, the system autonomously decide to which DIF appl will be registered to.
If RINA_F_NOWAIT is not specified in flags, this function will block the caller until the operation completes, and 0 is returned on success.
If RINA_F_NOWAIT is specified in flags, the function returns a file descriptor (different from fd) which can be used to wait for the operation to complete (e.g. using POLLIN with poll() or select()). In this case the operation can be completed by a subsequent call to rina_register_wait().
On error -1 is returned, with the errno code properly set.
############################################################################# int rina_unregister(int fd, const char *dif, const char *appl, int flags)
This function unregisters the application name appl from the DIF where it was registered to. The dif argument must match the one passed to rina_register(). After a successful unregistration, flow allocation requests can no longer be received on fd. The meaning of the RINA_F_NOWAIT flag is the same as in rina_register(), allowing non-blocking unregistration, to be later completed by calling rina_register_wait().
Returns 0 on success, -1 on error, with the errno code properly set.
############################################################################# int rina_register_wait(int fd, int wfd)
This function is called to wait for the completion of a (un)registration procedure previously initiated with a call to rina_register() or rina_unregister() on fd which had the RINA_F_NOWAIT flag set. The wfd file descriptor must match the one that was returned by rina_[un]register().
It returns 0 on success, -1 error, with the errno code properly set.
- Home
- Software Architecture Overview
- IRATI in depth
-
Tutorials
- 1. DIF-over-a-VLAN-(point-to-point-DIF)
- 2. DIF over two VLANs
- 3. Security experiments on small provider net
- 4. Multi-tenant Data Centre Network configured via the NMS-DAF
- 5. Congestion control in multi-tenant DC
- 6. Multi-tenant Data Centre network with Demonstrator
- 7. ISP Security with Demonstrator
- 8. Renumbering in a single DIF
- 9. Application discovery and Distributed Mobility Management over WiFi
- 10. Distributed Mobility Management over multiple providers
- 11. Multi-access: multiple providers, multiple technologies