 |
Crossfire Server, Trunk
1.75.0
|
Go to the documentation of this file.
35 #include <arpa/inet.h>
36 #include <sys/types.h>
38 #include <netinet/in.h>
39 #include <netinet/tcp.h>
71 if (getsockopt(ns->
fd, SOL_SOCKET, SO_SNDBUF, (
char *)&oldbufsize, &buflen) == -1)
73 if (oldbufsize < bufsize) {
75 LOG(
llevDebug,
"Default buffer size was %d bytes, will reset it to %d\n", oldbufsize, bufsize);
77 if (setsockopt(ns->
fd, SOL_SOCKET, SO_SNDBUF, (
char *)&bufsize,
sizeof(bufsize))) {
78 LOG(
llevError,
"init_connection: setsockopt unable to set output buf size to %d\n", bufsize);
81 buflen =
sizeof(oldbufsize);
82 getsockopt(ns->
fd, SOL_SOCKET, SO_SNDBUF, (
char *)&oldbufsize, &buflen);
84 LOG(
llevDebug,
"Socket buffer size now %d bytes\n", oldbufsize);
87 if (setsockopt(ns->
fd, IPPROTO_TCP, TCP_NODELAY, &tmp,
sizeof(tmp)))
100 #ifdef CF_MXE_CROSS_COMPILE
106 if (ioctlsocket(ns->
fd, FIONBIO , &temp) == -1)
107 LOG(
llevError,
"init_connection: Error on ioctlsocket.\n");
109 if (fcntl(ns->
fd, F_SETFL, O_NONBLOCK) == -1) {
193 struct linger linger_opt;
196 if (ns == NULL || ns->
listen == NULL) {
197 LOG(
llevError,
"init_listening_socket: missing listen info in socket_struct?!\n");
205 LOG(
llevError,
"Cannot create socket: %s\n", strerror(errno));
209 linger_opt.l_onoff = 0;
210 linger_opt.l_linger = 0;
211 if (setsockopt(ns->
fd, SOL_SOCKET, SO_LINGER, (
char *)&linger_opt,
sizeof(
struct linger))) {
212 LOG(
llevError,
"Cannot setsockopt(SO_LINGER): %s\n", strerror(errno));
218 #if defined(__osf__) || defined(hpux) || defined(sgi) || defined(NeXT) || \
219 defined(__sun__) || defined(__linux__) || defined(SVR4) || \
220 defined(__FreeBSD__) || defined(__OpenBSD__) || \
230 if (setsockopt(ns->
fd, SOL_SOCKET, SO_REUSEADDR, &tmp,
sizeof(tmp))) {
231 LOG(
llevError,
"Cannot setsockopt(SO_REUSEADDR): %s\n", strerror(errno));
233 #ifdef HAVE_GETADDRINFO
234 if ((ns->
listen->
family == AF_INET6) && setsockopt(ns->
fd, IPPROTO_IPV6, IPV6_V6ONLY, &tmp,
sizeof(tmp))) {
235 LOG(
llevError,
"Cannot setsockopt(IPV6_V6ONLY): %s\n", strerror(errno));
240 if (setsockopt(ns->
fd, SOL_SOCKET, SO_REUSEADDR, (
char *)NULL, 0)) {
241 LOG(
llevError,
"Cannot setsockopt(SO_REUSEADDR): %s\n", strerror(errno));
246 #ifdef HAVE_GETNAMEINFO
247 getnameinfo(ns->
listen->
addr, ns->
listen->
addrlen, buf1,
sizeof(buf1), buf2,
sizeof(buf2), NI_NUMERICHOST|NI_NUMERICSERV);
252 ip = ntohl(((
struct sockaddr_in *)ns->
listen->
addr)->sin_addr.s_addr);
253 port = ntohs(((
struct sockaddr_in *)ns->
listen->
addr)->sin_port);
254 snprintf(buf1,
sizeof(buf1),
"%ld.%ld.%ld.%ld", (ip>>24)&255, (ip>>16)&255, (ip>>8)&255, ip&255);
255 snprintf(buf2,
sizeof(buf2),
"%d", port&65535);
257 LOG(
llevError,
"Cannot bind socket to [%s]:%s: %s\n", buf1, buf2, strerror(errno));
259 shutdown(ns->
fd, SD_BOTH);
267 if (listen(ns->
fd, 5) == (-1)) {
268 LOG(
llevError,
"Cannot listen on socket: %s\n", strerror(errno));
270 shutdown(ns->
fd, SD_BOTH);
284 int i, e, listen_socket_count;
285 #ifdef HAVE_GETADDRINFO
286 struct addrinfo *ai, *ai_p;
287 struct addrinfo hints;
290 struct sockaddr_in *insock;
291 struct protoent *protox;
298 WSAStartup(0x0101, &w);
306 # ifdef HAVE_GETDTABLESIZE
309 #error "Unable to find usable function to get max filedescriptors"
325 #ifdef HAVE_GETADDRINFO
326 memset(&hints,
'\0',
sizeof(hints));
327 hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
328 hints.ai_socktype = SOCK_STREAM;
330 e = getaddrinfo(NULL,
buf, &hints, &ai);
332 LOG(
llevError,
"init_server: getaddrinfo: %s\n", gai_strerror(e));
336 listen_socket_count = 0;
337 for (ai_p = ai; ai_p != NULL; ai_p = ai_p->ai_next) {
338 listen_socket_count++;
341 assert(listen_socket_count > 0);
343 listen_socket_count = 1;
349 for (i = 0; i < listen_socket_count; i++) {
355 #ifdef HAVE_GETADDRINFO
356 for (i = 0, ai_p = ai; i < listen_socket_count && ai_p != NULL; i++, ai_p = ai_p->ai_next) {
362 memcpy(
init_sockets[i].listen->addr, ai_p->ai_addr, ai_p->ai_addrlen);
366 protox = getprotobyname(
"tcp");
367 if (protox == NULL) {
374 insock =
static_cast<struct sockaddr_in *
>(calloc(
sizeof(
struct sockaddr_in), 1));
375 insock->sin_family = AF_INET;
377 insock->sin_addr.s_addr = htonl(INADDR_ANY);
383 for (i = 0; i < listen_socket_count; i++) {
389 LOG(
llevError,
"init_server: can't open any listening socket\n");
403 LOG(
llevDebug,
"Freeing all new client/server information.\n");
420 shutdown(ns->
fd, SD_BOTH);
421 if (closesocket(ns->
fd)) {
uint32_t tick
Client wishes to get tick commands.
#define NS_FACESENT_FACE
Bitmask for the faces_sent[] array - what portion of the face have we sent?
struct Settings settings
Global settings.
bool heartbeat
Client will send hearbeats.
@ llevError
Error, serious thing.
void LOG(LogLevel logLevel, const char *format,...)
Logs a message to stderr, or to file.
Socket_Info socket_info
Socket information.
uint16_t container_position
Start of container contents to send to client.
uint16_t look_position
Start of drawing of look window.
Contains parameters for socket() and bind() for listening sockets.
uint32_t sound
Client sound mode.
Socket structure, represents a client-server connection.
int allocated_sockets
Number of allocated items in init_sockets.
void free_all_newserver(void)
Free's all the memory that ericserver allocates.
uint8_t num_look_objects
The maximum number of objects to show on the ground view; this number includes the prev/next group fa...
void SockList_AddString(SockList *sl, const char *data)
Adds a string without length.
int ssop_t
Parameter type for setsockopt, different between WIN32 and Linux.
#define DEFAULT_NUM_LOOK_OBJECTS
Default value for the number of objects to send for the 'look' window (container or ground view).
uint32_t extended_stats
Client wants base and maximum statistics information.
void init_listening_socket(socket_struct *ns)
This opens *ns for listening to connections.
uint32_t update_inventory
If true, we need to send the inventory list.
int max_filedescriptor
max filedescriptor on the system.
uint32_t is_bot
Client shouldn't be reported to metaserver.
static void set_output_sock_buf(socket_struct *ns, int bufsize)
struct listen_info * listen
SockList inbuf
If we get an incomplete packet, this is used to hold the data.
uint16_t csport
Port for new client/server.
void init_server(void)
This sets up the listening socket.
Holds some system-related information.
uint32_t update_look
If true, we need to send the look window.
socket_struct * init_sockets
Established connections for clients not yet playing.
Account_Chars * account_chars
Detailed information on characters on this account.
uint8_t mapy
How large a map the client wants.
uint32_t facecache
If true, client is caching images.
void account_char_free(Account_Chars *chars)
This frees all data associated with the character information.
Contains the last range/title information sent to client.
char * host
Which host it is connected from (ip address).
char * account_name
Name of the account logged in on this socket.
uint32_t monitor_spells
Client wishes to be informed when their spell list changes.
uint8_t faceset
Set the client is using, default 0.
void init_connection(socket_struct *ns, const char *from_ip)
Initializes a connection.
void SockList_Init(SockList *sl)
Initializes the SockList instance.
void fatal(enum fatal_error err)
fatal() is meant to be called whenever a fatal signal is intercepted.
#define MAX_BUF
Used for all kinds of things.
void free_newsocket(socket_struct *ns)
Frees a socket.
void SockList_Term(SockList *sl)
Frees all resources allocated by a SockList instance.
int8_t sounds_this_tick
Number of sounds sent this tick.
uint32_t want_pickup
Client wants pickup information when logging in.
#define FREE_AND_CLEAR(xyz)
Free the pointer and then set it to NULL.
struct timeval timeout
Timeout for select.
#define SOCKETBUFSIZE
SOCKETBUFSIZE is the size of the output socket buffer we request from the operating system.
void final_free_player(player *pl)
Sends the 'goodbye' command to the player, and closes connection.
void reset_stats(struct CS_Stats *stats)
size_t faces_sent_len
This is the number of elements allocated in faces_sent[].
void SockList_ResetRead(SockList *sl)
Resets the length of the stored data for reading.
uint8_t anims_sent[MAXANIMNUM]
What animations we sent.
uint8_t * faces_sent
This is a bitmap on sent face status.
#define VERSION_CS
Version >= 1023 understand setup cmd.
#define MAP_CLIENT_Y_DEFAULT
uint8_t login_method
Login method this client is using.
uint32_t darkness
True if client wants darkness information.
socket_struct * socket
Socket information for this player.
uint16_t notifications
Notifications this client wants to get.
uint8_t password_fails
How many times the player has failed to give the right password.
unsigned char buf[MAXSOCKBUF]
void account_char_save(Account_Chars *chars)
Saves the character information for the given account.
#define MAP_CLIENT_X_DEFAULT
void Send_With_Handling(socket_struct *ns, SockList *sl)
Calls Write_To_Socket to send data to the client.
Contains the base information we use to make up a packet we want to send.
@ llevDebug
Only for debugging purposes.
void free_player(player *pl)
Frees player structure, including pointed object (through object_free_drop_inventory()).
void SockList_AddPrintf(SockList *sl, const char *format,...)
Adds a printf like formatted string.
void account_logout(const char *account_name)
Remove 'account_name' from the list of logged in accounts.
short max_conn
Maximum connections received.