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