linux-hams.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] ax25ipd
  2009-12-08 22:15                     ` Cathryn Mataga
@ 2009-12-15 23:14                       ` Cathryn Mataga
  0 siblings, 0 replies; 3+ messages in thread
From: Cathryn Mataga @ 2009-12-15 23:14 UTC (permalink / raw)
  To: Thomas Osterried; +Cc: linux-hams

[-- Attachment #1: Type: text/plain, Size: 1158 bytes --]

I've been sitting on this code for about a week, and it's
been running fine here.  I've made a few small changes, mostly
to the comments.

1. This patch adds the ability to route packets over axip
links that are not from the gateway callsign.

2.  Integrates the Dynamic DNS patch and uses mutex and
a thread as suggested.

3.   If DNS fails during startup for a route, the IP of a route is set
to 0. Then later, after about an hour or so, DNS for the
route is checked again.

4.  ax25ipd.conf has two new flags for routes.  l and p.

route KE6I-1 0.0.0.0 l

The route to KE6I-1 will be updated based on the IP
addresses of incoming packets.

route KE6I-2 ke6i.ampr.org p

the 'p' flag forces the code to not recheck DNS later for
this route.   If DNS fails at startup, however, DNS will
be checked until it succeeds, and then DNS will not be checked
again.


ax25ipd should route as before, except in the case when packets
not from the callsign of the route but from the same IP
would have gone to the default route, they now will go to the
ip from which they originate. (Ugh, that's an awkward sentence.)


Anyway, let me know what you think, good or bad.

[-- Attachment #2: ax25ipddyn.patch --]
[-- Type: application/x-itunes-itlp, Size: 18732 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH] ax25ipd
@ 2010-03-06 18:13 Bernard Pidoux
  2010-03-06 19:30 ` Bernard Pidoux
  0 siblings, 1 reply; 3+ messages in thread
From: Bernard Pidoux @ 2010-03-06 18:13 UTC (permalink / raw)
  To: Cathryn Mataga; +Cc: linux-hams

[-- Attachment #1: Type: text/plain, Size: 913 bytes --]

Hi Cathryn,
 
Thanks for your excellent work on ax25ipd.

I have been using ax25-apps.0.0.8-rc2 with your ax25ipd  patch for a 
couple of months.
I did not notice any issue, although I use devfs legacy pseudo tty and 
not Unix98 devices.
However I know there are an increasing number of AX25 ROSE FPAC nodes 
using  Unix98
/dev/ptmx /dev/pts devices.

I noticed that your patch included a few minor errors that I corrected.
Also you added -pthread into ax25ipd Makefile while this file does
not exist when unpacking ax25-tools-0.0.8-rc2.
Thus I moved  this argument into apps configure file.

I included also a reference  to Steve Fraser vk5asf work, adding
provision for dynamic dns hosts in June 2005, and changed sub
version number to 1.0.6

Patched ax25-apps package may be found here:
http://f6bvp.free.fr/logiciels/ax25/From%20other%20sources/ax25-apps-0.0.8-rc2.ax25ipd.dyndns.tar.bz2


Bernard Pidoux





[-- Attachment #2: ax25-apps-0.0.8-rc2.ax25ipd.dyndns.patch --]
[-- Type: text/plain, Size: 20442 bytes --]

diff -ruN ax25-apps-0.0.8-rc2/ax25ipd/ax25ipd.h ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/ax25ipd.h
--- ax25-apps-0.0.8-rc2/ax25ipd/ax25ipd.h	2009-06-14 10:11:48.000000000 +0200
+++ ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/ax25ipd.h	2010-03-06 13:58:23.000000000 +0100
@@ -25,6 +25,18 @@
  * Terry Dawson, VK2KTJ, September 2001.
  */
 
+/*
+  Version 1.0.5
+  added provision for dynamic dns hosts
+  Steve Fraser vk5asf, June 2005
+*/
+
+/*
+  Version 1.0.6
+
+
+*/
+
 /* Define the current version number
  *
  * The first digit represents the major release (0 is a prototype release)
@@ -37,7 +49,7 @@
  *
  */
 
-#define VERS2 "Version 1.0.2"
+#define VERS2 "Version 1.0.6"
 
 #define IPPROTO_AX25 93
 #define DEFAULT_UDP_PORT 10093
@@ -118,6 +130,11 @@
 
 #define	AXRT_BCAST	1
 #define	AXRT_DEFAULT	2
+#define	AXRT_PERMANENT	4
+#define	AXRT_LEARN	8	
+
+
+#define IPSTORAGESIZE 6 /* Bytes needed for call_to_ip */
 
 /* start external prototypes */
 /* end external prototypes */
@@ -133,12 +150,16 @@
 
 /* routing.c */
 void route_init(void);
-void route_add(unsigned char *, unsigned char *, int, unsigned int);
+void route_add(char *, unsigned char *, unsigned char *, int, unsigned int);
+int route_ipmatch(struct sockaddr_in *, unsigned char *);
+unsigned char *retrieveip(unsigned char *, unsigned char *);
+void route_process(struct sockaddr_in *, unsigned char *);
 void bcast_add(unsigned char *);
-unsigned char *call_to_ip(unsigned char *);
+unsigned char *call_to_ip(unsigned char *, unsigned char *);
 int is_call_bcast(unsigned char *);
 void send_broadcast(unsigned char *, int);
 void dump_routes(void);
+void update_dns(unsigned);
 
 /* config.c */
 void config_init(void);
@@ -151,11 +172,13 @@
 /* process.c */
 void process_init(void);
 void from_kiss(unsigned char *, int);
-void from_ip(unsigned char *, int);
+void from_ip(unsigned char *, int, struct sockaddr_in *);
 /* void do_broadcast(void);  where did this go ?? xxx */
 void do_beacon(void);
 int addrmatch(unsigned char *, unsigned char *);
+int addrcompare(unsigned char *, unsigned char *);
 unsigned char *next_addr(unsigned char *);
+unsigned char *from_addr(unsigned char *);
 void add_crc(unsigned char *, int);
 void dump_ax25frame(char *, unsigned char *, int);
 
diff -ruN ax25-apps-0.0.8-rc2/ax25ipd/config.c ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/config.c
--- ax25-apps-0.0.8-rc2/ax25ipd/config.c	2009-06-14 10:07:11.000000000 +0200
+++ ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/config.c	2010-03-06 11:24:05.000000000 +0100
@@ -292,6 +292,8 @@
 		return 0;
 
 	} else if (strcmp(p, "route") == 0) {
+		char *thost;
+	
 		uport = 0;
 		flags = 0;
 
@@ -305,15 +307,26 @@
 		q = strtok(NULL, " \t\n\r");
 		if (q == NULL)
 			return -1;
-		he = gethostbyname(q);
-		if (he != NULL) {
-			memcpy(tip, he->h_addr_list[0], 4);
-		} else {	/* maybe user specified a numeric addr? */
-			j = inet_addr(q);
-			if (j == -1)
-				return -5;	/* if -1, bad deal! */
+		thost = strdup(q);
+		j = inet_addr(q);
+		if (j != -1){ /* maybe user specified a numeric addr? */
+			flags |= AXRT_PERMANENT; /* Prevent useless dns check on dotted ip */
 			memcpy(tip, (char *) &j, 4);
+			if (!j){/* IP of 0.0.0.0. Learn from incoming packets */
+				flags |= AXRT_LEARN;
+			}
+		}
+		else {
+			he = gethostbyname(q); 
+			if (he != NULL) {
+				memcpy(tip, he->h_addr_list[0], 4);
+			} else {	
+				j = inet_addr("0.0.0.0");/* try to rescue this idea of checking later.*/
+				memcpy(tip,  (char *) &j, 4);
+				fprintf(stderr,"ax25ipd: %s host IP address unknown - will probe it again later\n",thost);
+			}
 		}
+	
 
 		while ((q = strtok(NULL, " \t\n\r")) != NULL) {
 			if (strcmp(q, "udp") == 0) {
@@ -334,9 +347,19 @@
 				if (strchr(q, 'd')) {
 					flags |= AXRT_DEFAULT;
 				}
+
+				/* Test for "permanent" flag */
+				if (strchr(q, 'p')) {
+					flags |= AXRT_PERMANENT;
+				}
+				/* Test for "learn" flag */
+				if (strchr(q, 'l')) {
+					flags |= AXRT_LEARN;
+				}
 			}
 		}
-		route_add(tip, tcall, uport, flags);
+		route_add(thost, tip, tcall, uport, flags);
+		free(thost);
 		return 0;
 
 	} else if (strcmp(p, "broadcast") == 0) {
diff -ruN ax25-apps-0.0.8-rc2/ax25ipd/HISTORY.ax25ipd ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/HISTORY.ax25ipd
--- ax25-apps-0.0.8-rc2/ax25ipd/HISTORY.ax25ipd	2005-10-30 11:31:40.000000000 +0100
+++ ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/HISTORY.ax25ipd	2010-03-06 14:08:24.000000000 +0100
@@ -53,4 +53,54 @@
  *		ax25 goes directly to the bpqether interface in the kernel via
  *		ethertap/tuntap interfaces, which is a much better way than
  *              traditional kissattach to a ttyp/ptyp pair.
- */
+ *
+        1.0.5
+ *
+ *              added provision for dynamic dns hosts
+ *              Steve Fraser vk5asf, June 2005
+ *
+ *
+        1.0.6
+
+List:       linux-hams
+Subject:    [PATCH] ax25ipd
+From:       Cathryn Mataga <cathryn () junglevision ! com>
+Date:       2009-12-15 23:14:01
+
+I've been sitting on this code for about a week, and it's
+been running fine here.  I've made a few small changes, mostly
+to the comments.
+
+1. This patch adds the ability to route packets over axip
+links that are not from the gateway callsign.
+
+2.  Integrates the Dynamic DNS patch and uses mutex and
+a thread as suggested.
+
+3.   If DNS fails during startup for a route, the IP of a route is set
+to 0. Then later, after about an hour or so, DNS for the
+route is checked again.
+
+4.  ax25ipd.conf has two new flags for routes.  l and p.
+
+route KE6I-1 0.0.0.0 l
+
+The route to KE6I-1 will be updated based on the IP
+addresses of incoming packets.
+
+route KE6I-2 ke6i.ampr.org p
+
+the 'p' flag forces the code to not recheck DNS later for
+this route.   If DNS fails at startup, however, DNS will
+be checked until it succeeds, and then DNS will not be checked
+again.
+
+
+ax25ipd should route as before, except in the case when packets
+not from the callsign of the route but from the same IP
+would have gone to the default route, they now will go to the
+ip from which they originate. (Ugh, that's an awkward sentence.)
+
+Anyway, let me know what you think, good or bad.
+
+*/
diff -ruN ax25-apps-0.0.8-rc2/ax25ipd/io.c ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/io.c
--- ax25-apps-0.0.8-rc2/ax25ipd/io.c	2009-06-14 17:42:11.000000000 +0200
+++ ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/io.c	2010-03-06 11:24:54.000000000 +0100
@@ -378,10 +378,11 @@
 		if (nb == 0) {
 			fflush(stdout);
 			fflush(stderr);
+			update_dns(60*60); // Once/hour
 			/* just so we go back to the top of the loop! */
 			continue;
 		}
-
+		update_dns(60*60); // once/hour
 		if (FD_ISSET(ttyfd, &readfds)) {
 			do {
 				n = read(ttyfd, buf, MAX_FRAME);
@@ -418,7 +419,7 @@
 				LOGL4("udpdata from=%s port=%d l=%d\n", (char *) inet_ntoa(from.  sin_addr), ntohs(from.  sin_port), n);
 				stats.udp_in++;
 				if (n > 0)
-					from_ip(buf, n);
+					from_ip(buf, n, &from);
 			}
 		}
 		/* if udp_mode */
@@ -434,7 +435,7 @@
 				LOGL4("ipdata from=%s l=%d, hl=%d\n", (char *) inet_ntoa(from.  sin_addr), n, hdr_len);
 				stats.ip_in++;
 				if (n > hdr_len)
-					from_ip(buf + hdr_len, n - hdr_len);
+					from_ip(buf + hdr_len, n - hdr_len, &from);
 			}
 #ifdef USE_ICMP
 			if (FD_ISSET(icmpsock, &readfds)) {
@@ -461,6 +462,9 @@
 
 	if (l <= 0)
 		return;
+	if (* (unsigned *) targetip == 0){ /* If the ip is set to 0 don't send anything. I'm not sure what sending to 0 does, but I don't like the idea. */
+		return; 
+	}
 	memcpy((char *) &to.sin_addr,
 	       targetip, 4);
 	memcpy((char *) &to.sin_port,
diff -ruN ax25-apps-0.0.8-rc2/ax25ipd/process.c ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/process.c
--- ax25-apps-0.0.8-rc2/ax25ipd/process.c	2009-06-14 10:07:11.000000000 +0200
+++ ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/process.c	2010-03-06 11:24:58.000000000 +0100
@@ -68,6 +68,7 @@
 void from_kiss(unsigned char *buf, int l)
 {
 	unsigned char *a, *ipaddr;
+        unsigned char ipstorage[IPSTORAGESIZE];// Provide storage for the IP.  To keep all the locking stuff centralized. 
 
 	if (l < 15) {
 		LOGL2("from_kiss: dumped - length wrong!\n");
@@ -105,7 +106,7 @@
 	}			/* end of tnc mode */
 
 	/* Lookup the IP address for this route */
-	ipaddr = call_to_ip(a);
+	ipaddr = call_to_ip(a, ipstorage);
 
 	if (ipaddr == NULL) {
 		if (is_call_bcast(a)) {
@@ -146,10 +147,11 @@
  * We simply send the packet to the KISS send routine.
  */
 
-void from_ip(unsigned char *buf, int l)
+void from_ip(unsigned char *buf, int l, struct sockaddr_in *ip_addr)
 {
 	int port = 0;
 	unsigned char *a;
+	unsigned char *f;
 
 	if (!ok_crc(buf, l)) {
 		stats.ip_failed_crc++;
@@ -194,6 +196,10 @@
 		}
 #endif
 	}			/* end of tnc mode */
+
+	f = from_addr(buf);
+	route_process(ip_addr, f);
+
 	if (!ttyfd_bpq)
 		send_kiss(port, buf, l);
 	else {
@@ -277,6 +283,31 @@
 }
 
 /*
+ * return 0 if the addresses supplied match
+ * return a positive or negative value otherwise 
+ */
+int addrcompare(unsigned char *a, unsigned char *b)
+{
+	signed char diff;
+
+	if ((diff = (signed char )((*a++ - *b++) & 0xfe)))
+		return diff;	/* "K" */
+	if ((diff = (signed char )((*a++ - *b++) & 0xfe)))
+		return diff;	/* "A" */
+	if ((diff = (signed char )((*a++ - *b++) & 0xfe)))
+		return diff;	/* "9" */
+	if ((diff = (signed char )((*a++ - *b++) & 0xfe)))
+		return diff;	/* "W" */
+	if ((diff = (signed char )((*a++ - *b++) & 0xfe)))
+		return diff;	/* "S" */
+	if ((diff = (signed char )((*a++ - *b++) & 0xfe)))
+		return diff;	/* "B" */
+	if ((diff = (signed char )((*a++ - *b++) & 0xfe)))
+		return diff;	/* ssid */
+	return 0;
+}
+
+/*
  * return pointer to the next station to get this packet
  */
 unsigned char *next_addr(unsigned char *f)
@@ -301,6 +332,32 @@
 }
 
 /*
+ * return pointer to the last station this packet came from 
+ */
+unsigned char *from_addr(unsigned char *f)
+{
+	unsigned char *a;
+
+	a = f + 7;
+/* If no digis, return the source address */
+	if (NO_DIGIS(f))
+		return a;
+
+/* check each digi field. Go to last that has seen it */
+	do
+		a += 7;
+	while (NOT_LAST(a) && REPEATED(a));
+
+/* in DIGI mode: we have set REPEATED already, so the one before is it */	
+	if (digi || !REPEATED(a))
+		a -= 7;
+
+/* in TNC mode: always the last is it */
+	return a;
+}
+
+
+/*
  * tack on the CRC for the frame.  Note we assume the buffer is long
  * enough to have the two bytes tacked on.
  */
diff -ruN ax25-apps-0.0.8-rc2/ax25ipd/routing.c ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/routing.c
--- ax25-apps-0.0.8-rc2/ax25ipd/routing.c	2009-06-14 10:07:11.000000000 +0200
+++ ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/routing.c	2010-03-06 17:13:34.000000000 +0100
@@ -12,6 +12,8 @@
 #include <netinet/in.h>
 #include <memory.h>
 #include <syslog.h>
+#include <string.h>
+#include <pthread.h>
 
 /* The routing table structure is not visible outside this module. */
 
@@ -23,6 +25,7 @@
 	unsigned char pad1;
 	unsigned char pad2;
 	unsigned int flags;	/* route flags */
+	char *hostnm; /* host name */
 	struct route_table_entry *next;
 };
 
@@ -38,16 +41,31 @@
 
 struct bcast_table_entry *bcast_tbl;
 
+struct callsign_lookup_entry {
+	unsigned char callsign[7];
+	struct route_table_entry *route;
+	struct callsign_lookup_entry *prev, *next;
+};
+
+struct callsign_lookup_entry *callsign_lookup;
+
+time_t last_dns_time;
+volatile int threadrunning;
+pthread_mutex_t dnsmutex = PTHREAD_MUTEX_INITIALIZER;
+
 /* Initialize the routing module */
 void route_init(void)
 {
 	route_tbl = NULL;
 	default_route = NULL;
 	bcast_tbl = NULL;
+	callsign_lookup = NULL;
+	last_dns_time = time(NULL);
+	threadrunning = 0;
 }
 
 /* Add a new route entry */
-void route_add(unsigned char *ip, unsigned char *call, int udpport,
+void route_add(char *host, unsigned char *ip, unsigned char *call, int udpport,
 	unsigned int flags)
 {
 	struct route_table_entry *rl, *rn;
@@ -75,6 +93,7 @@
 		rn->callsign[i] = call[i] & 0xfe;
 	rn->callsign[6] = (call[6] & 0x1e) | 0x60;
 	rn->padcall = 0;
+	rn->hostnm = strdup(host);
 	memcpy(rn->ip_addr, ip, 4);
 	rn->udp_port = htons(udpport);
 	rn->pad1 = 0;
@@ -100,6 +119,130 @@
 	return;
 }
 
+/* For route rn, a different IP is being used.  Trigger a DNS check. 
+ * as long as DNS hasn't been checked within 5 minutes (300 seconds)
+ * */
+void route_updatedyndns(struct sockaddr_in *ip_addr, struct route_table_entry *rn)
+{
+	if (rn->flags & AXRT_LEARN){
+		pthread_mutex_lock(&dnsmutex);
+		* (unsigned *) rn->ip_addr = (unsigned) ip_addr->sin_addr.s_addr;
+		pthread_mutex_unlock(&dnsmutex);
+	}
+	if (!(rn->flags & AXRT_PERMANENT)){
+		LOGL4("received changed ip: %s", call_to_a(rn->callsign));
+		update_dns(300);
+	}
+}
+
+/* Save the calls in a binary tree.  This code links new callsigns 
+ * back to an existing route.  No new routes are created. */
+void route_updatereturnpath(unsigned char *mycall, struct route_table_entry *rn)
+{
+	struct callsign_lookup_entry **clookupp = &callsign_lookup;
+	struct callsign_lookup_entry *clookup = callsign_lookup;
+	for (;;){
+		int chk;
+		if (!clookup){
+			clookup = *clookupp = calloc(sizeof(struct callsign_lookup_entry), 1);
+			memcpy(clookup->callsign, mycall, 7);
+			LOGL4("added return route: %s %s %s %d\n",
+	      			call_to_a(mycall),
+				(char *) inet_ntoa(*(struct in_addr *) rn->ip_addr),
+	      			rn->udp_port ? "udp" : "ip", ntohs(rn->udp_port));
+
+			clookup->route = rn;
+			return;
+		}
+		chk = addrcompare(mycall, clookup->callsign);
+		if (chk > 0){
+			clookupp = &clookup->next;
+			clookup = *clookupp;
+		}
+		else if (chk < 0){
+			clookupp = &clookup->prev;
+			clookup = *clookupp;
+			}
+		else{
+			
+			if (clookup->route != rn){
+				clookup->route = rn;
+			}
+			return;
+		}	
+	}
+
+
+}
+
+
+/* Compare ip_addr to the format used by route_table_entry */
+int route_ipmatch(struct sockaddr_in *ip_addr, unsigned char *routeip)
+{
+	unsigned char ipstorage[IPSTORAGESIZE];
+	return (unsigned) ip_addr->sin_addr.s_addr == * (unsigned *) retrieveip(routeip, ipstorage);
+}
+
+
+/* Process calls and ip addresses for routing.  The idea behind
+ * this code that for the routes listed in the ax25ipd.conf file,
+ * only DNS or the given IP's should be used.  But for calls
+ * that are not referenced in ax25ipd.conf that arrive using
+ * a known gateway IP, the code links them back to that gateway.
+ *
+ * No new routes are created.  If a callsign comes in from an  
+ * unknown gateway, it will not create an entry.
+ *
+ * if the Callsign for a known route is received, and it does
+ * not match the current ip for that route, the update_dns code
+ * is triggered, which should fix the IP based on DNS.  
+ *
+ * */
+void route_process(struct sockaddr_in *ip_addr, unsigned char *call)
+{
+	struct route_table_entry *rp;
+	unsigned char mycall[7];
+	int i;
+	int isroute;
+
+	if (call == NULL)
+		return;
+
+	for (i = 0; i < 6; i++)
+		mycall[i] = call[i] & 0xfe;
+
+	mycall[6] = (call[6] & 0x1e) | 0x60;
+
+	rp = route_tbl;
+	isroute = 0;
+	while (rp) {
+		if (addrmatch(mycall, rp->callsign)) {
+			if (!route_ipmatch(ip_addr, rp->ip_addr)) {
+				route_updatedyndns(ip_addr, rp);
+				}
+			isroute = 1;
+		}
+		rp = rp->next;
+	}				
+
+	// Don't use any of the ip lookup code for the routes.
+	// Also, do not set return paths for broadcast callsigns. 
+	// Not sure if this ever happens.  But it's no good if it does.
+	if (!isroute && !is_call_bcast(call)){
+		rp = route_tbl;
+		while (rp) {
+			// Only do this once. 
+			if (route_ipmatch(ip_addr, rp->ip_addr)) {
+				route_updatereturnpath(mycall, rp);
+				break;
+			}
+			rp = rp->next;
+		}
+	}
+
+}
+
+
 /* Add a new broadcast address entry */
 void bcast_add(unsigned char *call)
 {
@@ -136,17 +279,35 @@
 }
 
 /*
+ * It's possible that the thread will update the IP in mid
+ * memcpy of an ip address, so I changed all the references to
+ * route_table_entry->ip_addr to use this routine
+ 
+ * Note that the printfs don't check this
+ */
+
+unsigned char *retrieveip(unsigned char *ip, unsigned char *ipstorage)
+{
+	if (!ipstorage)return ip;
+	pthread_mutex_lock(&dnsmutex);
+	memcpy((void *) ipstorage, (void *) ip, IPSTORAGESIZE);
+	pthread_mutex_unlock(&dnsmutex);
+	return ipstorage;
+}
+
+/*
  * Return an IP address and port number given a callsign.
  * We return a pointer to the address; the port number can be found
  * immediately following the IP address. (UGLY coding; to be fixed later!)
  */
-
-unsigned char *call_to_ip(unsigned char *call)
+ 
+unsigned char *call_to_ip(unsigned char *call, unsigned char *ipstorage)
 {
 	struct route_table_entry *rp;
 	unsigned char mycall[7];
 	int i;
-
+	struct callsign_lookup_entry *clookup;
+	
 	if (call == NULL)
 		return NULL;
 
@@ -163,11 +324,35 @@
 			LOGL4("found ip addr %s\n",
 			      (char *) inet_ntoa(*(struct in_addr *)
 						 rp->ip_addr));
-			return rp->ip_addr;
+			return retrieveip(rp->ip_addr, ipstorage);
 		}
 		rp = rp->next;
 	}
 
+	/* Check for callsigns that have been heard on known routes */
+	clookup = callsign_lookup;
+	for (;;){
+		int chk;
+		if (!clookup){
+			break;
+		}
+		chk = addrcompare(mycall, clookup->callsign);
+		if (chk > 0){
+			clookup = clookup->next;
+		}
+		else if (chk < 0){
+			clookup = clookup->prev;
+		}
+		else{
+			LOGL4("found cached ip addr %s\n",
+			      (char *) inet_ntoa(*(struct in_addr *)
+						 clookup->route->ip_addr));
+	
+			return retrieveip(clookup->route->ip_addr, ipstorage);
+		}	
+	}
+
+
 	/*
 	 * No match found in the routing table, use the default route if
 	 * we have one defined.
@@ -176,7 +361,7 @@
 		LOGL4("failed, using default ip addr %s\n",
 		      (char *) inet_ntoa(*(struct in_addr *)
 					 default_route->ip_addr));
-		return default_route->ip_addr;
+		return retrieveip(default_route->ip_addr, ipstorage);
 	}
 
 	LOGL4("failed.\n");
@@ -223,7 +408,9 @@
 	rp = route_tbl;
 	while (rp) {
 		if (rp->flags & AXRT_BCAST) {
-			send_ip(buf, l, rp->ip_addr);
+			unsigned char ipstorage[IPSTORAGESIZE];
+
+			send_ip(buf, l, retrieveip(rp->ip_addr, ipstorage));
 		}
 		rp = rp->next;
 	}
@@ -242,7 +429,7 @@
 
 	rp = route_tbl;
 	while (rp) {
-		LOGL1("  %s\t%s\t%s\t%d\t%d\n",
+		LOGL1("  %s %s %s %d %d\n",
 		      call_to_a(rp->callsign),
 		      (char *) inet_ntoa(*(struct in_addr *) rp->ip_addr),
 		      rp->udp_port ? "udp" : "ip",
@@ -251,3 +438,60 @@
 	}
 	fflush(stdout);
 }
+
+/* Update the IPs of DNS entries for all routes */
+void *update_dnsthread(void *arg)
+{
+	struct hostent *he;
+	struct route_table_entry *rp;
+
+	rp = route_tbl;
+	while (rp) {
+		// If IP is 0,  DNS lookup failed at startup.
+		// So check DNS even though it's permanent.
+		// I think checking the lock on this ip_addr reference
+		// isn't needed since the main code doesn't change
+		// ip_addr after startup, and worst case is that it
+		// does one extra dns check
+		if ((rp->hostnm[0])  && 
+			  (!(rp->flags & AXRT_PERMANENT) || ( * (unsigned *) rp->ip_addr == 0) )){
+			LOGL4("Checking DNS for %s\n", rp->hostnm);
+			he = gethostbyname(rp->hostnm);
+			if (he != NULL) {
+				pthread_mutex_lock(&dnsmutex);
+				* (unsigned *) rp->ip_addr = * (unsigned *) he->h_addr_list[0];  
+				pthread_mutex_unlock(&dnsmutex);
+				LOGL4("DNS returned IP=%s\n", (char *) inet_ntoa(*(struct in_addr *) rp->ip_addr)); 
+			}
+		}
+		rp = rp->next;
+	}
+	threadrunning = 0;
+	pthread_exit(0);
+	return 0;
+}
+
+/* check DNS for route IPs.  Packets from system whose ip 
+ * has changed  trigger a DNS lookup. The 
+ * the timer is needed when both systems are on dynamic
+ * IPs and they both reset at about the same time.  Also
+ * when the IP changes immediately, but DNS lags.  
+ */
+void update_dns(unsigned wait)
+{
+	pthread_t dnspthread;
+	int rc;
+
+	if (threadrunning)return;// Don't start a thread when one is going already.
+	if (wait && (time(NULL) < last_dns_time + wait))return;
+	threadrunning = 1;
+	LOGL4("Starting DNS thread\n");
+	last_dns_time = time(NULL);
+	rc = pthread_create(&dnspthread, NULL, update_dnsthread,  (void *) 0);
+	if (rc){
+		LOGL1("    Thread err%d\n", rc); // Should we exit here?
+		threadrunning = 0;
+	}	
+		
+}
+
diff -ruN ax25-apps-0.0.8-rc2/ax25ipd/run.bat ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/run.bat
--- ax25-apps-0.0.8-rc2/ax25ipd/run.bat	1970-01-01 01:00:00.000000000 +0100
+++ ax25-apps-0.0.8-rc2.ax25ipd.dyndns/ax25ipd/run.bat	2010-03-06 11:24:58.000000000 +0100
@@ -0,0 +1,2 @@
+killall ax25ipd
+./ax25ipd -c /etc/ax25/ax25ipd.conf

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] ax25ipd
  2010-03-06 18:13 [PATCH] ax25ipd Bernard Pidoux
@ 2010-03-06 19:30 ` Bernard Pidoux
  0 siblings, 0 replies; 3+ messages in thread
From: Bernard Pidoux @ 2010-03-06 19:30 UTC (permalink / raw)
  To: Cathryn Mataga; +Cc: linux-hams

Hi,

Sorry, I forgot to include the patch of configure file.

--- ax25-apps-0.0.8-rc2/configure       2009-06-21 20:18:29.000000000 +0200
+++ ax25-apps-0.0.8-rc2.ax25ipd.dyndns/configure        2010-03-06 
13:59:19.000000000 +0100
@@ -13437,7 +13437,7 @@

 if test "x$GCC" = "xyes"; then
   if test -z "`echo "$CFLAGS" | grep "\-Wall" 2> /dev/null`" ; then
-    CFLAGS="$CFLAGS -Wall"
+    CFLAGS="$CFLAGS -Wall -pthread"
   fi
 fi


Bernard Pidoux


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2010-03-06 19:30 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-03-06 18:13 [PATCH] ax25ipd Bernard Pidoux
2010-03-06 19:30 ` Bernard Pidoux
     [not found] <S1752195AbZK3HxQ/20091130075316Z+372@vger.kernel.org>
2009-11-30 20:38 ` nr0 doesn't show up (netrom) Cathryn Mataga
2009-11-30 21:13   ` Cathryn Mataga
2009-11-30 21:48     ` Cathryn Mataga
2009-12-01  6:05       ` Cathryn Mataga
2009-12-07 10:30         ` ax25ipd.c routing Cathryn Mataga
2009-12-07 16:25           ` Thomas Osterried
2009-12-07 20:02             ` Cathryn Mataga
2009-12-07 20:26               ` Thomas Osterried
     [not found]                 ` <4B1D84C4.8000206@exemail.com.au>
     [not found]                   ` <20091207235111.GS19524@x-berg.in-berlin.de>
2009-12-08 22:15                     ` Cathryn Mataga
2009-12-15 23:14                       ` [PATCH] ax25ipd Cathryn Mataga

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).