1 #include "osrf_transgroup.h"
2 #include <sys/select.h>
5 osrfTransportGroupNode* osrfNewTransportGroupNode(
6 char* domain, int port, char* username, char* password, char* resource ) {
8 if(!(domain && port && username && password && resource)) return NULL;
10 osrfTransportGroupNode* node = safe_malloc(sizeof(osrfTransportGroupNode));
11 node->domain = strdup(domain);
13 node->username = strdup(username);
14 node->password = strdup(password);
15 node->domain = strdup(domain);
16 node->resource = strdup(resource);
19 node->connection = client_init( domain, port, NULL, 0 );
25 osrfTransportGroup* osrfNewTransportGroup( osrfTransportGroupNode* nodes[], int count ) {
26 if(!nodes || count < 1) return NULL;
28 osrfTransportGroup* grp = safe_malloc(sizeof(osrfTransportGroup));
29 grp->nodes = osrfNewHash();
30 grp->itr = osrfNewHashIterator(grp->nodes);
33 for( i = 0; i != count; i++ ) {
34 if(!(nodes[i] && nodes[i]->domain) ) return NULL;
35 osrfHashSet( grp->nodes, nodes[i], nodes[i]->domain );
42 /* connect all of the nodes to their servers */
43 int osrfTransportGroupConnect( osrfTransportGroup* grp ) {
47 osrfTransportGroupNode* node;
48 osrfHashIteratorReset(grp->itr);
50 while( (node = osrfHashIteratorNext(grp->itr)) ) {
51 if(client_connect( node->connection, node->username,
52 node->password, node->resource, 10, AUTH_DIGEST )) {
58 osrfHashIteratorReset(grp->itr);
63 int osrfTransportGroupSendMatch( osrfTransportGroup* grp, transport_message* msg ) {
64 if(!(grp && msg)) return -1;
68 jid_get_domain( msg->recipient, domain, 255 );
70 osrfTransportGroupNode* node = osrfHashGet(grp->nodes, domain);
72 if( (client_send_message( node->connection, msg )) == 0 )
76 return warning_handler("Error sending message to domain %s", domain );
79 int osrfTransportGroupSend( osrfTransportGroup* grp, transport_message* msg ) {
81 if(!(grp && msg)) return -1;
85 bzero(domain, bufsize);
86 jid_get_domain( msg->recipient, domain, bufsize - 1 );
88 char msgrecip[bufsize];
89 bzero(msgrecip, bufsize);
90 jid_get_username(msg->recipient, msgrecip, bufsize - 1);
93 bzero(msgres, bufsize);
94 jid_get_resource(msg->recipient, msgres, bufsize - 1);
96 char* firstdomain = NULL;
100 /* if we don't host this domain, don't update the recipient but send it as is */
101 if(!osrfHashGet(grp->nodes, domain)) updateRecip = 0;
103 osrfTransportGroupNode* node;
107 node = osrfHashIteratorNext(grp->itr);
108 if(!node) osrfHashIteratorReset(grp->itr);
110 node = osrfHashIteratorNext(grp->itr);
113 if(firstdomain == NULL) {
114 firstdomain = node->domain;
117 if(!strcmp(firstdomain, node->domain)) { /* we've made a full loop */
118 return warning_handler("We've tried to send to all domains.. giving up");
122 /* update the recipient domain if necessary */
126 sprintf(newrcp, "%s@%s/%s", msgrecip, node->domain, msgres);
127 free(msg->recipient);
128 msg->recipient = strdup(newrcp);
131 if( (client_send_message( node->connection, msg )) == 0 )
139 static int __osrfTGWait( fd_set* fdset, int maxfd, int timeout ) {
140 if(!(fdset && maxfd)) return 0;
148 if( (retval = select( maxfd + 1, fdset, NULL, NULL, NULL)) == -1 )
152 if( (retval = select( maxfd + 1, fdset, NULL, NULL, &tv)) == -1 )
160 transport_message* osrfTransportGroupRecvAll( osrfTransportGroup* grp, int timeout ) {
161 if(!grp) return NULL;
167 osrfTransportGroupNode* node;
168 osrfHashIterator* itr = osrfNewHashIterator(grp->nodes);
170 while( (node = osrfHashIteratorNext(itr)) ) {
172 int fd = node->connection->session->sock_id;
173 if( fd < maxfd ) maxfd = fd;
174 FD_SET( fd, &fdset );
177 osrfHashIteratorReset(itr);
179 if( __osrfTGWait( &fdset, maxfd, timeout ) ) {
180 while( (node = osrfHashIteratorNext(itr)) ) {
182 int fd = node->connection->session->sock_id;
183 if( FD_ISSET( fd, &fdset ) ) {
184 return client_recv( node->connection, 0 );
190 osrfHashIteratorFree(itr);
194 transport_message* osrfTransportGroupRecv( osrfTransportGroup* grp, char* domain, int timeout ) {
195 if(!(grp && domain)) return NULL;
197 osrfTransportGroupNode* node = osrfHashGet(grp->nodes, domain);
198 if(!node && node->connection && node->connection->session) return NULL;
199 int fd = node->connection->session->sock_id;
203 FD_SET( fd, &fdset );
205 int active = __osrfTGWait( &fdset, fd, timeout );
206 if(active) return client_recv( node->connection, 0 );
211 void osrfTransportGroupSetInactive( osrfTransportGroup* grp, char* domain ) {
212 if(!(grp && domain)) return;
213 osrfTransportGroupNode* node = osrfHashGet(grp->nodes, domain );
214 if(node) node->active = 0;