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
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
[Linux Newbie]
[Kernel Newbies]
[Memory]
[Git]
[Security]
[Netfilter]
[Linux Admin]
[Bugtraq]
[Photo]
[Yosemite Photos]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[ARM Linux Kernel]
[Linux Networking]
[Linux Security]
[Linux RAID]
[Samba]
[Video 4 Linux]
[Linux Resources]