#define NETWORK_PATHNAME_PID "/var/run/udpgate.pid"
#define SOCK_SOURCE_CHECK_EVENTS (G_IO_IN) /* |G_IO_PRI */
#define SOCK_SOURCE_CHECK_REVENTS (SOCK_SOURCE_CHECK_EVENTS) /* |G_IO_ERR|G_IO_HUP|G_IO_NVAL */
-#define SERVER_INADDR 0x7F000001
-#undef SERVER_INADDR
-#define SERVER_INADDR 0x511F02EA /* paulina.vellum.cz = 81.31.2.234; host order */
+#define SERVER_INADDR 0xC37AD054 /* mms2.org = 195.122.208.84; host order */
#define SERVER_PORT 9201 /* host order */
#define PROBE_INADDR SERVER_INADDR /* host order */
#define PROBE_PORT 8201 /* host order */
#define CLIENT_TIMEOUT_SEC (5*60)
-#define PROBE_TIMEOUT_SEC (5)
+#define PROBE_TIMEOUT_SEC_BASE 5
+#define PROBE_TIMEOUT_SEC_MAX 3500
void (*network_notify_hostip)(guint32 hostip_guint32);
static struct client *master; /* no 'timeout' permitted */
static struct client *probe; /* 'timeout' permitted */
static guint32 probe_unique;
+static guint probe_timeout_sec_now;
+guint probe_timeout_sec_max=G_MAXUINT;
+static gint port_local; /* for 'probe' resends */
static gboolean write_daemon_running(pid_t pid);
static gboolean client_touch_timeout(struct client *client);
-static void client_touch(struct client *client)
+static void client_touch(struct client *client,guint timeout_sec)
{
g_return_if_fail(client!=NULL);
g_return_if_fail(client!=master);
+ g_return_if_fail(timeout_sec>0);
client_timeout_remove(client);
client->timeout_id=g_timeout_add(
- (client==probe ? PROBE_TIMEOUT_SEC*1000 : CLIENT_TIMEOUT_SEC*1000), /* interval; msec */
+ timeout_sec*1000, /* interval; msec */
(GSourceFunc)client_touch_timeout, /* function */
client); /* data */
if (optarg_verbose)
}
static void client_destroy(struct client *client);
+static gboolean probe_send(struct client *probe,gint port_local);
static gboolean client_touch_timeout(struct client *client)
{
client->timeout_id=0;
if (client==probe) {
+ if (probe_timeout_sec_now<probe_timeout_sec_max) {
+ probe_timeout_sec_now*=PROBE_TIMEOUT_SEC_BASE;
+ g_assert(probe_timeout_sec_max==G_MAXUINT || probe_timeout_sec_max<PROBE_TIMEOUT_SEC_MAX);
+ probe_timeout_sec_now=MIN(probe_timeout_sec_now,probe_timeout_sec_max);
+ probe_timeout_sec_now=MIN(probe_timeout_sec_now,PROBE_TIMEOUT_SEC_MAX);
+ if (probe_send(probe,port_local)) {
+ client_touch(probe,probe_timeout_sec_now); /* timeout */
+ return FALSE; /* GSource should be removed */
+ }
+ /* failure FALLTHRU */
+ }
network_stop();
/* Never destroy 'client' now - it has been destroyed by network_stop()! */
g_warning(_("No probe response from the server, stopping the daemon. Please check your public Internet connectivity."));
handle_master_probe(packet,gotlen,&sockaddr_in_from);
continue;
}
+ /* Not yet initialized by 'probe' reply - drop it. */
+ if (probe) {
+ if (optarg_verbose)
+ g_message(_("Data packet received from %s but no probe reply yet; dropping packet."),
+ SOCKADDR_IN_TO_STRING(&sockaddr_in_from));
+ continue;
+ }
/* FIXME: Performance: Ugly search... */
for (clientl=sock_client_list;clientl;clientl=clientl->next) {
client=client_new();
client->sockaddr_in_from=sockaddr_in_from;
}
- client_touch(client);
+ client_touch(client,CLIENT_TIMEOUT_SEC);
UDPGATE_MEMZERO(&sockaddr_in_server);
sockaddr_in_server.sin_family=AF_INET;
sockaddr_in_server.sin_port=htons(SERVER_PORT);
break;
if (sockaddr_in_from_length!=sizeof(sockaddr_in_from)) /* FIXME: errors reporting */
continue;
- client_touch(client);
+ client_touch(client,CLIENT_TIMEOUT_SEC);
/* FIXME: errors checking */
sendto(
master->gpollfd.fd, /* s */
client_destroy(sock_client_list->data);
g_assert(master==NULL);
+ g_assert(probe==NULL);
if (sock_gsource) {
g_source_destroy(sock_gsource);
/* Setup 'probe': */
if (!(probe=client_new()))
return FALSE;
- probe_send(probe,port);
- client_touch(probe); /* timeout */
+ port_local=port;
+ if (!probe_send(probe,port)) {
+ client_destroy(probe);
+ return FALSE;
+ }
+ probe_timeout_sec_now=PROBE_TIMEOUT_SEC_BASE;
+ client_touch(probe,probe_timeout_sec_now); /* timeout */
return TRUE;
}