1 /******************************************************************************
2     (c) 2001-2005 Christine Caulfield                 christine.caulfield@googlemail.com
3     (c) 2003 Dmitri Popov
4 
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 ******************************************************************************/
15 #include <sys/param.h>	/* for PATH_MAX and types */
16 #include <sys/uio.h>
17 #include <sys/un.h>
18 #include <sys/ioctl.h>
19 #include <sys/wait.h>
20 #include <sys/stat.h>
21 #include <sys/time.h>
22 #include <sys/socket.h>
23 #include <sys/utsname.h>
24 #ifdef HAVE_NET_ETHERNET_H
25 #include <net/ethernet.h>
26 #endif
27 #include <stdio.h>
28 #include <errno.h>
29 #include <unistd.h>
30 #include <signal.h>
31 #include <string.h>
32 #include <fcntl.h>
33 #include <dirent.h>
34 #include <syslog.h>
35 #include <ctype.h>
36 #include <regex.h>
37 #include <stdlib.h>
38 // #include <utmp.h>
39 #include <grp.h>
40 #include <signal.h>
41 #include <assert.h>
42 #include <netinet/in.h>
43 
44 #include <list>
45 #include <queue>
46 #include <map>
47 #include <string>
48 #include <algorithm>
49 #include <iterator>
50 #include <sstream>
51 #include <iomanip>
52 
53 #include "lat.h"
54 #include "utils.h"
55 #include "session.h"
56 #include "localport.h"
57 #include "connection.h"
58 #include "circuit.h"
59 #include "latcpcircuit.h"
60 #include "llogincircuit.h"
61 #include "server.h"
62 #include "services.h"
63 #include "lat_messages.h"
64 #include "dn_endian.h"
65 
66 #if defined (__APPLE__) && !defined(_SOCKLEN_T)
67 typedef int socklen_t;
68 #endif
69 
70 // Remove any dangling symlinks in the /dev/lat directory
tidy_dev_directory()71 void LATServer::tidy_dev_directory()
72 {
73     DIR *dir;
74     struct dirent *de;
75     char current_dir[PATH_MAX];
76 
77     getcwd(current_dir, sizeof(current_dir));
78     chdir(LAT_DIRECTORY);
79 
80     dir = opendir(LAT_DIRECTORY);
81     if (!dir) return; // Doesn't exist - this is OK
82 
83     while ( (de = readdir(dir)) )
84     {
85 	if (de->d_name[0] != '.')
86 	    unlink(de->d_name);
87     }
88     closedir(dir);
89     chdir(current_dir);
90 }
91 
get_local_node(void)92 unsigned char *LATServer::get_local_node(void)
93 {
94     unsigned int i;
95 
96     if (local_name[0] == '\0')
97     {
98 	struct utsname uts;
99 	char *trailer;
100 
101 	uname(&uts);
102 	if (strchr(uts.nodename, '.'))
103 	    *strchr(uts.nodename, '.') = '\0';
104 
105         // This gets rid of the name-Computer bit on Darwin
106 	trailer = strstr(uts.nodename, "-Computer");
107 	if (trailer)
108 	    *trailer = '\0';
109 
110 	// LAT node names must be <= 16 characters long
111 	if (strlen(uts.nodename) > 16)
112 	    uts.nodename[16] = '\0';
113 
114 	strcpy((char *)local_name, uts.nodename);
115 
116 	// Make it all upper case
117 	for (i=0; i<strlen((char *)local_name); i++)
118 	{
119 	    if (islower(local_name[i])) local_name[i] = toupper(local_name[i]);
120 	}
121     }
122     return local_name;
123 }
124 
alarm_signal(int sig)125 void LATServer::alarm_signal(int sig)
126 {
127      if (Instance()->alarm_mode == 0)
128      {
129 	 Instance()->send_service_announcement(sig);
130      }
131      Instance()->send_solicit_messages(sig);
132 
133 }
134 
135 
136 // Send ENQUIRY for a node - mainly needed for DS90L servers that
137 // don't advertise.
send_enq(const char * node)138 void LATServer::send_enq(const char *node)
139 {
140     unsigned char packet[1600];
141     static unsigned char id = 1;
142     LAT_Enquiry *enqmsg = (LAT_Enquiry *)packet;
143     int ptr = sizeof(LAT_Enquiry);
144 
145     enqmsg->cmd = LAT_CCMD_ENQUIRE;
146     enqmsg->dummy = 0;
147     enqmsg->hiver = LAT_VERSION;
148     enqmsg->lover = LAT_VERSION;
149     enqmsg->latver = LAT_VERSION;
150     enqmsg->latver_eco = LAT_VERSION_ECO;
151     enqmsg->mtu = dn_htons(1500);
152     enqmsg->id  = id++;
153     enqmsg->retrans_timer = 75; // * 10ms - give it more time to respond
154 
155     add_string(packet, &ptr, (const unsigned char *)node);
156     packet[ptr++] = 1; /* Length of group data */
157     packet[ptr++] = 1; /* Group mask */
158 
159     add_string(packet, &ptr, local_name);
160     packet[ptr++] = 0x00;
161     packet[ptr++] = 0x00;
162     packet[ptr++] = 0x00;
163     packet[ptr++] = 0x00;
164 
165     /* This is the LAT multicast address */
166     static unsigned char addr[6] = { 0x09, 0x00, 0x2b, 0x00, 0x00, 0x0f };
167 
168 debuglog(("send_enq : node: %s, local_name: %s\n", node, local_name));
169 
170     for (int i=0; i<num_interfaces;i++)
171     {
172 	if (iface->send_packet(interface_num[i], addr, packet, ptr) < 0)
173 	{
174 debuglog(("Error send packet\n"));
175 	    interface_error(interface_num[i], errno);
176 	}
177 	else
178 	{
179 	    interface_errs[interface_num[i]] = 0; // Clear errors
180 	}
181     }
182 
183     LATServices::Instance()->touch_dummy_node_respond_counter(node);
184 }
185 
add_slave_node(const char * node_name)186 void LATServer::add_slave_node(const char *node_name)
187 {
188     sig_blk_t _block(SIGALRM);
189     for (std::list<std::string>::iterator iter = slave_nodes.begin();
190          iter != slave_nodes.end();
191          iter++)
192     {
193         if (*iter == node_name) {
194            // do not duplicate nodes
195            return;
196         }
197     }
198     slave_nodes.push_front(node_name);
199 }
200 
201 /* Called on the multicast timer - advertise our service on the LAN */
send_service_announcement(int sig)202 void LATServer::send_service_announcement(int sig)
203 {
204     unsigned char packet[1600];
205     int ptr;
206     struct utsname uinfo;
207     char  *myname;
208 
209     // Only send it if we have some services
210     if (servicelist.size())
211     {
212 	LAT_ServiceAnnounce *announce = (LAT_ServiceAnnounce *)packet;
213 	ptr = sizeof(LAT_ServiceAnnounce);
214 
215 	announce->cmd             = LAT_CCMD_SERVICE;
216 	announce->circuit_timer   = circuit_timer;
217 	announce->hiver           = LAT_VERSION;
218 	announce->lover           = LAT_VERSION;
219 	announce->latver          = LAT_VERSION;
220 	announce->latver_eco      = LAT_VERSION_ECO;
221 	announce->incarnation     = --multicast_incarnation;
222 	announce->flags           = 0x1f;
223 	announce->mtu             = dn_htons(1500);
224 	announce->multicast_timer = multicast_timer;
225 	if (do_shutdown)
226 	{
227 	    announce->node_status     = 3;    // Not accepting connections
228 	}
229 	else
230 	{
231 	    announce->node_status     = 2;    // Accepting connections
232 	}
233 
234 	// Send group codes
235 	if (groups_set)
236 	{
237 	    announce->group_length = 32;
238 	    memcpy(&packet[ptr], groups, 32);
239 	    ptr += 32;
240 	    announce->flags |= 1;
241 	}
242 	else
243 	{
244 	    announce->group_length    = 1;
245 	    packet[ptr++] = 01;
246 	}
247 
248 	/* Get host info */
249 	uname(&uinfo);
250 
251 	// Node name
252 	myname = (char*)get_local_node();
253 	packet[ptr++] = strlen(myname);
254 	strcpy((char*)packet+ptr, myname);
255 	ptr += strlen(myname);
256 
257 	// Greeting
258 	packet[ptr++] = strlen((char*)greeting);
259 	strcpy((char*)packet+ptr, (char*)greeting);
260 	ptr += strlen((char*)greeting);
261 
262 	// Number of services
263 	packet[ptr++] = servicelist.size();
264 	std::list<serviceinfo>::iterator i(servicelist.begin());
265 	for (; i != servicelist.end(); i++)
266 	{
267 	    // Service rating
268 	    unsigned char real_rating;
269 	    if (i->get_static())
270 	    {
271 		real_rating = i->get_rating();
272 	    }
273 	    else
274 	    {
275 		/* Calculate dynamic rating */
276 		real_rating =  (unsigned char)(i->get_rating() / (get_loadavg()+1.0));
277 		debuglog(("Dynamic service rating is %d\n", real_rating));
278 	    }
279 	    packet[ptr++] = real_rating;
280 
281 	    // Service name
282 	    const std::string name = i->get_name();
283 	    packet[ptr++]     = name.length();
284 	    strcpy((char *)packet+ptr, i->get_name().c_str());
285 	    ptr += name.length();
286 
287 	    // Service Identification
288 	    std::string id = i->get_id();
289 	    if (id.length() == 0)
290 	    {
291 		// Default service identification string
292 		char stringbuf[1024];
293 		sprintf(stringbuf, "%s %s", uinfo.sysname, uinfo.release);
294 		id = std::string(stringbuf);
295 	    }
296 
297 	    packet[ptr++] = id.length();
298 	    strcpy((char *)packet+ptr, id.c_str());
299 	    ptr += id.length();
300 
301 	    // Make sure the service table knows about all our services
302 	    unsigned char dummy_macaddr[6];
303 	    memset(dummy_macaddr, 0, sizeof(dummy_macaddr));
304 	    if (!do_shutdown)
305 		LATServices::Instance()->add_service(std::string((char*)get_local_node()),
306 						     name,
307 						     id, real_rating, 0, dummy_macaddr);
308 	}
309 
310 	// Not sure what node service classes are
311 	// probably somthing to do with port services and stuff.
312 	packet[ptr++] = 0x01; // Node service classes length
313 	packet[ptr++] = 0x01; // Node service classes
314 	packet[ptr++] = 0x00;
315 	packet[ptr++] = 0x00;
316 
317 	unsigned char addr[6];
318 	/* This is the LAT multicast address */
319 	addr[0]  = 0x09;
320 	addr[1]  = 0x00;
321 	addr[2]  = 0x2b;
322 	addr[3]  = 0x00;
323 	addr[4]  = 0x00;
324 	addr[5]  = 0x0f;
325 
326 	for (int i=0; i<num_interfaces;i++)
327 	{
328 	    if (iface->send_packet(interface_num[i], addr, packet, ptr) < 0)
329 	    {
330 		debuglog(("sending service announcement, send error: %d\n", errno));
331 		interface_error(interface_num[i], errno);
332 	    }
333 	    else
334 		interface_errs[interface_num[i]] = 0; // Clear errors
335 	}
336     }
337     /* Send it every minute */
338     signal(SIGALRM, &alarm_signal);
339     alarm(multicast_timer);
340 }
341 
342 // Send solicit messages to slave nodes
send_solicit_messages(int sig)343 void LATServer::send_solicit_messages(int sig)
344 {
345     static unsigned int counter = 0;
346     static unsigned int last_list_size = 0;
347 
348     if (alarm_mode == 0)
349     {
350 	counter = 0;
351 	alarm_mode = 1;
352 	debuglog(("set alarm_mode to 1\n"));
353 
354 	if (!known_slave_nodes.empty())
355 	{
356 	    std::string known_node = known_slave_nodes.front();
357 	    known_slave_nodes.pop_front();
358 	    slave_nodes.push_back(known_node);
359 	    debuglog(("known(%d) => slave(%d) : %s\n", known_slave_nodes.size(),
360 		       slave_nodes.size(), known_node.c_str()));
361 	    if (slave_nodes.size() == 1)
362 	    {
363 		alarm_mode = 0;
364 		debuglog(("set alarm_mode to 0 - one slave\n"));
365 		send_enq(slave_nodes.front().c_str());
366 		// alarm() is already charged by send_service_announcement()
367 		return;
368 	    }
369 	}
370     }
371     else
372     {
373 	if (slave_nodes.size() < last_list_size)
374 	{
375 	    counter -= last_list_size - slave_nodes.size();
376 	}
377     }
378 
379     if (slave_nodes.size() > counter && !slave_nodes.empty())
380     {
381 	std::string node_name = slave_nodes.front();
382 	slave_nodes.pop_front();
383 	slave_nodes.push_back(node_name);
384 
385 	send_enq(node_name.c_str());
386 
387 	alarm(1);
388 	counter++;
389 	last_list_size = slave_nodes.size();
390     }
391     else
392     {
393 	alarm_mode = 0;
394 
395 	//well, it's not quite correct, I know...
396 	alarm(counter >= multicast_timer ? 1 : multicast_timer - counter);
397 	debuglog(("set alarm_mode to 0, timer %d\n", counter >= multicast_timer ? 1 : multicast_timer - counter));
398     }
399 }
400 
401 // Log an error against an interface. If we get three of these
402 // then we remove it.
403 // If that means we have no interfaces, then closedown.
interface_error(int ifnum,int err)404 void LATServer::interface_error(int ifnum, int err)
405 {
406     syslog(LOG_ERR, "Error on interface %s: %s\n", iface->ifname(ifnum).c_str(), strerror(err));
407 
408     // Too many errors, remove it
409     if (++interface_errs[ifnum] > 3)
410     {
411 	int i,j;
412 
413 	syslog(LOG_ERR, "Interface will be removed from LATD\n");
414 
415 	// Look for it
416 	for (i=0; i<num_interfaces; i++)
417 	{
418 	    if (interface_num[i] == ifnum) goto remove_if;
419 	}
420 
421 	// Ugh, didn't find it. that can't be right!
422 	if (i>=num_interfaces)
423 	{
424 	    syslog(LOG_ERR, "Don't seem to have a reference to this interface....\n");
425 	    return;
426 	}
427 
428     remove_if:
429 	// Shuffle the list down
430 	for (j=i; j<num_interfaces-1; j++)
431 	{
432 	    interface_num[j] = interface_num[j+1];
433 	}
434 
435 	if (--num_interfaces == 0)
436 	{
437 	    syslog(LOG_ERR, "No valid interfaces left. LATD closing down\n");
438 
439 	    // No point in going down cleanly as that just sends network messages
440 	    // and we have nowhere to send then through.
441 	    exit(9);
442 	}
443     }
444 }
445 
446 /* Main loop */
run()447 void LATServer::run()
448 {
449     int status;
450 
451     // Bind interfaces
452     for (int i=0; i<num_interfaces;i++)
453     {
454 	iface->set_lat_multicast(interface_num[i]);
455     }
456 
457     // Add it/them to the sockets list
458     if (iface->one_fd_per_interface())
459     {
460 	for (int i=0; i<num_interfaces;i++)
461 	{
462 	    fdlist.push_back(fdinfo(iface->get_fd(interface_num[i]), 0, LAT_SOCKET));
463 	}
464     }
465     else
466     {
467 	fdlist.push_back(fdinfo(iface->get_fd(0), 0, LAT_SOCKET));
468     }
469 
470     // Open LATCP socket
471     unlink(LATCP_SOCKNAME);
472     latcp_socket = socket(PF_UNIX, SOCK_STREAM, 0);
473     if (latcp_socket < 0)
474     {
475 	syslog(LOG_ERR, "Can't create latcp socket: %m");
476 	exit(1);
477     }
478 
479     struct sockaddr_un sockaddr;
480     strcpy(sockaddr.sun_path, LATCP_SOCKNAME);
481     sockaddr.sun_family = AF_UNIX;
482     if (bind(latcp_socket, (struct sockaddr *)&sockaddr, sizeof(sockaddr)))
483     {
484 	syslog(LOG_ERR, "can't bind latcp socket: %m");
485         exit(1);
486     }
487     if (listen(latcp_socket, 1) != 0)
488     {
489 	syslog(LOG_ERR, "listen latcp: %m");
490     }
491     // Make sure only root can talk to us via the latcp socket
492     chmod(LATCP_SOCKNAME, 0600);
493     fdlist.push_back(fdinfo(latcp_socket, 0, LATCP_RENDEZVOUS));
494 
495     // Open llogin socket
496     unlink(LLOGIN_SOCKNAME);
497     llogin_socket = socket(PF_UNIX, SOCK_STREAM, 0);
498     if (llogin_socket < 0)
499     {
500 	syslog(LOG_ERR, "Can't create llogin socket: %m");
501 	exit(1);
502     }
503 
504     strcpy(sockaddr.sun_path, LLOGIN_SOCKNAME);
505     sockaddr.sun_family = AF_UNIX;
506     if (bind(llogin_socket, (struct sockaddr *)&sockaddr, sizeof(sockaddr)))
507     {
508 	syslog(LOG_ERR, "can't bind llogin socket: %m");
509         exit(1);
510     }
511     if (listen(llogin_socket, 1) != 0)
512     {
513 	syslog(LOG_ERR, "listen llogin: %m");
514     }
515     // Make sure everyone can use it
516     chmod(LLOGIN_SOCKNAME, 0666);
517     fdlist.push_back(fdinfo(llogin_socket, 0, LLOGIN_RENDEZVOUS));
518 
519     // Don't start sending service announcements
520     // until we get an UNLOCK message from latcp.
521 
522     // We rely on POSIX's select() behaviour in that we use the
523     // time left in the timeval parameter to make sure the circuit timer
524     // goes off at a reasonably predictable interval.
525 
526 #ifndef __linux__
527     struct timeval next_circuit_time;
528     next_circuit_time.tv_sec = 0;
529     next_circuit_time.tv_usec = 0;
530 #endif
531 
532     struct timeval tv = {0, circuit_timer*10000};
533     time_t last_node_expiry = time(NULL);
534     do_shutdown = false;
535     do
536     {
537 	fd_set fds;
538 	FD_ZERO(&fds);
539 
540 	std::list<fdinfo>::iterator i(fdlist.begin());
541 	for (; i != fdlist.end(); i++)
542 	{
543 	    if (i->active())
544 	        FD_SET(i->get_fd(), &fds);
545 	}
546 
547 // Only Linux seems to have this select behaviour...
548 // for BSDs we need to work our for ourselves the delay
549 // until the next circuit timer tick.
550 #ifndef __linux__
551 	struct timeval now;
552 
553 	gettimeofday(&now, NULL);
554 	if (next_circuit_time.tv_sec == 0)
555 	{
556 	    next_circuit_time = now;
557 	    next_circuit_time.tv_usec += circuit_timer*10000;
558 	    next_circuit_time.tv_sec += (next_circuit_time.tv_usec / 1000000);
559 	    next_circuit_time.tv_usec = (next_circuit_time.tv_usec % 1000000);
560 	}
561 
562 	tv = next_circuit_time;
563 	if (tv.tv_sec < now.tv_sec
564 	    || (tv.tv_sec == now.tv_sec
565 		&& tv.tv_usec <= now.tv_usec))
566 	{
567 	    tv.tv_sec = tv.tv_usec = 0;
568 	}
569 	else
570 	{
571 	    tv.tv_sec -= now.tv_sec;
572 	    if ((tv.tv_usec -= now.tv_usec) < 0)
573 	    {
574 		tv.tv_sec--;
575 		tv.tv_usec += 1000000;
576 	    }
577 	}
578 #endif
579 
580 	status = select(FD_SETSIZE, &fds, NULL, NULL, &tv);
581 	if (status < 0)
582 	{
583 	    if (errno != EINTR)
584 	    {
585 		syslog(LOG_WARNING, "Error in select: %m");
586 		debuglog(("Error in select: %s\n", strerror(errno)));
587 		do_shutdown = true;
588 	    }
589 	}
590 	else
591 	{
592 	    if (status == 0) // Circuit timer
593 	    {
594 	      for (int i=1; i<MAX_CONNECTIONS; i++)
595 		if (connections[i])
596 		  connections[i]->circuit_timer();
597 	      tv.tv_usec = circuit_timer*10000;
598 
599 	      // Is it time we expired some more nodes ?
600 	      if (time(NULL) - last_node_expiry > 15)
601 		  LATServices::Instance()->expire_nodes();
602 #ifndef __linux__
603 	      next_circuit_time.tv_sec = 0;
604 #endif
605 	    }
606 	    else
607 	    {
608 		// Unix will never scale while this is necessary
609 		std::list<fdinfo>::iterator fdl(fdlist.begin());
610 		for (; fdl != fdlist.end(); fdl++)
611 		{
612 		    if (fdl->active() &&
613 			FD_ISSET(fdl->get_fd(), &fds))
614 		    {
615 			process_data(*fdl);
616 		    }
617 		}
618 	    }
619 	}
620 
621 	// Tidy deleted sessions
622 	if (!dead_session_list.empty())
623 	{
624 	    std::list<deleted_session>::iterator dsl(dead_session_list.begin());
625 	    for (; dsl != dead_session_list.end(); dsl++)
626 	    {
627 		delete_entry(*dsl);
628 	    }
629 	    dead_session_list.clear();
630 	}
631 
632 	// Tidy deleted connections
633 	if (!dead_connection_list.empty())
634 	{
635 	    std::list<int>::iterator dcl(dead_connection_list.begin());
636 	    for (; dcl != dead_connection_list.end(); dcl++)
637 	    {
638 		if (connections[*dcl])
639 	        {
640 		    delete connections[*dcl];
641 		    connections[*dcl] = NULL;
642 		}
643 	    }
644 	    dead_connection_list.clear();
645 	}
646 
647     } while (!do_shutdown);
648 
649     send_service_announcement(-1); // Say we are unavailable
650 
651     close(latcp_socket);
652     unlink(LATCP_SOCKNAME);
653     unlink(LLOGIN_SOCKNAME);
654 
655     tidy_dev_directory();
656 }
657 
658 /* LAT socket has something for us */
read_lat(int sock)659 void LATServer::read_lat(int sock)
660 {
661     unsigned char buf[1600];
662     unsigned char macaddr[6];
663     int    len;
664     int    i;
665     int    ifn;
666     bool   more = true;
667     LAT_Header *header = (LAT_Header *)buf;
668 
669     while (more)
670     {
671 	len = iface->recv_packet(sock, ifn, macaddr, buf, sizeof(buf), more);
672 	if (len == 0)
673 	    continue; // Probably a rogue packet
674 
675 	if (len < 0)
676 	{
677 	    if (errno != EINTR && errno != EAGAIN)
678 	    {
679 		syslog(LOG_ERR, "recvmsg: %m");
680 		return;
681 	    }
682 	}
683 
684 	// Not listening yet, but we must read the message otherwise we
685 	// we will spin until latcp unlocks us.
686 	if (locked)
687 	       continue;
688 
689 	// Parse & dispatch it.
690 	switch(header->cmd)
691 	{
692 	case LAT_CCMD_SREPLY:
693 	case LAT_CCMD_SDATA:
694 	case LAT_CCMD_SESSION:
695         {
696 	    debuglog(("session cmd for connid %d\n", header->remote_connid));
697 	    LATConnection *conn = NULL;
698             if(header->remote_connid < MAX_CONNECTIONS)
699             {
700                 conn = connections[header->remote_connid];
701             }
702 
703 	    if (conn)
704 	    {
705 	        conn->process_session_cmd(buf, len, macaddr);
706 	    }
707 	    else
708 	    {
709 		// Message format error
710 		send_connect_error(2, header, ifn, macaddr);
711 	    }
712 	}
713 	break;
714 
715 	case LAT_CCMD_CONNECT:
716         {
717 	    // Make a new connection
718 
719 	    //  Check that the connection is really for one of our services
720 	    unsigned char name[256];
721 	    int ptr = sizeof(LAT_Start);
722 	    get_string(buf, &ptr, name);
723 
724 	    debuglog(("got connect for node %s\n", name));
725 
726 	    if (strcmp((char *)name, (char *)get_local_node()))
727 	    {
728 		// How the &?* did that happen?
729 		send_connect_error(2, header, ifn, macaddr);
730 		continue;
731 	    }
732 
733      	    // Make a new connection.
734 	    if ( ((i=make_new_connection(buf, len, ifn, header, macaddr) )) > 0)
735 	    {
736 		debuglog(("Made new connection: %d\n", i));
737 		connections[i]->send_connect_ack();
738 	    }
739 	}
740 	break;
741 
742 	case LAT_CCMD_CONACK:
743         {
744 	    LATConnection *conn = NULL;
745 	    debuglog(("Got connect ACK for %d\n", header->remote_connid));
746 	    if (header->remote_connid < MAX_CONNECTIONS)
747 	    {
748 		conn = connections[header->remote_connid];
749 	    }
750 
751 	    if (conn)
752 	    {
753 		conn->got_connect_ack(buf);
754 	    }
755 	    else
756 	    {
757 		// Insufficient resources
758 		send_connect_error(7, header, ifn, macaddr);
759 	    }
760 	}
761 	break;
762 
763 	case LAT_CCMD_CONREF:
764 	case LAT_CCMD_DISCON:
765         {
766 	    debuglog(("Disconnecting connection %d: status %x(%s)\n",
767 		      header->remote_connid,
768 		      buf[sizeof(LAT_Header)],
769 		      lat_messages::connection_disconnect_msg(buf[sizeof(LAT_Header)]) ));
770 	    if (header->remote_connid < MAX_CONNECTIONS)
771 	    {
772 		LATConnection *conn = connections[header->remote_connid];
773 		if (conn)
774 		{
775 		    // We don't delete clients, we just quiesce them.
776 		    if (conn->isClient())
777 		    {
778 			conn->disconnect_client();
779 			if (conn->num_clients() == 0)
780 			{
781 			    delete conn;
782 			    connections[header->remote_connid] = NULL;
783 			}
784 		    }
785 		    else
786 		    {
787 			delete conn;
788 			connections[header->remote_connid] = NULL;
789 		    }
790 		}
791 	    }
792 	    else
793 	    {
794 		// Message format error
795 		send_connect_error(2, header, ifn, macaddr);
796 	    }
797 	}
798 	break;
799 
800 	case LAT_CCMD_SERVICE:
801 	    // Keep a list of known services
802 	    add_services(buf, len, ifn, macaddr);
803 	    break;
804 
805 	case LAT_CCMD_ENQUIRE:
806 	    reply_to_enq(buf, len, ifn, macaddr);
807 	    break;
808 
809 	case LAT_CCMD_ENQREPLY:
810 	    got_enqreply(buf, len, ifn, macaddr);
811 	    break;
812 
813 	case LAT_CCMD_STATUS:
814 	    forward_status_messages(buf, len);
815 	    break;
816 
817 	    // Request for a reverse-LAT connection.
818 	case LAT_CCMD_COMMAND:
819 	    process_command_msg(buf, len, ifn, macaddr);
820 	    break;
821 	}
822     }
823 }
824 
825 // Add an FD to the list of FDs to listen to
add_fd(int fd,fd_type type)826 void LATServer::add_fd(int fd, fd_type type)
827 {
828     std::list<fdinfo>::iterator fdi;
829 
830     debuglog(("Add_fd: %d\n", fd));
831 
832     fdi = find(fdlist.begin(), fdlist.end(), fd);
833     if (fdi != fdlist.end()) return; // Already exists
834 
835 
836     fdlist.push_back(fdinfo(fdinfo(fd, NULL, type)));
837 }
838 
839 // Remove FD from the FD list
remove_fd(int fd)840 void LATServer::remove_fd(int fd)
841 {
842     std::list<fdinfo>::iterator fdi;
843     debuglog(("remove_fd: %d\n", fd));
844 
845     fdi = find(fdlist.begin(), fdlist.end(), fd);
846     if (fdi == fdlist.end()) return; // Does not exist
847 
848     fdlist.remove(*fdi);
849 }
850 
851 // Change the DISABLED state of a PTY fd
set_fd_state(int fd,bool disabled)852 void LATServer::set_fd_state(int fd, bool disabled)
853 {
854     std::list<fdinfo>::iterator fdi;
855     debuglog(("set_fd_state: %d, %d\n", fd, disabled));
856 
857     fdi = find(fdlist.begin(), fdlist.end(), fd);
858     if (fdi == fdlist.end()) return; // Does not exist
859 
860     fdi->set_disabled(disabled);
861 }
862 
863 
864 
865 /* Send a LAT message to a specified MAC address */
send_message(unsigned char * buf,int len,int interface,unsigned char * macaddr)866 int LATServer::send_message(unsigned char *buf, int len, int interface, unsigned char *macaddr)
867 {
868   if (len < 46) len = 46; // Minimum packet length
869   if (len%2) len++;       // Must be an even number
870 
871 #ifdef PACKET_LOSS
872   static int c=0;
873   if ((++c % PACKET_LOSS) == 0) {
874       debuglog(("NOT SENDING THIS MESSAGE!\n"));
875       return 0;
876   }
877 #endif
878 
879   if (interface == 0) // Send to all
880   {
881       for (int i=0; i<num_interfaces;i++)
882       {
883 	  if (iface->send_packet(interface_num[i], macaddr, buf, len) < 0)
884 	  {
885 	      interface_error(interface_num[i], errno);
886 	  }
887 	  else
888 	      interface_errs[interface_num[i]] = 0; // Clear errors
889 
890       }
891   }
892   else
893   {
894       if (iface->send_packet(interface, macaddr, buf, len) < 0)
895       {
896 	  interface_error(interface, errno);
897 	  return -1;
898       }
899       interface_errs[interface] = 0; // Clear errors
900   }
901 
902   return 0;
903 
904 }
905 
906 /* Get the system load average */
get_loadavg(void)907 double LATServer::get_loadavg(void)
908 {
909     double avg[3];
910 
911     if (getloadavg(avg, 3) > 0)
912     {
913 	return avg[0];
914     }
915     else
916     {
917 	return 0;
918     }
919 }
920 
921 // Forward status messages to their recipient connection objects.
forward_status_messages(unsigned char * inbuf,int len)922 void LATServer::forward_status_messages(unsigned char *inbuf, int len)
923 {
924     int ptr = sizeof(LAT_Status);
925     unsigned char node[256];
926 
927     get_string(inbuf, &ptr, node);
928 
929     // Forward all the StatusEntry messages
930     while (ptr <= len)
931     {
932 	if (ptr%2) ptr++; // Word aligned
933 
934 	LAT_StatusEntry *entry = (LAT_StatusEntry *)&inbuf[ptr];
935 	if (entry->length == 0) break;
936 
937 	ptr += sizeof(LAT_StatusEntry);
938 	get_string(inbuf, &ptr, node); // Service name
939 	ptr += inbuf[ptr]+1; // Past port name
940 	ptr += inbuf[ptr]+1; // Past service description
941 
942 	if (entry->request_id < MAX_CONNECTIONS &&
943 	    connections[entry->request_id])
944 	    connections[entry->request_id]->got_status(node, entry);
945 
946     }
947 }
948 
949 /* Reply to an ENQUIRE message with our MAC address & service name */
reply_to_enq(unsigned char * inbuf,int len,int interface,unsigned char * remote_mac)950 void LATServer::reply_to_enq(unsigned char *inbuf, int len, int interface,
951 			     unsigned char *remote_mac)
952 {
953     int inptr, outptr, i;
954     unsigned char outbuf[1600];
955     unsigned char req_service[1600];
956     LAT_Header *outhead = (LAT_Header *)outbuf;
957     LAT_Header *inhead = (LAT_Header *)inbuf;
958 
959     inptr = sizeof(LAT_Header)+4;
960 
961     /* This is the service being enquired about */
962     get_string(inbuf, &inptr, req_service);
963 
964     debuglog(("got ENQ for %s\n", req_service));
965 
966     // Ignore empty requests:: TODO: is this right?? - maybe we issue
967     // a response with all our services in it.
968     if (strlen((char*)req_service) == 0) return;
969 
970     unsigned char reply_macaddr[6];
971     unsigned char *reply_node;
972 
973     // See if it is for us if we're not doing responder work.
974     if (!responder)
975     {
976 	std::list<serviceinfo>::iterator sii;
977 	sii = find(servicelist.begin(), servicelist.end(), (char *)req_service);
978 	if (sii == servicelist.end()) return; // Not ours
979     }
980 
981     std::string node;
982     if (LATServices::Instance()->get_highest(std::string((char *)req_service),
983 					     node, reply_macaddr, &interface))
984     {
985 	reply_node = (unsigned char *)node.c_str();
986     }
987     else
988     {
989 	return; // nevver 'eard of 'im.
990     }
991 
992     debuglog(("Sending ENQ reply for %s\n", req_service));
993 
994     inptr += 2;
995 
996     outptr = sizeof(LAT_Header);
997     outbuf[outptr++] = 0x93;
998     outbuf[outptr++] = 0x07;
999     outbuf[outptr++] = 0x00;
1000     outbuf[outptr++] = 0x00;
1001 
1002     /* The service's MAC address */
1003     outbuf[outptr++] = 0x06;
1004     outbuf[outptr++] = 0x00;
1005     for (i=0; i<5; i++)
1006 	outbuf[outptr++] = reply_macaddr[i];
1007 
1008     /* Don't know what this is */
1009     outbuf[outptr++] = 0x14;
1010     outbuf[outptr++] = 0x00;
1011 
1012     add_string(outbuf, &outptr, reply_node);
1013     outbuf[outptr++] = 0x01;
1014     outbuf[outptr++] = 0x01;
1015     add_string(outbuf, &outptr, req_service);
1016 
1017     outhead->cmd             = LAT_CCMD_ENQREPLY;
1018     outhead->num_slots       = 0;
1019     outhead->remote_connid   = inhead->remote_connid;
1020     outhead->local_connid    = inhead->local_connid;
1021     outhead->sequence_number = inhead->sequence_number;
1022     outhead->ack_number      = inhead->ack_number;
1023 
1024     send_message(outbuf, outptr, interface, remote_mac);
1025 }
1026 
shutdown()1027 void LATServer::shutdown()
1028 {
1029     do_shutdown = true;
1030 }
1031 
init(bool _static_rating,int _rating,char * _service,char * _greeting,char ** _interfaces,int _verbosity,int _timer)1032 void LATServer::init(bool _static_rating, int _rating,
1033 		     char *_service, char *_greeting, char **_interfaces,
1034 		     int _verbosity, int _timer)
1035 {
1036     // Server is locked until latcp has finished
1037     locked = true;
1038 
1039     /* Initialise the platform-specific interface code */
1040     iface = LATinterfaces::Create();
1041     if (iface->Start(LATinterfaces::ProtoLAT) == -1)
1042     {
1043 	syslog(LOG_ERR, "Can't create LAT protocol socket: %m\n");
1044 	exit(1);
1045 
1046     }
1047 
1048 #ifdef ENABLE_DEFAULT_SERVICE
1049     // Add the default session
1050     servicelist.push_back(serviceinfo(_service,
1051 				      _rating,
1052 				      _static_rating));
1053 #endif
1054 
1055     strcpy((char *)greeting, _greeting);
1056     verbosity = _verbosity;
1057 
1058     // Convert all the interface names to numbers and check they are usable
1059     if (_interfaces[0])
1060     {
1061 	int i=0;
1062 	while (_interfaces[i])
1063 	{
1064 	    interface_num[num_interfaces] = iface->find_interface(_interfaces[i]);
1065 	    if (interface_num[num_interfaces] == -1)
1066 	    {
1067 		syslog(LOG_ERR, "Can't use interface %s: ignored\n", _interfaces[i]);
1068 	    }
1069 	    else
1070 	    {
1071 		interface_errs[num_interfaces] = 0;  // Clear errors
1072 		num_interfaces++;
1073 	    }
1074 	    i++;
1075 	}
1076 	if (num_interfaces == 0)
1077 	{
1078 	    syslog(LOG_ERR, "No usable interfaces, latd exiting.\n");
1079 	    exit(9);
1080 	}
1081     }
1082     else
1083     {
1084 	iface->get_all_interfaces(interface_num, num_interfaces);
1085     }
1086 
1087     // Remove any old /dev/lat symlinks
1088     tidy_dev_directory();
1089 
1090     // Save these two for any newly added services
1091     rating = _rating;
1092     static_rating = _static_rating;
1093 
1094     next_connection = 1;
1095     multicast_incarnation = 0;
1096     circuit_timer = _timer/10;
1097     local_name[0] = '\0'; // Use default node name
1098 
1099     memset(connections, 0, sizeof(connections));
1100 
1101     // Enable user group 0
1102     memset(user_groups, 0, 32);
1103     user_groups[0] = 1;
1104 
1105     // Look in /etc/group for a group called "lat"
1106     struct group *gr = getgrnam("lat");
1107     if (gr)
1108 	lat_group = gr->gr_gid;
1109     else
1110 	lat_group = 0;
1111 
1112 }
1113 
1114 // Create a new connection object for this remote node.
make_new_connection(unsigned char * buf,int len,int interface,LAT_Header * header,unsigned char * macaddr)1115 int LATServer::make_new_connection(unsigned char *buf, int len,
1116 				   int interface,
1117 				   LAT_Header *header,
1118 				   unsigned char *macaddr)
1119 {
1120     int i;
1121     i = get_next_connection_number();
1122 
1123     if (i >= 0)
1124     {
1125 	next_connection = i+1;
1126 	connections[i] = new LATConnection(i, buf, len, interface,
1127 					   header->sequence_number,
1128 					   header->ack_number,
1129 					   macaddr);
1130     }
1131     else
1132     {
1133 // Number of virtual circuits exceeded
1134 	send_connect_error(9, header, interface, macaddr);
1135 	return -1;
1136     }
1137     return i;
1138 }
1139 
delete_session(int conn,unsigned char id,int fd)1140 void LATServer::delete_session(int conn, unsigned char id, int fd)
1141 {
1142     // Add this to the list and delete them later
1143     deleted_session s(LOCAL_PTY, conn, id, fd);
1144     dead_session_list.push_back(s);
1145 }
1146 
delete_connection(int conn)1147 void LATServer::delete_connection(int conn)
1148 {
1149     // Add this to the list and delete them later
1150     debuglog(("connection %d pending deletion\n", conn));
1151 
1152     dead_connection_list.push_back(conn);
1153 }
1154 
1155 // Got a reply from a DS90L - add it to the services list in a dummy service
got_enqreply(unsigned char * buf,int len,int interface,unsigned char * macaddr)1156 void LATServer::got_enqreply(unsigned char *buf, int len, int interface, unsigned char *macaddr)
1157 {
1158     int off = 14;
1159     unsigned char node_addr[6];
1160     char node_description[256];
1161     char node_name[256];
1162 
1163     memset(node_addr, 0x00, sizeof(node_addr));
1164     if (0 == memcmp(node_addr, buf + off, sizeof(node_addr)))
1165     {
1166 	return;
1167     }
1168 
1169     memset(node_addr, 0xFF, sizeof(node_addr));
1170     if (0 == memcmp(node_addr, buf + off, sizeof(node_addr)))
1171     {
1172 	return;
1173     }
1174 
1175     // Node MAC address
1176     memcpy(node_addr, buf + off, sizeof(node_addr));
1177 
1178     // Skip destination node name
1179     off = 22;
1180     off += buf[off] + 1;
1181 
1182     // Skip node groups
1183     off += buf[off] + 1;
1184 
1185     get_string(buf, &off, (unsigned char*)node_name);
1186     get_string(buf, &off, (unsigned char*)node_description);
1187 
1188 #if defined(debuglog)
1189     if (memcmp(node_addr, macaddr, sizeof(node_addr))) {
1190 	debuglog(("got_enqreply : macaddr is different : %02hhX-%02hhX-%02hhX-%02hhX-%02hhX-%02hhX\n",
1191 		  macaddr[0], macaddr[1], macaddr[2], macaddr[3], macaddr[4], macaddr[5]));
1192     }
1193 #endif
1194 
1195 // Add it to the dummy service.
1196     debuglog(("got_enqreply : node: '%s' : %02hhX-%02hhX-%02hhX-%02hhX-%02hhX-%02hhX\n",
1197 	      node_name,
1198 	      node_addr[0], node_addr[1], node_addr[2], node_addr[3], node_addr[4], node_addr[5]));
1199     LATServices::Instance()->add_service(std::string(node_name),
1200 					 std::string(""), // Dummy service name
1201 					 std::string(node_description),
1202 					 0,
1203 					 interface, node_addr);
1204 
1205     {
1206         sig_blk_t _block(SIGALRM);
1207 	std::list<std::string>::iterator sl_iter;
1208         sl_iter = find(slave_nodes.begin(), slave_nodes.end(), node_name);
1209         if (sl_iter != slave_nodes.end()) {
1210             debuglog(("got_enqreply : to remove from slave(%d), node: '%s'\n",
1211 		      slave_nodes.size(), sl_iter->c_str()));
1212 	    slave_nodes.erase(sl_iter);
1213 	}
1214 
1215         sl_iter = find(known_slave_nodes.begin(), known_slave_nodes.end(), node_name);
1216         if (sl_iter == known_slave_nodes.end()) {
1217 	    known_slave_nodes.push_back(node_name);
1218             debuglog(("got_enqreply : added to known(%d), node: '%s'\n",
1219 		      known_slave_nodes.size(),
1220 		       node_name));
1221 	}
1222     }
1223 }
1224 
1225 
1226 // Got a COMMAND message from a remote node. it probably wants
1227 // to set up a reverse-LAT session to us.
process_command_msg(unsigned char * buf,int len,int interface,unsigned char * macaddr)1228 void LATServer::process_command_msg(unsigned char *buf, int len, int interface, unsigned char *macaddr)
1229 {
1230     LAT_Command *msg = (LAT_Command *)buf;
1231     int ptr = sizeof(LAT_Command);
1232     unsigned char remnode[256];
1233     unsigned char remport[256];
1234     unsigned char service[256];
1235     unsigned char portname[256];
1236 
1237 // TODO: Check the params in the LAT_Command message...
1238     debuglog(("REVLAT cmd: %d, opcode:%d request_id: %d\n", msg->cmd, msg->opcode, msg->request_id));
1239 
1240     ptr += buf[ptr]+1; // Skip past groups for now.
1241     ptr += buf[ptr]+1; // Skip past groups for now.
1242 
1243     // Get the remote node name.
1244     get_string(buf, &ptr, remnode);
1245     get_string(buf, &ptr, remport);
1246     ptr += buf[ptr]+1; // Skip past greeting...
1247     get_string(buf, &ptr, service);
1248     get_string(buf, &ptr, portname);
1249 
1250     debuglog(("Got request for reverse-LAT connection to %s/%s from %s/%s\n",
1251 	      service, portname, remnode, remport));
1252 
1253     // Make a new connection
1254     // We can reuse connections here...
1255     int connid = find_connection_by_node((char *)remnode);
1256     if (connid == -1)
1257     {
1258 	connid = get_next_connection_number();
1259 	connections[connid] = new LATConnection(connid,
1260 						(char *)service,
1261 						(char *)remport,
1262 						(char *)portname,
1263 						(char *)remnode,
1264 						false,
1265 						true);
1266     }
1267 
1268     // Make a reverse-session and connect it.
1269     LAT_SessionStartCmd startcmd;
1270     memset(&startcmd, 0, sizeof(startcmd));
1271     startcmd.dataslotsize = 255;
1272     if (connections[connid]->create_reverse_session((const char *)service,
1273 						    (const char *)&startcmd,
1274 						    dn_ntohs(msg->request_id),
1275 						    interface, macaddr) == -1)
1276     {
1277 	// If we created this connection just for the new session
1278 	// then get rid of it.
1279 	if (connections[connid]->num_clients() == 0)
1280 	    delete_connection(connid);
1281     }
1282 }
1283 
1284 // Add services received from a service announcement multicast
add_services(unsigned char * buf,int len,int interface,unsigned char * macaddr)1285 void LATServer::add_services(unsigned char *buf, int len, int interface, unsigned char *macaddr)
1286 {
1287     LAT_ServiceAnnounce *announce = (LAT_ServiceAnnounce *)buf;
1288     int ptr = sizeof(LAT_ServiceAnnounce);
1289     unsigned char service_groups[32];
1290     unsigned char nodename[256];
1291     unsigned char greeting[255];
1292     unsigned char service[255];
1293     unsigned char ident[255];
1294 
1295     // Set the groups to all zeros initially
1296     memset(service_groups, 0, sizeof(service_groups));
1297 
1298     // Make sure someone isn't pulling our leg.
1299     if (announce->group_length > 32)
1300 	announce->group_length = 32;
1301 
1302     // Get group numbers
1303     memcpy(service_groups, buf+ptr, announce->group_length);
1304 
1305     // Compare with our user groups mask (which is always either completely
1306     // empty or the full 32 bytes)
1307     int i;
1308     bool gotone = false;
1309     for (i=0; i<announce->group_length; i++)
1310     {
1311 	if (user_groups[i] & service_groups[i])
1312 	{
1313 	    gotone = true;
1314 	    break;
1315 	}
1316     }
1317 
1318     if (!gotone)
1319     {
1320 	debuglog(("remote node not in our user groups list\n"));
1321 	return;
1322     }
1323 
1324     ptr += announce->group_length;
1325     get_string(buf, &ptr, nodename);
1326     get_string(buf, &ptr, greeting);
1327 
1328     int num_services = buf[ptr++];
1329 
1330     debuglog(("service announcement: status = %d\n", announce->node_status));
1331 
1332     // Get all the services & register them
1333     for (int i=1; i<=num_services; i++)
1334     {
1335 	int rating       = buf[ptr++];
1336 
1337 	get_string(buf, &ptr, service);
1338 	get_string(buf, &ptr, ident);
1339 
1340 	if ( (announce->node_status & 1) == 0)
1341 	{
1342 	    LATServices::Instance()->add_service(std::string((char*)nodename),
1343 						 std::string((char*)service),
1344 						 std::string((char*)ident),
1345 						 rating,
1346 						 interface, macaddr);
1347 	}
1348 	else
1349 	{
1350 	    LATServices::Instance()->remove_node(std::string((char*)nodename));
1351 	}
1352     }
1353 }
1354 
1355 // Wait for data available on a client PTY
add_pty(LocalPort * port,int fd)1356 void LATServer::add_pty(LocalPort *port, int fd)
1357 {
1358     fdlist.push_back(fdinfo(fd, port, LOCAL_PTY));
1359 }
1360 
1361 
1362 // Got a new connection from latcp
accept_latcp(int fd)1363 void LATServer::accept_latcp(int fd)
1364 {
1365     struct sockaddr_un socka;
1366     socklen_t sl = sizeof(socka);
1367 
1368     int latcp_client_fd = accept(fd, (struct sockaddr *)&socka, &sl);
1369     if (latcp_client_fd >= 0)
1370     {
1371 	debuglog(("Got LATCP connection\n"));
1372 	latcp_circuits[latcp_client_fd] = new LATCPCircuit(latcp_client_fd);
1373 
1374 	fdlist.push_back(fdinfo(latcp_client_fd, 0, LATCP_SOCKET));
1375     }
1376     else
1377 	syslog(LOG_WARNING, "accept on latcp failed: %m");
1378 }
1379 
1380 // Got a new connection from llogin
accept_llogin(int fd)1381 void LATServer::accept_llogin(int fd)
1382 {
1383     struct sockaddr_un socka;
1384     socklen_t sl = sizeof(socka);
1385 
1386     int llogin_client_fd = accept(fd, (struct sockaddr *)&socka, &sl);
1387     if (llogin_client_fd >= 0)
1388     {
1389 	debuglog(("Got llogin connection\n"));
1390 	latcp_circuits[llogin_client_fd] = new LLOGINCircuit(llogin_client_fd);
1391 
1392 	fdlist.push_back(fdinfo(llogin_client_fd, 0, LLOGIN_SOCKET));
1393     }
1394     else
1395 	syslog(LOG_WARNING, "accept on llogin failed: %m");
1396 }
1397 
1398 // Read a request from LATCP
read_latcp(int fd)1399 void LATServer::read_latcp(int fd)
1400 {
1401     debuglog(("Got command on latcp socket: %d\n", fd));
1402 
1403     if (!latcp_circuits[fd]->do_command())
1404     {
1405 	// Mark the FD for removal
1406 	deleted_session s(LATCP_SOCKET, 0, 0, fd);
1407 	dead_session_list.push_back(s);
1408     }
1409 }
1410 
1411 // Read a request from LLOGIN
read_llogin(int fd)1412 void LATServer::read_llogin(int fd)
1413 {
1414     debuglog(("Got command on llogin socket: %d\n", fd));
1415 
1416     if (!latcp_circuits[fd]->do_command())
1417     {
1418 	// Mark the FD for removal
1419 	deleted_session s(LLOGIN_SOCKET, 0, 0, fd);
1420 	dead_session_list.push_back(s);
1421     }
1422 }
1423 
delete_entry(deleted_session & dsl)1424 void LATServer::delete_entry(deleted_session &dsl)
1425 {
1426     switch (dsl.get_type())
1427     {
1428     case INACTIVE:
1429 	break; // do nothing;
1430 
1431     case LAT_SOCKET:
1432     case LATCP_RENDEZVOUS:
1433     case LLOGIN_RENDEZVOUS:
1434 	// These never get deleted
1435 	break;
1436 
1437     case LATCP_SOCKET:
1438     case LLOGIN_SOCKET:
1439 	remove_fd(dsl.get_fd());
1440 	close(dsl.get_fd());
1441 	delete latcp_circuits[dsl.get_fd()];
1442 	latcp_circuits.erase(dsl.get_fd());
1443 	break;
1444 
1445     case LOCAL_PTY:
1446     case DISABLED_PTY:
1447 	remove_fd(dsl.get_fd());
1448 	if (connections[dsl.get_conn()])
1449 	    connections[dsl.get_conn()]->remove_session(dsl.get_id());
1450 	break;
1451 
1452     default:
1453        debuglog(("Unknown socket type: %d\n", dsl.get_type()));
1454        break;
1455     }
1456 }
1457 
process_data(fdinfo & fdi)1458 void LATServer::process_data(fdinfo &fdi)
1459 {
1460     switch (fdi.get_type())
1461     {
1462     case INACTIVE:
1463     case DISABLED_PTY:
1464 	break; // do nothing;
1465 
1466     case LOCAL_PTY:
1467 	fdi.get_localport()->do_read();
1468 	break;
1469 
1470     case LAT_SOCKET:
1471 	read_lat(fdi.get_fd());
1472 	break;
1473 
1474     case LATCP_RENDEZVOUS:
1475 	accept_latcp(fdi.get_fd());
1476 	break;
1477 
1478     case LLOGIN_RENDEZVOUS:
1479 	accept_llogin(fdi.get_fd());
1480 	break;
1481 
1482     case LATCP_SOCKET:
1483 	read_latcp(fdi.get_fd());
1484 	break;
1485 
1486     case LLOGIN_SOCKET:
1487 	read_llogin(fdi.get_fd());
1488 	break;
1489     }
1490 }
1491 
1492 // Send a circuit disconnect with error code
send_connect_error(int reason,LAT_Header * msg,int interface,unsigned char * macaddr)1493 void LATServer::send_connect_error(int reason, LAT_Header *msg, int interface,
1494 				   unsigned char *macaddr)
1495 {
1496     unsigned char buf[1600];
1497     LAT_Header *header = (LAT_Header *)buf;
1498     int ptr=sizeof(LAT_Header);
1499 
1500     memset(buf, 0, sizeof(buf));
1501 
1502     header->cmd             = LAT_CCMD_DISCON;
1503     header->num_slots       = 0;
1504     header->local_connid    = 0; // Servers expect this to be clear
1505     header->remote_connid   = msg->local_connid;
1506     header->sequence_number = msg->sequence_number;
1507     header->ack_number      = msg->ack_number;
1508     buf[ptr++]              = reason;
1509     send_message(buf, ptr, interface, macaddr);
1510 }
1511 
1512 // Shutdown by latcp
Shutdown()1513 void LATServer::Shutdown()
1514 {
1515     // Shutdown all the connections first
1516     for (int i=1; i<MAX_CONNECTIONS; i++)
1517     {
1518 	if (connections[i])
1519 	    dead_connection_list.push_back(i);
1520     }
1521 
1522     // Exit the main loop.
1523     do_shutdown = true;
1524 }
1525 
1526 // Return true if 'name' is a local service
is_local_service(char * name)1527 bool LATServer::is_local_service(char *name)
1528 {
1529     // Look for it.
1530     std::list<serviceinfo>::iterator sii;
1531     sii = find(servicelist.begin(), servicelist.end(), name);
1532     if (sii != servicelist.end()) return true;
1533 
1534     return false;
1535 }
1536 
1537 // Return the command info for a service
get_service_info(char * name,std::string & cmd,int & maxcon,int & curcon,uid_t & uid,gid_t & gid)1538 int LATServer::get_service_info(char *name, std::string &cmd, int &maxcon, int &curcon, uid_t &uid, gid_t &gid)
1539 {
1540     // Look for it.
1541     std::list<serviceinfo>::iterator sii;
1542     sii = find(servicelist.begin(), servicelist.end(), name);
1543     if (sii != servicelist.end())
1544     {
1545 	cmd = sii->get_command();
1546 	maxcon = sii->get_max_connections();
1547 	curcon = sii->get_cur_connections();
1548 	uid = sii->get_uid();
1549 	gid = sii->get_gid();
1550 
1551 	return 0;
1552     }
1553 
1554     return -1;
1555 }
1556 
1557 // Add a new service from latcp
add_service(char * name,char * ident,char * command,int max_conn,uid_t uid,gid_t gid,int _rating,bool _static_rating)1558 bool LATServer::add_service(char *name, char *ident, char *command, int max_conn,
1559 			    uid_t uid, gid_t gid, int _rating, bool _static_rating)
1560 {
1561     // Look for it.
1562     std::list<serviceinfo>::iterator sii;
1563     sii = find(servicelist.begin(), servicelist.end(), name);
1564     if (sii != servicelist.end()) return false; // Already exists
1565 
1566     // if rating is 0 then use the node default.
1567     if (!_rating) _rating = rating;
1568 
1569     servicelist.push_back(serviceinfo(name,
1570 				      _rating,
1571 				      _static_rating,
1572 				      ident,
1573 				      max_conn,
1574 				      command,
1575 				      uid, gid));
1576 
1577     // Resend the announcement message.
1578     send_service_announcement(-1);
1579 
1580     return true;
1581 }
1582 
1583 
1584 // Change the rating of a service
set_rating(char * name,int _rating,bool _static_rating)1585 bool LATServer::set_rating(char *name, int _rating, bool _static_rating)
1586 {
1587     // Look for it.
1588     std::list<serviceinfo>::iterator sii;
1589     sii = find(servicelist.begin(), servicelist.end(), name);
1590     if (sii == servicelist.end()) return false; // Not found it
1591 
1592     sii->set_rating(_rating, _static_rating);
1593 
1594     // Resend the announcement message.
1595     send_service_announcement(-1);
1596     return true;
1597 }
1598 
1599 // Change the ident of a service
set_ident(char * name,char * ident)1600 bool LATServer::set_ident(char *name, char *ident)
1601 {
1602     // Look for it.
1603     std::list<serviceinfo>::iterator sii;
1604     sii = find(servicelist.begin(), servicelist.end(), name);
1605     if (sii == servicelist.end()) return false; // Not found it
1606 
1607     debuglog(("Setting ident for %s to '%s'\n", name, ident));
1608 
1609     sii->set_ident(ident);
1610 
1611     // Resend the announcement message.
1612     send_service_announcement(-1);
1613     return true;
1614 }
1615 
1616 
1617 // Remove reverse-LAT port via latcp
remove_port(char * name)1618 bool LATServer::remove_port(char *name)
1619 {
1620     debuglog(("remove port %s\n", name));
1621 
1622     // Search for it.
1623     std::list<LocalPort>::iterator p(portlist.begin());
1624     for (; p != portlist.end(); p++)
1625     {
1626 	if (strcmp(p->get_devname().c_str(), name) == 0)
1627 	{
1628 	    p->close_and_delete();
1629 	    portlist.erase(p);
1630 	    return true;
1631 	}
1632 
1633     }
1634     return false;
1635 }
1636 
1637 
1638 
1639 // Remove service via latcp
remove_service(char * name)1640 bool LATServer::remove_service(char *name)
1641 {
1642     // Only add the service if it does not already exist.
1643     std::list<serviceinfo>::iterator sii;
1644     sii = find(servicelist.begin(), servicelist.end(), name);
1645     if (sii == servicelist.end()) return false; // Does not exist
1646 
1647     servicelist.erase(sii);
1648 
1649     // This is overkill but it gets rid of the service in the known
1650     // services table.
1651     LATServices::Instance()->remove_node(std::string((char*)get_local_node()));
1652 
1653     // Resend the announcement message -- this will re-add our node
1654     // services back into the known services list.
1655     send_service_announcement(-1);
1656 
1657     return true;
1658 }
1659 
1660 // Change the multicast timer
set_multicast(int newtime)1661 void LATServer::set_multicast(int newtime)
1662 {
1663     if (newtime)
1664     {
1665 	multicast_timer = newtime;
1666 	alarm(newtime);
1667     }
1668 }
1669 
1670 // Change the node name
set_nodename(unsigned char * name)1671 void LATServer::set_nodename(unsigned char *name)
1672 {
1673     debuglog(("New node name is %s\n", name));
1674 
1675     // Remove all existing node services
1676     LATServices::Instance()->remove_node(std::string((char*)get_local_node()));
1677 
1678     // Set the new name
1679     strcpy((char *)local_name, (char *)name);
1680 
1681     // Resend the announcement message -- this will re-add our node
1682     // services back into the known services list.
1683     send_service_announcement(-1);
1684 
1685 }
1686 
1687 // Start sending service announcements
unlock()1688 void LATServer::unlock()
1689 {
1690     sig_blk_t _block(SIGALRM);
1691     locked = false;
1692     alarm_signal(SIGALRM);
1693 }
1694 
1695 // Generic make_connection code for llogin & port sessions.
make_connection(int fd,const char * service,const char * rnode,const char * port,const char * localport,const char * password,bool queued)1696 int LATServer::make_connection(int fd, const char *service, const char *rnode, const char *port,
1697 			       const char *localport, const char *password, bool queued)
1698 {
1699     unsigned char macaddr[6];
1700     std::string servicenode;
1701     int this_int;
1702     char node[255];
1703 
1704     // Take a local copy of the node so we can overwrite it.
1705     strcpy(node, rnode);
1706 
1707     // If no node was specified then use the highest rated one
1708     if (node[0] == '\0')
1709     {
1710 debuglog(("make_connection : no node, use highest\n"));
1711 	if (!LATServices::Instance()->get_highest(std::string((char*)service),
1712 						  servicenode, macaddr,
1713 						  &this_int))
1714 	{
1715 	    debuglog(("Can't find service %s\n", service));
1716 	    return -2; // Never eard of it!
1717 	}
1718 	strcpy((char *)node, servicenode.c_str());
1719     }
1720     else
1721     {
1722 debuglog(("make_connection : node : %s\n", node));
1723 	// Try to find the node
1724 	if (!LATServices::Instance()->get_node(std::string((char*)service),
1725 					       std::string((char*)node), macaddr,
1726 					       &this_int))
1727 	{
1728 	    debuglog(("Can't find node %s in service\n", node, service));
1729 
1730 	    return -2;
1731 	}
1732     }
1733 
1734 // Look for a connection that's already in use for this node, unless we
1735 // are queued in which case we need to allocate a new connection for
1736 // initiating the connection and receiving status requests on.
1737     int connid = -1;
1738     if (!queued) connid = find_connection_by_node(node);
1739     if (connid == -1)
1740     {
1741 	// None: create a new one
1742 	connid = get_next_connection_number();
1743 	connections[connid] = new LATConnection(connid,
1744 						(char *)service,
1745 						(char *)port,
1746 						(char *)localport,
1747 						(char *)node,
1748 						queued,
1749 						false);
1750     }
1751 
1752     return connid;
1753 }
1754 
1755 
make_llogin_connection(int fd,const char * service,const char * rnode,const char * port,const char * localport,const char * password,bool queued)1756 int LATServer::make_llogin_connection(int fd, const char *service, const char *rnode, const char *port,
1757 				      const char *localport, const char *password, bool queued)
1758 {
1759     int ret;
1760     int connid;
1761 
1762     connid = make_connection(fd, service, rnode, port, localport, password, queued);
1763     if (connid < 0)
1764 	return connid;
1765 
1766     debuglog(("lloginSession for %s has connid %d\n", service, connid));
1767 
1768     ret = connections[connid]->create_llogin_session(fd, service, port, localport, password);
1769 
1770     // Remove LLOGIN socket from the list as it's now been
1771     // added as a PTY (honest!)
1772     deleted_session s(LLOGIN_SOCKET, 0, 0, fd);
1773     dead_session_list.push_back(s);
1774 
1775     return ret;
1776 }
1777 
1778 
1779 // Called when activity is detected on a LocalPort - we connect it
1780 // to the service.
make_port_connection(int fd,LocalPort * lport,const char * service,const char * rnode,const char * port,const char * localport,const char * password,bool queued)1781 int LATServer::make_port_connection(int fd, LocalPort *lport,
1782 				    const char *service, const char *rnode,
1783 				    const char *port,
1784 				    const char *localport,
1785 				    const char *password,
1786 				    bool queued)
1787 {
1788     int ret;
1789     int connid;
1790     debuglog(("LATServer::make_port_connection : fd %d, lport '0x%X', service '%s', rnode '%s', port '%s', localport '%s', pwd '%s'\n",
1791 	      fd, lport, service, rnode, port, localport, password));
1792 
1793     connid = make_connection(fd, service, rnode, port, localport, password, queued);
1794     if (connid < 0)
1795 	return connid;
1796 
1797     debuglog(("localport for %s has connid %d\n", service, connid));
1798 
1799     ret = connections[connid]->create_localport_session(fd, lport, service,
1800 							port, localport, password);
1801 
1802     return ret;
1803 }
1804 
1805 
1806 // Called from latcp to create a /dev/lat/ port
1807 // Here we simply add it to a lookaside list and wait
1808 // for it to be activated by a user.
create_local_port(unsigned char * service,unsigned char * portname,unsigned char * devname,unsigned char * remnode,bool queued,bool clean,unsigned char * password)1809 int LATServer::create_local_port(unsigned char *service,
1810 				 unsigned char *portname,
1811 				 unsigned char *devname,
1812 				 unsigned char *remnode,
1813 				 bool queued,
1814 				 bool clean,
1815 				 unsigned char *password)
1816 {
1817     debuglog(("Server::create_local_port: %s\n", devname));
1818 
1819 // Don't create it if it already exists.
1820     std::list<LocalPort>::iterator i(portlist.begin());
1821     for (; i != portlist.end(); i++)
1822     {
1823 	if (strcmp(i->get_devname().c_str(), (char *)devname) == 0)
1824 	{
1825 	    return 1; // already in use
1826 	}
1827     }
1828 
1829     portlist.push_back(LocalPort(service, portname, devname, remnode, queued, clean, password));
1830 
1831 // Find the actual port in the list and start it up, this is because
1832 // the STL containers hold actual objects rather then pointers
1833     std::list<LocalPort>::iterator p(portlist.begin());
1834     for (; p != portlist.end(); p++)
1835     {
1836 	if (strcmp(p->get_devname().c_str(), (char *)devname) == 0)
1837 	{
1838 	    p->init_port();
1839 	    break;
1840 	}
1841     }
1842 
1843     return 0;
1844 }
1845 
1846 
1847 // Make this as much like VMS LATCP SHOW NODE as possible.
show_characteristics(bool verbose,std::ostringstream & output)1848 bool LATServer::show_characteristics(bool verbose, std::ostringstream &output)
1849 {
1850     output <<std::endl;
1851     output.setf(std::ios::left, std::ios::adjustfield);
1852 
1853     output << "Node Name:  ";
1854     output.width(15);
1855     output << get_local_node() << " " << "    LAT Protocol Version:       " << LAT_VERSION << "." << LAT_VERSION_ECO << std::endl;
1856     output.setf(std::ios::right, std::ios::adjustfield);
1857     output << "Node State: On " << "                 LATD Version:               " << VERSION << std::endl;
1858     output << "Node Ident: " << greeting << std::endl;
1859     output << std::endl;
1860 
1861     output << "Service Responder : " << (responder?"Enabled":"Disabled") << std::endl;
1862     output << "Interfaces        : ";
1863     for (int i=0; i<num_interfaces; i++)
1864     {
1865 	output << iface->ifname(interface_num[i]) << " ";
1866     }
1867     output << std::endl << std::endl;
1868 
1869     output << "Circuit Timer (msec): " << std::setw(6) << circuit_timer*10 << "    Keepalive Timer (sec): " << std::setw(6) << keepalive_timer << std::endl;
1870     output << "Retransmit Limit:     " << std::setw(6) << retransmit_limit << std::endl;
1871     output << "Multicast Timer (sec):" << std::setw(6) << multicast_timer << std::endl;
1872     output << std::endl;
1873 
1874     // Show groups
1875     output << "User Groups:     ";
1876     print_bitmap(output, true, user_groups);
1877     output << "Service Groups:  ";
1878     print_bitmap(output, groups_set, groups);
1879     output << std::endl;
1880 
1881     // Show services we are accepting for.
1882     output << "Service Name   Status   Rating  Identification" << std::endl;
1883     std::list<serviceinfo>::iterator i(servicelist.begin());
1884     for (; i != servicelist.end(); i++)
1885     {
1886 	output.width(15);
1887 	output.setf(std::ios::left, std::ios::adjustfield);
1888 	output << i->get_name().c_str();
1889 	output.setf(std::ios::right, std::ios::adjustfield);
1890 	output << "Enabled" << std::setw(6) << i->get_rating() <<
1891 	    (i->get_static()?"    ":" D  ") << i->get_id() << std::endl;
1892     }
1893 
1894     output << std::endl << "Port                    Service         Node            Remote Port     Queued" << std::endl;
1895 
1896     // Show allocated ports
1897     std::list<LocalPort>::iterator p(portlist.begin());
1898     for (; p != portlist.end(); p++)
1899     {
1900 	p->show_info(verbose, output);
1901     }
1902 
1903     // NUL-terminate it.
1904     output << std::endl << std::ends;
1905 
1906     return true;
1907 }
1908 
show_nodes(bool verbose,std::ostringstream & output)1909 bool LATServer::show_nodes(bool verbose, std::ostringstream &output)
1910 {
1911     return LATServices::Instance()->list_dummy_nodes(verbose, output);
1912 }
1913 
1914 // Return a number for a new connection
get_next_connection_number()1915 int LATServer::get_next_connection_number()
1916 {
1917     int i;
1918     for (i=next_connection; i < MAX_CONNECTIONS; i++)
1919     {
1920 	if (!connections[i])
1921 	{
1922 	    next_connection = i+1;
1923 	    return i;
1924 	}
1925     }
1926 
1927 // Didn't find a slot here - try from the start
1928     for (i=1; i < next_connection; i++)
1929     {
1930 	if (!connections[i])
1931 	{
1932 	    next_connection = i+1;
1933 	    return i;
1934 	}
1935     }
1936     return -1;
1937 }
1938 
set_servergroups(unsigned char * bitmap)1939 int LATServer::set_servergroups(unsigned char *bitmap)
1940 {
1941     // Assume all unset if this is the first mention of groups
1942     if (!groups_set)
1943     {
1944 	memset(groups, 0, 32);
1945 	user_groups[0] = 1; // But enable group 0
1946     }
1947     groups_set = true;
1948 
1949     for (int i=0; i<32; i++)
1950     {
1951 	groups[i] |= bitmap[i];
1952     }
1953     return true;
1954 }
1955 
unset_servergroups(unsigned char * bitmap)1956 int LATServer::unset_servergroups(unsigned char *bitmap)
1957 {
1958     // Assume all set if this is the first mention of groups
1959     if (!groups_set)
1960     {
1961 	memset(groups, 0xFF, 32);
1962     }
1963     groups_set = true;
1964 
1965     for (int i=0; i<32; i++)
1966     {
1967 	groups[i] &= ~bitmap[i];
1968     }
1969     return true;
1970 }
1971 
set_usergroups(unsigned char * bitmap)1972 int LATServer::set_usergroups(unsigned char *bitmap)
1973 {
1974     for (int i=0; i<32; i++)
1975     {
1976 	user_groups[i] |= bitmap[i];
1977     }
1978     return true;
1979 }
1980 
unset_usergroups(unsigned char * bitmap)1981 int LATServer::unset_usergroups(unsigned char *bitmap)
1982 {
1983     for (int i=0; i<32; i++)
1984     {
1985 	user_groups[i] &= ~bitmap[i];
1986     }
1987     return true;
1988 }
1989 
1990 // Look for a connection for this node name, if not found then
1991 // return -1
find_connection_by_node(const char * node)1992 int LATServer::find_connection_by_node(const char *node)
1993 {
1994     debuglog(("Looking for connection to node %s\n", node));
1995     for (int i=1; i<MAX_CONNECTIONS; i++)
1996     {
1997 	if (connections[i] &&
1998 	    connections[i]->node_is(node) &&
1999 	    connections[i]->num_clients() < LATConnection::MAX_SESSIONS-1)
2000 	{
2001 	    debuglog(("Reusing connection for node %s\n", node));
2002 	    return i;
2003 	}
2004     }
2005     return -1;
2006 }
2007 
2008 // Print a groups bitmap
2009 // TODO: print x-y format like we accept in latcp.
print_bitmap(std::ostringstream & output,bool isset,unsigned char * bitmap)2010 void LATServer::print_bitmap(std::ostringstream &output, bool isset, unsigned char *bitmap)
2011 {
2012     if (!isset)
2013     {
2014 	output << "0" << std::endl;
2015 	return;
2016     }
2017 
2018     bool printed = false;
2019 
2020     for (int i=0; i<32; i++) // Show bytes
2021     {
2022 	unsigned char thebyte = bitmap[i];
2023 
2024 	for (int j=0; j<8; j++) // Bits in the byte
2025 	{
2026 	    if (thebyte&1)
2027 	    {
2028 		if (printed) output << ",";
2029 		printed = true;
2030 		output << i*8+j;
2031 	    }
2032 	    thebyte = thebyte>>1;
2033 	}
2034     }
2035     output << std::endl;
2036 }
2037 
2038 LATServer *LATServer::instance = NULL;
2039 unsigned char LATServer::greeting[255] = {'\0'};
2040