1 /*
2 *
3 * XASTIR, Amateur Station Tracking and Information Reporting
4 * Copyright (C) 2000-2019 The Xastir Group
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 * Look at the README for more information on the program.
21 */
22
23
24
25 //
26 // The idea here: Have Xastir spawn off a separate server (via a
27 // system() call?) which can provide listening sockets for other
28 // APRS clients to connect to. This allows other clients to share
29 // Xastir's TNC ports. Forking Xastir directly and running the
30 // server code doesn't work out well: The new process ends up with
31 // the large Xastir memory image. We need a separate app with a
32 // small memory image for the server. It might spawn off quite a
33 // few processes, and we need it to be small and fast.
34 //
35 // The initial goal here is to take one box that is RF-rich (running
36 // one or more TNC's), and have the ability to let other APRS
37 // clients (Xastir or otherwise) to share the RF and/or internet
38 // connections of the "master" Xastir session. This could be useful
39 // in an EOC (Emergency Operations Center), a large SAR mission with
40 // multiple computers, or simply to allow one to connect to their
41 // home Xastir session from work and gain the use of the RF ports.
42 // My use: On a SAR mission, using wireless networking and laptops
43 // to let everyone see the same picture, multiplexing to one Xastir
44 // session running a TNC. As usual, I'm sure other users will
45 // figure out new and inventive uses for it.
46 //
47 // Yes, this does pose some security risks to the license of the
48 // operator. I wouldn't recommend having an open port on the
49 // internet to allow people to use your RF ports. Of course with
50 // the authentication stuff that'll be in here, it's as secure as
51 // the igating stuff that we currently have for APRS.
52 //
53 // I thought about using IPC Messaging or FIFO's (named pipes) in
54 // order to make the connection from this server back to the
55 // "master" Xastir session. I looked at the lack of support for
56 // them in Cygwin and decided to use sockets instead. We'll set up
57 // a special registration for Xastir so that this server code knows
58 // which port is the "master" port (controlling port).
59 //
60 // Xastir will end up with a togglebutton to enable the server:
61 // Starts up x_spider.
62 // Connects to x_spider with a socket.
63 // Sends a special string so x_spider knows which one is the
64 // controlling (master) socket.
65 // All packets received/transmitted by Xastir on any port also get
66 // sent to x_spider.
67 //
68 // x_spider:
69 // Accepts client socket connections.
70 // Spawns a new process for each one.
71 // Each new process talks to the main x_spider via two pipes.
72 // Authenticate each connecting client in the normal manner.
73 // Accept data from any socket, echo data out _all_ sockets.
74 // If the "master" Xastir sends a shutdown packet, all connections
75 // are dropped and x_spider and all it's children will exit.
76 // x_spider uses select() calls to multiplex all pipes and the
77 // listening socket. It shouldn't use up much CPU as it'll be
78 // in the blocking select call until it has data to process.
79 // x_spider's children should also wait in blocking calls until
80 // there is data to process.
81 //
82 // This makes the design of the server rather simple: It needs to
83 // authenticate clients and it needs to parse the shutdown message
84 // from the "master" socket. Other than that it just needs to
85 // re-transmit anything heard on one socket to all of the other
86 // connected sockets.
87 //
88 // Xastir itself will have to change a bit in order to add the
89 // togglebutton, to send anything transmit/received to the special
90 // socket, and to send the registration and shutdown strings to the
91 // server at the appropriate times. Not earth-shaking changes, but
92 // changes nonetheless.
93 //
94 // Most of this code is adapted directly from W. Richard Steven's
95 // book: "Unix Network Programming". Highly recommended book, as
96 // are the other books by him that I own. I was sorry to hear of
97 // his passing.
98 //
99 // Name for this? Spider, centipede, millipede, octopus,
100 // multiplexer, repeater.
101
102
103 #ifdef HAVE_CONFIG_H
104 #include "config.h"
105 #endif // HAVE_CONFIG_H
106
107 #include "x_spider.h"
108 #include "snprintf.h"
109
110 #include <stdarg.h>
111 #include <stdio.h>
112 #include <stdlib.h>
113 #include <assert.h>
114 #include <ctype.h>
115 #include <sys/stat.h>
116 #include <sys/file.h>
117 #include <unistd.h>
118 #include <dirent.h>
119 #include <signal.h>
120 #include <termios.h>
121 #include <pwd.h>
122
123 #include <termios.h>
124 #include <setjmp.h>
125 #include <sys/socket.h>
126 #include <fcntl.h>
127 #include <string.h>
128
129 #include <poll.h>
130 #include <netinet/in.h> // Moved ahead of inet.h as reports of some *BSD's not
131 // including this as they should.
132 #include <arpa/inet.h>
133 #include <netinet/tcp.h> // Needed for TCP_NODELAY setsockopt() (disabling Nagle algorithm)
134
135 #ifdef HAVE_NETDB_H
136 #include <netdb.h>
137 #endif // HAVE_NETDB_H
138
139 #include <sys/types.h>
140 #include <sys/wait.h>
141 #include <sys/ioctl.h>
142
143 #if TIME_WITH_SYS_TIME
144 #include <sys/time.h>
145 #include <time.h>
146 #else // TIME_WITH_SYS_TIME
147 #if HAVE_SYS_TIME_H
148 #include <sys/time.h>
149 #else // HAVE_SYS_TIME_H
150 #include <time.h>
151 #endif // HAVE_SYS_TIME_H
152 #endif // TIME_WITH_SYS_TIME
153
154 #include <errno.h>
155
156 #ifdef HAVE_LOCALE_H
157 #include <locale.h>
158 #endif // HAVE_LOCALE_H
159
160 #ifndef SIGRET
161 #define SIGRET void
162 #endif // SIGRET
163
164 #include "xastir.h"
165
166 // Must be last include file
167 #include "leak_detection.h"
168
169
170
171 // Define this if you wish to use this as a standalone program
172 // instead of as a function in another program.
173 //
174 //#define STANDALONE_PROGRAM
175
176
177
178 // These are from util.h/util.c. We can't include util.h here
179 // because it causes other problems.
180 extern short checkHash(char *theCall, short theHash);
181 extern void get_timestamp(char *timestring);
182 extern void split_string( char *data, char *cptr[], int max, char search_char );
183
184
185 // From database.h
186 extern char my_callsign[];
187
188 extern char *pname;
189
190 typedef struct _pipe_object
191 {
192 int to_child[2];
193 int to_parent[2];
194 char callsign[20];
195 int authenticated;
196 int active; // Mark for deletion after every task is finished
197 struct _pipe_object *next;
198 } pipe_object;
199
200
201 pid_t parent_pid;
202 pipe_object *pipe_head = NULL;
203 //int master_fd = -1; // Start with an invalid value
204
205 pipe_object *xastir_tcp_pipe = NULL;
206 pipe_object *xastir_udp_pipe = NULL;
207
208 // TCP server pipes to/from Xastir proper
209 int pipe_xastir_to_tcp_server = -1;
210 int pipe_tcp_server_to_xastir = -1;
211
212 // UDP server pipes to/from Xastir proper
213 int pipe_xastir_to_udp_server = -1; // (not currently used)
214 int pipe_udp_server_to_xastir = -1;
215
216
217
218
219
220 /*
221 // Read "n" bytes from a descriptor. Use in place of read() when fd
222 // is a stream socket. This routine is from "Unix Network
223 // Programming".
224 //
225 // This routine is not used currently.
226 //
227 int readn(int fd, char *ptr, int nbytes) {
228 int nleft, nread;
229
230 nleft = nbytes;
231 while (nleft > 0) {
232 nread = read(fd, ptr, nleft);
233 if (nread < 0) {
234 return(nread); // Error, return < 0
235 }
236 else if (nread == 0) {
237 break; // EOF
238 }
239
240 nleft -= nread;
241 ptr += nread;
242 }
243 return(nbytes - nleft); // Return >= 0
244 }
245 */
246
247
248
249
250
251 // Write "n" bytes to a descriptor. Use in place of write() when fd
252 // is a stream socket. This routine is from "Unix Network
253 // Programming".
254 //
writen(int fd,char * ptr,int nbytes)255 int writen(int fd, char *ptr, int nbytes)
256 {
257 int nleft, nwritten;
258
259 nleft = nbytes;
260 while (nleft > 0)
261 {
262 nwritten = write(fd, ptr, nleft);
263 if (nwritten <= 0)
264 {
265 return(nwritten); // Error
266 }
267
268 nleft -= nwritten;
269 ptr += nwritten;
270 }
271
272 // fprintf(stderr,
273 // "writen: %d bytes written, %d bytes left to write\n",
274 // nleft,
275 // nbytes - nleft);
276
277 return(nbytes - nleft);
278 }
279
280
281
282
283
284 // Read a line from a descriptor. Read the line one byte at a time,
285 // looking for the newline. We store the newline in the buffer,
286 // then follow it with a null (the same as fgets(3)). We return the
287 // number of characters up to, but not including, the null (the same
288 // as strlen(3)); This routine is from "Unix Network Programming".
289 //
readline(int fd,char * ptr,int maxlen)290 int readline(int fd, char *ptr, int maxlen)
291 {
292 int n, rc;
293 char c;
294
295 for (n = 1; n < maxlen; n++)
296 {
297 if ( (rc = read(fd, &c, 1)) == 1)
298 {
299 *ptr++ = c;
300 if (c == '\n')
301 {
302 break;
303 }
304 }
305 else if (rc == 0)
306 {
307 if (n == 1)
308 {
309 return(0); // EOF, no data read
310 }
311 else
312 {
313 break; // EOF, some data was read
314 }
315 }
316 else
317 {
318 return(-1); // Error
319 }
320 }
321 *ptr = 0;
322 return(n);
323 }
324
325
326
327
328
329 #define MAXLINE 512
330
331
332 // Read a stream socket one line at a time, and write each line back
333 // to the sender. Return when the connection is terminated. This
334 // routine is from "Unix Network Programming".
335 //
336 /*
337 void str_echo(int sockfd) {
338 int n;
339 char line[MAXLINE];
340
341 for ( ; ; ) {
342 n = readline(sockfd, line, MAXLINE);
343 if (n == 0) {
344 return; // Connection terminated
345 }
346 if (n < 0) {
347 fprintf(stderr,"str_echo: No data to read\n");
348 }
349
350 if (writen(sockfd, line, n) != n) {
351 fprintf(stderr,"str_echo: Writen error\n");
352 }
353 }
354 }
355 */
356
357
358
359
360
361 // Read a stream socket one line at a time, and write each line back
362 // to the sender. Return when the connection is terminated. This
363 // routine is from "Unix Network Programming".
364 //
str_echo2(int sockfd,int pipe_from_parent,int pipe_to_parent)365 void str_echo2(int sockfd, int pipe_from_parent, int pipe_to_parent)
366 {
367 int n;
368 char line[MAXLINE];
369
370
371 // Set socket to be non-blocking.
372 //
373 if (fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0)
374 {
375 fprintf(stderr,"str_echo2: Couldn't set socket non-blocking\n");
376 }
377
378 // Set read-end of pipe to be non-blocking.
379 //
380 if (fcntl(pipe_from_parent, F_SETFL, O_NONBLOCK) < 0)
381 {
382 fprintf(stderr,"str_echo2: Couldn't set read-end of pipe_from_parent non-blocking\n");
383 }
384
385
386 //Send our callsign to spider clients as "#callsign" much like APRS-IS sends "# javaAPRS"
387 // # xastir 1.5.1 callsign:<mycall>
388 sprintf(line,"# Welcome to Xastir's server port, callsign: %s\r\n",my_callsign);
389 writen(sockfd,line,strlen(line));
390
391 // Infinite loop
392 for ( ; ; )
393 {
394
395 //
396 // Read data from socket, write to pipe (parent)
397 //
398 if (!sockfd) // Socket is closed
399 {
400 return; // Connection terminated
401 }
402
403 n = readline(sockfd, line, MAXLINE);
404 if (n == 0)
405 {
406 return; // Connection terminated
407 }
408 if (n < 0)
409 {
410 //fprintf(stderr,"str_echo2: Readline error: %d\n",errno);
411 if (errno == EAGAIN || errno == EWOULDBLOCK)
412 {
413 // This is normal if we have no data to read
414 //fprintf(stderr,"EAGAIN or EWOULDBLOCK\n");
415 }
416 else // Non-normal error. Report it.
417 {
418 fprintf(stderr,"str_echo2: Readline error socket: %d\n",errno);
419 //close(sockfd);
420 return;
421 }
422 }
423 else // We received some data. Send it down the pipe.
424 {
425 // fprintf(stderr,"str_echo2: %s\n",line);
426 if (writen(pipe_to_parent, line, n) != n)
427 {
428 fprintf(stderr,"str_echo2: Writen error socket: %d\n",errno);
429 //close(sockfd);
430 return;
431 }
432 }
433
434
435 //
436 // Read data from pipe (parent), write to socket
437 //
438 if (!pipe_from_parent)
439 {
440 exit(0);
441 }
442
443 n = readline(pipe_from_parent, line, MAXLINE);
444 if (n == 0)
445 {
446 exit(0); // Connection terminated
447 }
448 if (n < 0)
449 {
450 //fprintf(stderr,"str_echo2: Readline error: %d\n",errno);
451 if (errno == EAGAIN || errno == EWOULDBLOCK)
452 {
453 // This is normal if we have no data to read
454 //fprintf(stderr,"EAGAIN or EWOULDBLOCK\n");
455 }
456 else // Non-normal error. Report it.
457 {
458 fprintf(stderr,"str_echo2: Readline error pipe: %d\n",errno);
459 //close(pipe_from_parent);
460 return;
461 }
462 }
463 else // We received some data. Send it down the socket.
464 {
465 // fprintf(stderr,"str_echo2: %s\n",line);
466
467 if (writen(sockfd, line, n) != n)
468 {
469 fprintf(stderr,"str_echo2: Writen error pipe: %d\n",errno);
470 //close(pipe_from_parent);
471 return;
472 }
473 }
474
475 // Slow the loop down to prevent excessive CPU.
476
477 // NOTE: We must be faster at processing packets than the
478 // main.c:UpdateTime() can send them to us through the pipe! If
479 // we're not, we lose or corrupt packets.
480
481 usleep(1000); // 1ms
482 }
483 }
484
485
486
487
488
489 // Function which checks the incoming pipes to see if there's any
490 // data. If there is, checks to see if it is a control packet or a
491 // registration packet from the master. If not, echoes the data out
492 // all outgoing pipes.
493 //
494 // If we get a shutdown from the verified master, send a "1" as the
495 // return value, which will shut down the server. Otherwise send a
496 // "0" return value.
497 //
498 // Incoming registration data: Record only the master socket. All
499 // others should be handled by the child processes, and they should
500 // not pass the registration info down to us. Same for control
501 // packets. Actually, the child process handling the master socket
502 // could skip notifying us as well, and just pass down the control
503 // packets if the master sent any (like the shutdown packet). If we
504 // lost the connection between Xastir and x_spider, we might not
505 // have a clean way of shutting down the server in that case though.
506 // Might be better to record it down here, and if the pipes ever
507 // closed, we shut down x_spider and all the child processes.
508 //
pipe_check(char * client_address)509 int pipe_check(char *client_address)
510 {
511 pipe_object *p = pipe_head;
512 int n;
513 char line[MAXLINE];
514
515
516 // Need a select here with a timeout? Also need a method of
517 // revising the read bits we send to select. Should we revise
518 // them every time through the loop, or set a variable in the
519 // main() routine whenever a new connect comes in. What about
520 // connects that go away? We need a way to free up the pipes
521 // and sockets in that case, and revise the select bits again.
522
523 // select();
524
525 //fprintf(stderr,"pipe_check()\n");
526
527 // All of the read ends of the pipes have been set non-blocking
528 // by this point.
529
530 // Check all the pipes in the linked list looking for something
531 // to read.
532 while (p != NULL)
533 {
534 // fprintf(stderr,"Running through pipes\n");
535
536 //
537 // Read data from pipe, write to all pipes except the one
538 // who sent it.
539 //
540 n = p->active ? readline(p->to_parent[0], line, MAXLINE): 0;
541 if (n == 0 && p->active)
542 {
543 char timestring[101];
544
545 get_timestamp(timestring);
546
547 if (p->authenticated)
548 {
549 fprintf(stderr,
550 "%s X_spider session terminated, callsign: %s, address: %s\n",
551 timestring,
552 p->callsign,
553 client_address);
554 }
555 else
556 {
557 fprintf(stderr,
558 "%s X_spider session terminated, unauthenticated user, address %s\n",
559 timestring,
560 client_address);
561 }
562
563 // Close the pipe
564 close(p->to_child[1]);
565 close(p->to_parent[0]);
566
567 p->active = 0; // This task is ready to let go.
568
569 wait(NULL); // Reap the status of the dead process
570 }
571 else if (n < 0)
572 {
573 //fprintf(stderr,"pipe_check: Readline error: %d\n",errno);
574 if (errno == EAGAIN || errno == EWOULDBLOCK)
575 {
576 // This is normal if we have no data to read
577 //fprintf(stderr,"EAGAIN or EWOULDBLOCK\n");
578 }
579 else // Non-normal error. Report it.
580 {
581 fprintf(stderr,"pipe_check: Readline error: %d\n",errno);
582 }
583 }
584 else if (p->active) // We received some data. Send it down all of the
585 {
586 // pipes except the one that sent it.
587
588 pipe_object *q;
589
590
591 // Check for an authentication string. If the pipe has not been
592 // authenticated, we don't allow it to send anything to the upstream
593 // server. It's probably ok to send it to downstream connections
594 // though.
595
596 // Check for "user" "pass" string.
597 // "user WE7U-13 pass XXXX vers XASTIR 1.3.3"
598 if (strstr(line,"user") && strstr(line,"pass"))
599 {
600 char line2[MAXLINE];
601 char *callsign;
602 char *passcode_str;
603 short passcode;
604 char *space;
605
606 // We have a string with user/pass in it, but they
607 // can be anywhere along the line. We'll have to
608 // search for each piece.
609
610 //fprintf(stderr,"x_spider:Found an authentication string\n");
611
612 // Copy the line
613 xastir_snprintf(line2, sizeof(line2), "%s", line);
614
615 // Add white space to the end.
616 strncat(line2,
617 " ",
618 sizeof(line2) - 1 - strlen(line2));
619
620 // Find the "user" string position
621 callsign = strstr(line2,"user");
622
623 if (callsign == NULL)
624 {
625 continue;
626 }
627
628 // Fast-forward past the "user" word.
629 callsign += 4;
630
631 // Skip past any additional spaces that might be
632 // present between "user" and callsign.
633 while (callsign[0] == ' ' && callsign[0] != '\0')
634 {
635 callsign += 1;
636 }
637
638 if (callsign[0] == '\0')
639 {
640 continue;
641 }
642
643 // We should now be pointing at the beginning of the
644 // callsign.
645
646 // Find the space after the callsign
647 space = strstr(callsign," ");
648
649 if (space == NULL)
650 {
651 continue;
652 }
653
654 // Terminate the callsign string
655 space[0] = '\0';
656
657 // Snag the passcode string
658
659 // Find the "pass" string
660 passcode_str = strstr(&space[1],"pass");
661
662 if (passcode_str == NULL)
663 {
664 continue;
665 }
666
667 // Fast-forward past the "pass" word.
668 passcode_str = passcode_str + 4;
669
670 // Skip past any additional spaces that might be
671 // present between "pass" and the passcode.
672 while (passcode_str[0] == ' ' && passcode_str[0] != '\0')
673 {
674 passcode_str += 1;
675 }
676
677 if (passcode_str[0] == '\0')
678 {
679 continue;
680 }
681
682 // Find the space after the passcode
683 space = strstr(&passcode_str[0]," ");
684
685 if (space == NULL)
686 {
687 continue;
688 }
689
690 // Terminate the passcode string
691 space[0] = '\0';
692
693 passcode = atoi(passcode_str);
694
695 //fprintf(stderr,"x_spider: user:.%s., pass:%d\n", callsign, passcode);
696
697 if (checkHash(callsign, passcode))
698 {
699 // Authenticate the pipe. It is now allowed to send
700 // to the upstream server.
701 //fprintf(stderr,
702 // "x_spider: Authenticated user %s\n",
703 // callsign);
704 p->authenticated = 1;
705 xastir_snprintf(p->callsign,
706 sizeof(p->callsign),
707 "%s",
708 callsign);
709 p->callsign[19] = '\0';
710 }
711 else
712 {
713 fprintf(stderr,
714 "X_spider: Bad authentication, user %s, pass %d\n",
715 callsign,
716 passcode);
717 fprintf(stderr,
718 "Line: %s\n",
719 line);
720 }
721 }
722
723 q = pipe_head;
724
725 while (q != NULL)
726 {
727 // fprintf(stderr,"pipe_check: %s\n",line);
728
729 // Only send to active pipes
730 if (q != p && q->active)
731 {
732 if (writen(q->to_child[1], line, n) != n)
733 {
734 fprintf(stderr,"pipe_check: Writen error1: %d\n",errno);
735 }
736 }
737 q = q->next;
738 }
739
740 // Here we send it to Xastir itself. We use a couple of
741 // global variables just like channel_data() does, but
742 // we don't have to protect them in the same manner as
743 // we only have one process on each end.
744 //
745
746 // Send it down the pipe to Xastir's main thread. Knock off any
747 // carriage return that might be present. We only want a linefeed
748 // on the end.
749 if (n > 0 && (line[n-1] == '\r' || line[n-1] == '\n'))
750 {
751 line[n-1] = '\0';
752 n--;
753 }
754 if (n > 0 && (line[n-1] == '\r' || line[n-1] == '\n'))
755 {
756 line[n-1] = '\0';
757 n--;
758 }
759 // Add the linefeed on the end
760 strncat(line,"\n",sizeof(line)-strlen(line)-1);
761 n++;
762
763 // Only send to upstream server if this client has authenticated.
764 if (p->authenticated)
765 {
766
767 //fprintf(stderr,"Data available, sending to server\n");
768 //fprintf(stderr,"\t%s\n",line);
769
770 if (writen(pipe_tcp_server_to_xastir, line, n) != n)
771 {
772 fprintf(stderr, "pipe_check: Writen error2: %d\n", errno);
773 }
774 }
775 }
776
777 if (p)
778 {
779 p = p->next;
780 }
781 }
782
783
784 // Check the pipe from Xastir's main thread to see if it is
785 // sending us any data
786 n = readline(pipe_xastir_to_tcp_server, line, MAXLINE);
787
788 if (n == 0)
789 {
790 exit(0); // Connection terminated
791 }
792
793 if (n < 0)
794 {
795 //fprintf(stderr,"pipe_check: Readline error: %d\n",errno);
796 if (errno == EAGAIN || errno == EWOULDBLOCK)
797 {
798 // This is normal if we have no data to read
799 //fprintf(stderr,"EAGAIN or EWOULDBLOCK\n");
800 }
801 else // Non-normal error. Report it.
802 {
803 fprintf(stderr,"pipe_check: Readline error: %d\n",errno);
804 }
805 }
806
807 else // We received some data. Send it down all of the
808 {
809 // pipes.
810 // Also send it down the socket.
811
812 // Check for disconnected clients and delete their records
813 // from the chain.
814 pipe_object *q = pipe_head;
815 pipe_object *r = pipe_head;
816 for (q = pipe_head; q != NULL; )
817 {
818
819 if (!q->active) // Marked for deletion.
820 {
821
822 // Check for head of list, handle it in a special
823 // manner. We don't have to fix up the "next"
824 // pointer on the previous object (it doesn't exist)
825 // but must fix up "pipe_head" pointer.
826 if (q == pipe_head)
827 {
828 pipe_head = q->next; // New head of list
829 p = q; // Assign temporary pointer
830 q = q->next; // Keep pointer to next object
831 r = q; // Keep 'r' and 'q' the same for now,
832 // later 'r' will lag 'q' by one object
833 free(p); // Free struct at temporary pointer
834 }
835 else // Not the head object
836 {
837 r->next = q->next; // Bridge soon-to-be-made gap
838 p = q; // Assign temporary pointer
839 q = q->next; // Keep pointer to next connection.
840 free(p); // Free struct at temp pointer
841 }
842 }
843 else
844 {
845 r = q; // Pointer to last object (so we can get to
846 // the "next" pointer)
847 q = q->next; // Pointer to next object
848 }
849 }
850 q = pipe_head; // Reset pointer to beginning of list
851
852 //fprintf(stderr,"n:%d\n",n);
853 // Terminate it
854 line[n] = '\0';
855 //fprintf(stderr,"sp %s\n", line);
856
857 // The internet protocol for sending lines is "\r\n". Knock
858 // off any line-end characters that might be present, then
859 // add a "\r\n" combo on the end.
860 //
861 if (n >= 1 && (line[n-1] == '\r' || line[n-1] == '\n'))
862 {
863 line[n-1] = '\0';
864 n--;
865 }
866 if (n >= 1 && (line[n-1] == '\r' || line[n-1] == '\n'))
867 {
868 line[n-1] = '\0';
869 n--;
870 }
871 // Add carriage-return/linefeed onto the end
872 strncat(line, "\r\n", sizeof(line)-strlen(line)-1);
873 n += 2;
874
875 while (q != NULL && q->active)
876 {
877 // fprintf(stderr,"pipe_check: %s\n",line);
878
879 if (writen(q->to_child[1], line, n) != n)
880 {
881 fprintf(stderr,"pipe_check: Writen error1: %d\n",errno);
882 }
883 q = q->next;
884 }
885 }
886
887 return(0);
888 }
889
890
891
892
893
894 // The below three functions init_set_proc_title() and
895 // set_proc_title() are from:
896 // http://lightconsulting.com/~thalakan/process-title-notes.html
897 // They seems to work fine on Linux, but they only change the "ps"
898 // listings, not the top listings. I don't know why yet.
899
900 // Here's another good web page for Linux:
901 // http://www.uwsg.iu.edu/hypermail/linux/kernel/0006.1/0610.html
902
903 // clear_proc_title is to clean up internal pointers for environment.
904
905 /* Globals */
906 static char **Argv = ((void *)0);
907 #ifdef __linux__
908 #ifndef __LSB__
909 extern char *__progname, *__progname_full;
910 #endif // __LSB__
911 #endif // __linux__
912 static char *LastArgv = ((void *)0);
913 static char **local_environ;
914 #ifdef __linux__
915 #ifndef __LSB__
916 static char *old_progname, *old_progname_full;
917 #endif // __LSB__
918 #endif // __linux__
919
920
clear_proc_title(void)921 void clear_proc_title(void)
922 {
923 int i;
924 for(i = 0; local_environ && local_environ[i] != NULL; i++)
925 {
926 free(local_environ[i]);
927 }
928 if (local_environ)
929 {
930 free(local_environ);
931 local_environ = NULL;
932 }
933 #ifdef __linux__
934 #ifndef __LSB__
935 free(__progname);
936 free(__progname_full);
937 __progname = old_progname;
938 __progname_full = old_progname_full;
939 #endif // __LSB__
940 #endif // __linux__
941 }
942
init_set_proc_title(int UNUSED (argc),char * argv[],char * envp[])943 void init_set_proc_title(int UNUSED(argc), char *argv[], char *envp[])
944 {
945 int i, envpsize;
946 char **p;
947
948 for(i = envpsize = 0; envp[i] != NULL; i++)
949 {
950 envpsize += strlen(envp[i]) + 1;
951 }
952
953 if((p = (char **) malloc((i + 1) * sizeof(char *))) != NULL )
954 {
955 local_environ = p;
956
957 for(i = 0; envp[i] != NULL; i++)
958 {
959 if((local_environ[i] = malloc(strlen(envp[i]) + 1)) != NULL)
960 xastir_snprintf(local_environ[i],
961 strlen(envp[i])+1,
962 "%s",
963 envp[i]);
964 }
965 }
966 local_environ[i] = NULL;
967
968 Argv = argv;
969
970 for(i = 0; argv[i] != NULL; i++)
971 {
972 if((LastArgv + 1) == argv[i]) // Not sure if this conditional is needed
973 {
974 LastArgv = envp[i] + strlen(envp[i]);
975 }
976 }
977 #ifdef __linux__
978 #ifndef __LSB__
979 // Pretty sure you don't need this either
980 old_progname = __progname;
981 old_progname_full = __progname_full;
982 __progname = strdup("xastir");
983 __progname_full = strdup(argv[0]);
984 #endif // __LSB__
985 #endif // __linux__
986 atexit(clear_proc_title);
987 }
988
989
set_proc_title(char * fmt,...)990 void set_proc_title(char *fmt,...)
991 {
992 va_list msg;
993 static char statbuf[8192];
994 char *p;
995 int i,maxlen = (LastArgv - Argv[0]) - 2;
996
997 //fprintf(stderr,"DEBUG: maxlen: %i\n", maxlen);
998
999 va_start(msg,fmt);
1000
1001 memset(statbuf, 0, sizeof(statbuf));
1002 xastir_vsnprintf(statbuf, sizeof(statbuf), fmt, msg);
1003
1004 va_end(msg);
1005
1006 i = strlen(statbuf);
1007
1008 xastir_snprintf(Argv[0], maxlen, "%s", statbuf);
1009 p = &Argv[0][i];
1010
1011 while(p < LastArgv)
1012 {
1013 *p++ = '\0';
1014 }
1015 Argv[1] = ((void *)0) ;
1016 }
1017
1018 #define ADDR_STR_LEN 39
1019
addr_str(const struct sockaddr * sa,char * s)1020 char *addr_str(const struct sockaddr *sa, char *s)
1021 {
1022 switch(sa->sa_family)
1023 {
1024 case AF_INET:
1025 inet_ntop(AF_INET, &(((struct sockaddr_in *)sa)->sin_addr),
1026 s, ADDR_STR_LEN);
1027 break;
1028
1029 case AF_INET6:
1030 inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)sa)->sin6_addr),
1031 s, ADDR_STR_LEN);
1032 break;
1033
1034 default:
1035 xastir_snprintf(s, ADDR_STR_LEN, "<unknown family: %d>",
1036 sa->sa_family);
1037 return NULL;
1038 }
1039
1040 return s;
1041 }
1042
1043
1044 #define MAXSOCK 8
open_spider_server_sockets(int socktype,int port,int ** s_in)1045 int open_spider_server_sockets(int socktype, int port, int **s_in)
1046 {
1047 struct addrinfo hints, *res, *res0;
1048 int error;
1049 int nsock;
1050 int buf;
1051 int *s;
1052 char port_str[16];
1053
1054 xastir_snprintf(port_str, 16, "%d", port);
1055
1056 *s_in = calloc(MAXSOCK, sizeof(int));
1057 s = *s_in;
1058
1059 // Query for socketrs we need to create (probably 1 each for IPv4 + IPv6)
1060 memset(&hints, 0, sizeof(hints));
1061 hints.ai_family = PF_UNSPEC;
1062 hints.ai_socktype = socktype;
1063 hints.ai_flags = AI_PASSIVE;
1064
1065 error = getaddrinfo(NULL, port_str, &hints, &res0);
1066 if (error)
1067 {
1068 fprintf(stderr, "Error: Unable to lookup addresses for port %s\n", port_str);
1069 return 0;
1070 }
1071
1072 // Create and setup each socket
1073 nsock = 0;
1074 for (res = res0; res && nsock < MAXSOCK; res = res->ai_next)
1075 {
1076 s[nsock] = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
1077
1078 if (s[nsock] < 0)
1079 {
1080 fprintf(stderr, "Error: Opening socket (family %d protocol %d\n",
1081 res->ai_family, res->ai_protocol);
1082 fprintf(stderr,"Could some processes still be running from a previous run of Xastir?\n");
1083 continue;
1084 }
1085
1086 #ifdef IPV6_V6ONLY
1087 if(res->ai_family == AF_INET6)
1088 {
1089 buf = 1;
1090 if (setsockopt(s[nsock], IPPROTO_IPV6, IPV6_V6ONLY, (char *)&buf, sizeof(buf)) < 0)
1091 {
1092 fprintf(stderr, "x_spider: Unable to set IPV6_V6ONLY.\n");
1093 }
1094 }
1095
1096 #endif
1097 if(socktype == SOCK_STREAM)
1098 {
1099 // Set the new socket to be non-blocking.
1100 //
1101 if (fcntl(s[nsock], F_SETFL, O_NONBLOCK) < 0)
1102 {
1103 fprintf(stderr,"x_spider: Couldn't set socket non-blocking\n");
1104 fprintf(stderr,"Could some processes still be running from a previous run of Xastir?\n");
1105 }
1106
1107 // Set up to reuse the port number (good for debug so we can
1108 // restart the server quickly against the same port).
1109 buf = 1;
1110 if (setsockopt(s[nsock], SOL_SOCKET, SO_REUSEADDR, (char *)&buf, sizeof(buf)) < 0)
1111 {
1112 fprintf(stderr,"x_spider: Couldn't set socket REUSEADDR\n");
1113 fprintf(stderr,"Could some processes still be running from a previous run of Xastir?\n");
1114 }
1115 }
1116
1117 if (bind(s[nsock], res->ai_addr, res->ai_addrlen) < 0)
1118 {
1119 fprintf(stderr, "x_spider: Can't bind local address for AF %d: %d - %s\n",
1120 res->ai_family, errno, strerror(errno));
1121 fprintf(stderr, "Either this OS maps IPv4 addresses to IPv6 and this may be expected or\n");
1122 fprintf(stderr,"could some processes still be running from a previous run of Xastir?\n");
1123 close(s[nsock]);
1124 continue;
1125 }
1126
1127 if(socktype == SOCK_STREAM)
1128 {
1129 // Set up to listen. We allow up to five backlog connections
1130 // (unserviced connects that get put on a queue until we can
1131 // service them).
1132 (void) listen(s[nsock], 5);
1133 }
1134
1135 nsock++;
1136 }
1137 if (nsock == 0)
1138 {
1139 fprintf(stderr, "x_spider: Couldn't open any sockets\n");
1140 }
1141 freeaddrinfo(res0);
1142 return nsock;
1143 }
1144
1145
1146 // Create a poll structure from an array of sockets
setup_poll_array(int nsock,int * sockfds)1147 struct pollfd* setup_poll_array(int nsock, int* sockfds)
1148 {
1149 int i;
1150 struct pollfd* polls;
1151
1152 polls = calloc(nsock, sizeof(struct pollfd));
1153 for(i=0; i<nsock; i++)
1154 {
1155 polls[i].fd = sockfds[i];
1156 polls[i].events = POLLIN;
1157 }
1158 return polls;
1159 }
1160
1161
1162 // This TCP server provides a listening socket. When a client
1163 // connects, the server forks off a separate process to handle it
1164 // and goes back to listening for new connects. The initial code
1165 // framework here is from the book: "Unix Network Programming".
1166 //
1167 // Create two pipes between this server and each child process.
1168 // Identify and record which socket is the master socket connection
1169 // (back to the Xastir session that started up x_spider). Set this
1170 // variable once, don't change it if another client connects and
1171 // claims to be the master. If we get control commands from the
1172 // master, service them.
1173 //
1174 // If anything that comes in from a client that's not a registration
1175 // or a control packet, repeat it to all of the other connected
1176 // clients, including sending it to the controlling Xastir socket
1177 // (which is also a data channel).
1178 //
1179 // We need to make the "accept" call non-blocking so that we can
1180 // keep servicing all of the pipes from the children. If any pipe
1181 // has data, check whether it's a registration from the master or a
1182 // control packet. If not, send the data out each client
1183 // connection. Each child will take care of normal APRS
1184 // authentication. If the client doesn't authenticate, close the
1185 // socket and exit from the child process. Notify the main process
1186 // as well?
1187 //
1188 #ifdef STANDALONE_PROGRAM
main(int argc,char * argv[])1189 int main(int argc, char *argv[])
1190 {
1191 #else // !STANDALONE_PROGRAM
1192 void TCP_Server(int argc, char *argv[], char *envp[])
1193 {
1194 #endif // STANDALONE_PROGRAM
1195
1196 int sockfd, newsockfd, childpid;
1197 int *sockfds;
1198 int nsock;
1199 int i, rc;
1200 socklen_t clilen;
1201 struct sockaddr_storage cli_addr;
1202 struct pollfd *polls;
1203 pipe_object *p;
1204 int pipe_to_parent; /* symbolic names to reduce confusion */
1205 int pipe_from_parent;
1206 char timestring[101];
1207 char addrstring[ADDR_STR_LEN+1];
1208
1209
1210 nsock = open_spider_server_sockets(SOCK_STREAM, SERV_TCP_PORT, &sockfds);
1211 if(!nsock)
1212 {
1213 fprintf(stderr, "Unable to setup any x_spider server sockets.\n");
1214 exit(1);
1215 }
1216
1217 // Setup socket polling array and free the socket array
1218 // (since the FDs were copied into the poll array)
1219 polls = setup_poll_array(nsock, sockfds);
1220 free(sockfds);
1221
1222 memset((char *)&cli_addr, 0, sizeof(cli_addr));
1223
1224 // Infinite loop
1225 //
1226 for ( ; ; )
1227 {
1228 int flag;
1229
1230
1231 // Look for a connection from a client process. This is a
1232 // concurrent server (allows multiple concurrent
1233 // connections).
1234
1235 clilen = (socklen_t)sizeof(cli_addr);
1236
1237 rc = poll(polls, nsock, 0);
1238
1239 if(rc==0)
1240 {
1241 // We returned from the non-blocking poll but with
1242 // no incoming socket connection. Check the pipe
1243 // queues for incoming data.
1244 //
1245 if (pipe_check(addr_str((struct sockaddr*)&cli_addr, addrstring)) == -1)
1246 {
1247
1248 // We received a shutdown command from the
1249 // master socket connection.
1250 exit(0);
1251 }
1252 goto finis;
1253 }
1254 else if(rc==-1)
1255 {
1256 // Some error with poll
1257 fprintf(stderr, "x_spider: Error with TCP poll(): %d - %s\n", errno, strerror(errno));
1258 goto finis;
1259 }
1260
1261 // A connection should be waiting. Scan the poll set for an FD that has one
1262 // waiting and use that.
1263 sockfd = -1;
1264 for(i=0; i<nsock; i++)
1265 {
1266 if(polls[i].revents == POLLIN)
1267 {
1268 sockfd = polls[i].fd;
1269 }
1270 }
1271
1272 if(sockfd == -1)
1273 {
1274 // Something unexpected is going on as we didn't find a socket with a
1275 // connection waiting.
1276 fprintf(stderr, "x_spider: Weird, poll() said connection waiting but none found.\n");
1277 goto finis;
1278 }
1279
1280 // "accept" is the call where we wait for a connection. We
1281 // made the socket non-blocking above so that we pop out of
1282 // it with an EAGAIN if we don't have an incoming socket
1283 // connection. This lets us check all of our pipe
1284 // connections for incoming data periodically.
1285 //
1286 newsockfd = accept(sockfd,
1287 (struct sockaddr *)&cli_addr,
1288 &clilen);
1289
1290 if (newsockfd == -1)
1291 {
1292 if (errno == EAGAIN || errno == EWOULDBLOCK)
1293 {
1294 // Something unexpected is going on as poll() had said that we had a
1295 // connection waiting.
1296 fprintf(stderr, "x_spider: Weird, poll() said connection waiting but accept() failed.\n");
1297 goto finis;
1298 }
1299 else if (newsockfd < 0)
1300 {
1301
1302 // Some error happened in accept(). Skip the rest
1303 // of the loop.
1304 //
1305 fprintf(stderr,"x_spider: Accept error: %d\n", errno);
1306 fprintf(stderr,"Could some processes still be running from a previous run of Xastir?\n");
1307 goto finis;
1308 }
1309 }
1310
1311 // Else we returned from the accept with an incoming
1312 // connection. Service it.
1313 //
1314 // Allocate a new pipe before we fork.
1315 //
1316 p = (pipe_object *)malloc(sizeof(pipe_object));
1317 if (p == NULL)
1318 {
1319 fprintf(stderr,"x_spider: Couldn't malloc pipe_object\n");
1320 close(newsockfd);
1321 goto finis;
1322 }
1323
1324 // We haven't authenticated this user client yet.
1325 p->authenticated = 0;
1326 p->callsign[0] = '\0';
1327
1328 get_timestamp(timestring);
1329
1330 fprintf(stderr,"%s X_spider client connected from address %s\n",
1331 timestring,
1332 addr_str((struct sockaddr*)&cli_addr, addrstring));
1333
1334 if (pipe(p->to_child) < 0 || pipe(p->to_parent) < 0)
1335 {
1336 fprintf(stderr,"x_spider: Can't create pipes\n");
1337 if (p->to_child[1])
1338 {
1339 close(p->to_child[1]);
1340 }
1341 if (p->to_child[0])
1342 {
1343 close(p->to_child[0]);
1344 }
1345 free(p); // Free the malloc'd memory.
1346 p = NULL;
1347 close(newsockfd);
1348 goto finis;
1349 }
1350
1351 // Indicate active connection!
1352 p->active = 1;
1353
1354 // Link it into the head of the chain.
1355 //
1356 p->next = pipe_head;
1357 pipe_head = p;
1358
1359 flag = 1;
1360
1361 // Turn on the socket keepalive option
1362 (void)setsockopt(newsockfd, SOL_SOCKET, SO_KEEPALIVE, (char *) &flag, sizeof(int));
1363
1364 // Disable the Nagle algorithm (speeds things up)
1365 (void)setsockopt(newsockfd, IPPROTO_TCP, TCP_NODELAY, (char *) &flag, sizeof(int));
1366
1367 if ( (childpid = fork()) < 0)
1368 {
1369 //
1370 // Problem forking. Clean up and continue loop.
1371 //
1372
1373 fprintf(stderr,"x_spider: Fork error\n");
1374 // Close pipes
1375 close(p->to_child[0]);
1376 close(p->to_child[1]);
1377 close(p->to_parent[0]);
1378 close(p->to_parent[1]);
1379 pipe_head = p->next;
1380 free(p); // Free the malloc'd memory.
1381 p = NULL;
1382 close(newsockfd);
1383 goto finis;
1384 }
1385 else if (childpid == 0)
1386 {
1387 //
1388 // child process
1389 //
1390
1391
1392 // Go back to default signal handler instead of calling
1393 // restart() on SIGHUP
1394 (void) signal(SIGHUP,SIG_DFL);
1395
1396
1397 /*
1398 fprintf(stderr,
1399 "Client address: %s\n",
1400 inet_ntoa(cli_addr.sin_addr));
1401 */
1402
1403 // Change the name of the new child process. So far
1404 // this only works for "ps" listings, not for "top".
1405 // This code only works on Linux. For BSD use
1406 // setproctitle(3), NetBSD can use setprogname(2).
1407 #ifdef __linux__
1408 init_set_proc_title(argc, argv, envp);
1409 set_proc_title("%s%s %s",
1410 "x-spider client @",
1411 addr_str((struct sockaddr*)&cli_addr, addrstring),
1412 "(xastir)");
1413 //fprintf(stderr,"DEBUG: %s\n", Argv[0]);
1414 (void) signal(SIGHUP, exit);
1415 #endif // __linux__
1416
1417 // It'd be very cool here to include the IP address of the remote
1418 // client on the "ps" line, and include the callsign of the
1419 // connecting client once the client authenticates. Both of these
1420 // are do-able.
1421
1422
1423 // New naming system so that we don't have to remember
1424 // the longer name:
1425 //
1426 pipe_to_parent = p->to_parent[1];
1427 pipe_from_parent = p->to_child[0];
1428
1429 close(sockfd); // Close original socket. Child
1430 // doesn't need the listening
1431 // socket.
1432 close(p->to_child[1]); // Close write end of pipe
1433 close(p->to_parent[0]); // Close read end of pipe
1434
1435 // str_echo(newsockfd); // Process the request
1436 str_echo2(newsockfd,
1437 pipe_from_parent,
1438 pipe_to_parent);
1439
1440
1441 // Clean up and exit
1442 //
1443 close(pipe_to_parent);
1444 close(pipe_from_parent);
1445 exit(0);
1446
1447 }
1448 //
1449 // Parent process
1450 //
1451
1452 close(newsockfd);
1453 close(p->to_parent[1]); // Close write end of pipe
1454 close(p->to_child[0]); // Close read end of pipe
1455
1456 // Set read-end of pipe to be non-blocking.
1457 //
1458 if (fcntl(p->to_parent[0], F_SETFL, O_NONBLOCK) < 0)
1459 {
1460 fprintf(stderr,"x_spider: Couldn't set read-end of pipe_to_parent non-blocking\n");
1461 fprintf(stderr,"Could some processes still be running from a previous run of Xastir?\n");
1462 }
1463
1464 finis:
1465 // Need a delay so that we don't use too much CPU, at least
1466 // for debug. Put the delay into the select() call in the
1467 // pipe_check() function once we get to that stage of
1468 // coding.
1469 //
1470
1471 // NOTE: We must be faster at processing packets than the
1472 // main.c:UpdateTime() can send them to us through the pipe! If
1473 // we're not, we lose or corrupt packets.
1474
1475 usleep(1000); // 1ms
1476 }
1477 }
1478
1479
1480
1481
1482 // Send a nack back to the xastir_udp_client program
1483 void send_udp_nack(int sock, struct sockaddr *from, int fromlen)
1484 {
1485 int n;
1486
1487 n = sendto(sock,
1488 "NACK", // Negative Acknowledgment
1489 5,
1490 0,
1491 (struct sockaddr *)from,
1492 fromlen);
1493 if (n < 0)
1494 {
1495 fprintf(stderr, "Error: sendto");
1496 }
1497 }
1498
1499
1500
1501
1502
1503 // Create a UDP listening port. This allows scripts and other
1504 // programs to inject packets into Xastir via UDP protocol.
1505 //
1506 void UDP_Server(int UNUSED(argc), char * UNUSED(argv[]), char * UNUSED(envp[]) )
1507 {
1508 int sock, n1, n2;
1509 socklen_t fromlen;
1510 struct sockaddr_storage from;
1511 struct pollfd *polls;
1512 char buf[1024];
1513 char buf2[512];
1514 char *callsign;
1515 short passcode;
1516 char *cptr[10];
1517 char *message = NULL;
1518 char message2[1024];
1519 int send_to_inet;
1520 int send_to_rf;
1521 int *sockfds;
1522 int nsock;
1523 int i, rc;
1524 char addrstring[ADDR_STR_LEN+1];
1525
1526
1527 nsock = open_spider_server_sockets(SOCK_DGRAM, SERV_UDP_PORT, &sockfds);
1528 if(!nsock)
1529 {
1530 fprintf(stderr, "Unable to setup any x_spider UDP server sockets.\n");
1531 fprintf(stderr,"Could some processes still be running from a previous run of Xastir?\n");
1532 return;
1533 }
1534
1535 // Setup socket polling array and free the socket array
1536 // (since the FDs were copied into the poll array)
1537 polls = setup_poll_array(nsock, sockfds);
1538 free(sockfds);
1539
1540 while (1)
1541 {
1542 rc = poll(polls, nsock, 5000); // Wait for data
1543 if(rc == -1)
1544 {
1545 fprintf(stderr, "x_spider: UDP poll() returned error %d: %s.\n",
1546 errno, strerror(errno));
1547 continue;
1548 }
1549 else if (rc == 0)
1550 {
1551 // Timeout, check if parent is still alive
1552 rc = kill(parent_pid, 0);
1553 if(rc == -1 && errno == ESRCH)
1554 {
1555 // Parent died, exit
1556 return;
1557 }
1558 continue;
1559 }
1560
1561 // Data should be waiting. Scan the poll set for an FD that has one waiting and use that.
1562 sock = -1;
1563 for(i=0; i<nsock; i++)
1564 {
1565 if(polls[i].revents == POLLIN)
1566 {
1567 sock = polls[i].fd;
1568 }
1569 }
1570
1571 if(sock == -1)
1572 {
1573 // Something unexpected is going on as we didn't find a socket with data waiting.
1574 fprintf(stderr, "x_spider: Weird, poll() said data waiting but none found.\n");
1575 continue;
1576 }
1577
1578 fromlen = sizeof(struct sockaddr_storage);
1579 n1 = recvfrom(sock,
1580 buf,
1581 1024,
1582 0,
1583 (struct sockaddr *)&from,
1584 &fromlen);
1585 if (n1 < 0)
1586 {
1587 fprintf(stderr, "Error: recvfrom");
1588 }
1589 else if (n1 == 0)
1590 {
1591 continue;
1592 }
1593 else
1594 {
1595 buf[n1] = '\0'; // Terminate the buffer
1596 }
1597
1598 fprintf(stderr, "Received datagram from %s: %s",
1599 addr_str((struct sockaddr*)&from, addrstring), buf);
1600
1601
1602 send_to_inet = 0;
1603 send_to_rf = 0;
1604
1605
1606 //
1607 // Authenticate the packet. First line should contain:
1608 //
1609 // callsign,passcode,[TO_RF],[TO_INET]
1610 //
1611 // The second line should contain the APRS packet
1612 //
1613
1614 // Copy the entire buffer so that we can modify it
1615 memcpy(buf2, buf, sizeof(buf2));
1616 buf2[sizeof(buf2)-1] = '\0'; // Terminate string
1617 split_string(buf2, cptr, 10, ',');
1618
1619 if (cptr[0] == NULL || cptr[0][0] == '\0') // callsign
1620 {
1621 send_udp_nack(sock, (struct sockaddr *)&from, fromlen);
1622 continue;
1623 }
1624
1625 callsign = cptr[0];
1626
1627 if (cptr[1] == NULL || cptr[1][0] == '\0') // passcode
1628 {
1629 send_udp_nack(sock, (struct sockaddr *)&from, fromlen);
1630 continue;
1631 }
1632
1633 passcode = atoi(cptr[1]);
1634
1635 fprintf(stderr,"x_spider udp: user:%s pass:%d\n", callsign, passcode);
1636
1637 if (checkHash(callsign, passcode))
1638 {
1639 // Authenticate the pipe. It is now allowed to send
1640 // to the upstream server.
1641 //fprintf(stderr,
1642 // "x_spider: Authenticated user %s\n",
1643 // callsign);
1644 }
1645 else
1646 {
1647 fprintf(stderr,
1648 "X_spider: Bad authentication, user %s, pass %d\n",
1649 callsign,
1650 passcode);
1651 fprintf(stderr,
1652 "UDP Packet: %s\n",
1653 buf);
1654 send_udp_nack(sock, (struct sockaddr *)&from, fromlen);
1655 continue;
1656 }
1657
1658
1659 // Here's where we would look for the optional flags in the
1660 // first line. Here we implement these flags:
1661 // -identify
1662 // -to_rf
1663 // -to_inet
1664
1665
1666 // Look for the "-identify" flag in the UDP packet
1667 //
1668 if (strstr(buf, "-identify"))
1669 {
1670
1671 // Send the callsign back to the xastir_udp_client
1672 // program
1673 n1 = sendto(sock,
1674 my_callsign,
1675 strlen(my_callsign)+1,
1676 0,
1677 (struct sockaddr *)&from,
1678 fromlen);
1679 if (n1 < 0)
1680 {
1681 fprintf(stderr, "Error: sendto");
1682 }
1683 continue;
1684 }
1685
1686
1687 // Look for the "-to_inet" flag in the UDP packet
1688 //
1689 if (strstr(buf, "-to_inet"))
1690 {
1691 //fprintf(stderr,"Sending to INET\n");
1692 send_to_inet++;
1693 }
1694
1695
1696 // Look for the "-to_rf" flag in the UDP packet
1697 //
1698 if (strstr(buf, "-to_rf"))
1699 {
1700 //fprintf(stderr,"Sending to local RF\n");
1701 send_to_rf++;
1702 }
1703
1704
1705 // Now snag the text message from the second line using the
1706 // original buffer. Look for the first '\n' character which
1707 // is just before the text message itself.
1708 message = strchr(buf, '\n');
1709 message++; // Point to the first char after the '\n'
1710
1711 if (message == NULL || message[0] == '\0')
1712 {
1713 //fprintf(stderr,"Empty message field\n");
1714 send_udp_nack(sock, (struct sockaddr *)&from, fromlen);
1715 continue;
1716 }
1717
1718 //fprintf(stderr,"Message: %s", message);
1719
1720 xastir_snprintf(message2,
1721 sizeof(message2),
1722 "%s%s%s",
1723 (send_to_inet) ? "TO_INET," : "",
1724 (send_to_rf) ? "TO_RF," : "",
1725 message);
1726
1727 //fprintf(stderr,"Message2: %s", message2);
1728
1729
1730
1731 //
1732 //
1733 // NOTE:
1734 // Should we refuse to send the message on if "callsign" and the
1735 // FROM callsign in the packet don't match?
1736 //
1737 // Should we change to third-party format if "my_callsign" and the
1738 // FROM callsign in the packet don't match?
1739 //
1740 // Require all three callsigns to match?
1741 //
1742 //
1743
1744
1745
1746 n1 = strlen(message);
1747 n2 = strlen(message2);
1748
1749
1750 // Send to Xastir udp pipe
1751 //
1752 //fprintf(stderr,"Sending to Xastir itself\n");
1753 if (writen(pipe_udp_server_to_xastir, message2, n2) != n2)
1754 {
1755 fprintf(stderr,"UDP_Server: Writen error1: %d\n", errno);
1756 }
1757
1758 // Send to the x_spider TCP server, so it can go to all
1759 // connected TCP clients
1760 //fprintf(stderr,"Sending to TCP clients\n");
1761 if (writen(pipe_xastir_to_tcp_server, message, n1) != n1)
1762 {
1763 fprintf(stderr, "UDP_Server: Writen error2: %d\n", errno);
1764 }
1765
1766 // Send an ACK back to the xastir_udp_client program
1767 n1 = sendto(sock,
1768 "ACK", // Acknowledgment. Good UDP packet.
1769 4,
1770 0,
1771 (struct sockaddr *)&from,
1772 fromlen);
1773 if (n1 < 0)
1774 {
1775 fprintf(stderr, "Error: sendto");
1776 }
1777 }
1778 }
1779
1780
1781
1782
1783
1784 // Function used to start a separate process for the server. This
1785 // way the server can be running concurrently with the main part of
1786 // Xastir.
1787 //
1788 // Turns out that with a "fork", the memory image of the server was
1789 // too large. Might try it with a thread instead before abandoning
1790 // that method altogether. It would be nice to have this be more
1791 // integrated with Xastir, instead of having to have a socket to
1792 // communicate between Xastir and the server.
1793 //
1794 #ifndef STANDALONE_PROGRAM
1795 int Fork_TCP_server(int argc, char *argv[], char *envp[])
1796 {
1797 int childpid;
1798
1799
1800 // Allocate a pipe before we fork.
1801 //
1802 xastir_tcp_pipe = (pipe_object *)malloc(sizeof(pipe_object));
1803 if (xastir_tcp_pipe == NULL)
1804 {
1805 fprintf(stderr,"x_spider: Couldn't malloc pipe_object\n");
1806 return(0);
1807 }
1808
1809 if (pipe(xastir_tcp_pipe->to_child) < 0 || pipe(xastir_tcp_pipe->to_parent) < 0)
1810 {
1811 fprintf(stderr,"x_spider: Can't create pipes\n");
1812 free(xastir_tcp_pipe); // Free the malloc'd memory.
1813 xastir_tcp_pipe = NULL;
1814 return(0);
1815 }
1816
1817 xastir_tcp_pipe->authenticated = 1;
1818 xastir_tcp_pipe->callsign[0] = '\0';
1819
1820 if ( (childpid = fork()) < 0)
1821 {
1822 fprintf(stderr,"Fork_TCP_server: Fork error\n");
1823
1824 // Close pipes
1825 close(xastir_tcp_pipe->to_child[0]);
1826 close(xastir_tcp_pipe->to_child[1]);
1827 close(xastir_tcp_pipe->to_parent[0]);
1828 close(xastir_tcp_pipe->to_parent[1]);
1829 free(xastir_tcp_pipe); // Free the malloc'd memory.
1830 xastir_tcp_pipe = NULL;
1831 return(0);
1832 }
1833 else if (childpid == 0)
1834 {
1835 //
1836 // Child process
1837 //
1838
1839
1840 // Go back to default signal handler instead of calling
1841 // restart() on SIGHUP
1842 (void) signal(SIGHUP,SIG_DFL);
1843
1844
1845 // Change the name of the new child process. So far this
1846 // only works for "ps" listings, not for "top". This code
1847 // only works on Linux. For BSD use setproctitle(3), NetBSD
1848 // can use setprogname(2).
1849 #ifdef __linux__
1850 init_set_proc_title(argc, argv, envp);
1851 set_proc_title("%s", "x-spider TCP daemon (xastir)");
1852 //fprintf(stderr,"DEBUG: %s\n", Argv[0]);
1853 (void) signal(SIGHUP, exit);
1854 #endif // __linux__
1855
1856
1857 close(xastir_tcp_pipe->to_child[1]); // Close write end of pipe
1858 close(xastir_tcp_pipe->to_parent[0]); // Close read end of pipe
1859
1860 // Assign the global variables
1861 pipe_tcp_server_to_xastir = xastir_tcp_pipe->to_parent[1];
1862 pipe_xastir_to_tcp_server = xastir_tcp_pipe->to_child[0];
1863
1864 // Set read-end of pipe to be non-blocking.
1865 //
1866 if (fcntl(pipe_xastir_to_tcp_server, F_SETFL, O_NONBLOCK) < 0)
1867 {
1868 fprintf(stderr,"x_spider: Couldn't set read-end of pipe_xastir_to_tcp_server non-blocking\n");
1869 fprintf(stderr,"Could some processes still be running from a previous run of Xastir?\n");
1870 }
1871
1872 TCP_Server(argc, argv, envp);
1873 fprintf(stderr,"TCP_Server process died.\n");
1874 exit(1);
1875 }
1876 //
1877 // Parent process
1878 //
1879
1880 close(xastir_tcp_pipe->to_parent[1]); // Close write end of pipe
1881 close(xastir_tcp_pipe->to_child[0]); // Close read end of pipe
1882
1883 // Assign the global variables so that Xastir itself will know
1884 // how to talk to the pipes
1885 pipe_tcp_server_to_xastir = xastir_tcp_pipe->to_parent[0];
1886 pipe_xastir_to_tcp_server = xastir_tcp_pipe->to_child[1];
1887
1888 // Set read-end of pipe to be non-blocking.
1889 //
1890 if (fcntl(pipe_tcp_server_to_xastir, F_SETFL, O_NONBLOCK) < 0)
1891 {
1892 fprintf(stderr,"x_spider: Couldn't set read-end of pipe_tcp_server_to_xastir non-blocking\n");
1893 fprintf(stderr,"Could some processes still be running from a previous run of Xastir?\n");
1894 }
1895
1896 // // Set write-end of pipe to be non-blocking.
1897 // //
1898 // if (fcntl(pipe_xastir_to_tcp_server, F_SETFL, O_NONBLOCK) < 0) {
1899 // fprintf(stderr,"x_spider: Couldn't set read-end of pipe_xastir_to_tcp_server non-blocking\n");
1900 // }
1901
1902 // We don't need to do anything here except return back to the
1903 // calling routine with the PID of the new server process, so
1904 // that it can request the server and all it's children to quit
1905 // when Xastir quits or segfaults.
1906 return(childpid); // Really the parent PID in this case
1907 }
1908 #endif // STANDALONE_PROGRAM
1909
1910
1911
1912
1913
1914 int Fork_UDP_server(int argc, char *argv[], char *envp[])
1915 {
1916 int childpid;
1917
1918
1919 // Allocate a pipe before we fork.
1920 //
1921 xastir_udp_pipe = (pipe_object *)malloc(sizeof(pipe_object));
1922 if (xastir_udp_pipe == NULL)
1923 {
1924 fprintf(stderr,"x_spider: Couldn't malloc pipe_object\n");
1925 return(0);
1926 }
1927
1928 if (pipe(xastir_udp_pipe->to_child) < 0 || pipe(xastir_udp_pipe->to_parent) < 0)
1929 {
1930 fprintf(stderr,"x_spider: Can't create pipes\n");
1931 free(xastir_udp_pipe); // Free the malloc'd memory.
1932 xastir_udp_pipe = NULL;
1933 return(0);
1934 }
1935
1936 xastir_udp_pipe->authenticated = 1;
1937 xastir_udp_pipe->callsign[0] = '\0';
1938
1939 if ( (childpid = fork()) < 0)
1940 {
1941 fprintf(stderr,"Fork_UDP_server: Fork error\n");
1942
1943 // Close pipes
1944 close(xastir_udp_pipe->to_child[0]);
1945 close(xastir_udp_pipe->to_child[1]);
1946 close(xastir_udp_pipe->to_parent[0]);
1947 close(xastir_udp_pipe->to_parent[1]);
1948 free(xastir_udp_pipe); // Free the malloc'd memory.
1949 xastir_udp_pipe = NULL;
1950 return(0);
1951 }
1952 else if (childpid == 0)
1953 {
1954 //
1955 // Child process
1956 //
1957
1958
1959 // Go back to default signal handler instead of calling
1960 // restart() on SIGHUP
1961 (void) signal(SIGHUP,SIG_DFL);
1962
1963 // Store parent pid
1964 parent_pid = getppid();
1965
1966 // Change the name of the new child process. So far this
1967 // only works for "ps" listings, not for "top". This code
1968 // only works on Linux. For BSD use setproctitle(3), NetBSD
1969 // can use setprogname(2).
1970 #ifdef __linux__
1971 init_set_proc_title(argc, argv, envp);
1972 set_proc_title("%s", "x-spider UDP daemon (xastir)");
1973 //fprintf(stderr,"DEBUG: %s\n", Argv[0]);
1974 (void) signal(SIGHUP, exit);
1975 #endif // __linux__
1976
1977
1978 close(xastir_udp_pipe->to_child[1]); // Close write end of pipe
1979 close(xastir_udp_pipe->to_parent[0]); // Close read end of pipe
1980
1981 // Assign the global variables
1982 pipe_udp_server_to_xastir = xastir_udp_pipe->to_parent[1];
1983 pipe_xastir_to_udp_server = xastir_udp_pipe->to_child[0];
1984
1985 // Set read-end of pipe to be non-blocking.
1986 //
1987 // if (fcntl(pipe_xastir_to_udp_server, F_SETFL, O_NONBLOCK) < 0) {
1988 // fprintf(stderr,
1989 // "x_spider: Couldn't set read-end of pipe_xastir_to_udp_server non-blocking\n");
1990 // }
1991
1992 UDP_Server(argc, argv, envp);
1993 fprintf(stderr,"UDP_Server process died.\n");
1994 exit(1);
1995 }
1996 //
1997 // Parent process
1998 //
1999
2000 close(xastir_udp_pipe->to_parent[1]); // Close write end of pipe
2001 close(xastir_udp_pipe->to_child[0]); // Close read end of pipe
2002
2003 // Assign the global variables so that Xastir itself will know
2004 // how to talk to the pipes
2005 pipe_udp_server_to_xastir = xastir_udp_pipe->to_parent[0];
2006 pipe_xastir_to_udp_server = xastir_udp_pipe->to_child[1];
2007
2008
2009 // Set read-end of pipe to be non-blocking.
2010 //
2011 if (fcntl(pipe_udp_server_to_xastir, F_SETFL, O_NONBLOCK) < 0)
2012 {
2013 fprintf(stderr,"x_spider: Couldn't set read-end of pipe_udp_server_to_xastir non-blocking\n");
2014 fprintf(stderr,"Could some processes still be running from a previous run of Xastir?\n");
2015 }
2016
2017 // // Set write-end of pipe to be non-blocking.
2018 // //
2019 // if (fcntl(pipe_xastir_to_udp_server, F_SETFL, O_NONBLOCK) < 0) {
2020 // fprintf(stderr,"x_spider: Couldn't set read-end of pipe_xastir_to_udp_server non-blocking\n");
2021 // }
2022
2023
2024 // We don't need to do anything here except return back to the
2025 // calling routine with the PID of the new server process, so
2026 // that it can request the server and all it's children to quit
2027 // when Xastir quits or segfaults.
2028 return(childpid); // Really the parent PID in this case
2029 }
2030