1 /**********************************************************************
2 Freeciv - Copyright (C) 1996-2005 - Freeciv Development Team
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
15 #include <fc_config.h>
21 #ifdef HAVE_SYS_TYPES_H
22 #include <sys/types.h>
24 #ifdef HAVE_SYS_SOCKET_H
25 #include <sys/socket.h>
27 #ifdef HAVE_NETINET_IN_H
28 #include <netinet/in.h>
30 #ifdef HAVE_ARPA_INET_H
31 #include <arpa/inet.h>
39 #ifdef HAVE_SYS_SELECT_H
40 #include <sys/select.h>
42 #ifdef HAVE_SYS_TIME_H
65 #include "rand.h" /* fc_rand() */
77 #include "chatline_common.h"
78 #include "chatline_g.h"
79 #include "client_main.h"
82 #include "gui_main_g.h"
85 enum server_scan_type type
;
86 ServerScanErrorFunc error_func
;
88 struct srv_list srvrs
;
91 /* Only used for metaserver */
93 enum server_scan_status status
;
99 FILE *fp
; /* temp file */
103 extern enum announce_type announce
;
105 static bool begin_metaserver_scan(struct server_scan
*scan
);
106 static void delete_server_list(struct server_list
*server_list
);
108 /**************************************************************************
109 The server sends a stream in a registry 'ini' type format.
110 Read it using secfile functions and fill the server_list structs.
111 **************************************************************************/
112 static struct server_list
*parse_metaserver_data(fz_FILE
*f
)
114 struct server_list
*server_list
;
115 struct section_file
*file
;
117 const char *latest_ver
;
119 /* This call closes f. */
120 if (!(file
= secfile_from_stream(f
, TRUE
))) {
124 latest_ver
= secfile_lookup_str_default(file
, NULL
, "versions." FOLLOWTAG
);
126 if (latest_ver
!= NULL
) {
127 const char *my_comparable
= fc_comparable_version();
130 log_verbose("Metaserver says latest '%s' version is '%s'; we have '%s'",
131 FOLLOWTAG
, latest_ver
, my_comparable
);
132 if (cvercmp_greater(latest_ver
, my_comparable
)) {
133 const char *const followtag
= "?vertag:" FOLLOWTAG
;
134 fc_snprintf(vertext
, sizeof(vertext
),
135 /* TRANS: Type is version tag name like "stable", "S2_4",
136 * "win32" (which can also be localised -- msgids start
138 _("Latest %s release of Freeciv is %s, this is %s."),
139 Q_(followtag
), latest_ver
, my_comparable
);
141 fc_snprintf(vertext
, sizeof(vertext
),
142 _("There is no newer %s release of Freeciv available."),
146 version_message(vertext
);
149 server_list
= server_list_new();
150 nservers
= secfile_lookup_int_default(file
, 0, "main.nservers");
152 for (i
= 0; i
< nservers
; i
++) {
153 const char *host
, *port
, *version
, *state
, *message
, *nplayers
, *nhumans
;
155 struct server
*pserver
= (struct server
*)fc_malloc(sizeof(struct server
));
157 host
= secfile_lookup_str_default(file
, "", "server%d.host", i
);
158 pserver
->host
= fc_strdup(host
);
160 port
= secfile_lookup_str_default(file
, "", "server%d.port", i
);
161 pserver
->port
= atoi(port
);
163 version
= secfile_lookup_str_default(file
, "", "server%d.version", i
);
164 pserver
->version
= fc_strdup(version
);
166 state
= secfile_lookup_str_default(file
, "", "server%d.state", i
);
167 pserver
->state
= fc_strdup(state
);
169 message
= secfile_lookup_str_default(file
, "", "server%d.message", i
);
170 pserver
->message
= fc_strdup(message
);
172 nplayers
= secfile_lookup_str_default(file
, "0", "server%d.nplayers", i
);
174 pserver
->nplayers
= n
;
176 nhumans
= secfile_lookup_str_default(file
, "-1", "server%d.humans", i
);
180 if (pserver
->nplayers
> 0) {
181 pserver
->players
= fc_malloc(pserver
->nplayers
* sizeof(*pserver
->players
));
183 pserver
->players
= NULL
;
186 for (j
= 0; j
< pserver
->nplayers
; j
++) {
187 const char *name
, *nation
, *type
, *host
;
189 name
= secfile_lookup_str_default(file
, "",
190 "server%d.player%d.name", i
, j
);
191 pserver
->players
[j
].name
= fc_strdup(name
);
193 type
= secfile_lookup_str_default(file
, "",
194 "server%d.player%d.type", i
, j
);
195 pserver
->players
[j
].type
= fc_strdup(type
);
197 host
= secfile_lookup_str_default(file
, "",
198 "server%d.player%d.host", i
, j
);
199 pserver
->players
[j
].host
= fc_strdup(host
);
201 nation
= secfile_lookup_str_default(file
, "",
202 "server%d.player%d.nation", i
, j
);
203 pserver
->players
[j
].nation
= fc_strdup(nation
);
206 server_list_append(server_list
, pserver
);
209 secfile_destroy(file
);
214 /****************************************************************************
215 Read the reply string from the metaserver.
216 ****************************************************************************/
217 static bool meta_read_response(struct server_scan
*scan
)
221 struct server_list
*srvrs
;
223 f
= fz_from_stream(scan
->meta
.fp
);
225 fc_snprintf(str
, sizeof(str
),
226 _("Failed to read the metaserver data from %s."),
228 scan
->error_func(scan
, str
);
233 /* parse message body */
234 fc_allocate_mutex(&scan
->srvrs
.mutex
);
235 srvrs
= parse_metaserver_data(f
);
236 scan
->srvrs
.servers
= srvrs
;
237 fc_release_mutex(&scan
->srvrs
.mutex
);
239 /* 'f' (hence 'meta.fp') was closed in parse_metaserver_data(). */
240 scan
->meta
.fp
= NULL
;
243 fc_snprintf(str
, sizeof(str
),
244 _("Failed to parse the metaserver data from %s:\n"
246 metaserver
, secfile_error());
247 scan
->error_func(scan
, str
);
255 /****************************************************************************
256 Metaserver scan thread entry point
257 ****************************************************************************/
258 static void metaserver_scan(void *arg
)
260 struct server_scan
*scan
= arg
;
262 if (!scan
->meta
.fp
) {
264 char filename
[MAX_PATH
];
266 GetTempPath(sizeof(filename
), filename
);
267 cat_snprintf(filename
, sizeof(filename
), "fctmp%d", fc_rand(1000));
269 scan
->meta
.fp
= fc_fopen(filename
, "w+b");
271 scan
->meta
.fp
= tmpfile();
272 #endif /* WIN32_NATIVE */
274 if (!scan
->meta
.fp
) {
275 scan
->error_func(scan
, _("Could not open temp file."));
281 if (!begin_metaserver_scan(scan
)) {
282 fc_allocate_mutex(&scan
->meta
.mutex
);
283 scan
->meta
.status
= SCAN_STATUS_ERROR
;
286 rewind(scan
->meta
.fp
);
288 if (!meta_read_response(scan
)) {
289 fc_allocate_mutex(&scan
->meta
.mutex
);
290 scan
->meta
.status
= SCAN_STATUS_ERROR
;
292 fc_allocate_mutex(&scan
->meta
.mutex
);
293 if (scan
->meta
.status
== SCAN_STATUS_WAITING
) {
294 scan
->meta
.status
= SCAN_STATUS_DONE
;
299 fc_release_mutex(&scan
->meta
.mutex
);
303 /****************************************************************************
304 Begin a metaserver scan for servers.
306 Returns FALSE on error (in which case errbuf will contain an error
308 ****************************************************************************/
309 static bool begin_metaserver_scan(struct server_scan
*scan
)
311 struct netfile_post
*post
;
314 post
= netfile_start_post();
315 netfile_add_form_str(post
, "client_cap", our_capability
);
317 if (!netfile_send_post(metaserver
, post
, scan
->meta
.fp
, NULL
)) {
318 scan
->error_func(scan
, _("Error connecting to metaserver"));
322 netfile_close_post(post
);
327 /**************************************************************************
328 Frees everything associated with a server list including
329 the server list itself (so the server_list is no longer
330 valid after calling this function)
331 **************************************************************************/
332 static void delete_server_list(struct server_list
*server_list
)
338 server_list_iterate(server_list
, ptmp
) {
340 int n
= ptmp
->nplayers
;
348 for (i
= 0; i
< n
; i
++) {
349 free(ptmp
->players
[i
].name
);
350 free(ptmp
->players
[i
].type
);
351 free(ptmp
->players
[i
].host
);
352 free(ptmp
->players
[i
].nation
);
358 } server_list_iterate_end
;
360 server_list_destroy(server_list
);
363 /**************************************************************************
364 Broadcast an UDP package to all servers on LAN, requesting information
365 about the server. The packet is send to all Freeciv servers in the same
366 multicast group as the client.
367 **************************************************************************/
368 static bool begin_lanserver_scan(struct server_scan
*scan
)
370 union fc_sockaddr addr
;
371 struct data_out dout
;
374 unsigned char buffer
[MAX_LEN_PACKET
];
375 #else /* HAVE_WINSOCK */
376 char buffer
[MAX_LEN_PACKET
];
377 #endif /* HAVE_WINSOCK */
378 struct ip_mreq mreq4
;
384 struct ipv6_mreq mreq6
;
391 if (announce
== ANNOUNCE_NONE
) {
392 /* Succeeded in doing nothing */
397 if (announce
== ANNOUNCE_IPV6
) {
400 #endif /* IPv6 support */
405 /* Create a socket for broadcasting to servers. */
406 if ((sock
= socket(family
, SOCK_DGRAM
, 0)) < 0) {
407 log_error("socket failed: %s", fc_strerror(fc_get_errno()));
411 /* Set the UDP Multicast group IP address. */
412 group
= get_multicast_group(announce
== ANNOUNCE_IPV6
);
413 memset(&addr
, 0, sizeof(addr
));
416 if (family
== AF_INET
) {
417 #ifdef HAVE_INET_ATON
418 inet_aton(group
, &addr
.saddr_in4
.sin_addr
);
419 #else /* HAVE_INET_ATON */
420 addr
.saddr_in4
.sin_addr
.s_addr
= inet_addr(group
);
421 #endif /* HAVE_INET_ATON */
422 #else /* IPv6 support */
423 if (family
== AF_INET6
) {
424 addr
.saddr
.sa_family
= AF_INET6
;
425 inet_pton(AF_INET6
, group
, &addr
.saddr_in6
.sin6_addr
);
426 addr
.saddr_in6
.sin6_port
= htons(SERVER_LAN_PORT
);
427 } else if (family
== AF_INET
) {
428 inet_pton(AF_INET
, group
, &addr
.saddr_in4
.sin_addr
);
429 #endif /* IPv6 support */
430 addr
.saddr
.sa_family
= AF_INET
;
431 addr
.saddr_in4
.sin_port
= htons(SERVER_LAN_PORT
);
435 log_error("Unsupported address family in begin_lanserver_scan()");
440 /* this setsockopt call fails on Windows 98, so we stick with the default
441 * value of 1 on Windows, which should be fine in most cases */
443 /* Set the Time-to-Live field for the packet */
444 ttl
= SERVER_LAN_TTL
;
445 if (setsockopt(sock
, IPPROTO_IP
, IP_MULTICAST_TTL
, (const char*)&ttl
,
447 log_error("setsockopt failed: %s", fc_strerror(fc_get_errno()));
450 #endif /* HAVE_WINSOCK */
452 if (setsockopt(sock
, SOL_SOCKET
, SO_BROADCAST
, (const char*)&opt
,
454 log_error("setsockopt failed: %s", fc_strerror(fc_get_errno()));
458 dio_output_init(&dout
, buffer
, sizeof(buffer
));
459 dio_put_uint8(&dout
, SERVER_LAN_VERSION
);
460 size
= dio_output_used(&dout
);
463 if (sendto(sock
, buffer
, size
, 0, &addr
.saddr
,
464 sockaddr_size(&addr
)) < 0) {
465 /* This can happen when there's no network connection - it should
466 * give an in-game message. */
467 log_error("lanserver scan sendto failed: %s",
468 fc_strerror(fc_get_errno()));
471 log_debug("Sending request for server announcement on LAN.");
474 fc_closesocket(sock
);
476 /* Create a socket for listening for server packets. */
477 if ((scan
->sock
= socket(family
, SOCK_DGRAM
, 0)) < 0) {
478 scan
->error_func(scan
, fc_strerror(fc_get_errno()));
482 fc_nonblock(scan
->sock
);
484 if (setsockopt(scan
->sock
, SOL_SOCKET
, SO_REUSEADDR
,
485 (char *)&opt
, sizeof(opt
)) == -1) {
486 log_error("SO_REUSEADDR failed: %s", fc_strerror(fc_get_errno()));
489 memset(&addr
, 0, sizeof(addr
));
492 if (family
== AF_INET6
) {
493 addr
.saddr
.sa_family
= AF_INET6
;
494 addr
.saddr_in6
.sin6_port
= htons(SERVER_LAN_PORT
+ 1);
495 addr
.saddr_in6
.sin6_addr
= in6addr_any
;
497 #endif /* IPv6 support */
498 if (family
== AF_INET
) {
499 addr
.saddr
.sa_family
= AF_INET
;
500 addr
.saddr_in4
.sin_port
= htons(SERVER_LAN_PORT
+ 1);
501 addr
.saddr_in4
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
503 /* This is not only error situation worth assert() This
504 * is error situation that has check (with assert) against
505 * earlier already. */
511 if (bind(scan
->sock
, &addr
.saddr
, sockaddr_size(&addr
)) < 0) {
512 scan
->error_func(scan
, fc_strerror(fc_get_errno()));
518 #ifdef HAVE_INET_ATON
519 inet_aton(group
, &mreq4
.imr_multiaddr
);
520 #else /* HAVE_INET_ATON */
521 mreq4
.imr_multiaddr
.s_addr
= inet_addr(group
);
522 #endif /* HAVE_INET_ATON */
523 #else /* IPv6 support */
524 if (family
== AF_INET6
) {
525 inet_pton(AF_INET6
, group
, &mreq6
.ipv6mr_multiaddr
.s6_addr
);
526 mreq6
.ipv6mr_interface
= 0; /* TODO: Interface selection */
528 if (setsockopt(scan
->sock
, IPPROTO_IPV6
, FC_IPV6_ADD_MEMBERSHIP
,
529 (const char*)&mreq6
, sizeof(mreq6
)) < 0) {
530 scan
->error_func(scan
, fc_strerror(fc_get_errno()));
533 inet_pton(AF_INET
, group
, &mreq4
.imr_multiaddr
.s_addr
);
534 #endif /* IPv6 support */
535 mreq4
.imr_interface
.s_addr
= htonl(INADDR_ANY
);
537 if (setsockopt(scan
->sock
, IPPROTO_IP
, IP_ADD_MEMBERSHIP
,
538 (const char*)&mreq4
, sizeof(mreq4
)) < 0) {
539 scan
->error_func(scan
, fc_strerror(fc_get_errno()));
544 fc_allocate_mutex(&scan
->srvrs
.mutex
);
545 scan
->srvrs
.servers
= server_list_new();
546 fc_release_mutex(&scan
->srvrs
.mutex
);
551 /**************************************************************************
552 Listens for UDP packets broadcasted from a server that responded
553 to the request-packet sent from the client.
554 **************************************************************************/
555 static enum server_scan_status
556 get_lan_server_list(struct server_scan
*scan
)
559 union fc_sockaddr fromend
;
563 char servername
[512];
571 bool found_new
= FALSE
;
574 struct server
*pserver
;
575 bool duplicate
= FALSE
;
577 dio_input_init(&din
, msgbuf
, sizeof(msgbuf
));
578 fromlen
= sizeof(fromend
);
580 /* Try to receive a packet from a server. No select loop is needed;
581 * we just keep on reading until recvfrom returns -1. */
582 if (recvfrom(scan
->sock
, msgbuf
, sizeof(msgbuf
), 0,
583 &fromend
.saddr
, &fromlen
) < 0) {
587 dio_get_uint8(&din
, &type
);
588 if (type
!= SERVER_LAN_VERSION
) {
591 dio_get_string(&din
, servername
, sizeof(servername
));
592 dio_get_string(&din
, portstr
, sizeof(portstr
));
593 port
= atoi(portstr
);
594 dio_get_string(&din
, version
, sizeof(version
));
595 dio_get_string(&din
, status
, sizeof(status
));
596 dio_get_string(&din
, players
, sizeof(players
));
597 dio_get_string(&din
, humans
, sizeof(humans
));
598 dio_get_string(&din
, message
, sizeof(message
));
600 if (!fc_strcasecmp("none", servername
)) {
601 bool nameinfo
= FALSE
;
603 char dst
[INET6_ADDRSTRLEN
];
604 char host
[NI_MAXHOST
], service
[NI_MAXSERV
];
606 if (!getnameinfo(&fromend
.saddr
, fromlen
, host
, NI_MAXHOST
,
607 service
, NI_MAXSERV
, NI_NUMERICSERV
)) {
611 if (fromend
.saddr
.sa_family
== AF_INET6
) {
612 inet_ntop(AF_INET6
, &fromend
.saddr_in6
.sin6_addr
,
614 } else if (fromend
.saddr
.sa_family
== AF_INET
) {
615 inet_ntop(AF_INET
, &fromend
.saddr_in4
.sin_addr
, dst
, sizeof(dst
));;
619 log_error("Unsupported address family in get_lan_server_list()");
621 fc_snprintf(dst
, sizeof(dst
), "Unknown");
624 #else /* IPv6 support */
625 const char *dst
= NULL
;
626 struct hostent
*from
;
627 const char *host
= NULL
;
629 from
= gethostbyaddr((char *) &fromend
.saddr_in4
.sin_addr
,
630 sizeof(fromend
.saddr_in4
.sin_addr
), AF_INET
);
636 dst
= inet_ntoa(fromend
.saddr_in4
.sin_addr
);
638 #endif /* IPv6 support */
640 sz_strlcpy(servername
, nameinfo
? host
: dst
);
643 /* UDP can send duplicate or delayed packets. */
644 fc_allocate_mutex(&scan
->srvrs
.mutex
);
645 server_list_iterate(scan
->srvrs
.servers
, aserver
) {
646 if (0 == fc_strcasecmp(aserver
->host
, servername
)
647 && aserver
->port
== port
) {
651 } server_list_iterate_end
;
654 fc_release_mutex(&scan
->srvrs
.mutex
);
658 log_debug("Received a valid announcement from a server on the LAN.");
660 pserver
= fc_malloc(sizeof(*pserver
));
661 pserver
->host
= fc_strdup(servername
);
662 pserver
->port
= port
;
663 pserver
->version
= fc_strdup(version
);
664 pserver
->state
= fc_strdup(status
);
665 pserver
->nplayers
= atoi(players
);
666 pserver
->humans
= atoi(humans
);
667 pserver
->message
= fc_strdup(message
);
668 pserver
->players
= NULL
;
671 server_list_prepend(scan
->srvrs
.servers
, pserver
);
672 fc_release_mutex(&scan
->srvrs
.mutex
);
676 return SCAN_STATUS_PARTIAL
;
678 return SCAN_STATUS_WAITING
;
681 /****************************************************************************
682 Creates a new server scan and returns it, or NULL if impossible.
684 Depending on 'type' the scan will look for either local or internet
687 error_func provides a callback to be used in case of error; this
688 callback probably should call server_scan_finish.
690 NB: You must call server_scan_finish() when you are done with the
691 scan to free the memory and resources allocated by it.
692 ****************************************************************************/
693 struct server_scan
*server_scan_begin(enum server_scan_type type
,
694 ServerScanErrorFunc error_func
)
696 struct server_scan
*scan
;
699 scan
= fc_calloc(1, sizeof(*scan
));
701 scan
->error_func
= error_func
;
703 fc_init_mutex(&scan
->srvrs
.mutex
);
706 case SERVER_SCAN_GLOBAL
:
710 fc_init_mutex(&scan
->meta
.mutex
);
711 scan
->meta
.status
= SCAN_STATUS_WAITING
;
712 thr_ret
= fc_thread_start(&scan
->meta
.thr
, metaserver_scan
, scan
);
720 case SERVER_SCAN_LOCAL
:
721 ok
= begin_lanserver_scan(scan
);
728 server_scan_finish(scan
);
735 /****************************************************************************
736 A simple query function to determine the type of a server scan (previously
737 allocated in server_scan_begin).
738 ****************************************************************************/
739 enum server_scan_type
server_scan_get_type(const struct server_scan
*scan
)
742 return SERVER_SCAN_LAST
;
747 /****************************************************************************
748 A function to query servers of the server scan. This will check any
749 pending network data and update the server list.
751 The return value indicates the status of the server scan:
752 SCAN_STATUS_ERROR - The scan failed and should be aborted.
753 SCAN_STATUS_WAITING - The scan is in progress (continue polling).
754 SCAN_STATUS_PARTIAL - The scan received some data, with more expected.
755 Get the servers with server_scan_get_list(), and
757 SCAN_STATUS_DONE - The scan received all data it expected to receive.
758 Get the servers with server_scan_get_list(), and
759 stop calling this function.
760 SCAN_STATUS_ABORT - The scan has been aborted
761 ****************************************************************************/
762 enum server_scan_status
server_scan_poll(struct server_scan
*scan
)
765 return SCAN_STATUS_ERROR
;
768 switch (scan
->type
) {
769 case SERVER_SCAN_GLOBAL
:
771 enum server_scan_status status
;
773 fc_allocate_mutex(&scan
->meta
.mutex
);
774 status
= scan
->meta
.status
;
775 fc_release_mutex(&scan
->meta
.mutex
);
780 case SERVER_SCAN_LOCAL
:
781 return get_lan_server_list(scan
);
787 return SCAN_STATUS_ERROR
;
790 /**************************************************************************
791 Returns the srv_list currently held by the scan (may be NULL).
792 **************************************************************************/
794 server_scan_get_list(struct server_scan
*scan
)
803 /**************************************************************************
804 Closes the socket listening on the scan, frees the list of servers, and
805 frees the memory allocated for 'scan' by server_scan_begin().
806 **************************************************************************/
807 void server_scan_finish(struct server_scan
*scan
)
813 if (scan
->type
== SERVER_SCAN_GLOBAL
) {
814 /* Signal metserver scan thread to stop */
815 fc_allocate_mutex(&scan
->meta
.mutex
);
816 scan
->meta
.status
= SCAN_STATUS_ABORT
;
817 fc_release_mutex(&scan
->meta
.mutex
);
819 /* Wait thread to stop */
820 fc_thread_wait(&scan
->meta
.thr
);
821 fc_destroy_mutex(&scan
->meta
.mutex
);
823 /* This mainly duplicates code from below "else" block.
824 * That's intentional, since they will be completely different in future versions.
825 * We are better prepared for that by having them separately already. */
826 if (scan
->sock
>= 0) {
827 fc_closesocket(scan
->sock
);
831 if (scan
->srvrs
.servers
) {
832 fc_allocate_mutex(&scan
->srvrs
.mutex
);
833 delete_server_list(scan
->srvrs
.servers
);
834 scan
->srvrs
.servers
= NULL
;
835 fc_release_mutex(&scan
->srvrs
.mutex
);
839 fclose(scan
->meta
.fp
);
840 scan
->meta
.fp
= NULL
;
843 if (scan
->sock
>= 0) {
844 fc_closesocket(scan
->sock
);
848 if (scan
->srvrs
.servers
) {
849 delete_server_list(scan
->srvrs
.servers
);
850 scan
->srvrs
.servers
= NULL
;
854 fc_destroy_mutex(&scan
->srvrs
.mutex
);