24#ifdef FREECIV_HAVE_SYS_TYPES_H
27#ifdef HAVE_SYS_SELECT_H
29#include <sys/select.h>
73 "Closing a socket (%s) before calling "
92 if (
reason !=
nullptr &&
pconn->closing_reason ==
nullptr) {
97 (*conn_close_callback) (
pconn);
151#ifdef NONBLOCKING_SOCKETS
173 for (start = 0;
buf->ndata-start >
limit;) {
182 tv.tv_sec = 0;
tv.tv_usec = 0;
203 (
const char *)
buf->data+start,
nblock)) == -1) {
204#ifdef NONBLOCKING_SOCKETS
220 pc->last_write !=
nullptr
221 ?
nullptr :
"socket write");
233 if (
pc &&
pc->used &&
pc->send_buffer->ndata > 0) {
235 if (
pc->notify_of_writable_data) {
236 pc->notify_of_writable_data(
pc,
pc->send_buffer
237 &&
pc->send_buffer->ndata > 0);
245#ifndef FREECIV_JSON_CONNECTION
250 if (
pc->notify_of_writable_data) {
251 pc->notify_of_writable_data(
pc,
pc->send_buffer
252 &&
pc->send_buffer->ndata > 0);
262 const unsigned char *data,
int len)
289 const unsigned char *
data,
int len)
297 pconn->statistics.bytes_send +=
len;
299#ifndef FREECIV_JSON_CONNECTION
300 if (0 <
pconn->send_buffer->do_buffer_sends) {
303 log_verbose(
"cut connection %s due to huge send buffer (1)",
313 log_verbose(
"cut connection %s due to huge send buffer (2)",
327 if (
pc &&
pc->used) {
328 pc->send_buffer->do_buffer_sends++;
339 if (
pc ==
nullptr || !
pc->used
344 pc->send_buffer->do_buffer_sends--;
345 if (0 >
pc->send_buffer->do_buffer_sends) {
346 log_error(
"Too many calls to unbuffer %s!",
pc->username);
347 pc->send_buffer->do_buffer_sends = 0;
350 if (0 ==
pc->send_buffer->do_buffer_sends) {
427 "Trying to look at the id of a non existing connection");
429 if (
pconn->id ==
id) {
447 buf->do_buffer_sends = 0;
482 if (*
pconn->username !=
'\0') {
488 if (
pconn->closing_reason !=
nullptr) {
492 }
else if (!
pconn->established) {
497 if (
pconn->playing !=
nullptr) {
502 if (
pconn->observer) {
517 && (
pconn->playing !=
nullptr ||
pconn->observer));
536 if ((result & 0xffff) == 0) {
537 log_packet(
"INFORMATION: request_id has wrapped around; "
538 "setting from %d to 2", result);
551#ifdef USE_COMPRESSION
568 pc->phs.sent[
i] =
nullptr;
569 pc->phs.received[
i] =
nullptr;
582 if (
pc->phs.sent[
i] !=
nullptr) {
587 pc->phs.sent =
nullptr;
590 if (
pc->phs.received) {
592 if (
pc->phs.received[
i] !=
nullptr) {
597 pc->phs.received =
nullptr;
610 pconn->closing_reason =
nullptr;
611 pconn->last_write =
nullptr;
614 pconn->statistics.bytes_send = 0;
615#ifdef FREECIV_JSON_CONNECTION
621#ifdef USE_COMPRESSION
623 pconn->compression.frozen_level = 0;
635 log_error(
"WARNING: Trying to close already closed connection");
640 if (
pconn->closing_reason !=
nullptr) {
645 pconn->buffer =
nullptr;
648 pconn->send_buffer =
nullptr;
650 if (
pconn->last_write) {
652 pconn->last_write =
nullptr;
681 if (
pc->phs.sent !=
nullptr &&
pc->phs.sent[
i] !=
nullptr) {
684 if (
pc->phs.received !=
nullptr &&
pc->phs.received[
i] !=
nullptr) {
698#ifdef USE_COMPRESSION
699 if (0 ==
pconn->compression.frozen_level) {
702 pconn->compression.frozen_level++;
712#ifdef USE_COMPRESSION
713 return 0 <
pconn->compression.frozen_level;
724#ifdef USE_COMPRESSION
736#ifdef USE_COMPRESSION
767 if (
pconn ==
nullptr) {
771 return pconn->playing;
780 if (
pconn ==
nullptr) {
784 return pconn->access_level;
826 const char *
test =
nullptr;
842 if (
test !=
nullptr) {
845 log_error(
"%s(): Invalid pattern type (%d)",
902 _(
"\"%s\" is not a valid pattern type"),
size_t conn_pattern_to_string(const struct conn_pattern *ppattern, char *buf, size_t buf_len)
static conn_close_fn_t conn_close_callback
struct player * conn_get_player(const struct connection *pconn)
void conn_list_do_unbuffer(struct conn_list *dest)
static void default_conn_close_callback(struct connection *pconn)
struct connection * conn_by_user_prefix(const char *user_name, enum m_pre_result *result)
bool can_conn_edit(const struct connection *pconn)
struct connection * conn_by_user(const char *user_name)
void conn_list_compression_thaw(const struct conn_list *pconn_list)
void connections_set_close_callback(conn_close_fn_t func)
static void flush_connection_send_buffer_packets(struct connection *pc)
static const char * connection_accessor(int i)
void flush_connection_send_buffer_all(struct connection *pc)
int get_next_request_id(int old_request_id)
struct socket_packet_buffer * new_socket_packet_buffer(void)
void conn_list_do_buffer(struct conn_list *dest)
bool can_conn_enable_editing(const struct connection *pconn)
void connection_do_buffer(struct connection *pc)
static bool add_connection_data(struct connection *pconn, const unsigned char *data, int len)
bool conn_pattern_match(const struct conn_pattern *ppattern, const struct connection *pconn)
static bool buffer_ensure_free_extra_space(struct socket_packet_buffer *buf, int extra_space)
void conn_set_capability(struct connection *pconn, const char *capability)
static void init_packet_hashes(struct connection *pc)
void conn_pattern_destroy(struct conn_pattern *ppattern)
void conn_reset_delta_state(struct connection *pc)
void connection_common_init(struct connection *pconn)
void connection_close(struct connection *pconn, const char *reason)
void conn_list_compression_freeze(const struct conn_list *pconn_list)
struct conn_pattern * conn_pattern_new(enum conn_pattern_type type, const char *wildcard)
bool conn_controls_player(const struct connection *pconn)
bool conn_is_global_observer(const struct connection *pconn)
const char * conn_description(const struct connection *pconn)
void connection_common_close(struct connection *pconn)
struct conn_pattern * conn_pattern_from_string(const char *pattern, enum conn_pattern_type prefer, char *error_buf, size_t error_buf_len)
void conn_compression_freeze(struct connection *pconn)
static void free_packet_hashes(struct connection *pc)
static void free_socket_packet_buffer(struct socket_packet_buffer *buf)
struct connection * conn_by_number(int id)
void free_compression_queue(struct connection *pc)
const char blank_addr_str[]
int read_socket_data(int sock, struct socket_packet_buffer *buffer)
bool connection_send_data(struct connection *pconn, const unsigned char *data, int len)
static int write_socket_data(struct connection *pc, struct socket_packet_buffer *buf, int limit)
enum cmdlevel conn_get_access(const struct connection *pconn)
bool conn_is_valid(const struct connection *pconn)
bool conn_compression_frozen(const struct connection *pconn)
bool conn_pattern_list_match(const struct conn_pattern_list *plist, const struct connection *pconn)
void connection_do_unbuffer(struct connection *pc)
#define conn_pattern_list_iterate_end
void(* conn_close_fn_t)(struct connection *pconn)
bool conn_compression_thaw(struct connection *pconn)
#define conn_list_iterate(connlist, pconn)
#define conn_pattern_list_iterate(plist, ppatern)
#define conn_list_iterate_end
static bool is_server(void)
void genhash_destroy(struct genhash *pgenhash)
void genhash_clear(struct genhash *pgenhash)
#define fc_assert_msg(condition, message,...)
#define fc_assert_ret(condition)
#define log_verbose(message,...)
#define fc_assert(condition)
#define log_debug(message,...)
#define log_error(message,...)
#define fc_realloc(ptr, sz)
void fc_closesocket(int sock)
int fc_readsocket(int sock, void *buf, size_t size)
int fc_writesocket(int sock, const void *buf, size_t size)
int fc_select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, fc_timeval *timeout)
struct timeval fc_timeval
void packet_header_init(struct packet_header *packet_header)
const struct packet_handlers * packet_handlers_initial(void)
const struct packet_handlers * packet_handlers_get(const char *capability)
bool packet_has_game_info_flag(enum packet_type type)
const char * player_name(const struct player *pplayer)
bool wildcard_fit_string(const char *pattern, const char *test)
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)
void remove_leading_trailing_spaces(char *s)
struct packet_game_info info
struct conn_list * all_connections
enum conn_pattern_type type
char username[MAX_LEN_NAME]
int fc_snprintf(char *str, size_t n, const char *format,...)
size_t fc_strlcpy(char *dest, const char *src, size_t n)
int fc_strcasecmp(const char *str0, const char *str1)
int cat_snprintf(char *str, size_t n, const char *format,...)
int fc_strncasequotecmp(const char *str0, const char *str1, size_t n)
size_t effectivestrlenquote(const char *str)
#define sz_strlcpy(dest, src)
#define sz_strlcat(dest, src)
void timer_destroy(struct timer *t)
void timer_start(struct timer *t)
struct timer * timer_renew(struct timer *t, enum timer_timetype type, enum timer_use use, const char *name)