-
Notifications
You must be signed in to change notification settings - Fork 28
Writing XIA Applications
Similarities To The Standard Socket Library
- The Xsocket API was designed to be as similar as possible to the standard socket library to make porting applications easier. Parameter lists are in almost all instances identical to the corresponding Berkley socket API.
- XIA supports socket of type
SOCK_STREAM,SOCK_DGRAM, andSOCK_RAW.
- API calls are prefixed with an X (Xbind, Xpoll, etc...)
- The address family is
AF_XIAinstead ofAF_INET - XIA does not have IP addresses or ports. It uses DAGs in their place
- XIA uses a
sockaddr_xstructure instead ofsockaddr_into hold addresses - XIA provides additional APIs for content management and DAG manipulation
TODO: DO we need to keep these around?
- C Example
- Python Example
- Register with the name server
- DAGs
- caching
Several APIs are provided for working with DAGs
- Xgetaddrinfo() is used to look up DAGs in the name server similar to how standard DNS works. It can also be used to create local DAGs that can be used to bind to sockets.
-
inet_ntop() is used to convert DAGs contained in a
sockaddr_xstructure into a printable sting in the DAG format. -
inet pton() is used to convert strings in the DAG, RE, or URL format into a
sockaddr_x. - The DAG library
Sometimes it's helpful to be able to see a visual representation of a DAG; to this end, we've created a DAG visualization tool.
DAG 2 0 - AD:24b1979de47c480b786b45f1c57b4d19d2681a25 1 - HID:d5b3cf4904b8f8462fbb916ae54ea55ad7fd8836 2 - SID:69276369b5dc391ab12895b928cac945fd82a5d2
TODO: inset a picture of the example DAG
The RE format is simple and relatively easy to use but cannot represent all DAGs. Because of this, RE formatted DAGs are input only, there is no code that returns an RE DAG to the user.
An RE string consists of the characters "RE " followed by a chain of XIDs, each of which can optionally have a fallback path from the previous node in the chain to itself. Nodes are separated by spaces and parens are used to mark fallback paths. Open and close parens must have a space on either side. The "start" node is implicit and does not appear in the string. For example:
RE ( AD:24b1979de47c480b786b45f1c57b4d19d2681a25 HID:d5b3cf4904b8f8462fbb916ae54ea55ad7fd8836 ) SID:69276369b5dc391ab12895b928cac945fd82a5d2
The DAG format is capable of encoding arbitrary graphs but is difficult to construct manually. A DAG string is a list of XIDs and their outgoing edges separated by the '-' character; by convention, we use "- \n" as the separator to make DAG strings easier to read when printed. Nodes are implicitly numbered starting from 0. This index is used by other nodes to denote an outgoing edge to a node. A DAG string begins with the characters "DAG " and is followed by the start node's outgoing edges (separated by spaces). This is followed by the list of XIDs and their outgoing edges.
DAG 2 0 - AD:24b1979de47c480b786b45f1c57b4d19d2681a25 1 - HID:d5b3cf4904b8f8462fbb916ae54ea55ad7fd8836 2 - SID:69276369b5dc391ab12895b928cac945fd82a5d2
In this example, the nodes are implicitly ordered:
- 0 AD:24b1979de47c480b786b45f1c57b4d19d2681a25
- 1 HID:d5b3cf4904b8f8462fbb916ae54ea55ad7fd8836
- 2 SID:69276369b5dc391ab12895b928cac945fd82a5d2
When processing this DAG, the first value is 2, if a route to the node 2 (SID) is present the next pointer in the DAG will be advanced to node 2. Otherwise processing will continue to the next edge on the first line (0). If a route to 0 is found, the next pointer will be advanced to node 0 and the process repeats. We again check the next edge which is '-'. This indicates that there are no more paths to evaluate and and no valid route has been found.
URL formatted DAGs are essentially identical to the DAG format with the newlines stripped out and URL-safe characters replacing spaces and other problematic characters.
http://DAG.2.0.-.AD$24b1979de47c480b786b45f1c57b4d19d2681a25.1.-.HID$d5b3cf4904b8f8462fbb916ae54ea55ad7fd8836.2.-.SID$69276369b5dc391ab12895b928cac945fd82a5d2
#include "Xsocket.h"
Xgetaddrinfo("test.sample.xia", NULL, NULL, &pai);
sockaddr_x *psa = (sockaddr_x*)pai->ai_addr;
xia_ntop(AF_XIA, psa, s, sizeof(s));
printf("DAG retrieved from the name server:\n%s\n", s);
Xfreeaddrinfo(pai);
#include "Xsocket.h"
#include "Dagaddr.hpp"
char str[1024];
sockaddr_x addr; // assume addr has been filled in earlier
// get a string in DAG format
xia_ntop(AF_XIA, &addr, str, sizeof(str));
// alternatively use the Graph object
// if a URL formatted string is required, you must use Graph
Graph g(&addr);
printf("DAG format:\n%s\n", g.dag_string().c_str());
printf("URL format:\n%s\n", g.http_url_string().c_str());
#include "Xsocket.h"
sockaddr_x sax;
const char *re = "RE ( AD:24b1979de47c480b786b45f1c57b4d19d2681a25 HID:d5b3cf4904b8f8462fbb916ae54ea55ad7fd8836 ) SID:69276369b5dc391ab12895b928cac945fd82a5d2";
// convert any RE, DAG, or URL formatted string into a sockaddr_x
xia_pton(AF_XIA, re, &sax);
// register the DAG with the nameserver
XregisterName("test.sample.xia", &sax);
Use Xgetaddrinfo to create a DAG for the local host using the newly created SID. If hints is NULL a simple no fallback DAG will be created. If the hints.ai_flags</a> has <code>XIA_FALLBACK flag is set the returned DAG will have a primary path that goes directly to the SID, and A fallback path that first goes through the AD and HID.
#include "Xsocket.h"
#include "Xkeys.h"
#include "dagaddr.hpp"
struct addrinfo hints;
struct addrinfo *pai;
// create a unique SID
XmakeNewSID(sid, sizeof(sid));
bzero(&hints, sizeof(hints));
hints.ai_family = AF_XIA;
hints.ai_flags = XAI_FALLBACK;
Xgetaddrinfo(NULL, sid, &hints, &pai);
sockaddr_x *psa = (sockaddr_x*)pai->ai_addr;
Xfreeaddrinfo(&pai);
#include "dagaddr.hpp"
Node src; // dummy node needed to start a Graph
Node n_ad("AD:1234567890123456789012345678901234567890");
Node n_hid("HID:1111111111111111111111111111111111111111");
Node n_sid("SID:2222222222222222222222222222222222222222");
// create a simple DAG with no fallbacks
Graph straight = src * n_ad * n_hid * n_sid;
// add a fallback path to the DAG
// now create a DAG that just includes the SID. This is alegal DAG on it's own,
// but is not very useful by itself unless the SID is in the routing table
Graph sidonly = src * n_sid;
// now put them together to create a DAG with a fallback path
Graph fallback = sidonly + straight;
// put the address into a sockaddr_x for use elsewhere
sockaddr_x addr;
g.fill_sockaddr(&addr);
The straight DAG
DAG 0 - AD:1234567890123456789012345678901234567890 1 - HID:1111111111111111111111111111111111111111 2 - SID:2222222222222222222222222222222222222222The fallback DAG
fallback DAG created by hand DAG 2 0 - AD:1234567890123456789012345678901234567890 1 - HID:1111111111111111111111111111111111111111 2 - SID:2222222222222222222222222222222222222222