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); } }
/* ** do one send/receive operation on the specified socket */ int process(int sock) { int size; int sent, received; char tdag[1024]; size_t dlen; char buf1[XIA_MAXBUF], buf2[XIA_MAXBUF]; if (pktSize == 0) size = (rand() % XIA_MAXBUF) + 1; else size = pktSize; randomString(buf1, size); if ((sent = Xsendto(sock, buf1, size, 0, sdag, strlen(sdag)+1)) < 0) { die(-4, "Send error %d on socket %d\n", errno, sock); } say("Xsock %4d sent %d bytes\n", sock, sent); memset(buf2, sizeof(buf2), 0); dlen = sizeof(tdag); if ((received = Xrecvfrom(sock, buf2, sizeof(buf2), 0, tdag, &dlen)) < 0) die(-5, "Receive error %d on socket %d\n", errno, sock); say("Xsock %4d received %d bytes\n", sock, received); if (sent != received || strcmp(buf1, buf2) != 0) { warn("Xsock %4d received data different from sent data! (bytes sent/recv'd: %d/%d)\n", sock, sent, received); } return 0; }
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; }
/*peek data from the master socket to see where it comes from, and dispatch to matching channel. * If the channel does not exist, create it */ static int on_udp_data(belle_sip_udp_listening_point_t *lp, unsigned int events){ int err; unsigned char buf[4096]; sockaddr_x addr; socklen_t addrlen=sizeof(sockaddr_x); if (events & BELLE_SIP_EVENT_READ){ belle_sip_debug("udp_listening_point: data to read."); err=Xrecvfrom(lp->sock,(char*)buf,sizeof(buf),MSG_PEEK,(struct sockaddr*)&addr,&addrlen); if (err==-1){ char *tmp=belle_sip_object_to_string((belle_sip_object_t*) ((belle_sip_listening_point_t*)lp)->listening_uri); belle_sip_error("udp_listening_point: recvfrom() failed on [%s], : [%s] reopening server socket" ,tmp ,belle_sip_get_socket_error_string()); belle_sip_free(tmp); belle_sip_udp_listening_point_uninit(lp); /*clean all udp channels that are actually sharing the server socket with the listening points*/ belle_sip_listening_point_clean_channels((belle_sip_listening_point_t*)lp); belle_sip_udp_listening_point_init_socket(lp); }else{ belle_sip_channel_t *chan; struct addrinfo ai={0}; belle_sip_address_remove_v4_mapping((struct sockaddr*)&addr,(struct sockaddr*)&addr,&addrlen); ai.ai_family=((struct sockaddr*)&addr)->sa_family; ai.ai_addr=(struct sockaddr*)&addr; ai.ai_addrlen=addrlen; chan=_belle_sip_listening_point_get_channel((belle_sip_listening_point_t*)lp,NULL,&ai); if (chan==NULL){ /*TODO: should rather create the channel with real local ip and port and not just 0.0.0.0"*/ chan=belle_sip_channel_new_udp_with_addr(lp->base.stack ,lp->sock ,belle_sip_uri_get_host(lp->base.listening_uri) ,belle_sip_uri_get_port(lp->base.listening_uri) ,&ai); if (chan!=NULL){ belle_sip_message("udp_listening_point: new channel created to %s:%i",chan->peer_name,chan->peer_port); chan->lp=(belle_sip_listening_point_t*)lp; /*FIXME, exactly the same code as for channel creation from provider. might be good to factorize*/ belle_sip_listening_point_add_channel((belle_sip_listening_point_t*)lp,chan); } } if (chan){ /*notify the channel*/ belle_sip_debug("Notifying udp channel, local [%s:%i] remote [%s:%i]" ,chan->local_ip ,chan->local_port ,chan->peer_name ,chan->peer_port); belle_sip_channel_process_data(chan,events); } } } return BELLE_SIP_CONTINUE; }
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; }
/* ** do one send/receive operation on the specified socket */ int process(int sock) { int size; int sent, received, rc; char buf1[XIA_MAXBUF], buf2[XIA_MAXBUF]; if (pktSize == 0) size = (rand() % XIA_MAXBUF) + 1; else size = pktSize; randomString(buf1, size); if ((sent = Xsendto(sock, buf1, size, 0, (sockaddr*)sa, sizeof(sockaddr_x))) < 0) { die(-4, "Send error %d on socket %d\n", errno, sock); } say("Xsock %4d sent %d bytes\n", sock, sent); struct pollfd pfds[2]; pfds[0].fd = sock; pfds[0].events = POLLIN; if ((rc = Xpoll(pfds, 1, 5000)) <= 0) { die(-5, "Poll returned %d\n", rc); } memset(buf2, 0, sizeof(buf2)); if ((received = Xrecvfrom(sock, buf2, sizeof(buf2), 0, NULL, NULL)) < 0) die(-5, "Receive error %d on socket %d\n", errno, sock); say("Xsock %4d received %d bytes\n", sock, received); if (sent != received || strcmp(buf1, buf2) != 0) { warn("Xsock %4d received data different from sent data! (bytes sent/recv'd: %d/%d)\n", sock, sent, received); } return 0; }
/*! ** @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; }
/*! ** @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; }
static int udp_tl_read_message(fd_set * osip_fdset, fd_set * osip_wrset) { char *buf; int i; if (udp_socket <= 0) return -1; if (FD_ISSET(udp_socket, osip_fdset)) { sockaddr_x sa; #ifdef __linux socklen_t slen; #else int slen; #endif /* if (eXtl_udp.proto_family == AF_INET) slen = sizeof(struct sockaddr_in); else slen = sizeof(struct sockaddr_in6); */ slen = sizeof(sockaddr_x); buf = (char *) osip_malloc(SIP_MESSAGE_MAX_LENGTH * sizeof(char) + 1); if (buf == NULL) return OSIP_NOMEM; /* i = recvfrom(udp_socket, buf, SIP_MESSAGE_MAX_LENGTH, 0, (struct sockaddr *) &sa, &slen); */ i = Xrecvfrom(udp_socket, buf, SIP_MESSAGE_MAX_LENGTH, 0, (struct sockaddr *) &sa, &slen); if (i > 5) { char src6host[NI_MAXHOST]; /* int recvport = 0; int err; */ buf[i] = '\0'; OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO1, NULL, "Received message: \n%s\n", buf)); memset(src6host, 0, sizeof(src6host)); /* if (eXtl_udp.proto_family == AF_INET) recvport = ntohs(((struct sockaddr_in *) &sa)->sin_port); else recvport = ntohs(((struct sockaddr_in6 *) &sa)->sin6_port); #if defined(__arc__) { struct sockaddr_in *fromsa = (struct sockaddr_in *) &sa; char *tmp; tmp = inet_ntoa(fromsa->sin_addr); if (tmp == NULL) { OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Message received from: NULL:%i inet_ntoa failure\n", recvport)); } else { snprintf(src6host, sizeof(src6host), "%s", tmp); OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Message received from: %s:%i\n", src6host, recvport)); } } #else err = getnameinfo((struct sockaddr *) &sa, slen, src6host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); if (err != 0) { OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Message received from: NULL:%i getnameinfo failure\n", recvport)); snprintf(src6host, sizeof(src6host), "127.0.0.1"); } else { OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Message received from: %s:%i\n", src6host, recvport)); } #endif OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Message received from: %s:%i\n", src6host, recvport)); */ _eXosip_handle_incoming_message(buf, i, udp_socket, src6host, 0); } #ifndef MINISIZE else if (i < 0) { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "Could not read socket\n")); if (udp_socket > 0) close(udp_socket); udp_tl_open(); } else { OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO1, NULL, "Dummy SIP message received\n")); } #endif osip_free(buf); } return OSIP_SUCCESS; }
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; }
/*! ** @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 ** */ char *XgetDAGbyName(const char *name) { int sock; char pkt[NS_MAX_PACKET_SIZE],ddag[NS_MAX_PACKET_SIZE], ns_dag[NS_MAX_PACKET_SIZE]; char *dag; char _name[NS_MAX_DAG_LENGTH], _dag[NS_MAX_DAG_LENGTH]; int result; //Open socket sock=Xsocket(XSOCK_DGRAM); //Read the nameserver DAG (the one that the name-query will be sent to) if ( XreadNameServerDAG(sock, ns_dag) < 0 ) error("Reading nameserver address"); //Construct a name-query packet ns_pkt query_pkt; query_pkt.type = NS_TYPE_QUERY; query_pkt.name = (char*)malloc(strlen(name)+1); sprintf(query_pkt.name, "%s", name); //query_pkt.dag = (char*)malloc(strlen(DAG)+1); //sprintf(query_pkt.dag, "%s", DAG); 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; //memcpy(pkt+offset, query_pkt.dag, strlen(query_pkt.dag)+1); //offset += strlen(query_pkt.dag)+1; //Send a name query to the name server Xsendto(sock, pkt, offset, 0, ns_dag, strlen(ns_dag)+1); //Check the response from the name server memset(pkt, 0, sizeof(pkt)); memset(ddag, 0, sizeof(ddag)); size_t ddaglen = sizeof(ddag); int rc = Xrecvfrom(sock, pkt, NS_MAX_PACKET_SIZE, 0, ddag, &ddaglen); if (rc < 0) { error("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: fprintf(stderr, "dafault\n"); result = -1; break; } if (result < 0) { return NULL; } dag = (char*)malloc(sizeof(_dag) + 1); strcpy(dag, _dag); //Close socket Xclose(sock); free(query_pkt.name); return dag; }