Author: cazfi
Date: Sun Apr 12 08:27:10 2015
New Revision: 28766

URL: http://svn.gna.org/viewcvs/freeciv?rev=28766&view=rev
Log:
Client starts to listen LAN announcement before requesting them.

See bug #23319

Modified:
    branches/S2_5/client/servers.c

Modified: branches/S2_5/client/servers.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_5/client/servers.c?rev=28766&r1=28765&r2=28766&view=diff
==============================================================================
--- branches/S2_5/client/servers.c      (original)
+++ branches/S2_5/client/servers.c      Sun Apr 12 08:27:10 2015
@@ -369,7 +369,7 @@
 {
   union fc_sockaddr addr;
   struct data_out dout;
-  int sock, opt = 1;
+  int send_sock, opt = 1;
 #ifndef HAVE_WINSOCK
   unsigned char buffer[MAX_LEN_PACKET];
 #else  /* HAVE_WINSOCK */
@@ -402,16 +402,108 @@
     family = AF_INET;
   }
 
-  /* Create a socket for broadcasting to servers. */
-  if ((sock = socket(family, SOCK_DGRAM, 0)) < 0) {
-    log_error("socket failed: %s", fc_strerror(fc_get_errno()));
-    return FALSE;
-  }
-
   /* Set the UDP Multicast group IP address. */
   group = get_multicast_group(announce == ANNOUNCE_IPV6);
+
+  /* Create a socket for listening for server packets. */
+  if ((scan->sock = socket(family, SOCK_DGRAM, 0)) < 0) {
+    char errstr[2048];
+
+    fc_snprintf(errstr, sizeof(errstr),
+                _("Opening socket to listen LAN announcements failed:\n%s"),
+                fc_strerror(fc_get_errno()));
+    scan->error_func(scan, errstr);
+
+    return FALSE;
+  }
+
+  fc_nonblock(scan->sock);
+
+  if (setsockopt(scan->sock, SOL_SOCKET, SO_REUSEADDR,
+                 (char *)&opt, sizeof(opt)) == -1) {
+    log_error("SO_REUSEADDR failed: %s", fc_strerror(fc_get_errno()));
+  }
+
   memset(&addr, 0, sizeof(addr));
 
