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)
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 ***********************************************************************/
18 #endif /* __cplusplus */
23 #include "connection.h" /* struct connection, MAX_LEN_* */
24 #include "diptreaty.h"
27 #include "improvement.h" /* bv_imprs */
29 #include "requirements.h"
30 #include "shared.h" /* MAX_LEN_ADDR */
31 #include "spaceship.h"
34 #include "traderoutes.h"
39 /* Used in network protocol. */
40 #define MAX_LEN_MSG 1536
41 #define MAX_LEN_ROUTE 2000 /* MAX_LEN_PACKET/2 - header */
43 /* The size of opaque (void *) data sent in the network packet. To avoid
44 * fragmentation issues, this SHOULD NOT be larger than the standard
45 * ethernet or PPP 1500 byte frame size (with room for headers).
47 * Do not spend much time optimizing, you have no idea of the actual dynamic
48 * path characteristics between systems, such as VPNs and tunnels.
50 * Used in network protocol.
52 #define ATTRIBUTE_CHUNK_SIZE (1400)
54 /* Used in network protocol. */
56 REPORT_WONDERS_OF_THE_WORLD
,
62 /* Used in network protocol. */
65 UNIT_INFO_CITY_SUPPORTED
,
66 UNIT_INFO_CITY_PRESENT
69 /* Used in network protocol. */
70 enum authentication_type
{
71 AUTH_LOGIN_FIRST
, /* request a password for a returning user */
72 AUTH_NEWUSER_FIRST
, /* request a password for a new user */
73 AUTH_LOGIN_RETRY
, /* inform the client to try a different password */
74 AUTH_NEWUSER_RETRY
/* inform the client to try a different [new] password */
77 #include "packets_gen.h"
79 struct packet_handlers
{
81 int (*no_packet
)(struct connection
*pconn
);
82 int (*packet
)(struct connection
*pconn
, const void *packet
);
83 int (*force_to_send
)(struct connection
*pconn
, const void *packet
,
86 void *(*receive
[PACKET_LAST
])(struct connection
*pconn
);
89 void *get_packet_from_connection(struct connection
*pc
,
90 enum packet_type
*ptype
);
91 void remove_packet_from_buffer(struct socket_packet_buffer
*buffer
);
93 void send_attribute_block(const struct player
*pplayer
,
94 struct connection
*pconn
);
95 void generic_handle_player_attribute_chunk(struct player
*pplayer
,
97 packet_player_attribute_chunk
99 void packet_handlers_fill_initial(struct packet_handlers
*phandlers
);
100 void packet_handlers_fill_capability(struct packet_handlers
*phandlers
,
101 const char *capability
);
102 const char *packet_name(enum packet_type type
);
103 bool packet_has_game_info_flag(enum packet_type type
);
105 void packet_header_init(struct packet_header
*packet_header
);
106 void post_send_packet_server_join_reply(struct connection
*pconn
,
107 const struct packet_server_join_reply
109 void post_receive_packet_server_join_reply(struct connection
*pconn
,
111 packet_server_join_reply
*packet
);
113 void pre_send_packet_player_attribute_chunk(struct connection
*pc
,
114 struct packet_player_attribute_chunk
117 const struct packet_handlers
*packet_handlers_initial(void);
118 const struct packet_handlers
*packet_handlers_get(const char *capability
);
120 void packets_deinit(void);
122 #define SEND_PACKET_START(packet_type) \
123 unsigned char buffer[MAX_LEN_PACKET]; \
124 struct data_out dout; \
126 dio_output_init(&dout, buffer, sizeof(buffer)); \
127 dio_put_type(&dout, pc->packet_header.length, 0); \
128 dio_put_type(&dout, pc->packet_header.type, packet_type);
130 #define SEND_PACKET_END(packet_type) \
132 size_t size = dio_output_used(&dout); \
134 dio_output_rewind(&dout); \
135 dio_put_type(&dout, pc->packet_header.length, size); \
136 fc_assert(!dout.too_short); \
137 return send_packet_data(pc, buffer, size, packet_type); \
140 #define RECEIVE_PACKET_START(packet_type, result) \
141 struct data_in din; \
142 struct packet_type packet_buf, *result = &packet_buf; \
144 dio_input_init(&din, pc->buffer->data, \
145 data_type_size(pc->packet_header.length)); \
149 dio_get_type(&din, pc->packet_header.length, &size); \
150 dio_input_init(&din, pc->buffer->data, MIN(size, pc->buffer->ndata)); \
152 dio_input_skip(&din, (data_type_size(pc->packet_header.length) \
153 + data_type_size(pc->packet_header.type)));
155 #define RECEIVE_PACKET_END(result) \
156 if (!packet_check(&din, pc)) { \
159 remove_packet_from_buffer(pc->buffer); \
160 result = fc_malloc(sizeof(*result)); \
161 *result = packet_buf; \
164 #define RECEIVE_PACKET_FIELD_ERROR(field, ...) \
165 log_packet("Error on field '" #field "'" __VA_ARGS__); \
168 int send_packet_data(struct connection
*pc
, unsigned char *data
, int len
,
169 enum packet_type packet_type
);
170 bool packet_check(struct data_in
*din
, struct connection
*pc
);
172 /* Utilities to exchange strings and string vectors. */
173 #define PACKET_STRVEC_SEPARATOR '\3'
174 #define PACKET_STRVEC_COMPUTE(str, strvec) \
175 if (NULL != strvec) { \
176 strvec_to_str(strvec, PACKET_STRVEC_SEPARATOR, str, sizeof(str)); \
180 #define PACKET_STRVEC_EXTRACT(strvec, str) \
181 if ('\0' != str[0]) { \
182 strvec = strvec_new(); \
183 strvec_from_str(strvec, PACKET_STRVEC_SEPARATOR, str); \
190 #endif /* __cplusplus */
192 #endif /* FC__PACKETS_H */