Freeciv-3.1: /fast/freeciv/nightly/S3_1/common/networking/connection.c Source File

Freeciv-3.1

Loading...
Searching...
No Matches
connection.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
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)
6 any later version.
7
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***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include "fc_prehdrs.h"
19
20#include <errno.h>
21#include <string.h>
22#include <time.h>
23
24#ifdef FREECIV_HAVE_SYS_TYPES_H
25#include <sys/types.h>
26#endif
27#ifdef HAVE_SYS_SELECT_H
28/* For some platforms this must be below sys/types.h. */
29#include <sys/select.h>
30#endif
31#ifdef HAVE_UNISTD_H
32#include <unistd.h>
33#endif
34
35/* utility */
36#include "fcintl.h"
37#include "genhash.h"
38#include "log.h"
39#include "mem.h"
40#include "netintf.h"
41#include "support.h" /* fc_str(n)casecmp */
42
43/* common */
44#include "game.h" /* game.all_connections */
45#include "packets.h"
46
47#include "connection.h"
48
49
50static void default_conn_close_callback(struct connection *pconn);
51
52/* String used for connection.addr and related cases to indicate
53 * blank/unknown/not-applicable address:
54 */
55 const char blank_addr_str[] = "---.---.---.---";
56
57/****************************************************************************
58 This callback is used when an error occurs trying to write to the
59 connection. The effect of the callback should be to close the connection.
60 This is here so that the server and client can take appropriate
61 (different) actions: server lost a client, client lost connection to
62 server. Never attempt to call this function directly, call
63 connection_close() instead.
64****************************************************************************/
65 static conn_close_fn_t conn_close_callback = default_conn_close_callback;
66
67/************************************************************************/
70 static void default_conn_close_callback(struct connection *pconn)
71{
72 fc_assert_msg(conn_close_callback != default_conn_close_callback,
73 "Closing a socket (%s) before calling "
74 "close_socket_set_callback().", conn_description(pconn));
75}
76
77/**********************************************************************/
80 void connections_set_close_callback(conn_close_fn_t func)
81{
82 conn_close_callback = func;
83}
84
85/**********************************************************************/
88 void connection_close(struct connection *pconn, const char *reason)
89{
90 fc_assert_ret(NULL != pconn);
91
92 if (NULL != reason && NULL == pconn->closing_reason) {
93 /* NB: we don't overwrite the original reason. */
94 pconn->closing_reason = fc_strdup(reason);
95 }
96
97 (*conn_close_callback) (pconn);
98}
99
100/**********************************************************************/
104 static bool buffer_ensure_free_extra_space(struct socket_packet_buffer *buf,
105 int extra_space)
106{
107 /* room for more? */
108 if (buf->nsize - buf->ndata < extra_space) {
109 buf->nsize = buf->ndata + extra_space;
110
111 /* added this check so we don't gobble up too much mem */
112 if (buf->nsize > MAX_LEN_BUFFER) {
113 return FALSE;
114 }
115 buf->data = (unsigned char *) fc_realloc(buf->data, buf->nsize);
116 }
117
118 return TRUE;
119}
120
121/**********************************************************************/
129 int read_socket_data(int sock, struct socket_packet_buffer *buffer)
130{
131 int didget;
132
133 if (!buffer_ensure_free_extra_space(buffer, MAX_LEN_PACKET)) {
134 log_error("can't grow buffer");
135 return -1;
136 }
137
138 log_debug("try reading %d bytes", buffer->nsize - buffer->ndata);
139 didget = fc_readsocket(sock, (char *) (buffer->data + buffer->ndata),
140 buffer->nsize - buffer->ndata);
141
142 if (didget > 0) {
143 buffer->ndata += didget;
144 log_debug("didget:%d", didget);
145 return didget;
146 } else if (didget == 0) {
147 log_debug("EOF on socket read");
148 return -2;
149 }
150
151#ifdef NONBLOCKING_SOCKETS
152 else if (errno == EWOULDBLOCK || errno == EAGAIN) {
153 log_debug("EGAIN on socket read");
154 return 0;
155 }
156#endif /* NONBLOCKING_SOCKETS */
157
158 return -1;
159}
160
161/**********************************************************************/
164 static int write_socket_data(struct connection *pc,
165 struct socket_packet_buffer *buf, int limit)
166{
167 int start, nput, nblock;
168
169 if (is_server() && pc->server.is_closing) {
170 return 0;
171 }
172
173 for (start = 0; buf->ndata-start > limit;) {
174 fd_set writefs, exceptfs;
175 fc_timeval tv;
176
177 FC_FD_ZERO(&writefs);
178 FC_FD_ZERO(&exceptfs);
179 FD_SET(pc->sock, &writefs);
180 FD_SET(pc->sock, &exceptfs);
181
182 tv.tv_sec = 0; tv.tv_usec = 0;
183
184 if (fc_select(pc->sock + 1, NULL, &writefs, &exceptfs, &tv) <= 0) {
185 if (errno != EINTR) {
186 break;
187 } else {
188 /* EINTR can happen sometimes, especially when compiling with -pg.
189 * Generally we just want to run select again. */
190 continue;
191 }
192 }
193
194 if (FD_ISSET(pc->sock, &exceptfs)) {
195 connection_close(pc, _("network exception"));
196 return -1;
197 }
198
199 if (FD_ISSET(pc->sock, &writefs)) {
200 nblock=MIN(buf->ndata-start, MAX_LEN_PACKET);
201 log_debug("trying to write %d limit=%d", nblock, limit);
202 if ((nput = fc_writesocket(pc->sock,
203 (const char *)buf->data+start, nblock)) == -1) {
204#ifdef NONBLOCKING_SOCKETS
205 if (errno == EWOULDBLOCK || errno == EAGAIN) {
206 break;
207 }
208#endif /* NONBLOCKING_SOCKETS */
209 connection_close(pc, _("lagging connection"));
210 return -1;
211 }
212 start += nput;
213 }
214 }
215
216 if (start > 0) {
217 buf->ndata -= start;
218 memmove(buf->data, buf->data+start, buf->ndata);
219 pc->last_write = timer_renew(pc->last_write, TIMER_USER, TIMER_ACTIVE);
220 timer_start(pc->last_write);
221 }
222
223 return 0;
224}
225
226/**********************************************************************/
229 void flush_connection_send_buffer_all(struct connection *pc)
230{
231 if (pc && pc->used && pc->send_buffer->ndata > 0) {
232 write_socket_data(pc, pc->send_buffer, 0);
233 if (pc->notify_of_writable_data) {
234 pc->notify_of_writable_data(pc, pc->send_buffer
235 && pc->send_buffer->ndata > 0);
236 }
237 }
238}
239
240/**********************************************************************/
243#ifndef FREECIV_JSON_CONNECTION
244 static void flush_connection_send_buffer_packets(struct connection *pc)
245{
246 if (pc && pc->used && pc->send_buffer->ndata >= MAX_LEN_PACKET) {
247 write_socket_data(pc, pc->send_buffer, MAX_LEN_PACKET-1);
248 if (pc->notify_of_writable_data) {
249 pc->notify_of_writable_data(pc, pc->send_buffer
250 && pc->send_buffer->ndata > 0);
251 }
252 }
253}
254#endif /* FREECIV_JSON_CONNECTION */
255
256/**********************************************************************/
259 static bool add_connection_data(struct connection *pconn,
260 const unsigned char *data, int len)
261{
262 struct socket_packet_buffer *buf;
263
264 if (NULL == pconn
265 || !pconn->used
266 || (is_server() && pconn->server.is_closing)) {
267 return TRUE;
268 }
269
270 buf = pconn->send_buffer;
271 log_debug("add %d bytes to %d (space =%d)", len, buf->ndata, buf->nsize);
272 if (!buffer_ensure_free_extra_space(buf, len)) {
273 connection_close(pconn, _("buffer overflow"));
274 return FALSE;
275 }
276
277 memcpy(buf->data + buf->ndata, data, len);
278 buf->ndata += len;
279
280 return TRUE;
281}
282
283/**********************************************************************/
286 bool connection_send_data(struct connection *pconn,
287 const unsigned char *data, int len)
288{
289 if (NULL == pconn
290 || !pconn->used
291 || (is_server() && pconn->server.is_closing)) {
292 return TRUE;
293 }
294
295 pconn->statistics.bytes_send += len;
296
297#ifndef FREECIV_JSON_CONNECTION
298 if (0 < pconn->send_buffer->do_buffer_sends) {
299 flush_connection_send_buffer_packets(pconn);
300 if (!add_connection_data(pconn, data, len)) {
301 log_verbose("cut connection %s due to huge send buffer (1)",
302 conn_description(pconn));
303 return FALSE;
304 }
305 flush_connection_send_buffer_packets(pconn);
306 } else
307#endif /* FREECIV_JSON_CONNECTION */
308 {
309 flush_connection_send_buffer_all(pconn);
310 if (!add_connection_data(pconn, data, len)) {
311 log_verbose("cut connection %s due to huge send buffer (2)",
312 conn_description(pconn));
313 return FALSE;
314 }
315 flush_connection_send_buffer_all(pconn);
316 }
317 return TRUE;
318}
319
320/**********************************************************************/
323 void connection_do_buffer(struct connection *pc)
324{
325 if (pc && pc->used) {
326 pc->send_buffer->do_buffer_sends++;
327 }
328}
329
330/**********************************************************************/
335 void connection_do_unbuffer(struct connection *pc)
336{
337 if (NULL == pc || !pc->used || (is_server() && pc->server.is_closing)) {
338 return;
339 }
340
341 pc->send_buffer->do_buffer_sends--;
342 if (0 > pc->send_buffer->do_buffer_sends) {
343 log_error("Too many calls to unbuffer %s!", pc->username);
344 pc->send_buffer->do_buffer_sends = 0;
345 }
346
347 if (0 == pc->send_buffer->do_buffer_sends) {
348 flush_connection_send_buffer_all(pc);
349 }
350}
351
352/**********************************************************************/
355 void conn_list_do_buffer(struct conn_list *dest)
356{
357 conn_list_iterate(dest, pconn) {
358 connection_do_buffer(pconn);
359 } conn_list_iterate_end;
360}
361
362/**********************************************************************/
365 void conn_list_do_unbuffer(struct conn_list *dest)
366{
367 conn_list_iterate(dest, pconn) {
368 connection_do_unbuffer(pconn);
369 } conn_list_iterate_end;
370}
371
372/**********************************************************************/
376 struct connection *conn_by_user(const char *user_name)
377{
378 conn_list_iterate(game.all_connections, pconn) {
379 if (fc_strcasecmp(user_name, pconn->username) == 0) {
380 return pconn;
381 }
382 } conn_list_iterate_end;
383
384 return NULL;
385}
386
387/**********************************************************************/
393 static const char *connection_accessor(int i) {
394 return conn_list_get(game.all_connections, i)->username;
395}
396
397 struct connection *conn_by_user_prefix(const char *user_name,
398 enum m_pre_result *result)
399{
400 int ind;
401
402 *result = match_prefix(connection_accessor,
403 conn_list_size(game.all_connections),
404 MAX_LEN_NAME-1, fc_strncasequotecmp,
405 effectivestrlenquote, user_name, &ind);
406
407 if (*result < M_PRE_AMBIGUOUS) {
408 return conn_list_get(game.all_connections, ind);
409 } else {
410 return NULL;
411 }
412}
413
414/**********************************************************************/
420 struct connection *conn_by_number(int id)
421{
422 conn_list_iterate(game.all_connections, pconn) {
423 fc_assert_msg(pconn != NULL,
424 "Trying to look at the id of a non existing connection");
425
426 if (pconn->id == id) {
427 return pconn;
428 }
429 }
430 conn_list_iterate_end;
431
432 return NULL;
433}
434
435/**********************************************************************/
438 struct socket_packet_buffer *new_socket_packet_buffer(void)
439{
440 struct socket_packet_buffer *buf;
441
442 buf = fc_malloc(sizeof(*buf));
443 buf->ndata = 0;
444 buf->do_buffer_sends = 0;
445 buf->nsize = 10*MAX_LEN_PACKET;
446 buf->data = (unsigned char *)fc_malloc(buf->nsize);
447
448 return buf;
449}
450
451/**********************************************************************/
454 static void free_socket_packet_buffer(struct socket_packet_buffer *buf)
455{
456 if (buf) {
457 if (buf->data) {
458 free(buf->data);
459 }
460 free(buf);
461 }
462}
463
464/**********************************************************************/
473 const char *conn_description(const struct connection *pconn)
474{
475 static char buffer[MAX_LEN_NAME*2 + MAX_LEN_ADDR + 128];
476
477 buffer[0] = '\0';
478
479 if (*pconn->username != '\0') {
480 fc_snprintf(buffer, sizeof(buffer), _("%s from %s"),
481 pconn->username, pconn->addr);
482 } else {
483 sz_strlcpy(buffer, "server");
484 }
485 if (NULL != pconn->closing_reason) {
486 /* TRANS: Appending the reason why a connection has closed.
487 * Preserve leading space. */
488 cat_snprintf(buffer, sizeof(buffer), _(" (%s)"), pconn->closing_reason);
489 } else if (!pconn->established) {
490 /* TRANS: preserve leading space. */
491 sz_strlcat(buffer, _(" (connection incomplete)"));
492 return buffer;
493 }
494 if (NULL != pconn->playing) {
495 /* TRANS: preserve leading space. */
496 cat_snprintf(buffer, sizeof(buffer), _(" (player %s)"),
497 player_name(pconn->playing));
498 }
499 if (pconn->observer) {
500 /* TRANS: preserve leading space. */
501 sz_strlcat(buffer, _(" (observer)"));
502 }
503
504 return buffer;
505}
506
507/**********************************************************************/
510 bool can_conn_edit(const struct connection *pconn)
511{
512 return (can_conn_enable_editing(pconn)
513 && game.info.is_edit_mode
514 && (NULL != pconn->playing || pconn->observer));
515}
516
517/**********************************************************************/
520 bool can_conn_enable_editing(const struct connection *pconn)
521{
522 return pconn->access_level == ALLOW_HACK;
523}
524
525/**********************************************************************/
529 int get_next_request_id(int old_request_id)
530{
531 int result = old_request_id + 1;
532
533 if ((result & 0xffff) == 0) {
534 log_packet("INFORMATION: request_id has wrapped around; "
535 "setting from %d to 2", result);
536 result = 2;
537 }
538 fc_assert(0 != result);
539
540 return result;
541}
542
543/**********************************************************************/
546 void free_compression_queue(struct connection *pc)
547{
548#ifdef USE_COMPRESSION
549 byte_vector_free(&pc->compression.queue);
550#endif /* USE_COMPRESSION */
551}
552
553/**********************************************************************/
556 static void init_packet_hashes(struct connection *pc)
557{
558 enum packet_type i;
559
560 pc->phs.sent = fc_malloc(sizeof(*pc->phs.sent) * PACKET_LAST);
561 pc->phs.received = fc_malloc(sizeof(*pc->phs.received) * PACKET_LAST);
562 pc->phs.handlers = packet_handlers_initial();
563
564 for (i = 0; i < PACKET_LAST; i++) {
565 pc->phs.sent[i] = NULL;
566 pc->phs.received[i] = NULL;
567 }
568}
569
570/**********************************************************************/
573 static void free_packet_hashes(struct connection *pc)
574{
575 int i;
576
577 if (pc->phs.sent) {
578 for (i = 0; i < PACKET_LAST; i++) {
579 if (pc->phs.sent[i] != NULL) {
580 genhash_destroy(pc->phs.sent[i]);
581 }
582 }
583 free(pc->phs.sent);
584 pc->phs.sent = NULL;
585 }
586
587 if (pc->phs.received) {
588 for (i = 0; i < PACKET_LAST; i++) {
589 if (pc->phs.received[i] != NULL) {
590 genhash_destroy(pc->phs.received[i]);
591 }
592 }
593 free(pc->phs.received);
594 pc->phs.received = NULL;
595 }
596}
597
598/**********************************************************************/
602 void connection_common_init(struct connection *pconn)
603{
604 pconn->established = FALSE;
605 pconn->used = TRUE;
606 packet_header_init(&pconn->packet_header);
607 pconn->closing_reason = NULL;
608 pconn->last_write = NULL;
609 pconn->buffer = new_socket_packet_buffer();
610 pconn->send_buffer = new_socket_packet_buffer();
611 pconn->statistics.bytes_send = 0;
612#ifdef FREECIV_JSON_CONNECTION
613 pconn->json_mode = TRUE;
614#endif /* FREECIV_JSON_CONNECTION */
615
616 init_packet_hashes(pconn);
617
618#ifdef USE_COMPRESSION
619 byte_vector_init(&pconn->compression.queue);
620 pconn->compression.frozen_level = 0;
621#endif /* USE_COMPRESSION */
622}
623
624/**********************************************************************/
627 void connection_common_close(struct connection *pconn)
628{
629 if (!pconn->used) {
630 log_error("WARNING: Trying to close already closed connection");
631 } else {
632 fc_closesocket(pconn->sock);
633 pconn->used = FALSE;
634 pconn->established = FALSE;
635 if (NULL != pconn->closing_reason) {
636 free(pconn->closing_reason);
637 }
638
639 free_socket_packet_buffer(pconn->buffer);
640 pconn->buffer = NULL;
641
642 free_socket_packet_buffer(pconn->send_buffer);
643 pconn->send_buffer = NULL;
644
645 if (pconn->last_write) {
646 timer_destroy(pconn->last_write);
647 pconn->last_write = NULL;
648 }
649
650 free_compression_queue(pconn);
651 free_packet_hashes(pconn);
652 }
653}
654
655/**********************************************************************/
658 void conn_set_capability(struct connection *pconn, const char *capability)
659{
660 fc_assert(strlen(capability) < sizeof(pconn->capability));
661
662 sz_strlcpy(pconn->capability, capability);
663 pconn->phs.handlers = packet_handlers_get(capability);
664}
665
666/**********************************************************************/
670 void conn_reset_delta_state(struct connection *pc)
671{
672 int i;
673
674 for (i = 0; i < PACKET_LAST; i++) {
675 if (packet_has_game_info_flag(i)) {
676 if (NULL != pc->phs.sent && NULL != pc->phs.sent[i]) {
677 genhash_clear(pc->phs.sent[i]);
678 }
679 if (NULL != pc->phs.received && NULL != pc->phs.received[i]) {
680 genhash_clear(pc->phs.received[i]);
681 }
682 }
683 }
684}
685
686/**********************************************************************/
691 void conn_compression_freeze(struct connection *pconn)
692{
693#ifdef USE_COMPRESSION
694 if (0 == pconn->compression.frozen_level) {
695 byte_vector_reserve(&pconn->compression.queue, 0);
696 }
697 pconn->compression.frozen_level++;
698#endif /* USE_COMPRESSION */
699}
700
701/**********************************************************************/
705 bool conn_compression_frozen(const struct connection *pconn)
706{
707#ifdef USE_COMPRESSION
708 return 0 < pconn->compression.frozen_level;
709#else /* USE_COMPRESSION */
710 return FALSE;
711#endif /* USE_COMPRESSION */
712}
713
714/**********************************************************************/
717 void conn_list_compression_freeze(const struct conn_list *pconn_list)
718{
719#ifdef USE_COMPRESSION
720 conn_list_iterate(pconn_list, pconn) {
721 conn_compression_freeze(pconn);
722 } conn_list_iterate_end;
723#endif /* USE_COMPRESSION */
724}
725
726/**********************************************************************/
729 void conn_list_compression_thaw(const struct conn_list *pconn_list)
730{
731#ifdef USE_COMPRESSION
732 conn_list_iterate(pconn_list, pconn) {
733 conn_compression_thaw(pconn);
734 } conn_list_iterate_end;
735#endif /* USE_COMPRESSION */
736}
737
738/**********************************************************************/
742 bool conn_controls_player(const struct connection *pconn)
743{
744 return pconn && pconn->playing && !pconn->observer;
745}
746
747/**********************************************************************/
750 bool conn_is_global_observer(const struct connection *pconn)
751{
752 return pconn && !pconn->playing && pconn->observer;
753}
754
755/**********************************************************************/
760 struct player *conn_get_player(const struct connection *pconn)
761{
762 if (!pconn) {
763 return NULL;
764 }
765 return pconn->playing;
766}
767
768/**********************************************************************/
772 enum cmdlevel conn_get_access(const struct connection *pconn)
773{
774 if (!pconn) {
775 return ALLOW_NONE; /* Would not want to give hack on error... */
776 }
777 return pconn->access_level;
778}
779
780
781/**************************************************************************
782 Connection patterns.
783**************************************************************************/
784 struct conn_pattern {
785 enum conn_pattern_type type;
786 char *wildcard;
787};
788
789/**********************************************************************/
792 struct conn_pattern *conn_pattern_new(enum conn_pattern_type type,
793 const char *wildcard)
794{
795 struct conn_pattern *ppattern = fc_malloc(sizeof(*ppattern));
796
797 ppattern->type = type;
798 ppattern->wildcard = fc_strdup(wildcard);
799
800 return ppattern;
801}
802
803/**********************************************************************/
806 void conn_pattern_destroy(struct conn_pattern *ppattern)
807{
808 fc_assert_ret(NULL != ppattern);
809 free(ppattern->wildcard);
810 free(ppattern);
811}
812
813/**********************************************************************/
816 bool conn_pattern_match(const struct conn_pattern *ppattern,
817 const struct connection *pconn)
818{
819 const char *test = NULL;
820
821 switch (ppattern->type) {
822 case CPT_USER:
823 test = pconn->username;
824 break;
825 case CPT_HOST:
826 test = pconn->addr;
827 break;
828 case CPT_IP:
829 if (is_server()) {
830 test = pconn->server.ipaddr;
831 }
832 break;
833 }
834
835 if (NULL != test) {
836 return wildcard_fit_string(ppattern->wildcard, test);
837 } else {
838 log_error("%s(): Invalid pattern type (%d)",
839 __FUNCTION__, ppattern->type);
840 return FALSE;
841 }
842}
843
844/**********************************************************************/
847 bool conn_pattern_list_match(const struct conn_pattern_list *plist,
848 const struct connection *pconn)
849{
850 conn_pattern_list_iterate(plist, ppattern) {
851 if (conn_pattern_match(ppattern, pconn)) {
852 return TRUE;
853 }
854 } conn_pattern_list_iterate_end;
855
856 return FALSE;
857}
858
859/**********************************************************************/
862 size_t conn_pattern_to_string(const struct conn_pattern *ppattern,
863 char *buf, size_t buf_len)
864{
865 return fc_snprintf(buf, buf_len, "<%s=%s>",
866 conn_pattern_type_name(ppattern->type),
867 ppattern->wildcard);
868}
869
870/**********************************************************************/
875 struct conn_pattern *conn_pattern_from_string(const char *pattern,
876 enum conn_pattern_type prefer,
877 char *error_buf,
878 size_t error_buf_len)
879{
880 enum conn_pattern_type type;
881 const char *p;
882
883 /* Determine pattern type. */
884 if ((p = strchr(pattern, '='))) {
885 /* Special character to separate the type of the pattern. */
886 const size_t pattern_type_len = ++p - pattern;
887 char pattern_type[pattern_type_len];
888
889 fc_strlcpy(pattern_type, pattern, pattern_type_len);
890 remove_leading_trailing_spaces(pattern_type);
891 type = conn_pattern_type_by_name(pattern_type, fc_strcasecmp);
892 if (!conn_pattern_type_is_valid(type)) {
893 if (NULL != error_buf) {
894 fc_snprintf(error_buf, error_buf_len,
895 _("\"%s\" is not a valid pattern type"),
896 pattern_type);
897 }
898 return NULL;
899 }
900 } else {
901 /* Use 'prefer' type. */
902 p = pattern;
903 type = prefer;
904 if (!conn_pattern_type_is_valid(type)) {
905 if (NULL != error_buf) {
906 fc_strlcpy(error_buf, _("Missing pattern type"), error_buf_len);
907 }
908 return NULL;
909 }
910 }
911
912 /* Remove leading spaces. */
913 while (fc_isspace(*p)) {
914 p++;
915 }
916
917 if ('\0' == *p) {
918 if (NULL != error_buf) {
919 fc_strlcpy(error_buf, _("Missing pattern"), error_buf_len);
920 }
921 return NULL;
922 }
923
924 return conn_pattern_new(type, p);
925}
926
927/**********************************************************************/
931 bool conn_is_valid(const struct connection *pconn)
932{
933 return (pconn && pconn->used && !pconn->server.is_closing);
934}
user_name
char user_name[512]
Definition client_main.c:141
conn_pattern_to_string
size_t conn_pattern_to_string(const struct conn_pattern *ppattern, char *buf, size_t buf_len)
Definition connection.c:862
conn_close_callback
static conn_close_fn_t conn_close_callback
Definition connection.c:65
conn_get_player
struct player * conn_get_player(const struct connection *pconn)
Definition connection.c:760
conn_list_do_unbuffer
void conn_list_do_unbuffer(struct conn_list *dest)
Definition connection.c:365
default_conn_close_callback
static void default_conn_close_callback(struct connection *pconn)
Definition connection.c:70
conn_by_user_prefix
struct connection * conn_by_user_prefix(const char *user_name, enum m_pre_result *result)
Definition connection.c:397
can_conn_edit
bool can_conn_edit(const struct connection *pconn)
Definition connection.c:510
conn_by_user
struct connection * conn_by_user(const char *user_name)
Definition connection.c:376
conn_list_compression_thaw
void conn_list_compression_thaw(const struct conn_list *pconn_list)
Definition connection.c:729
connections_set_close_callback
void connections_set_close_callback(conn_close_fn_t func)
Definition connection.c:80
flush_connection_send_buffer_packets
static void flush_connection_send_buffer_packets(struct connection *pc)
Definition connection.c:244
connection_accessor
static const char * connection_accessor(int i)
Definition connection.c:393
flush_connection_send_buffer_all
void flush_connection_send_buffer_all(struct connection *pc)
Definition connection.c:229
get_next_request_id
int get_next_request_id(int old_request_id)
Definition connection.c:529
new_socket_packet_buffer
struct socket_packet_buffer * new_socket_packet_buffer(void)
Definition connection.c:438
conn_list_do_buffer
void conn_list_do_buffer(struct conn_list *dest)
Definition connection.c:355
can_conn_enable_editing
bool can_conn_enable_editing(const struct connection *pconn)
Definition connection.c:520
connection_do_buffer
void connection_do_buffer(struct connection *pc)
Definition connection.c:323
add_connection_data
static bool add_connection_data(struct connection *pconn, const unsigned char *data, int len)
Definition connection.c:259
conn_pattern_match
bool conn_pattern_match(const struct conn_pattern *ppattern, const struct connection *pconn)
Definition connection.c:816
buffer_ensure_free_extra_space
static bool buffer_ensure_free_extra_space(struct socket_packet_buffer *buf, int extra_space)
Definition connection.c:104
conn_set_capability
void conn_set_capability(struct connection *pconn, const char *capability)
Definition connection.c:658
init_packet_hashes
static void init_packet_hashes(struct connection *pc)
Definition connection.c:556
conn_pattern_destroy
void conn_pattern_destroy(struct conn_pattern *ppattern)
Definition connection.c:806
conn_reset_delta_state
void conn_reset_delta_state(struct connection *pc)
Definition connection.c:670
connection_common_init
void connection_common_init(struct connection *pconn)
Definition connection.c:602
connection_close
void connection_close(struct connection *pconn, const char *reason)
Definition connection.c:88
conn_list_compression_freeze
void conn_list_compression_freeze(const struct conn_list *pconn_list)
Definition connection.c:717
conn_pattern_new
struct conn_pattern * conn_pattern_new(enum conn_pattern_type type, const char *wildcard)
Definition connection.c:792
conn_controls_player
bool conn_controls_player(const struct connection *pconn)
Definition connection.c:742
conn_is_global_observer
bool conn_is_global_observer(const struct connection *pconn)
Definition connection.c:750
conn_description
const char * conn_description(const struct connection *pconn)
Definition connection.c:473
connection_common_close
void connection_common_close(struct connection *pconn)
Definition connection.c:627
conn_pattern_from_string
struct conn_pattern * conn_pattern_from_string(const char *pattern, enum conn_pattern_type prefer, char *error_buf, size_t error_buf_len)
Definition connection.c:875
conn_compression_freeze
void conn_compression_freeze(struct connection *pconn)
Definition connection.c:691
free_packet_hashes
static void free_packet_hashes(struct connection *pc)
Definition connection.c:573
free_socket_packet_buffer
static void free_socket_packet_buffer(struct socket_packet_buffer *buf)
Definition connection.c:454
conn_by_number
struct connection * conn_by_number(int id)
Definition connection.c:420
free_compression_queue
void free_compression_queue(struct connection *pc)
Definition connection.c:546
blank_addr_str
const char blank_addr_str[]
Definition connection.c:55
read_socket_data
int read_socket_data(int sock, struct socket_packet_buffer *buffer)
Definition connection.c:129
connection_send_data
bool connection_send_data(struct connection *pconn, const unsigned char *data, int len)
Definition connection.c:286
write_socket_data
static int write_socket_data(struct connection *pc, struct socket_packet_buffer *buf, int limit)
Definition connection.c:164
conn_get_access
enum cmdlevel conn_get_access(const struct connection *pconn)
Definition connection.c:772
conn_is_valid
bool conn_is_valid(const struct connection *pconn)
Definition connection.c:931
conn_compression_frozen
bool conn_compression_frozen(const struct connection *pconn)
Definition connection.c:705
conn_pattern_list_match
bool conn_pattern_list_match(const struct conn_pattern_list *plist, const struct connection *pconn)
Definition connection.c:847
connection_do_unbuffer
void connection_do_unbuffer(struct connection *pc)
Definition connection.c:335
connection.h
conn_pattern_list_iterate_end
#define conn_pattern_list_iterate_end
Definition connection.h:340
conn_close_fn_t
void(* conn_close_fn_t)(struct connection *pconn)
Definition connection.h:283
conn_compression_thaw
bool conn_compression_thaw(struct connection *pconn)
Definition packets.c:194
MAX_LEN_PACKET
#define MAX_LEN_PACKET
Definition connection.h:56
conn_list_iterate
#define conn_list_iterate(connlist, pconn)
Definition connection.h:113
MAX_LEN_BUFFER
#define MAX_LEN_BUFFER
Definition connection.h:61
conn_pattern_list_iterate
#define conn_pattern_list_iterate(plist, ppatern)
Definition connection.h:338
conn_list_iterate_end
#define conn_list_iterate_end
Definition connection.h:115
is_server
static bool is_server(void)
Definition fc_interface.h:69
fc_prehdrs.h
MAX_LEN_NAME
#define MAX_LEN_NAME
Definition fc_types.h:66
fcintl.h
_
#define _(String)
Definition fcintl.h:67
game
struct civ_game game
Definition game.c:57
game.h
genhash_destroy
void genhash_destroy(struct genhash *pgenhash)
Definition genhash.c:293
genhash_clear
void genhash_clear(struct genhash *pgenhash)
Definition genhash.c:582
genhash.h
type
GType type
Definition repodlgs.c:1312
func
get_token_fn_t func
Definition inputfile.c:128
log.h
fc_assert_msg
#define fc_assert_msg(condition, message,...)
Definition log.h:181
fc_assert_ret
#define fc_assert_ret(condition)
Definition log.h:191
log_packet
#define log_packet
Definition log.h:137
log_verbose
#define log_verbose(message,...)
Definition log.h:109
fc_assert
#define fc_assert(condition)
Definition log.h:176
log_debug
#define log_debug(message,...)
Definition log.h:115
log_error
#define log_error(message,...)
Definition log.h:103
mem.h
fc_strdup
#define fc_strdup(str)
Definition mem.h:43
fc_realloc
#define fc_realloc(ptr, sz)
Definition mem.h:36
fc_malloc
#define fc_malloc(sz)
Definition mem.h:34
fc_closesocket
void fc_closesocket(int sock)
Definition netintf.c:186
fc_readsocket
int fc_readsocket(int sock, void *buf, size_t size)
Definition netintf.c:144
fc_writesocket
int fc_writesocket(int sock, const void *buf, size_t size)
Definition netintf.c:163
fc_select
int fc_select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, fc_timeval *timeout)
Definition netintf.c:125
netintf.h
fc_timeval
struct timeval fc_timeval
Definition netintf.h:90
FC_FD_ZERO
#define FC_FD_ZERO(p)
Definition netintf.h:57
packet_header_init
void packet_header_init(struct packet_header *packet_header)
Definition packets.c:617
packet_handlers_initial
const struct packet_handlers * packet_handlers_initial(void)
Definition packets.c:823
packet_handlers_get
const struct packet_handlers * packet_handlers_get(const char *capability)
Definition packets.c:840
packets.h
packet_has_game_info_flag
bool packet_has_game_info_flag(enum packet_type type)
Definition packets_gen.c:570
packet_type
packet_type
Definition packets_gen.h:1883
PACKET_LAST
@ PACKET_LAST
Definition packets_gen.h:2078
len
int len
Definition packhand.c:125
player_name
const char * player_name(const struct player *pplayer)
Definition player.c:886
wildcard_fit_string
bool wildcard_fit_string(const char *pattern, const char *test)
Definition shared.c:2141
match_prefix
enum m_pre_result match_prefix(m_pre_accessor_fn_t accessor_fn, size_t n_names, size_t max_len_name, m_pre_strncmp_fn_t cmp_fn, m_strlen_fn_t len_fn, const char *prefix, int *ind_result)
Definition shared.c:1578
remove_leading_trailing_spaces
void remove_leading_trailing_spaces(char *s)
Definition shared.c:443
MIN
#define MIN(x, y)
Definition shared.h:55
m_pre_result
m_pre_result
Definition shared.h:207
M_PRE_AMBIGUOUS
@ M_PRE_AMBIGUOUS
Definition shared.h:210
MAX_LEN_ADDR
#define MAX_LEN_ADDR
Definition shared.h:31
civ_game::info
struct packet_game_info info
Definition game.h:89
civ_game::all_connections
struct conn_list * all_connections
Definition game.h:96
conn_pattern
Definition connection.c:784
conn_pattern::wildcard
char * wildcard
Definition connection.c:786
conn_pattern::type
enum conn_pattern_type type
Definition connection.c:785
connection
Definition connection.h:141
connection::received
struct genhash ** received
Definition connection.h:266
connection::established
bool established
Definition connection.h:145
connection::statistics
struct connection::@61 statistics
connection::playing
struct player * playing
Definition connection.h:156
connection::closing_reason
char * closing_reason
Definition connection.h:147
connection::access_level
enum cmdlevel access_level
Definition connection.h:182
connection::handlers
const struct packet_handlers * handlers
Definition connection.h:267
connection::is_closing
bool is_closing
Definition connection.h:236
connection::phs
struct connection::@59 phs
connection::observer
bool observer
Definition connection.h:152
connection::packet_header
struct packet_header packet_header
Definition connection.h:146
connection::username
char username[MAX_LEN_NAME]
Definition connection.h:169
connection::server
struct connection::@57::@63 server
connection::last_write
struct timer * last_write
Definition connection.h:160
connection::compression
struct connection::@60 compression
connection::ipaddr
char ipaddr[MAX_LEN_ADDR]
Definition connection.h:226
connection::bytes_send
int bytes_send
Definition connection.h:278
connection::send_buffer
struct socket_packet_buffer * send_buffer
Definition connection.h:159
connection::queue
struct byte_vector queue
Definition connection.h:274
connection::capability
char capability[MAX_LEN_CAPSTR]
Definition connection.h:176
connection::frozen_level
int frozen_level
Definition connection.h:272
connection::notify_of_writable_data
void(* notify_of_writable_data)(struct connection *pc, bool data_available_and_socket_full)
Definition connection.h:186
connection::sock
int sock
Definition connection.h:143
connection::addr
char addr[MAX_LEN_ADDR]
Definition connection.h:170
connection::sent
struct genhash ** sent
Definition connection.h:265
connection::buffer
struct socket_packet_buffer * buffer
Definition connection.h:158
connection::used
bool used
Definition connection.h:144
packet_game_info::is_edit_mode
bool is_edit_mode
Definition packets_gen.h:185
player
Definition player.h:249
socket_packet_buffer
Definition connection.h:121
socket_packet_buffer::ndata
int ndata
Definition connection.h:122
socket_packet_buffer::nsize
int nsize
Definition connection.h:124
socket_packet_buffer::do_buffer_sends
int do_buffer_sends
Definition connection.h:123
socket_packet_buffer::data
unsigned char * data
Definition connection.h:125
fc_snprintf
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:969
fc_strlcpy
size_t fc_strlcpy(char *dest, const char *src, size_t n)
Definition support.c:787
fc_strcasecmp
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:189
fc_isspace
bool fc_isspace(char c)
Definition support.c:1249
cat_snprintf
int cat_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:995
fc_strncasequotecmp
int fc_strncasequotecmp(const char *str0, const char *str1, size_t n)
Definition support.c:379
effectivestrlenquote
size_t effectivestrlenquote(const char *str)
Definition support.c:359
support.h
sz_strlcpy
#define sz_strlcpy(dest, src)
Definition support.h:161
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
sz_strlcat
#define sz_strlcat(dest, src)
Definition support.h:162
timer_destroy
void timer_destroy(struct timer *t)
Definition timing.c:191
timer_start
void timer_start(struct timer *t)
Definition timing.c:224
timer_renew
struct timer * timer_renew(struct timer *t, enum timer_timetype type, enum timer_use use)
Definition timing.c:176
TIMER_ACTIVE
@ TIMER_ACTIVE
Definition timing.h:45
TIMER_USER
@ TIMER_USER
Definition timing.h:41