+#ifdef IPV6_SUPPORT
+  if (family == AF_INET6) {
+    addr.saddr.sa_family = AF_INET6;
+    addr.saddr_in6.sin6_port = htons(SERVER_LAN_PORT + 1);
+    addr.saddr_in6.sin6_addr = in6addr_any;
+  } else
+#endif /* IPv6 support */
+  if (family == AF_INET) {
+    addr.saddr.sa_family = AF_INET;
+    addr.saddr_in4.sin_port = htons(SERVER_LAN_PORT + 1);
+    addr.saddr_in4.sin_addr.s_addr = htonl(INADDR_ANY);
+  } else {
+    /* This is not only error situation worth assert() This
+     * is error situation that has check (with assert) against
+     * earlier already. */
+    fc_assert(FALSE);
+
+    return FALSE;
+  }
+
+  if (bind(scan->sock, &addr.saddr, sockaddr_size(&addr)) < 0) {
+    char errstr[2048];
+
+    fc_snprintf(errstr, sizeof(errstr),
+                _("Binding socket to listen LAN announcements failed:\n%s"),
+                fc_strerror(fc_get_errno()));
+    scan->error_func(scan, errstr);
+
+    return FALSE;
+  }
+
+#ifndef IPV6_SUPPORT
+  {
+#ifdef HAVE_INET_ATON
+    inet_aton(group, &mreq4.imr_multiaddr);
+#else  /* HAVE_INET_ATON */
+    mreq4.imr_multiaddr.s_addr = inet_addr(group);
+#endif /* HAVE_INET_ATON */
+#else  /* IPv6 support */
+  if (family == AF_INET6) {
+    inet_pton(AF_INET6, group, &mreq6.ipv6mr_multiaddr.s6_addr);
+    mreq6.ipv6mr_interface = 0; /* TODO: Interface selection */
+
+    if (setsockopt(scan->sock, IPPROTO_IPV6, FC_IPV6_ADD_MEMBERSHIP,
+                   (const char*)&mreq6, sizeof(mreq6)) < 0) {
+      char errstr[2048];
+
+      fc_snprintf(errstr, sizeof(errstr),
+                  _("Adding membership for IPv6 LAN announcement group 
failed:\n%s"),
+                fc_strerror(fc_get_errno()));
+      scan->error_func(scan, errstr);
+    }
+  } else {
+    inet_pton(AF_INET, group, &mreq4.imr_multiaddr.s_addr);
+#endif /* IPv6 support */
+    mreq4.imr_interface.s_addr = htonl(INADDR_ANY);
+
+    if (setsockopt(scan->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+                   (const char*)&mreq4, sizeof(mreq4)) < 0) {
+      char errstr[2048];
+
+      fc_snprintf(errstr, sizeof(errstr),
+                  _("Adding membership for IPv4 LAN announcement group 
failed:\n%s"),
+                  fc_strerror(fc_get_errno()));
+      scan->error_func(scan, errstr);
+
+      return FALSE;
+    }
+  }
+
+  /* Create a socket for broadcasting to servers. */
+  if ((send_sock = socket(family, SOCK_DGRAM, 0)) < 0) {
+    log_error("socket failed: %s", fc_strerror(fc_get_errno()));
+    return FALSE;
+  }
+
+  memset(&addr, 0, sizeof(addr));
+  
 #ifndef IPV6_SUPPORT
   if (family == AF_INET) {
 #ifdef HAVE_INET_ATON
@@ -442,14 +534,14 @@
 #ifndef HAVE_WINSOCK
   /* Set the Time-to-Live field for the packet  */
   ttl = SERVER_LAN_TTL;
-  if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&ttl, 
+  if (setsockopt(send_sock, IPPROTO_IP, IP_MULTICAST_TTL, (const char*)&ttl, 
                  sizeof(ttl))) {
     log_error("setsockopt failed: %s", fc_strerror(fc_get_errno()));
     return FALSE;
   }
 #endif /* HAVE_WINSOCK */
 
-  if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (const char*)&opt, 
+  if (setsockopt(send_sock, SOL_SOCKET, SO_BROADCAST, (const char*)&opt, 
                  sizeof(opt))) {
     log_error("setsockopt failed: %s", fc_strerror(fc_get_errno()));
     return FALSE;
@@ -460,7 +552,7 @@
   size = dio_output_used(&dout);
  
 
-  if (sendto(sock, buffer, size, 0, &addr.saddr,
+  if (sendto(send_sock, buffer, size, 0, &addr.saddr,
              sockaddr_size(&addr)) < 0) {
     /* This can happen when there's no network connection - it should
      * give an in-game message. */
@@ -471,98 +563,7 @@
     log_debug("Sending request for server announcement on LAN.");
   }
 
-  fc_closesocket(sock);
-
-  /* Create a socket for listening for server packets. */
-  if ((scan->sock = socket(family, SOCK_DGRAM, 0)) < 0) {
-    char errstr[2048];
-
-    fc_snprintf(errstr, sizeof(errstr),
-                _("Opening socket to listen LAN announcements failed:\n%s"),
-                fc_strerror(fc_get_errno()));
-    scan->error_func(scan, errstr);
-
-    return FALSE;
-  }
-
-  fc_nonblock(scan->sock);
-
-  if (setsockopt(scan->sock, SOL_SOCKET, SO_REUSEADDR,
-                 (char *)&opt, sizeof(opt)) == -1) {
-    log_error("SO_REUSEADDR failed: %s", fc_strerror(fc_get_errno()));
-  }
-
-  memset(&addr, 0, sizeof(addr));
-
-#ifdef IPV6_SUPPORT
-  if (family == AF_INET6) {
-    addr.saddr.sa_family = AF_INET6;
-    addr.saddr_in6.sin6_port = htons(SERVER_LAN_PORT + 1);
-    addr.saddr_in6.sin6_addr = in6addr_any;
-  } else
-#endif /* IPv6 support */
-  if (family == AF_INET) {
-    addr.saddr.sa_family = AF_INET;
-    addr.saddr_in4.sin_port = htons(SERVER_LAN_PORT + 1);
-    addr.saddr_in4.sin_addr.s_addr = htonl(INADDR_ANY);
-  } else {
-    /* This is not only error situation worth assert() This
-     * is error situation that has check (with assert) against
-     * earlier already. */
-    fc_assert(FALSE);
-
-    return FALSE;
-  }
-
-  if (bind(scan->sock, &addr.saddr, sockaddr_size(&addr)) < 0) {
-    char errstr[2048];
-
-    fc_snprintf(errstr, sizeof(errstr),
-                _("Binding socket to listen LAN announcements failed:\n%s"),
-                fc_strerror(fc_get_errno()));
-    scan->error_func(scan, errstr);
-
-    return FALSE;
-  }
-
-#ifndef IPV6_SUPPORT
-  {
-#ifdef HAVE_INET_ATON
-    inet_aton(group, &mreq4.imr_multiaddr);
-#else  /* HAVE_INET_ATON */
-    mreq4.imr_multiaddr.s_addr = inet_addr(group);
-#endif /* HAVE_INET_ATON */
-#else  /* IPv6 support */
-  if (family == AF_INET6) {
-    inet_pton(AF_INET6, group, &mreq6.ipv6mr_multiaddr.s6_addr);
-    mreq6.ipv6mr_interface = 0; /* TODO: Interface selection */
-
-    if (setsockopt(scan->sock, IPPROTO_IPV6, FC_IPV6_ADD_MEMBERSHIP,
-                   (const char*)&mreq6, sizeof(mreq6)) < 0) {
-      char errstr[2048];
-
-      fc_snprintf(errstr, sizeof(errstr),
-                  _("Adding membership for IPv6 LAN announcement group 
failed:\n%s"),
-                fc_strerror(fc_get_errno()));
-      scan->error_func(scan, errstr);
-    }
-  } else {
-    inet_pton(AF_INET, group, &mreq4.imr_multiaddr.s_addr);
-#endif /* IPv6 support */
-    mreq4.imr_interface.s_addr = htonl(INADDR_ANY);
-
-    if (setsockopt(scan->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
-                   (const char*)&mreq4, sizeof(mreq4)) < 0) {
-      char errstr[2048];
-
-      fc_snprintf(errstr, sizeof(errstr),
-                  _("Adding membership for IPv4 LAN announcement group 
failed:\n%s"),
-                  fc_strerror(fc_get_errno()));
-      scan->error_func(scan, errstr);
-
-      return FALSE;
-    }
-  }
+  fc_closesocket(send_sock);
 
   fc_allocate_mutex(&scan->srvrs.mutex);
   scan->srvrs.servers = server_list_new();


_______________________________________________
Freeciv-commits mailing list
Freeciv-commits@gna.org
https://mail.gna.org/listinfo/freeciv-commits

Reply via email to