TEST(XreadLocalHostAddr, InvalidPointers) { int sock = Xsocket(AF_XIA, XSOCK_STREAM, 0); int rc = XreadLocalHostAddr(sock, NULL, XID_LEN, NULL, XID_LEN, NULL, XID_LEN); ASSERT_EQ(-1, rc); Xclose(sock); }
//Just registering the service and openning the necessary sockets int registerReceiver() { int sock; say ("\n%s (%s): started\n", TITLE, VERSION); // create a socket, and listen for incoming connections if ((sock = Xsocket(AF_XIA, SOCK_STREAM, 0)) < 0) die(-1, "Unable to create the listening socket\n"); // read the localhost AD and HID if ( XreadLocalHostAddr(sock, myAD, sizeof(myAD), myHID, sizeof(myHID), my4ID, sizeof(my4ID)) < 0 ) die(-1, "Reading localhost address\n"); struct addrinfo *ai; //FIXME: SID is hardcoded if (Xgetaddrinfo(NULL, SID, NULL, &ai) != 0) die(-1, "getaddrinfo failure!\n"); sockaddr_x *dag = (sockaddr_x*)ai->ai_addr; //FIXME NAME is hard coded if (XregisterName(NAME, dag) < 0 ) die(-1, "error registering name: %s\n", NAME); if (Xbind(sock, (struct sockaddr*)dag, sizeof(dag)) < 0) { Xclose(sock); die(-1, "Unable to bind to the dag: %s\n", dag); } Graph g(dag); say("listening on dag: %s\n", g.dag_string().c_str()); return sock; }
void echo_dgram() { int sock; char buf[XIA_MAXBUF]; sockaddr_x cdag; socklen_t dlen; int n; say("Datagram service started\n"); if ((sock = Xsocket(AF_XIA, SOCK_DGRAM, 0)) < 0) die(-2, "unable to create the datagram socket\n"); struct addrinfo *ai; if (Xgetaddrinfo(NULL, SID_DGRAM, NULL, &ai) != 0) die(-1, "getaddrinfo failure!\n"); sockaddr_x *sa = (sockaddr_x*)ai->ai_addr; Graph g((sockaddr_x*)ai->ai_addr); printf("\nDatagram DAG\n%s\n", g.dag_string().c_str()); if (XregisterName(DGRAM_NAME, sa) < 0 ) die(-1, "error registering name: %s\n", DGRAM_NAME); say("registered name: \n%s\n", DGRAM_NAME); if (Xbind(sock, (sockaddr *)sa, sizeof(sa)) < 0) { die(-3, "unable to bind to the dag\n"); } pid_t pid = 0; // only need to fork if doing stream echo at the same time if (stream == 1) pid = fork(); if (pid == 0) { while (1) { say("Dgram Server waiting\n"); dlen = sizeof(cdag); memset(buf, 0, sizeof(buf)); if ((n = Xrecvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&cdag, &dlen)) < 0) { warn("Recv error on socket %d, closing connection\n", pid); break; } say("dgram received %d bytes\n", n); if ((n = Xsendto(sock, buf, n, 0, (struct sockaddr *)&cdag, dlen)) < 0) { warn("%5d send error\n", pid); break; } say("dgram sent %d bytes\n", n); } Xclose(sock); } }
int getFile(int sock, char *p_ad, char* p_hid, const char *fin, const char *fout) { int chunkSock; int offset; char cmd[512]; char reply[512]; int status = 0; //TODO: check the arguments to be correct // send the file request sprintf(cmd, "get %s", fin); sendCmd(sock, cmd); // get back number of chunks in the file if (getChunkCount(sock, reply, sizeof(reply)) < 1){ warn("could not get chunk count. Aborting. \n"); return -1; } int count = atoi(&reply[4]); if ((chunkSock = Xsocket(AF_XIA, XSOCK_CHUNK, 0)) < 0) die(-1, "unable to create chunk socket\n"); FILE *f = fopen(fout, "w"); offset = 0; while (offset < count) { int num = NUM_CHUNKS; if (count - offset < num) num = count - offset; // tell the server we want a list of <num> cids starting at location <offset> sprintf(cmd, "block %d:%d", offset, num); sendCmd(sock, cmd); if (getChunkCount(sock, reply, sizeof(reply)) < 1){ warn("could not get chunk count. Aborting. \n"); return -1; } offset += NUM_CHUNKS; if (getListedChunks(chunkSock, f, &reply[4], p_ad, p_hid) < 0) { status= -1; break; } } fclose(f); if (status < 0) { unlink(fin); } say("Received file %s\n", fout); sendCmd(sock, "done"); Xclose(chunkSock); return status; }
int main(int argc, char *argv[]) { int sock, n, chunkSock, acceptSock; size_t dlen; char buf[1024],theirDAG[1024]; //char* reply="Got your message"; char reply[1024]; pid_t pid; char myAD[1024]; char myHID[1024]; //Open socket sock=Xsocket(XSOCK_DGRAM); if (sock < 0) error("Opening socket"); // read the localhost AD and HID if ( XreadLocalHostAddr(sock, myAD, sizeof(myAD), myHID, sizeof(myHID)) < 0 ) error("Reading localhost address"); // make the src DAG (the one the server listens on) char * dag = (char*) malloc(snprintf(NULL, 0, "RE %s %s %s", myAD, myHID, SID0) + 1); sprintf(dag, "RE %s %s %s", myAD, myHID, SID0); //Register this service name to the name server char * sname = (char*) malloc(snprintf(NULL, 0, "%s", SNAME) + 1); sprintf(sname, "%s", SNAME); if (XregisterName(sname, dag) < 0 ) error("name register"); //Bind to the DAG Xbind(sock,dag); while (1) { //Receive packet memset(&buf[0], 0, sizeof(buf)); dlen = sizeof(theirDAG); n = Xrecvfrom(sock,buf,1024,0,theirDAG,&dlen); //n = Xrecv(acceptSock,buf,1024,0); if (n < 0) error("recvfrom"); //printf("\nReceived a datagram from:%s len %d strlen %d\n",theirDAG, (int)dlen, (int)strlen(theirDAG)); write(1,buf,n); memset(&reply[0], 0, sizeof(reply)); strcat (reply, "Got your message: "); strcat (reply, buf); //Reply to client Xsendto(sock,reply,strlen(reply)+1,0,theirDAG,strlen(theirDAG)); //Xsend(acceptSock,reply,strlen(reply),0); } return 0; }
TEST(XreadLocalHostAddr, ShortBuffers) { char ad[XID_LEN], hid[XID_LEN], fid[XID_LEN]; int sock = Xsocket(AF_XIA, XSOCK_STREAM, 0); int rc = XreadLocalHostAddr(sock, ad, 10, hid, 10, fid, 10); ASSERT_EQ(0, rc); EXPECT_STRNE(ad, ""); EXPECT_STRNE(hid, ""); EXPECT_STRNE(fid, ""); }
/* ** create a socket and connect to the remote server */ int connectToServer() { int ssock; if ((ssock = Xsocket(AF_XIA, SOCK_DGRAM, 0)) < 0) { die(-2, "unable to create the socket\n"); } say("Xsock %4d created\n", ssock); return ssock; }
int initializeClient(const char *name) { int sock, rc; sockaddr_x dag; socklen_t daglen; char sdag[1024]; char IP[MAX_XID_SIZE]; // lookup the xia service daglen = sizeof(dag); if (XgetDAGbyName(name, &dag, &daglen) < 0) die(-1, "unable to locate: %s\n", name); // create a socket, and listen for incoming connections if ((sock = Xsocket(AF_XIA, SOCK_STREAM, 0)) < 0) die(-1, "Unable to create the listening socket\n"); if (Xconnect(sock, (struct sockaddr*)&dag, daglen) < 0) { Xclose(sock); die(-1, "Unable to bind to the dag: %s\n", dag); } rc = XreadLocalHostAddr(sock, my_ad, MAX_XID_SIZE, my_hid, MAX_XID_SIZE, IP, MAX_XID_SIZE); if (rc < 0) { Xclose(sock); die(-1, "Unable to read local address.\n"); } else{ warn("My AD: %s, My HID: %s\n", my_ad, my_hid); } // save the AD and HID for later. This seems hacky // we need to find a better way to deal with this Graph g(&dag); strncpy(sdag, g.dag_string().c_str(), sizeof(sdag)); // say("sdag = %s\n",sdag); char *ads = strstr(sdag,"AD:"); char *hids = strstr(sdag,"HID:"); // i = sscanf(ads,"%s",s_ad ); // i = sscanf(hids,"%s", s_hid); if(sscanf(ads,"%s",s_ad ) < 1 || strncmp(s_ad,"AD:", 3) !=0){ die(-1, "Unable to extract AD."); } if(sscanf(hids,"%s", s_hid) < 1 || strncmp(s_hid,"HID:", 4) !=0 ){ die(-1, "Unable to extract AD."); } warn("Service AD: %s, Service HID: %s\n", s_ad, s_hid); return sock; }
void integerGet(int opt, int val) { int s = Xsocket(AF_XIA, SOCK_DGRAM, 0); socklen_t sz = sizeof(int); int v = 999; EXPECT_EQ(0, Xsetsockopt(sock, opt, (const void *)&val, sz)); EXPECT_EQ(0, Xgetsockopt(sock, opt, (void *)&v, &sz)); EXPECT_EQ(sizeof(int), sz); EXPECT_EQ(v, val); Xclose(s); }
// XreadLocalHostAddr ********************************************************* TEST(XreadLocalHostAddr, ValidParameters) { char ad[XID_LEN], hid[XID_LEN], fid[XID_LEN]; int sock = Xsocket(AF_XIA, XSOCK_STREAM, 0); int rc = XreadLocalHostAddr(sock, ad, XID_LEN, hid, XID_LEN, fid, XID_LEN); ASSERT_EQ(0, rc); EXPECT_STRNE(ad, ""); EXPECT_STRNE(hid, ""); EXPECT_STRNE(fid, ""); EXPECT_EQ(0, strncmp(ad, "AD:", 3)); EXPECT_EQ(0, strncmp(hid, "HID:", 4)); EXPECT_EQ(0, strncmp(fid, "IP:", 3)); }
int main(int argc, char *argv[]) { int sock, n; size_t dlen; char reply[128]; char buffer[2048],theirDAG[1024]; //Open socket sock=Xsocket(XSOCK_DGRAM); if (sock < 0) error("Opening socket"); //Name query to the name server char * sname = (char*) malloc(snprintf(NULL, 0, "%s", SNAME) + 1); sprintf(sname, "%s", SNAME); char * dag = XgetDAGbyName(sname); while(1) { printf("\nPlease enter the message (0 to exit): "); bzero(buffer,2048); fgets(buffer,2048,stdin); if (buffer[0]=='0'&&strlen(buffer)==2) break; //Use Xconnect() with Xsend() //Xsend(sock,buffer,strlen(buffer),0); //Or use Xsendto() Xsendto(sock,buffer,strlen(buffer),0,dag,strlen(dag)+1); printf("Sent\n"); //Process reply from server dlen = sizeof(theirDAG); n = Xrecvfrom(sock,reply,128,0,theirDAG,&dlen); //n = Xrecv(sock,reply,128,0); if (n < 0) error("recvfrom"); //printf("Received a datagram from:%s\n",theirDAG); write(1,reply,n); printf("\n"); } Xclose(sock); return 0; }
static belle_sip_socket_t create_udp_socket(const char *addr, int port, int *family){ /* struct addrinfo hints={0}; */ struct addrinfo *res=NULL; int err; belle_sip_socket_t sock; char portnum[10]; /* int optval=1; */ snprintf(portnum,sizeof(portnum),"%i",port); /* hints.ai_family=AF_UNSPEC; hints.ai_socktype=SOCK_DGRAM; hints.ai_protocol=IPPROTO_UDP; hints.ai_flags=AI_NUMERICSERV; */ err=Xgetaddrinfo(addr,NULL,NULL,&res); if (err!=0){ printf("getaddrinfo() failed for %s port %i: %s",addr,port,gai_strerror(err)); return -1; } *family=res->ai_family; /* sock=Xsocket(res->ai_family,res->ai_socktype,res->ai_protocol); */ sock=Xsocket(AF_XIA, SOCK_DGRAM, 0); if (sock==-1){ printf("Cannot create UDP socket: %s",belle_sip_get_socket_error_string()); Xfreeaddrinfo(res); return -1; } /* err = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&optval, sizeof (optval)); if (err == -1){ belle_sip_warning ("Fail to set SIP/UDP address reusable: %s.", belle_sip_get_socket_error_string()); } */ err=Xbind(sock,res->ai_addr,res->ai_addrlen); if (err==-1){ printf("udp bind() failed for %s port %i: %s",addr,port,belle_sip_get_socket_error_string()); close_socket(sock); Xfreeaddrinfo(res); return -1; } Xfreeaddrinfo(res); return sock; }
virtual void SetUp() { sockaddr_x sa; int sock = Xsocket(AF_XIA, SOCK_STREAM, 0); XreadLocalHostAddr(sock, ad, XID_LEN, hid, XID_LEN, fid, XID_LEN); sprintf(fdag, FULL_DAG, ad, hid, SID); Graph gf(fdag); gf.fill_sockaddr(&sa); XregisterName(FULL_NAME, &sa); sprintf(hdag, HOST_DAG, ad, hid); Graph gh(hdag); gh.fill_sockaddr(&sa); XregisterName(HOST_NAME, &sa); Xclose(sock); nad = new Node(ad); nhid = new Node(hid); nsid = new Node(SID); ai = NULL; }
int main(int argc, char **argv) { struct addrinfo *ai; sockaddr_x *sa; int seq = 0; // FIXME: put signal handlers back into code once Xselect is working // signal(SIGINT, handler); // signal(SIGTERM, handler); getConfig(argc, argv); if (Xgetaddrinfo(NAME, NULL, NULL, &ai) < 0) die("Unable to lookup address for %s\n", NAME); sa = (sockaddr_x*)ai->ai_addr; if ((sock = Xsocket(AF_XIA, SOCK_STREAM, 0)) < 0) die("Unable to create a socket\n"); say("Opening firehose: %s\n", NAME); if (Xconnect(sock, (struct sockaddr*)sa, sizeof(sockaddr_x)) < 0) { Xclose(sock); die("Unable to connect to %s\n", NAME); } // tell firehose how many packets we expect if (Xsend(sock, &fhc, sizeof(fhc), 0) < 0) { Xclose(sock); die("Unable to send config information to the firehose\n"); } int count = 0; char *buf = (char *)malloc(pktSize); while (!timetodie) { int n; fd_set fds; FD_ZERO(&fds); FD_SET(sock, &fds); struct timeval tv; tv.tv_sec = 2; tv.tv_usec = 0; if ((n = Xselect(sock + 1, &fds, NULL, NULL, &tv)) < 0) { printf("select failed\n"); break; } else if (n == 0) { printf("recv timeout\n"); break; } else if (!FD_ISSET(sock, &fds)) { // this shouldn't happen! printf("something is really wrong, exiting\n"); break; } int rc = Xrecv(sock, buf, sizeof(buf), 0); if (rc < 0) die("Receive failure\n"); memcpy(&seq, buf, sizeof(int)); say("expecting %d, got %d", count, seq); if (count == seq) say("\n"); else say(" lost %d\n", seq - count); count++; if (count == numPkts) break; if (delay) usleep(delay); } seq++; if (count != seq) printf("lost %d packets, received %d, expected %d\n", seq - count, count, seq); else printf("success!\n"); Xclose(sock); }
int main() { int sock; socklen_t len; char buf[XIA_MAXBUF]; sockaddr_x client; time_t now; struct tm *t; // create a datagram socket if ((sock = Xsocket(AF_XIA, SOCK_DGRAM, 0)) < 0) { printf("error: unable to create the listening socket.\n"); exit(1); } struct addrinfo *ai; if (Xgetaddrinfo(NULL, SID0, NULL, &ai) != 0) { printf("error: unable to create source dag."); exit(1); } sockaddr_x *sa = (sockaddr_x*)ai->ai_addr; //Register this service name to the name server if (XregisterName(SNAME, sa) < 0) { printf("error: unable to register name/dag combo"); exit(1); } // bind to the DAG if (Xbind(sock, (struct sockaddr*)sa, sizeof(sockaddr_x)) < 0) { Xclose(sock); printf("error: unable to bind to %s\n", SNAME); exit(1); } while (1) { len = sizeof(client); if (Xrecvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr*)&client, &len) < 0) { printf("error receiving client request\n"); // assume it's ok, and just keep listening continue; } // we don't care what the client said, so we'll just ignore it now = time(NULL); t = gmtime(&now); strftime(buf, sizeof(buf), "%c %Z", t); Graph g(&client); printf("request from:\n%s\n", g.dag_string().c_str()); //Reply to client if (Xsendto(sock, buf, strlen(buf) + 1, 0, (struct sockaddr*)&client, sizeof(client)) < 0) printf("error sending time to the client\n"); } Xclose(sock); return 0; }
int main(int argc, char **argv) { int sock = -1; int peer = -1; struct addrinfo hints, *ai; // FIXME: put signal handlers back into code once Xselect is working // signal(SIGINT, handler); // signal(SIGTERM, handler); configure(argc, argv); say("XIA firehose listening on %s\n", name); // get our local AD/HID and append the SID to the resultant dag memset(&hints, 0, sizeof(hints)); hints.ai_flags = XAI_XIDSERV; int rc = Xgetaddrinfo(NULL, SID, &hints, &ai); if (rc != 0) die("%s\n", Xgai_strerror(rc)); sockaddr_x *sa = (sockaddr_x*)ai->ai_addr; if ( XregisterName(NAME, sa) < 0) die("Unable to register name %s\n", name); if ((sock = Xsocket(AF_XIA, SOCK_STREAM, 0)) < 0) die("Unable to create socket\n"); if (Xbind(sock, (struct sockaddr*)sa, sizeof(sockaddr_x)) < 0) { Xclose(sock); die("Unable to bind to DAG\n"); } while (!timetodie) { fd_set fds; FD_ZERO(&fds); FD_SET(sock, &fds); struct timeval tv; tv.tv_sec = 2; tv.tv_usec = 0; if ((rc = Xselect(sock + 1, &fds, NULL, NULL, &tv)) < 0) { printf("select failed\n"); break; } else if (rc == 0) { // timed out, try again continue; } else if (!FD_ISSET(sock, &fds)) { // this shouldn't happen! printf("something is really wrong, exiting\n"); break; } peer = Xaccept(sock, NULL, NULL); if (peer < 0) { printf("Xaccept failed\n"); break; } say("peer connected...\n"); pid_t pid = fork(); if (pid == -1) { printf("fork failed\n"); break; } else if (pid == 0) { process(peer); exit(0); } else { // use regular close so we don't rip out the Xsocket state from under the child close(peer); } } say("firehose exiting\n"); Xclose(sock); return 0; }
void echo_stream() { int acceptor, sock; if (signal(SIGCHLD, reaper) == SIG_ERR) { die(-1, "unable to catch SIGCHLD"); } say("Stream service started\n"); /* Prepare XSSL context and get SID (based on RSA key) */ XSSL_CTX *ctx = XSSL_CTX_new(); if (ctx == NULL) { die(-5, "Unable to create new XSSL_CTX\n"); } char *SID = SID_from_keypair(ctx->keypair); /* Prepare listen socket, binding to generated SID */ if ((acceptor = Xsocket(AF_XIA, SOCK_STREAM, 0)) < 0) die(-2, "unable to create the stream socket\n"); struct addrinfo *ai; if (Xgetaddrinfo(NULL, SID, NULL, &ai) != 0) die(-1, "getaddrinfo failure!\n"); Graph g((sockaddr_x*)ai->ai_addr); sockaddr_x *sa = (sockaddr_x*)ai->ai_addr; printf("\nStream DAG\n%s\n", g.dag_string().c_str()); if (XregisterName(STREAM_NAME, sa) < 0 ) die(-1, "error registering name: %s\n", STREAM_NAME); say("registered name: \n%s\n", STREAM_NAME); if (Xbind(acceptor, (struct sockaddr *)sa, sizeof(sockaddr_x)) < 0) { die(-3, "unable to bind to the dag\n"); } Xlisten(acceptor, 5); while (1) { say("Xsock %4d waiting for a new connection.\n", acceptor); if ((sock = Xaccept(acceptor, NULL, 0)) < 0) { warn("Xsock %d accept failure! error = %d\n", acceptor, errno); // FIXME: should we die here instead or try and recover? continue; } say ("Xsock %4d new session\n", sock); pid_t pid = fork(); if (pid == -1) { die(-1, "FORK FAILED\n"); } else if (pid == 0) { process(sock, ctx); exit(0); } else { // FIXME: we need to close the socket in the main process or the file // descriptor limit will be hit. But if Xclose is called, the connection // is torn down in click as well keeping the child process from using it. // for now use a regular close to shut it here without affecting the child. close(sock); } } Xclose(acceptor); XSSL_CTX_free(ctx); free(SID); }
virtual void SetUp() { sock = Xsocket(AF_XIA, SOCK_DGRAM, 0); }
// Xclose ********************************************************************* TEST(Xclose, ValidSocket) { int sock = Xsocket(AF_XIA, SOCK_STREAM, 0); EXPECT_EQ(0, Xclose(sock)); }
TEST(Xsocket, InvalidProtocol) { int sock = Xsocket(AF_XIA, SOCK_STREAM, 10); EXPECT_EQ(sock, -1); }
TEST(Xsocket, InvalidFamily) { int sock = Xsocket(AF_INET, SOCK_STREAM, 0); EXPECT_EQ(sock, -1); }
TEST(Xsocket, InvalidType) { int sock = Xsocket(AF_XIA, 7, 0); EXPECT_EQ(sock, -1); }
TEST(Xsocket, Raw) { int sock = Xsocket(AF_XIA, SOCK_RAW, 0); EXPECT_GT(sock, -1); Xclose(sock); }
TEST(Xsocket, Chunk) { int sock = Xsocket(AF_XIA, XSOCK_CHUNK, 0); EXPECT_GT(sock, -1); Xclose(sock); }
void echo_stream() { int acceptor, sock; char sid_string[strlen("SID:") + XIA_SHA_DIGEST_STR_LEN]; if (signal(SIGCHLD, reaper) == SIG_ERR) { die(-1, "unable to catch SIGCHLD"); } say("Stream service started\n"); if ((acceptor = Xsocket(AF_XIA, SOCK_STREAM, 0)) < 0) die(-2, "unable to create the stream socket\n"); // Generate an SID to use if(XmakeNewSID(sid_string, sizeof(sid_string))) { die(-1, "Unable to create a temporary SID"); } struct addrinfo hints, *ai; bzero(&hints, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; hints.ai_family = AF_XIA; if (Xgetaddrinfo(NULL, sid_string, &hints, &ai) != 0) die(-1, "getaddrinfo failure!\n"); Graph g((sockaddr_x*)ai->ai_addr); sockaddr_x *sa = (sockaddr_x*)ai->ai_addr; printf("\nStream DAG\n%s\n", g.dag_string().c_str()); if (XregisterName(STREAM_NAME, sa) < 0 ) die(-1, "error registering name: %s\n", STREAM_NAME); say("registered name: \n%s\n", STREAM_NAME); if (Xbind(acceptor, (struct sockaddr *)sa, sizeof(sockaddr_x)) < 0) { die(-3, "unable to bind to the dag\n"); } Xlisten(acceptor, 5); while (1) { say("Xsock %4d waiting for a new connection.\n", acceptor); sockaddr_x sa; socklen_t sz = sizeof(sa); if ((sock = Xaccept(acceptor, (sockaddr*)&sa, &sz)) < 0) { warn("Xsock %d accept failure! error = %d\n", acceptor, errno); // FIXME: should we die here instead or try and recover? continue; } Graph g(&sa); say ("Xsock %4d new session\n", sock); say("peer:%s\n", g.dag_string().c_str()); pid_t pid = Xfork(); if (pid == -1) { die(-1, "FORK FAILED\n"); } else if (pid == 0) { // close the parent's listening socket Xclose(acceptor); process(sock); exit(0); } else { // close the child's socket Xclose(sock); } } Xclose(acceptor); }
/*! ** @brief Lookup a DAG based using a host or service name. ** ** The name should be a string such as www_s.example.xia or host.example.xia. ** By convention services are indicated by '_s' appended to the service name. ** The memory returned is dynamically allocated and should be released with a ** call to free() when the caller is done with it. ** ** This is a very simple implementation of the name query function. ** It will be replaces in a future release. ** ** @param name The name of an XIA service or host. ** ** @returns a character point to the dag on success ** @returns NULL on failure ** */ int XgetDAGbyName(const char *name, sockaddr_x *addr, socklen_t *addrlen) { int sock; sockaddr_x ns_dag; char pkt[NS_MAX_PACKET_SIZE]; char *dag; char _name[NS_MAX_DAG_LENGTH], _dag[NS_MAX_DAG_LENGTH]; int result; if (!addr || !addrlen || *addrlen < sizeof(sockaddr_x)) { errno = EINVAL; return -1; } // see if name is registered in the local hosts.xia file if((dag = hostsLookup(name))) { Graph g(dag); free(dag); // check to see if the returned dag was valid // we may want a better check for this in the future if (g.num_nodes() > 0) { std::string s = g.dag_string(); g.fill_sockaddr((sockaddr_x*)addr); *addrlen = sizeof(sockaddr_x); return 0; } } // not found locally, check the name server if ((sock = Xsocket(AF_XIA, SOCK_DGRAM, 0)) < 0) return -1; //Read the nameserver DAG (the one that the name-query will be sent to) if ( XreadNameServerDAG(sock, &ns_dag) < 0 ) { LOG("Unable to find nameserver address"); errno = NO_RECOVERY; return -1; } //Construct a name-query packet ns_pkt query_pkt; query_pkt.type = NS_TYPE_QUERY; query_pkt.name = strdup(name); memset(pkt, 0, sizeof(pkt)); int offset = 0; memcpy(pkt, &query_pkt.type, sizeof(query_pkt.type)); offset += sizeof(query_pkt.type); memcpy(pkt+offset, query_pkt.name, strlen(query_pkt.name)+1); offset += strlen(query_pkt.name)+1; //Send a name query to the name server Xsendto(sock, pkt, offset, 0, (const struct sockaddr*)&ns_dag, sizeof(sockaddr_x)); //Check the response from the name server memset(pkt, 0, sizeof(pkt)); int rc = Xrecvfrom(sock, pkt, NS_MAX_PACKET_SIZE, 0, NULL, NULL); if (rc < 0) { perror("recvfrom"); } memset(_name, '\0', NS_MAX_DAG_LENGTH); memset(_dag, '\0', NS_MAX_DAG_LENGTH); ns_pkt *tmp = (ns_pkt *)pkt; char* tmp_name = (char*)(pkt+sizeof(tmp->type)); char* tmp_dag = (char*)(pkt+sizeof(tmp->type)+ strlen(tmp_name)+1); switch (tmp->type) { case NS_TYPE_RESPONSE: sprintf(_name, "%s", tmp_name); sprintf(_dag, "%s", tmp_dag); result = 1; break; case NS_TYPE_RESPONSE_ERROR: result = -1; break; default: LOG("Unknown nameserver response"); result = -1; break; } Xclose(sock); free(query_pkt.name); if (result < 0) { return result; } Graph g(_dag); g.fill_sockaddr(addr); return 0; }
// Xsocket ******************************************************************* TEST(Xsocket, Stream) { int sock = Xsocket(AF_XIA, SOCK_STREAM, 0); EXPECT_GT(sock, -1); Xclose(sock); }
static int udp_tl_open(void) { int res; struct addrinfo *addrinfo = NULL; struct addrinfo *curinfo; int sock = -1; sockaddr_x *sa; if (eXtl_udp.proto_port < 0) eXtl_udp.proto_port = 5060; res = eXosip_get_addrinfo(&addrinfo, eXtl_udp.proto_ifs, eXtl_udp.proto_port, eXtl_udp.proto_num); if (res) return -1; for (curinfo = addrinfo; curinfo; curinfo = curinfo->ai_next) { socklen_t len; if (curinfo->ai_protocol && curinfo->ai_protocol != eXtl_udp.proto_num) { OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_INFO3, NULL, "eXosip: Skipping protocol %d\n", curinfo->ai_protocol)); continue; } /* sock = (int) socket(curinfo->ai_family, curinfo->ai_socktype, curinfo->ai_protocol); */ sock = (int) Xsocket(AF_XIA, SOCK_DGRAM, 0); if (sock < 0) { OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: Cannot create socket %s!\n", strerror(errno))); continue; } /* if (curinfo->ai_family == AF_INET6) { #ifdef IPV6_V6ONLY if (setsockopt_ipv6only(sock)) { close(sock); sock = -1; OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: Cannot set socket option %s!\n", strerror(errno))); continue; } #endif } */ /* res = bind(sock, curinfo->ai_addr, curinfo->ai_addrlen); */ sa = (sockaddr_x*)(curinfo->ai_addr); res = Xbind(sock, (struct sockaddr *)sa, sizeof(sockaddr_x)); if (res < 0) { OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: Cannot bind socket node:%s family:%d %s\n", eXtl_udp.proto_ifs, curinfo->ai_family, strerror(errno))); Xclose(sock); sock = -1; continue; } len = sizeof(ai_addr); /* res = getsockname(sock, (struct sockaddr *) &ai_addr, &len); */ res = Xgetsockname(sock, (struct sockaddr *) &ai_addr, &len); if (res != 0) { OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: Cannot get socket name (%s)\n", strerror(errno))); memcpy(&ai_addr, curinfo->ai_addr, curinfo->ai_addrlen); } /* if (eXtl_udp.proto_num != IPPROTO_UDP) { res = listen(sock, SOMAXCONN); if (res < 0) { OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: Cannot bind socket node:%s family:%d %s\n", eXtl_udp.proto_ifs, curinfo->ai_family, strerror(errno))); close(sock); sock = -1; continue; } } */ break; } eXosip_freeaddrinfo(addrinfo); /* Xfreeaddrinfo(addrinfo); */ if (sock < 0) { OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: Cannot bind on port: %i\n", eXtl_udp.proto_port)); return -1; } udp_socket = sock; /* if (eXtl_udp.proto_family == AF_INET) { int tos = (eXosip.dscp << 2) & 0xFC; res = setsockopt(udp_socket, IPPROTO_IP, IP_TOS, (SOCKET_OPTION_VALUE)&tos, sizeof(tos)); } else { int tos = (eXosip.dscp << 2) & 0xFC; #ifdef IPV6_TCLASS res = setsockopt(udp_socket, IPPROTO_IPV6, IPV6_TCLASS, (SOCKET_OPTION_VALUE)&tos, sizeof(tos)); #else res = setsockopt(udp_socket, IPPROTO_IPV6, IP_TOS, (SOCKET_OPTION_VALUE)&tos, sizeof(tos)); #endif } if (eXtl_udp.proto_port == 0) { get port number from socket if (eXtl_udp.proto_family == AF_INET) eXtl_udp.proto_port = ntohs(((struct sockaddr_in *) &ai_addr)->sin_port); else eXtl_udp.proto_port = ntohs(((struct sockaddr_in6 *) &ai_addr)->sin6_port); OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "eXosip: Binding on port %i!\n", eXtl_udp.proto_port)); } snprintf(udp_firewall_port, sizeof(udp_firewall_port), "%i", eXtl_udp.proto_port); */ return OSIP_SUCCESS; }
/*! ** @brief Register a service or hostname with the name server. ** ** Register a host or service name with the XIA nameserver. ** By convention services are indicated by '_s' appended to the service name. ** The memory returned is dynamically allocated and should be released with a ** call to free() when the caller is done with it. ** ** This is a very simple implementation and will be replaced in a ** future release. This version does not check correctness of the name or dag, ** nor does it check to ensure that the client is allowed to bind to name. ** ** @param name - The name of an XIA service or host. ** @param DAG - the DAG to be bound to name. ** ** @returns 0 on success ** @returns -1 on failure with errno set ** */ int XregisterName(const char *name, sockaddr_x *DAG) { int sock; sockaddr_x ns_dag; char pkt[NS_MAX_PACKET_SIZE]; char _name[NS_MAX_DAG_LENGTH], _dag[NS_MAX_DAG_LENGTH]; int result; if ((sock = Xsocket(AF_XIA, SOCK_DGRAM, 0)) < 0) return -1; //Read the nameserver DAG (the one that the name-registration will be sent to) if (XreadNameServerDAG(sock, &ns_dag) < 0) { LOG("Unable to find nameserver address"); errno = NO_RECOVERY; return -1; } if (!DAG) { errno = EINVAL; return -1; } Graph g(DAG); if (g.num_nodes() <= 0) { errno = EINVAL; return -1; } //Construct a registration packet ns_pkt register_pkt; register_pkt.type = NS_TYPE_REGISTER; register_pkt.name = strdup(name); register_pkt.dag = strdup(g.dag_string().c_str()); memset(pkt, 0, sizeof(pkt)); int offset = 0; memcpy(pkt, ®ister_pkt.type, sizeof(register_pkt.type)); offset += sizeof(register_pkt.type); memcpy(pkt+offset, register_pkt.name, strlen(register_pkt.name)+1); offset += strlen(register_pkt.name)+1; memcpy(pkt+offset, register_pkt.dag, strlen(register_pkt.dag)+1); offset += strlen(register_pkt.dag)+1; //Send the name registration packet to the name server //FIXME: use sockaddr here Xsendto(sock, pkt, offset, 0, (const struct sockaddr *)&ns_dag, sizeof(sockaddr_x)); //Check the response from the name server memset(pkt, 0, sizeof(pkt)); int rc = Xrecvfrom(sock, pkt, NS_MAX_PACKET_SIZE, 0, NULL, NULL); if (rc < 0) { perror("recvfrom"); } memset(_name, '\0', NS_MAX_DAG_LENGTH); memset(_dag, '\0', NS_MAX_DAG_LENGTH); ns_pkt *tmp = (ns_pkt *)pkt; char* tmp_name = (char*)(pkt+sizeof(tmp->type)); char* tmp_dag = (char*)(pkt+sizeof(tmp->type)+ strlen(tmp_name)+1); switch (tmp->type) { case NS_TYPE_RESPONSE: sprintf(_name, "%s", tmp_name); sprintf(_dag, "%s", tmp_dag); result = 0; break; case NS_TYPE_RESPONSE_ERROR: result = -1; break; default: fprintf(stderr, "dafault\n"); result = -1; break; } free(register_pkt.name); free(register_pkt.dag); Xclose(sock); return result; }
TEST(Xsocket, Dgram) { int sock = Xsocket(AF_XIA, SOCK_DGRAM, 0); EXPECT_GT(sock, -1); Xclose(sock); }