]> git.evergreen-ils.org Git - OpenSRF.git/blob - src/router/router.c
f5f8be5e5ca8e2572c67468c1194416e460d5cfa
[OpenSRF.git] / src / router / router.c
1 #include "router.h"
2 #include <sys/types.h>
3 #include <signal.h>
4
5 #define ROUTER_MAX_MSGS_PER_PACKET 12
6 char* router_resource;
7 transport_router_registrar* routt;
8 void _build_trusted_sites( transport_router_registrar* router );
9
10
11 void sig_hup_handler( int a ) { 
12         router_registrar_free( routt ); 
13         config_reader_free();   
14         log_free();
15         free( router_resource );
16         exit(0); 
17 }
18
19
20 int main( int argc, char* argv[] ) {
21
22         if( argc < 2 ) {
23                 fatal_handler( "Usage: %s <path_to_config_file>", argv[0] );
24                 exit(0);
25         }
26
27         char b[256];
28         memset(b,0,256);
29         jid_get_domain( "client@elroy/test", b );
30         fprintf(stderr, "Domain %s\n", b );
31
32         config_reader_init( argv[1] );  
33         if( conf_reader == NULL ) fatal_handler( "main(): Config is NULL" ); 
34
35         /* laod the config options */
36         char* server                    = config_value("//router/transport/server");
37         char* port                              = config_value("//router/transport/port");
38         char* username                  = config_value("//router/transport/username");
39         char* password                  = config_value("//router/transport/password");
40         router_resource         = config_value("//router/transport/resource");
41         char* con_timeout               = config_value("//router/transport/connect_timeout" );
42         char* max_retries               = config_value("//router/transport/max_reconnect_attempts" );
43         char* component         = config_value("//router/component" );
44
45         fprintf(stderr, "Router connecting as \nserver: %s \nport: %s \nuser:%s \nresource:%s\n", 
46                         server, port, username, router_resource );
47
48         int iport                       = atoi( port );
49         int con_itimeout        = atoi( con_timeout );
50         int max_retries_        = atoi(max_retries);
51         int icomponent = 0;
52         if(component) 
53                 icomponent = atoi(component);
54
55         if( iport < 1 ) { 
56                 fatal_handler( "Port is negative or 0" );
57                 return 99;
58         }
59
60
61         /* build the router_registrar */
62         transport_router_registrar* router_registrar = 
63                 router_registrar_init( server, iport, username, password, router_resource, 0, con_itimeout, icomponent ); 
64
65         routt = router_registrar;
66
67         free(server);
68         free(port);
69         free(username);
70         free(password);
71         free(con_timeout);
72         free(max_retries);
73
74         signal(SIGHUP,sig_hup_handler);
75
76
77         int counter = 0;
78         /* wait for incoming... */
79         while( ++counter <= max_retries_ ) {
80
81                 /* connect to jabber */
82                 if( router_registrar_connect( router_registrar ) )  {
83                         info_handler( "Connected..." );
84                         fprintf(stderr, "- Connected -\n");
85                         counter = 0;
86                         listen_loop( router_registrar );
87                 } else  
88                         fatal_handler( "Could not connect to Jabber Server" );
89
90                 /* this should never happen */
91                 warning_handler( "Jabber server probably went away, attempting reconnect" );
92
93                 sleep(5);
94         }
95
96
97         router_registrar_free( router_registrar );
98         config_reader_free();   
99         return 1;
100
101 }
102
103 transport_router_registrar* router_registrar_init( char* server, 
104                 int port, char* username, char* password, 
105                 char* resource, int client_timeout, int con_timeout, int component ) {
106
107         if( server == NULL ) { return NULL; }
108         
109         /* allocate a new router_registrar object */
110         size_t size = sizeof( transport_router_registrar );
111         transport_router_registrar* router_registrar = (transport_router_registrar*) safe_malloc( size );
112
113         router_registrar->client_timeout        = client_timeout;
114         router_registrar->jabber = jabber_connect_init( server, port, username, password, resource, con_timeout, component );
115         _build_trusted_sites( router_registrar );
116         info_handler( "Trusted stuff %s, %s, %s", router_registrar->trusted_servers[0], 
117                 router_registrar->trusted_clients[0], router_registrar->trusted_clients[1] );
118         return router_registrar;
119
120 }
121
122 void _build_trusted_sites( transport_router_registrar* router ) {
123
124         router->trusted_servers = (char**) safe_malloc(sizeof(char**));
125         router->trusted_clients = (char**) safe_malloc(sizeof(char**));
126
127         *(router->trusted_servers) = (char*) safe_malloc(ROUTER_MAX_TRUSTED);
128         *(router->trusted_clients) = (char*) safe_malloc(ROUTER_MAX_TRUSTED);
129
130         int i = 0;
131         while( ++i ) {
132                 char* server = config_value("//router/trusted_domains/server%d", i );
133                 if(server == NULL)
134                         break;
135                 
136                 router->trusted_servers[i-1] = server;
137         }
138
139         i = 0;
140         while( ++i ) {
141                 char* client = config_value( "//router/trusted_domains/client%d", i );
142                 if(client == NULL)
143                         break;
144                 router->trusted_clients[i-1] = client;
145         }
146
147         if( router->trusted_servers[0] == NULL ||
148                         router->trusted_clients[0] == NULL )
149
150                 fatal_handler( "You must specify at least one trusted server and client in the config file");
151 }
152
153
154 jabber_connect* jabber_connect_init( char* server, 
155                 int port, char* username, char* password, char* resource, int connect_timeout, int component ) {
156
157         size_t len = sizeof(jabber_connect);
158         jabber_connect* jabber = (jabber_connect*) safe_malloc( len );
159
160         jabber->port                            = port;
161         jabber->connect_timeout = connect_timeout;
162
163         jabber->server                          = strdup(server);
164         jabber->username                        = strdup(username);
165         jabber->password                        = strdup(password);
166         jabber->resource                        = strdup(resource);
167
168         if( jabber->server == NULL || jabber->username == NULL ||
169                         jabber->password == NULL || jabber->resource == NULL ) {
170                 fatal_handler( "jabber_init(): Out of Memory" );
171                 return NULL;
172         }
173
174         /* build the transport client */
175         jabber->t_client = client_init( jabber->server, jabber->port, component );
176
177         return jabber;
178 }
179
180 /* connect the router_registrar to jabber */
181 int router_registrar_connect( transport_router_registrar* router ) {
182         return j_connect( router->jabber );
183 }
184
185 /* connect a jabber_connect object jabber */
186 int j_connect( jabber_connect* jabber ) {
187         if( jabber == NULL ) { return 0; }
188         return client_connect( jabber->t_client, 
189                         jabber->username, jabber->password, jabber->resource, 
190                         jabber->connect_timeout, AUTH_DIGEST );
191 }
192
193 int fill_fd_set( transport_router_registrar* router, fd_set* set ) {
194         
195         int max_fd;
196         FD_ZERO(set);
197
198         int router_fd = router->jabber->t_client->session->sock_obj->sock_fd;
199         max_fd = router_fd;
200         FD_SET( router_fd, set );
201
202         server_class_node* cur_node = router->server_class_list;
203         while( cur_node != NULL ) {
204                 int cur_class_fd = cur_node->jabber->t_client->session->sock_obj->sock_fd;
205                 if( cur_class_fd > max_fd ) 
206                         max_fd = cur_class_fd;
207                 FD_SET( cur_class_fd, set );
208                 cur_node = cur_node->next;
209         }
210
211         FD_CLR( 0, set );
212         return max_fd;
213 }
214
215
216 void listen_loop( transport_router_registrar* router ) {
217
218         if( router == NULL )
219                 return;
220
221         int select_ret;
222         int router_fd = router->jabber->t_client->session->sock_obj->sock_fd;
223         transport_message* cur_msg;
224
225         while(1) {
226
227                 fd_set listen_set;
228                 int max_fd = fill_fd_set( router, &listen_set );
229
230                 if( max_fd < 1 ) 
231                         fatal_handler( "fill_fd_set return bogus max_fd: %d", max_fd );
232
233                 int num_handled = 0;
234                 info_handler( "Going into select" );
235
236                 if( (select_ret=select(max_fd+ 1, &listen_set, NULL, NULL, NULL)) < 0 ) {
237
238                         warning_handler( "Select returned error %d", select_ret );
239                         warning_handler( "Select Error %d on fd %d", errno );
240                         perror( "Select Error" );
241                         warning_handler( "Errors: EBADF %d, EINTR %d, EINVAL %d, ENOMEM %d",
242                                         EBADF, EINTR, EINVAL, ENOMEM );
243                         continue;
244
245                 } else {
246
247                         info_handler( "Select returned %d", select_ret );
248                         
249                         if( FD_ISSET( router_fd, &listen_set ) ) {
250                                 cur_msg = client_recv( router->jabber->t_client, 1 );
251
252                                 /* We only process a message if we have some trusted servers and the current
253                                         message came from one of those servers */
254                                 if(router->trusted_servers && router->trusted_servers[0]) {
255                                         int i = 0;
256                                         int found = 0;
257
258                                         char server_buf[256];
259                                         memset(server_buf,0,256);
260                                         jid_get_domain( cur_msg->sender, server_buf );
261                                         info_handler("Received top level message from %s", server_buf );
262
263                                         while(1) {
264                                                 if(router->trusted_servers[i] == NULL)
265                                                         break;
266                                                 if(!strcmp(router->trusted_servers[i], server_buf)) {
267                                                         found = 1;
268                                                         break;
269                                                 }
270                                                 i++;
271                                         }
272                                         if(found)
273                                                 router_registrar_handle_msg( router, cur_msg );
274                                         else
275                                                 warning_handler( "Received top level message from unpriveleged sender %s", cur_msg->sender );
276                                 }
277
278                                 message_free( cur_msg );
279                                 if( ++num_handled == select_ret ) 
280                                         continue;
281                         }
282
283                         /* cycle through the children and find any whose fd's are ready for reading */
284                         server_class_node* cur_node = router->server_class_list;
285                         while( cur_node != NULL ) {
286                                 int cur_fd = cur_node->jabber->t_client->session->sock_obj->sock_fd;
287
288                                 if( FD_ISSET(cur_fd, &listen_set) ) {
289                                         ++num_handled;
290                                         FD_CLR(cur_fd,&listen_set);
291
292                                         cur_msg = client_recv( cur_node->jabber->t_client, 1 );
293                                         info_handler( "%s received from %s", cur_node->server_class, cur_msg->sender );
294                                         int handle_ret = server_class_handle_msg( router, cur_node, cur_msg );
295
296                                         if( handle_ret == -1 ) {
297                                                 warning_handler( "server_class_handle_msg() returned -1" );
298                                                 cur_node = router->server_class_list; /*start over*/
299                                                 continue;
300
301                                         } else if( handle_ret == 0 ) {
302                                                 /* delete and continue */
303                                                 warning_handler( "server_class_handle_msg() returned 0" );
304                                                 server_class_node* tmp_node = cur_node->next;
305                                                 remove_server_class( router, cur_node );        
306                                                 cur_node = tmp_node;
307                                                 continue;
308                                         } 
309
310                                         info_handler( "%s handled message successfully", cur_node->server_class );
311                                         /* dont free message here */
312                                         if( num_handled == select_ret ) 
313                                                 break;
314                                 }
315                                 if( num_handled == select_ret ) 
316                                         break;
317                                 cur_node = cur_node->next;
318
319                         } /* cycling through the server_class list */
320
321                 } /* no select errors */
322         } 
323 }
324
325
326 /* determine where to route top level messages */
327 int router_registrar_handle_msg( transport_router_registrar* router_registrar, transport_message* msg ) {
328
329         info_handler( "Received class: %s : command %s ", msg->router_class, msg->router_command );
330
331         if( router_registrar == NULL || msg == NULL ) { return 0; }
332
333         if( msg->router_command == NULL || !strcmp(msg->router_command,"") ) {
334                 return router_registrar_handle_app_request( router_registrar, msg );
335         }
336
337         // user issued a ruoter query
338         /* a query command has router_command="query" and the actual query type
339                 is the content of the message */
340         if( !strcmp(msg->router_command,"query")) {
341                 info_handler( "Router received query command" );
342
343                 // user issues a servers query
344                 if( !strcmp(msg->body, "servers")) {
345
346                         info_handler( "Router received servers query command" );
347                         router_return_server_info( router_registrar, msg );
348                         return 1;
349                 }
350         }
351
352
353         info_handler("Looking for server_class_node %s...",msg->router_class);
354         server_class_node* active_class_node = find_server_class( router_registrar, msg->router_class );
355
356         if( active_class_node == NULL ) { 
357                 info_handler("Could not find server_class_node %s, creating one.",msg->router_class);
358
359                 /* there is no server_class for msg->router_class so we build it here */
360                 if( strcmp( msg->router_command, "register") == 0 ) {
361
362                         info_handler("Adding server_class_node for %s",msg->router_class);
363                         active_class_node = 
364                                 init_server_class( router_registrar, msg->sender, msg->router_class ); 
365
366                         if( active_class_node == NULL ) {
367                                 fatal_handler( "router_listen(): active_class_node == NULL for %s", msg->sender );
368                                 return 0;
369                         }
370
371                         if (router_registrar->server_class_list != NULL) {
372                                 active_class_node->next = router_registrar->server_class_list;
373                                 router_registrar->server_class_list->prev = active_class_node;
374                         }
375                         router_registrar->server_class_list = active_class_node;
376
377                         //spawn_server_class( (void*) active_class_node );
378
379                 } else {
380                         warning_handler( "router_register_handler_msg(): Bad Command [%s] for class [%s]",
381                                 msg->router_command, msg->router_class );
382                 }
383
384         } else if( strcmp( msg->router_command, "register") == 0 ) {
385                 /* there is a server_class for msg->router_class so we 
386                         need to either add a new server_node or update the existing one */
387
388                 
389                 server_node* s_node = find_server_node( active_class_node, msg->sender );
390
391                 if( s_node != NULL ) {
392                         s_node->available = 1;
393                         s_node->upd_time = time(NULL);
394                         info_handler( "Found matching registered server: %s. Updating.",
395                                         s_node->remote_id );
396                 } else {
397                         s_node = init_server_node( msg->sender );
398
399                         info_handler( "Adding server_node for: %s.", s_node->remote_id );
400
401                         if (s_node == NULL ) {
402                                 warning_handler( " Could not create new xerver_node for %s.",
403                                         msg->sender );
404                                 return 0;
405                         }
406
407                         s_node->next = active_class_node->current_server_node->next;
408                         s_node->prev = active_class_node->current_server_node;
409
410                         active_class_node->current_server_node->next->prev = s_node;
411                         active_class_node->current_server_node->next = s_node;
412                 }
413
414
415         } else if( strcmp( msg->router_command, "unregister") == 0 ) {
416
417                 if( ! unregister_server_node( active_class_node, msg->sender ) )
418                         remove_server_class( router_registrar, active_class_node );
419
420         } else {
421                 warning_handler( "router_register_handler_msg(): Bad Command [%s] for class [%s]",
422                         msg->router_command, msg->router_class );
423         }
424
425         return 1;
426 }
427
428
429 /* removes a server class node from the top level router_registrar */
430 int unregister_server_node( server_class_node* active_class_node, char* remote_id ) {
431
432         server_node* d_node = find_server_node( active_class_node, remote_id );
433
434         if ( d_node != NULL ) {
435
436                 info_handler( "Removing server_node for: %s.", d_node->remote_id );
437
438                 if ( d_node->next == NULL ) {
439                         warning_handler( "NEXT is NULL in ring [%s] -- "
440                                 "THIS SHOULD NEVER HAPPEN",
441                                 d_node->remote_id );
442
443                 }
444                 
445                 if ( d_node->prev == NULL ) {
446                         warning_handler( "PREV is NULL in a ring [%s] -- "
447                                 "THIS SHOULD NEVER HAPPEN",
448                                 d_node->remote_id );
449
450                 }
451
452                 if ( d_node->next == d_node && d_node->prev == d_node) {
453                         info_handler( "Last node, setting ring to NULL: %s.",
454                                 d_node->remote_id );
455
456                         active_class_node->current_server_node = NULL;
457
458                         server_node_free( d_node );
459                         return 0;
460
461                 } else {
462                         info_handler( "Nodes remain, splicing: %s, %s",
463                                 d_node->prev->remote_id,
464                                 d_node->next->remote_id);
465
466                 info_handler( "d_node => %x, next => %x, prev => %x",
467                                         d_node, d_node->next, d_node->prev );
468
469
470                         d_node->prev->next = d_node->next;
471                         d_node->next->prev = d_node->prev;
472
473                         info_handler( "prev => %x, prev->next => %x, prev->prev => %x",
474                                 d_node->prev, d_node->prev->next, d_node->prev->prev );
475
476                         info_handler( "next => %x, next->next => %x, next->prev => %x",
477                                 d_node->next, d_node->next->next, d_node->next->prev );
478                                 
479                         if (active_class_node->current_server_node == d_node)
480                                 active_class_node->current_server_node = d_node->next;
481
482
483                         server_node_free( d_node );
484                 }
485         } 
486
487         return 1;
488 }
489
490 server_node * find_server_node ( server_class_node * class, const char * remote_id ) {
491
492         if ( class == NULL ) {
493                 warning_handler(" find_server_node(): bad arg!");
494                 return NULL;
495         }
496
497         server_node * start_node = class->current_server_node;
498         server_node * node = class->current_server_node;
499
500         do {
501                 if (node == NULL)
502                         return NULL;
503
504                 if ( strcmp(node->remote_id, remote_id) == 0 )
505                         return node;
506
507                 node = node->next;
508
509         } while ( node != start_node );
510
511         return NULL;
512 }
513
514 /* if we return -1, then we just deleted the server_class you were looking for
515         if we return 0, then some other error has occured
516         we return 1 otherwise */
517 int remove_server_class( transport_router_registrar* router, server_class_node* class ) {
518         if( class == NULL )
519                 return 0;
520
521         transport_message * msg = NULL;
522         while ( (msg = client_recv(class->jabber->t_client, 0)) != NULL ) {
523                 server_class_handle_msg(router, class, msg);
524                 message_free(msg);
525         }
526         
527         free( class->server_class );
528         class->server_class = NULL;
529
530         find_server_class( router, router_resource ); /* find deletes for us */
531
532         if( router->server_class_list == NULL ) 
533                 return 0;
534         return 1;
535 }
536
537 server_class_node * find_server_class ( transport_router_registrar * router, const char * class_id ) {
538
539         if ( router == NULL ) {
540                 warning_handler(" find_server_class(): bad arg!");
541                 return NULL;
542         }
543
544         info_handler( "Finding server class for %s", class_id );
545         server_class_node * class = router->server_class_list;
546         server_class_node * dead_class = NULL;
547
548         while ( class != NULL ) {
549
550                 if ( class->server_class == NULL ) {
551                         info_handler( "Found an empty server class" );
552
553                         if ( class->prev != NULL ) {
554                                 class->prev->next = class->next;
555                                 if( class->next != NULL ) {
556                                         class->next->prev = class->prev;
557                                 }
558
559                         } else {
560                                 info_handler( "Empty class is the first on the list" );
561                                 if( class->next != NULL ) 
562                                         router->server_class_list = class->next;
563
564                                 else { /* we're the last class node in the class node list */
565                                         info_handler( "Empty class is the last on the list" );
566                                         server_class_node_free( router->server_class_list );
567                                         router->server_class_list = NULL;
568                                         break;
569                                 }
570                                         
571                         }
572
573                         dead_class = class;
574                         class = class->next;
575
576                         info_handler( "Tossing our dead class" );
577                         server_class_node_free( dead_class );
578
579                         if ( class == NULL )
580                                 return NULL;
581                 }
582
583                 if ( strcmp(class->server_class, class_id) == 0 )
584                         return class;
585                 info_handler( "%s != %s", class->server_class, class_id );
586
587                 class = class->next;
588         }
589
590         return NULL;
591 }
592
593 /* builds a new server class and connects to the jabber server with the new resource */
594 server_class_node* init_server_class( 
595                 transport_router_registrar* router, char* remote_id, char* server_class ) {
596
597         size_t len = sizeof( server_class_node );
598         server_class_node* node = (server_class_node*) safe_malloc( len );
599
600         node->jabber = jabber_connect_init( router->jabber->server,
601                         router->jabber->port, router->jabber->username, 
602                         router->jabber->password, server_class, router->jabber->connect_timeout, router->component );
603
604
605
606         node->server_class = strdup( server_class );
607         if( server_class == NULL ) {
608                 fatal_handler( "imit_server_class(): out of memory for %s", server_class );
609                 return NULL;
610         }
611
612         info_handler( "Received class to init_server_class: %s", server_class );
613         node->current_server_node = init_server_node( remote_id );
614         if( node->current_server_node == NULL ) {
615                 fatal_handler( "init_server_class(): NULL server_node for %s", remote_id );
616                 return NULL;
617         }
618
619
620         if( ! j_connect( node->jabber ) ) {
621                 fatal_handler( "Unable to init server class %s", node->server_class );
622                 return NULL;
623         }
624
625         info_handler( "Jabber address in init for %s : address %x : username %s : resource %s", 
626                         node->server_class, node->jabber->t_client->session->sock_obj->sock_fd, 
627                         node->jabber->username,  node->jabber->resource );
628
629         return node;
630
631 }
632
633 /* builds a new server_node to be added to the ring of server_nodes */
634 server_node* init_server_node(  char* remote_id ) {
635
636         info_handler( "Initing server node for %s", remote_id );
637         server_node* current_server_node;
638         size_t size = sizeof( server_node);
639         current_server_node = (server_node*) safe_malloc( size );
640
641         current_server_node->remote_id = strdup(remote_id);
642         if( current_server_node->remote_id == NULL ) {
643                 fatal_handler("init_server_class(): Out of Memory for %s", remote_id );
644                 return NULL;
645         }
646         
647         current_server_node->reg_time = time(NULL);     
648         current_server_node->available = 1;
649         current_server_node->next = current_server_node;
650         current_server_node->prev = current_server_node;
651
652
653         return current_server_node;
654
655 }
656
657 int  server_class_handle_msg( transport_router_registrar* router, 
658                 server_class_node* s_node, transport_message* msg ) {
659
660         if( s_node->current_server_node == NULL ) {
661                 /* return error to client ??!*/
662                 /* WE have no one to send the message to */
663                 warning_handler( "We no longer have any servers for %s : " 
664                                 "no one to send the message to. Sending error message to %s", s_node->server_class, msg->sender );
665                 free( msg->recipient );  
666
667                 char* rec = strdup( msg->sender );
668                 if( rec == NULL ) {
669                         fatal_handler( "class msg_handler: out of memory");
670                         return 0;
671                 }
672
673                 info_handler( "Building error message to return for %s", s_node->server_class);
674                 msg->recipient = rec;
675                 set_msg_error(msg, "cancel", 501);
676
677                 client_send_message( s_node->jabber->t_client, msg );
678                 message_free( msg );
679
680                 remove_server_class( router, s_node );
681
682                 return -1;
683         }
684
685         info_handler( "[%s] Received \nfrom: %s \nto: %s", 
686                         s_node->server_class, msg->sender, msg->recipient );
687
688         if( msg->is_error ) {
689                 warning_handler( "We've received an error message type: %s : code: %d", 
690                                 msg->error_type, msg->error_code );
691
692                 if( strcmp( msg->error_type, "cancel" ) == 0 ) {
693                         warning_handler( "Looks like we've lost a server!" );
694                         server_node* dead_node = find_server_node( s_node, msg->sender );
695
696                         if( dead_node != NULL ) { 
697                                 //message_free( msg );
698                                 transport_message* tmp = dead_node->last_sent;
699
700                                 /* copy over last sent, it will be freed in the unregister function */
701                                 transport_message* tmp2 = message_init( tmp->body, tmp->subject, tmp->thread,
702                                                 tmp->recipient, tmp->sender );
703                                         
704                                 message_set_router_info( tmp2, tmp->router_from,  
705                                                 tmp->router_to, tmp->router_class, tmp->router_command, tmp->broadcast );
706
707                                 if( ! unregister_server_node( s_node, dead_node->remote_id ) ) { 
708                                         /* WE have no one to send the message to */
709                                         warning_handler( "We no longer have any servers for %s : " 
710                                                         "no one to send the message to.", s_node->server_class );
711                                         free( msg->recipient );  
712
713                                         char* rec = strdup( msg->router_from );
714                                         if( rec == NULL ) {
715                                                 fatal_handler( "class msg_handler: out of memory");
716                                                 return 0;
717                                         }
718
719                                         info_handler( "Building error message to return for %s", s_node->server_class);
720                                         msg->recipient = rec;
721                                         client_send_message( s_node->jabber->t_client, msg );
722                                         message_free( tmp2 );
723                                         message_free( msg );
724                                         return 0;
725
726                                 } else {
727                                         msg = tmp2;
728                                 }
729                         }
730                 }
731         } 
732
733
734         server_node* c_node = s_node->current_server_node->next;
735
736         /* not implemented yet */
737         while( ! c_node->available ) {
738                 if( c_node == s_node->current_server_node ) {
739                         warning_handler("No server_node's are available for %s", s_node->server_class );
740                         /* XXX send error message to client */
741                         return 0;
742                 }
743                 c_node = c_node->next;
744         }
745         s_node->current_server_node = c_node;
746
747         transport_message * new_msg =
748                 message_init(   msg->body, msg->subject, msg->thread, 
749                                 s_node->current_server_node->remote_id, msg->sender );
750
751         message_set_router_info( new_msg, msg->sender, NULL, NULL, NULL, 0 );
752
753         info_handler( "[%s] Routing message from [%s]\nto [%s]", s_node->server_class, msg->sender, new_msg->recipient );
754         //info_handler( "New Message Details: sender:%s recipient: %s \nbody: %s", 
755         //              new_msg->sender, new_msg->recipient, new_msg->body );
756
757         message_free( s_node->current_server_node->last_sent );
758         s_node->current_server_node->last_sent = msg;
759
760         if ( new_msg != NULL && client_send_message( s_node->jabber->t_client, new_msg ) ) {
761                 s_node->current_server_node->serve_count++;
762                 s_node->current_server_node->la_time = time(NULL);
763                 message_free( new_msg ); // XXX
764                 return 1;
765         }
766         message_free( new_msg ); // XXX
767
768         return 0;
769 }
770
771
772 int router_return_server_info( 
773                 transport_router_registrar* router, transport_message* msg ) {
774
775         server_class_node* cur_class = router->server_class_list;
776         growing_buffer* buffer = buffer_init(1024);
777
778         while( cur_class != NULL ) {
779
780                 server_node* start_node = cur_class->current_server_node;
781                 server_node* cur_node = start_node;
782                 if( cur_node == NULL ) continue; 
783
784                 do {
785
786                         char tbuf[124];
787                         memset(tbuf,0,124);
788                         sprintf( tbuf, "%d", (int)cur_node->reg_time ); 
789                         buffer_add( buffer, tbuf );
790                         buffer_add( buffer, " | ");
791
792                         memset(tbuf,0,124);
793                         sprintf( tbuf, "%d", (int)cur_node->upd_time ); 
794                         buffer_add( buffer, tbuf );
795                         buffer_add( buffer, " | ");
796
797                         memset(tbuf,0,124);
798                         sprintf( tbuf, "%d", (int)cur_node->la_time );  
799                         buffer_add( buffer, tbuf );
800                         buffer_add( buffer, " | ");
801
802
803                         char sbuf[64];
804                         memset(sbuf,0,64);
805                         sprintf(sbuf,"%d",cur_node->serve_count);
806
807                         buffer_add( buffer, "#" ); 
808                         buffer_add( buffer, sbuf ); 
809                         buffer_add( buffer, " | ");
810
811                         buffer_add( buffer, cur_class->server_class );
812                         buffer_add( buffer, " | ");
813
814                         buffer_add( buffer, cur_node->remote_id );
815
816                         buffer_add( buffer, "\n" );
817                         cur_node = cur_node->next;
818
819                 } while( cur_node != start_node );
820
821                 cur_class = cur_class->next;
822
823         }
824
825         info_handler( "Router returning servers query command: %s", buffer->buf );
826
827         transport_message* new_msg; 
828
829         if( buffer->buf == NULL || strlen(buffer->buf) == 0 )
830                 new_msg = message_init( "0", NULL, NULL, msg->sender, NULL );
831         else
832                 new_msg = message_init( buffer->buf, NULL, NULL, msg->sender, NULL );
833
834         client_send_message( router->jabber->t_client, new_msg );
835         message_free( new_msg );
836
837         return 1;
838
839 }
840
841 int router_registrar_handle_app_request( 
842                 transport_router_registrar* router, transport_message* msg ) {
843
844         osrf_message* arr[ROUTER_MAX_MSGS_PER_PACKET];
845         memset(arr, 0, ROUTER_MAX_MSGS_PER_PACKET );
846         int num_msgs = osrf_message_from_xml( msg->body, arr );
847
848         int i;
849         for( i = 0; i != num_msgs; i++ ) {
850
851                 osrf_message* omsg = arr[i];
852                 osrf_message* success;
853
854                 char* newxml =  osrf_message_to_xml(omsg);
855                 debug_handler( "Received potential app request from client:\n%s\n", newxml ); 
856                 free(newxml);
857
858                 if(omsg->m_type == CONNECT) {
859
860                         success = osrf_message_init( 
861                                         STATUS, omsg->thread_trace, omsg->protocol );
862
863                         osrf_message_set_status_info( 
864                                         success, "oilsConnectStatus", "Connection Successful", OSRF_STATUS_OK );
865
866                 } else if( omsg->m_type == REQUEST ) {
867
868                         success = router_registrar_process_app_request( router, omsg );
869                         
870                 } else if(omsg->m_type == DISCONNECT) { 
871                         success = NULL;
872
873                 } else {
874
875                         success = osrf_message_init( 
876                                         STATUS, omsg->thread_trace, omsg->protocol );
877                         osrf_message_set_status_info( 
878                                         success, "oilsMethodException", "Method Not Found", OSRF_STATUS_NOTFOUND );
879                 }
880
881
882                 /* now send our new message back */
883                 if(success) {
884
885                         char* xml =  osrf_message_to_xml(success);
886                         debug_handler( "Sending XML to client app request:\n%s\n", xml );
887                         transport_message* return_m = message_init( 
888                                 xml, "", msg->thread, msg->sender, "" );
889
890
891                         client_send_message(router->jabber->t_client, return_m);
892
893                         free(xml);
894                         osrf_message_free(success);
895                 } 
896
897         }
898
899         return 1;
900
901 }
902
903
904
905 osrf_message* router_registrar_process_app_request( 
906                 transport_router_registrar* router, osrf_message* omsg ) {
907
908
909         if( omsg->method_name == NULL )
910                 return NULL;
911
912         json* result_content = NULL;
913
914         debug_handler( "Received method from client: %s", omsg->method_name );
915
916         if(!strcmp(omsg->method_name,"opensrf.router.info.class.list")) {
917
918                 debug_handler("Processing opensrf.router.info.class.list request");
919
920                 result_content = json_object_new_array();
921                 server_class_node* cur_class = router->server_class_list;
922                 while( cur_class != NULL ) {
923
924                         debug_handler("Adding %s to request list", cur_class->server_class);
925
926                         json_object_array_add(
927                                         result_content, json_object_new_string(cur_class->server_class));
928                         cur_class = cur_class->next;
929                 }
930
931                 //if( json_object_array_length(result_content) < 1 ) 
932                 //      result_content = NULL;
933
934         }
935
936         if( result_content == NULL ) 
937                 return NULL;
938
939         osrf_message* success = osrf_message_init(
940                 RESULT, omsg->thread_trace, omsg->protocol );
941         osrf_message_set_result_content( success, result_content );
942         json_object_put(result_content);
943
944         return success;
945 }
946
947
948
949
950 int router_registrar_free( transport_router_registrar* router_registrar ) {
951         if( router_registrar == NULL ) return 0;
952         jabber_connect_free( router_registrar->jabber );
953
954         /* free the server_class list XXX */
955         while( router_registrar->server_class_list != NULL ) {
956                 remove_server_class(router_registrar, router_registrar->server_class_list);
957         }
958
959         transport_router_registrar* router = router_registrar;
960
961         int i = 0;
962         
963         while(1) {
964
965                 if( router->trusted_servers[i] == NULL &&
966                                 router->trusted_clients[i] == NULL )
967                         break;
968
969                 if(router->trusted_servers[i] != NULL)
970                         free(router->trusted_servers[i]);
971                 if(router->trusted_clients[i] != NULL)
972                         free(router->trusted_clients[i]);
973                 i++;
974         }
975
976         free( router_registrar );
977
978
979
980         return 1;
981 }
982
983
984 int server_class_node_free( server_class_node* node ) {
985         if( node == NULL ) { return 0; }
986         if( node->server_class != NULL ) 
987                 free( node->server_class );
988
989         jabber_connect_free( node->jabber );
990
991         /* just in case, free the list */
992         while( node->current_server_node != NULL ) {
993                 unregister_server_node( node, node->current_server_node->remote_id );
994         }
995         free( node );
996         return 1;
997 }
998
999 int server_node_free( server_node* node ) {
1000         if( node == NULL ) { return 0; }
1001         message_free( node->last_sent );
1002         free( node->remote_id );
1003         free( node );
1004         return 1;
1005 }
1006
1007 int jabber_connect_free( jabber_connect* jabber ) {
1008         if( jabber == NULL ) { return 0; }
1009         client_free( jabber->t_client );
1010         free( jabber->username );
1011         free( jabber->password );
1012         free( jabber->resource );
1013         free( jabber->server );
1014         free( jabber );
1015         return 1;
1016 }
1017
1018