Freeciv-3.2: /fast/freeciv/nightly/S3_2/common/networking/connection.c Source File

Freeciv-3.2

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 pc->last_write != NULL ? NULL : "socket write");
221 timer_start(pc->last_write);
222 }
223
224 return 0;
225}
226
227/**********************************************************************/
230 void flush_connection_send_buffer_all(struct connection *pc)
231{
232 if (pc && pc->used && pc->send_buffer->ndata > 0) {
233 write_socket_data(pc, pc->send_buffer, 0);
234 if (pc->notify_of_writable_data) {
235 pc->notify_of_writable_data(pc, pc->send_buffer
236 && pc->send_buffer->ndata > 0);
237 }
238 }
239}
240
241/**********************************************************************/
244#ifndef FREECIV_JSON_CONNECTION
245 static void flush_connection_send_buffer_packets(struct connection *pc)
246{
247 if (pc && pc->used && pc->send_buffer->ndata >= MAX_LEN_PACKET) {
248 write_socket_data(pc, pc->send_buffer, MAX_LEN_PACKET-1);
249 if (pc->notify_of_writable_data) {
250 pc->notify_of_writable_data(pc, pc->send_buffer
251 && pc->send_buffer->ndata > 0);
252 }
253 }
254}
255#endif /* FREECIV_JSON_CONNECTION */
256
257/**********************************************************************/
260 static bool add_connection_data(struct connection *pconn,
261 const unsigned char *data, int len)
262{
263 struct socket_packet_buffer *buf;
264
265 if (NULL == pconn
266 || !pconn->used
267 || (is_server() && pconn->server.is_closing)) {
268 return TRUE;
269 }
270
271 buf = pconn->send_buffer;
272 log_debug("add %d bytes to %d (space =%d)", len, buf->ndata, buf->nsize);
273 if (!buffer_ensure_free_extra_space(buf, len)) {
274 connection_close(pconn, _("buffer overflow"));
275 return FALSE;
276 }
277
278 memcpy(buf->data + buf->ndata, data, len);
279 buf->ndata += len;
280
281 return TRUE;
282}
283
284/**********************************************************************/
287 bool connection_send_data(struct connection *pconn,
288 const unsigned char *data, int len)
289{
290 if (NULL == pconn
291 || !pconn->used
292 || (is_server() && pconn->server.is_closing)) {
293 return TRUE;
294 }
295
296 pconn->statistics.bytes_send += len;
297
298#ifndef FREECIV_JSON_CONNECTION
299 if (0 < pconn->send_buffer->do_buffer_sends) {
300 flush_connection_send_buffer_packets(pconn);
301 if (!add_connection_data(pconn, data, len)) {
302 log_verbose("cut connection %s due to huge send buffer (1)",
303 conn_description(pconn));
304 return FALSE;
305 }
306 flush_connection_send_buffer_packets(pconn);
307 } else
308#endif /* FREECIV_JSON_CONNECTION */
309 {
310 flush_connection_send_buffer_all(pconn);
311 if (!add_connection_data(pconn, data, len)) {
312 log_verbose("cut connection %s due to huge send buffer (2)",
313 conn_description(pconn));
314 return FALSE;
315 }
316 flush_connection_send_buffer_all(pconn);
317 }
318 return TRUE;
319}
320
321/**********************************************************************/
324 void connection_do_buffer(struct connection *pc)
325{
326 if (pc && pc->used) {
327 pc->send_buffer->do_buffer_sends++;
328 }
329}
330
331/**********************************************************************/
336 void connection_do_unbuffer(struct connection *pc)
337{
338 if (NULL == pc || !pc->used || (is_server() && pc->server.is_closing)) {
339 return;
340 }
341
342 pc->send_buffer->do_buffer_sends--;
343 if (0 > pc->send_buffer->do_buffer_sends) {
344 log_error("Too many calls to unbuffer %s!", pc->username);
345 pc->send_buffer->do_buffer_sends = 0;
346 }
347
348 if (0 == pc->send_buffer->do_buffer_sends) {
349 flush_connection_send_buffer_all(pc);
350 }
351}
352
353/**********************************************************************/
356 void conn_list_do_buffer(struct conn_list *dest)
357{
358 conn_list_iterate(dest, pconn) {
359 connection_do_buffer(pconn);
360 } conn_list_iterate_end;
361}
362
363/**********************************************************************/
366 void conn_list_do_unbuffer(struct conn_list *dest)
367{
368 conn_list_iterate(dest, pconn) {
369 connection_do_unbuffer(pconn);
370 } conn_list_iterate_end;
371}
372
373/**********************************************************************/
377 struct connection *conn_by_user(const char *user_name)
378{
379 conn_list_iterate(game.all_connections, pconn) {
380 if (fc_strcasecmp(user_name, pconn->username) == 0) {
381 return pconn;
382 }
383 } conn_list_iterate_end;
384
385 return NULL;
386}
387
388/**********************************************************************/
394 static const char *connection_accessor(int i) {
395 return conn_list_get(game.all_connections, i)->username;
396}
397
398 struct connection *conn_by_user_prefix(const char *user_name,
399 enum m_pre_result *result)
400{
401 int ind;
402
403 *result = match_prefix(connection_accessor,
404 conn_list_size(game.all_connections),
405 MAX_LEN_NAME-1, fc_strncasequotecmp,
406 effectivestrlenquote, user_name, &ind);
407
408 if (*result < M_PRE_AMBIGUOUS) {
409 return conn_list_get(game.all_connections, ind);
410 } else {
411 return NULL;
412 }
413}
414
415/**********************************************************************/
421 struct connection *conn_by_number(int id)
422{
423 conn_list_iterate(game.all_connections, pconn) {
424 fc_assert_msg(pconn != NULL,
425 "Trying to look at the id of a non existing connection");
426
427 if (pconn->id == id) {
428 return pconn;
429 }
430 }
431 conn_list_iterate_end;
432
433 return NULL;
434}
435
436/**********************************************************************/
439 struct socket_packet_buffer *new_socket_packet_buffer(void)
440{
441 struct socket_packet_buffer *buf;
442
443 buf = fc_malloc(sizeof(*buf));
444 buf->ndata = 0;
445 buf->do_buffer_sends = 0;
446 buf->nsize = 10*MAX_LEN_PACKET;
447 buf->data = (unsigned char *)fc_malloc(buf->nsize);
448
449 return buf;
450}
451
452/**********************************************************************/
455 static void free_socket_packet_buffer(struct socket_packet_buffer *buf)
456{
457 if (buf) {
458 if (buf->data) {
459 free(buf->data);
460 }
461 free(buf);
462 }
463}
464
465/**********************************************************************/
474 const char *conn_description(const struct connection *pconn)
475{
476 static char buffer[MAX_LEN_NAME*2 + MAX_LEN_ADDR + 128];
477
478 buffer[0] = '\0';
479
480 if (*pconn->username != '\0') {
481 fc_snprintf(buffer, sizeof(buffer), _("%s from %s"),
482 pconn->username, pconn->addr);
483 } else {
484 sz_strlcpy(buffer, "server");
485 }
486 if (NULL != pconn->closing_reason) {
487 /* TRANS: Appending the reason why a connection has closed.
488 * Preserve leading space. */
489 cat_snprintf(buffer, sizeof(buffer), _(" (%s)"), pconn->closing_reason);
490 } else if (!pconn->established) {
491 /* TRANS: preserve leading space. */
492 sz_strlcat(buffer, _(" (connection incomplete)"));
493 return buffer;
494 }
495 if (NULL != pconn->playing) {
496 /* TRANS: preserve leading space. */
497 cat_snprintf(buffer, sizeof(buffer), _(" (player %s)"),
498 player_name(pconn->playing));
499 }
500 if (pconn->observer) {
501 /* TRANS: preserve leading space. */
502 sz_strlcat(buffer, _(" (observer)"));
503 }
504
505 return buffer;
506}
507
508/**********************************************************************/
511 bool can_conn_edit(const struct connection *pconn)
512{
513 return (can_conn_enable_editing(pconn)
514 && game.info.is_edit_mode
515 && (NULL != pconn->playing || pconn->observer));
516}
517
518/**********************************************************************/
521 bool can_conn_enable_editing(const struct connection *pconn)
522{
523 return pconn->access_level == ALLOW_HACK;
524}
525
526/**********************************************************************/
530 int get_next_request_id(int old_request_id)
531{
532 int result = old_request_id + 1;
533
534 if ((result & 0xffff) == 0) {
535 log_packet("INFORMATION: request_id has wrapped around; "
536 "setting from %d to 2", result);
537 result = 2;
538 }
539 fc_assert(0 != result);
540
541 return result;
542}
543
544/**********************************************************************/
547 void free_compression_queue(struct connection *pc)
548{
549#ifdef USE_COMPRESSION
550 byte_vector_free(&pc->compression.queue);
551#endif /* USE_COMPRESSION */
552}
553
554/**********************************************************************/
557 static void init_packet_hashes(struct connection *pc)
558{
559 enum packet_type i;
560
561 pc->phs.sent = fc_malloc(sizeof(*pc->phs.sent) * PACKET_LAST);
562 pc->phs.received = fc_malloc(sizeof(*pc->phs.received) * PACKET_LAST);
563 pc->phs.handlers = packet_handlers_initial();
564
565 for (i = 0; i < PACKET_LAST; i++) {
566 pc->phs.sent[i] = NULL;
567 pc->phs.received[i] = NULL;
568 }
569}
570
571/**********************************************************************/
574 static void free_packet_hashes(struct connection *pc)
575{
576 int i;
577
578 if (pc->phs.sent) {
579 for (i = 0; i < PACKET_LAST; i++) {
580 if (pc->phs.sent[i] != NULL) {
581 genhash_destroy(pc->phs.sent[i]);
582 }
583 }
584 free(pc->phs.sent);
585 pc->phs.sent = NULL;
586 }
587
588 if (pc->phs.received) {
589 for (i = 0; i < PACKET_LAST; i++) {
590 if (pc->phs.received[i] != NULL) {
591 genhash_destroy(pc->phs.received[i]);
592 }
593 }
594 free(pc->phs.received);
595 pc->phs.received = NULL;
596 }
597}
598
599/**********************************************************************/
603 void connection_common_init(struct connection *pconn)
604{
605 pconn->established = FALSE;
606 pconn->used = TRUE;
607 packet_header_init(&pconn->packet_header);
608 pconn->closing_reason = NULL;
609 pconn->last_write = NULL;
610 pconn->buffer = new_socket_packet_buffer();
611 pconn->send_buffer = new_socket_packet_buffer();
612 pconn->statistics.bytes_send = 0;
613#ifdef FREECIV_JSON_CONNECTION
614 pconn->json_mode = TRUE;
615#endif /* FREECIV_JSON_CONNECTION */
616
617 init_packet_hashes(pconn);
618
619#ifdef USE_COMPRESSION
620 byte_vector_init(&pconn->compression.queue);
621 pconn->compression.frozen_level = 0;
622#endif /* USE_COMPRESSION */
623
624 pconn->client_gui = GUI_STUB;
625}
626
627/**********************************************************************/
630 void connection_common_close(struct connection *pconn)
631{
632 if (!pconn->used) {
633 log_error("WARNING: Trying to close already closed connection");
634 } else {
635 fc_closesocket(pconn->sock);
636 pconn->used = FALSE;
637 pconn->established = FALSE;
638 if (NULL != pconn->closing_reason) {
639 free(pconn->closing_reason);
640 }
641
642 free_socket_packet_buffer(pconn->buffer);
643 pconn->buffer = NULL;
644
645 free_socket_packet_buffer(pconn->send_buffer);
646 pconn->send_buffer = NULL;
647
648 if (pconn->last_write) {
649 timer_destroy(pconn->last_write);
650 pconn->last_write = NULL;
651 }
652
653 free_compression_queue(pconn);
654 free_packet_hashes(pconn);
655 }
656}
657
658/**********************************************************************/
661 void conn_set_capability(struct connection *pconn, const char *capability)
662{
663 fc_assert(strlen(capability) < sizeof(pconn->capability));
664
665 sz_strlcpy(pconn->capability, capability);
666 pconn->phs.handlers = packet_handlers_get(capability);
667}
668
669/**********************************************************************/
673 void conn_reset_delta_state(struct connection *pc)
674{
675 int i;
676
677 for (i = 0; i < PACKET_LAST; i++) {
678 if (packet_has_game_info_flag(i)) {
679 if (NULL != pc->phs.sent && NULL != pc->phs.sent[i]) {
680 genhash_clear(pc->phs.sent[i]);
681 }
682 if (NULL != pc->phs.received && NULL != pc->phs.received[i]) {
683 genhash_clear(pc->phs.received[i]);
684 }
685 }
686 }
687}
688
689/**********************************************************************/
694 void conn_compression_freeze(struct connection *pconn)
695{
696#ifdef USE_COMPRESSION
697 if (0 == pconn->compression.frozen_level) {
698 byte_vector_reserve(&pconn->compression.queue, 0);
699 }
700 pconn->compression.frozen_level++;
701#endif /* USE_COMPRESSION */
702}
703
704/**********************************************************************/
708 bool conn_compression_frozen(const struct connection *pconn)
709{
710#ifdef USE_COMPRESSION
711 return 0 < pconn->compression.frozen_level;
712#else /* USE_COMPRESSION */
713 return FALSE;
714#endif /* USE_COMPRESSION */
715}
716
717/**********************************************************************/
720 void conn_list_compression_freeze(const struct conn_list *pconn_list)
721{
722#ifdef USE_COMPRESSION
723 conn_list_iterate(pconn_list, pconn) {
724 conn_compression_freeze(pconn);
725 } conn_list_iterate_end;
726#endif /* USE_COMPRESSION */
727}
728
729/**********************************************************************/
732 void conn_list_compression_thaw(const struct conn_list *pconn_list)
733{
734#ifdef USE_COMPRESSION
735 conn_list_iterate(pconn_list, pconn) {
736 conn_compression_thaw(pconn);
737 } conn_list_iterate_end;
738#endif /* USE_COMPRESSION */
739}
740
741/**********************************************************************/
745 bool conn_controls_player(const struct connection *pconn)
746{
747 return pconn && pconn->playing && !pconn->observer;
748}
749
750/**********************************************************************/
753 bool conn_is_global_observer(const struct connection *pconn)
754{
755 return pconn && !pconn->playing && pconn->observer;
756}
757
758/**********************************************************************/
763 struct player *conn_get_player(const struct connection *pconn)
764{
765 if (!pconn) {
766 return NULL;
767 }
768 return pconn->playing;
769}
770
771/**********************************************************************/
775 enum cmdlevel conn_get_access(const struct connection *pconn)
776{
777 if (!pconn) {
778 return ALLOW_NONE; /* Would not want to give hack on error... */
779 }
780 return pconn->access_level;
781}
782
783
784/**************************************************************************
785 Connection patterns.
786**************************************************************************/
787 struct conn_pattern {
788 enum conn_pattern_type type;
789 char *wildcard;
790};
791
792/**********************************************************************/
795 struct conn_pattern *conn_pattern_new(enum conn_pattern_type type,
796 const char *wildcard)
797{
798 struct conn_pattern *ppattern = fc_malloc(sizeof(*ppattern));
799
800 ppattern->type = type;
801 ppattern->wildcard = fc_strdup(wildcard);
802
803 return ppattern;
804}
805
806/**********************************************************************/
809 void conn_pattern_destroy(struct conn_pattern *ppattern)
810{
811 fc_assert_ret(NULL != ppattern);
812 free(ppattern->wildcard);
813 free(ppattern);
814}
815
816/**********************************************************************/
819 bool conn_pattern_match(const struct conn_pattern *ppattern,
820 const struct connection *pconn)
821{
822 const char *test = NULL;
823
824 switch (ppattern->type) {
825 case CPT_USER:
826 test = pconn->username;
827 break;
828 case CPT_HOST:
829 test = pconn->addr;
830 break;
831 case CPT_IP:
832 if (is_server()) {
833 test = pconn->server.ipaddr;
834 }
835 break;
836 }
837
838 if (NULL != test) {
839 return wildcard_fit_string(ppattern->wildcard, test);
840 } else {
841 log_error("%s(): Invalid pattern type (%d)",
842 __FUNCTION__, ppattern->type);
843 return FALSE;
844 }
845}
846
847/**********************************************************************/
850 bool conn_pattern_list_match(const struct conn_pattern_list *plist,
851 const struct connection *pconn)
852{
853 conn_pattern_list_iterate(plist, ppattern) {
854 if (conn_pattern_match(ppattern, pconn)) {
855 return TRUE;
856 }
857 } conn_pattern_list_iterate_end;
858
859 return FALSE;
860}
861
862/**********************************************************************/
865 size_t conn_pattern_to_string(const struct conn_pattern *ppattern,
866 char *buf, size_t buf_len)
867{
868 return fc_snprintf(buf, buf_len, "<%s=%s>",
869 conn_pattern_type_name(ppattern->type),
870 ppattern->wildcard);
871}
872
873/**********************************************************************/
878 struct conn_pattern *conn_pattern_from_string(const char *pattern,
879 enum conn_pattern_type prefer,
880 char *error_buf,
881 size_t error_buf_len)
882{
883 enum conn_pattern_type type;
884 const char *p;
885
886 /* Determine pattern type. */
887 if ((p = strchr(pattern, '='))) {
888 /* Special character to separate the type of the pattern. */
889 const size_t pattern_type_len = ++p - pattern;
890 char pattern_type[pattern_type_len];
891
892 fc_strlcpy(pattern_type, pattern, pattern_type_len);
893 remove_leading_trailing_spaces(pattern_type);
894 type = conn_pattern_type_by_name(pattern_type, fc_strcasecmp);
895 if (!conn_pattern_type_is_valid(type)) {
896 if (NULL != error_buf) {
897 fc_snprintf(error_buf, error_buf_len,
898 _("\"%s\" is not a valid pattern type"),
899 pattern_type);
900 }
901 return NULL;
902 }
903 } else {
904 /* Use 'prefer' type. */
905 p = pattern;
906 type = prefer;
907 if (!conn_pattern_type_is_valid(type)) {
908 if (NULL != error_buf) {
909 fc_strlcpy(error_buf, _("Missing pattern type"), error_buf_len);
910 }
911 return NULL;
912 }
913 }
914
915 /* Remove leading spaces. */
916 while (fc_isspace(*p)) {
917 p++;
918 }
919
920 if ('\0' == *p) {
921 if (NULL != error_buf) {
922 fc_strlcpy(error_buf, _("Missing pattern"), error_buf_len);
923 }
924 return NULL;
925 }
926
927 return conn_pattern_new(type, p);
928}
929
930/**********************************************************************/
934 bool conn_is_valid(const struct connection *pconn)
935{
936 return (pconn && pconn->used && !pconn->server.is_closing);
937}
user_name
char user_name[512]
Definition client_main.c:142
incite_cost
char * incite_cost
Definition comments.c:74
MAX_LEN_PACKET
#define MAX_LEN_PACKET
Definition conn_types.h:29
MAX_LEN_BUFFER
#define MAX_LEN_BUFFER
Definition conn_types.h:34
conn_pattern_to_string
size_t conn_pattern_to_string(const struct conn_pattern *ppattern, char *buf, size_t buf_len)
Definition connection.c:865
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:763
conn_list_do_unbuffer
void conn_list_do_unbuffer(struct conn_list *dest)
Definition connection.c:366
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:398
can_conn_edit
bool can_conn_edit(const struct connection *pconn)
Definition connection.c:511
conn_by_user
struct connection * conn_by_user(const char *user_name)
Definition connection.c:377
conn_list_compression_thaw
void conn_list_compression_thaw(const struct conn_list *pconn_list)
Definition connection.c:732
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:245
connection_accessor
static const char * connection_accessor(int i)
Definition connection.c:394
flush_connection_send_buffer_all
void flush_connection_send_buffer_all(struct connection *pc)
Definition connection.c:230
get_next_request_id
int get_next_request_id(int old_request_id)
Definition connection.c:530
new_socket_packet_buffer
struct socket_packet_buffer * new_socket_packet_buffer(void)
Definition connection.c:439
conn_list_do_buffer
void conn_list_do_buffer(struct conn_list *dest)
Definition connection.c:356
can_conn_enable_editing
bool can_conn_enable_editing(const struct connection *pconn)
Definition connection.c:521
connection_do_buffer
void connection_do_buffer(struct connection *pc)
Definition connection.c:324
add_connection_data
static bool add_connection_data(struct connection *pconn, const unsigned char *data, int len)
Definition connection.c:260
conn_pattern_match
bool conn_pattern_match(const struct conn_pattern *ppattern, const struct connection *pconn)
Definition connection.c:819
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:661
init_packet_hashes
static void init_packet_hashes(struct connection *pc)
Definition connection.c:557
conn_pattern_destroy
void conn_pattern_destroy(struct conn_pattern *ppattern)
Definition connection.c:809
conn_reset_delta_state
void conn_reset_delta_state(struct connection *pc)
Definition connection.c:673
connection_common_init
void connection_common_init(struct connection *pconn)
Definition connection.c:603
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:720
conn_pattern_new
struct conn_pattern * conn_pattern_new(enum conn_pattern_type type, const char *wildcard)
Definition connection.c:795
conn_controls_player
bool conn_controls_player(const struct connection *pconn)
Definition connection.c:745
conn_is_global_observer
bool conn_is_global_observer(const struct connection *pconn)
Definition connection.c:753
conn_description
const char * conn_description(const struct connection *pconn)
Definition connection.c:474
connection_common_close
void connection_common_close(struct connection *pconn)
Definition connection.c:630
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:878
conn_compression_freeze
void conn_compression_freeze(struct connection *pconn)
Definition connection.c:694
free_packet_hashes
static void free_packet_hashes(struct connection *pc)
Definition connection.c:574
free_socket_packet_buffer
static void free_socket_packet_buffer(struct socket_packet_buffer *buf)
Definition connection.c:455
conn_by_number
struct connection * conn_by_number(int id)
Definition connection.c:421
free_compression_queue
void free_compression_queue(struct connection *pc)
Definition connection.c:547
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:287
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:775
conn_is_valid
bool conn_is_valid(const struct connection *pconn)
Definition connection.c:934
conn_compression_frozen
bool conn_compression_frozen(const struct connection *pconn)
Definition connection.c:708
conn_pattern_list_match
bool conn_pattern_list_match(const struct conn_pattern_list *plist, const struct connection *pconn)
Definition connection.c:850
connection_do_unbuffer
void connection_do_unbuffer(struct connection *pc)
Definition connection.c:336
connection.h
conn_pattern_list_iterate_end
#define conn_pattern_list_iterate_end
Definition connection.h:338
conn_close_fn_t
void(* conn_close_fn_t)(struct connection *pconn)
Definition connection.h:281
conn_compression_thaw
bool conn_compression_thaw(struct connection *pconn)
Definition packets.c:194
conn_list_iterate
#define conn_list_iterate(connlist, pconn)
Definition connection.h:108
conn_pattern_list_iterate
#define conn_pattern_list_iterate(plist, ppatern)
Definition connection.h:336
conn_list_iterate_end
#define conn_list_iterate_end
Definition connection.h:110
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:62
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:1313
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:571
packet_type
packet_type
Definition packets_gen.h:1893
PACKET_LAST
@ PACKET_LAST
Definition packets_gen.h:2094
len
int len
Definition packhand.c:127
player_name
const char * player_name(const struct player *pplayer)
Definition player.c:895
wildcard_fit_string
bool wildcard_fit_string(const char *pattern, const char *test)
Definition shared.c:2152
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:1587
remove_leading_trailing_spaces
void remove_leading_trailing_spaces(char *s)
Definition shared.c:444
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:787
conn_pattern::wildcard
char * wildcard
Definition connection.c:789
conn_pattern::type
enum conn_pattern_type type
Definition connection.c:788
connection
Definition connection.h:136
connection::username
char username[MAX_LEN_NAME]
Definition connection.h:164
packet_game_info::is_edit_mode
bool is_edit_mode
Definition packets_gen.h:185
player
Definition player.h:247
socket_packet_buffer
Definition connection.h:116
socket_packet_buffer::ndata
int ndata
Definition connection.h:117
socket_packet_buffer::nsize
int nsize
Definition connection.h:119
socket_packet_buffer::data
unsigned char * data
Definition connection.h:120
fc_snprintf
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:974
fc_strlcpy
size_t fc_strlcpy(char *dest, const char *src, size_t n)
Definition support.c:791
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:1254
cat_snprintf
int cat_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:1000
fc_strncasequotecmp
int fc_strncasequotecmp(const char *str0, const char *str1, size_t n)
Definition support.c:380
effectivestrlenquote
size_t effectivestrlenquote(const char *str)
Definition support.c:359
support.h
sz_strlcpy
#define sz_strlcpy(dest, src)
Definition support.h:189
TRUE
#define TRUE
Definition support.h:46
FALSE
#define FALSE
Definition support.h:47
sz_strlcat
#define sz_strlcat(dest, src)
Definition support.h:190
timer_destroy
void timer_destroy(struct timer *t)
Definition timing.c:208
timer_start
void timer_start(struct timer *t)
Definition timing.c:264
timer_renew
struct timer * timer_renew(struct timer *t, enum timer_timetype type, enum timer_use use, const char *name)
Definition timing.c:180
TIMER_ACTIVE
@ TIMER_ACTIVE
Definition timing.h:46
TIMER_USER
@ TIMER_USER
Definition timing.h:42