… | |
… | |
49 | # include <arpa/inet.h> |
49 | # include <arpa/inet.h> |
50 | #endif |
50 | #endif |
51 | #include <newserver.h> |
51 | #include <newserver.h> |
52 | |
52 | |
53 | Socket_Info socket_info; |
53 | Socket_Info socket_info; |
54 | NewSocket *init_sockets; |
54 | client_socket *init_sockets; |
|
|
55 | |
|
|
56 | client_socket::client_socket () |
|
|
57 | { |
|
|
58 | } |
|
|
59 | |
|
|
60 | client_socket::~client_socket () |
|
|
61 | { |
|
|
62 | } |
55 | |
63 | |
56 | /** |
64 | /** |
57 | * Initializes a connection. Really, it just sets up the data structure, |
65 | * Initializes a connection. Really, it just sets up the data structure, |
58 | * socket setup is handled elsewhere. We do send a version to the |
66 | * socket setup is handled elsewhere. We do send a version to the |
59 | * client. |
67 | * client. |
60 | */ |
68 | */ |
61 | void |
69 | void |
62 | InitConnection (NewSocket *ns, const char *from_ip) |
70 | client_socket::init (const char *from_ip) |
63 | { |
71 | { |
64 | int bufsize = 65535; /*Supposed absolute upper limit */ |
72 | int bufsize = 65535; /*Supposed absolute upper limit */ |
65 | int oldbufsize; |
73 | int oldbufsize; |
66 | int buflen = sizeof (int); |
74 | int buflen = sizeof (int); |
67 | |
75 | |
68 | if (fcntl (ns->fd, F_SETFL, O_NONBLOCK) == -1) |
76 | if (fcntl (fd, F_SETFL, O_NONBLOCK) == -1) |
69 | LOG (llevError, "InitConnection: Error on fcntl.\n"); |
77 | LOG (llevError, "InitConnection: Error on fcntl.\n"); |
70 | |
78 | |
71 | if (getsockopt (ns->fd, SOL_SOCKET, SO_SNDBUF, (char *) &oldbufsize, (socklen_t *) & buflen) == -1) |
79 | if (getsockopt (fd, SOL_SOCKET, SO_SNDBUF, (char *) &oldbufsize, (socklen_t *) & buflen) == -1) |
72 | oldbufsize = 0; |
80 | oldbufsize = 0; |
73 | |
81 | |
74 | if (oldbufsize < bufsize) |
82 | if (oldbufsize < bufsize) |
75 | if (setsockopt (ns->fd, SOL_SOCKET, SO_SNDBUF, (char *) &bufsize, sizeof (&bufsize))) |
83 | if (setsockopt (fd, SOL_SOCKET, SO_SNDBUF, (char *) &bufsize, sizeof (&bufsize))) |
76 | LOG (llevError, "InitConnection: setsockopt unable to set output buf size to %d\n", bufsize); |
84 | LOG (llevError, "InitConnection: setsockopt unable to set output buf size to %d\n", bufsize); |
77 | |
85 | |
78 | buflen = sizeof (oldbufsize); |
86 | buflen = sizeof (oldbufsize); |
79 | getsockopt (ns->fd, SOL_SOCKET, SO_SNDBUF, (char *) &oldbufsize, (socklen_t *) & buflen); |
87 | getsockopt (fd, SOL_SOCKET, SO_SNDBUF, (char *) &oldbufsize, (socklen_t *) & buflen); |
80 | #ifdef ESRV_DEBUG |
88 | #ifdef ESRV_DEBUG |
81 | LOG (llevDebug, "Socket buffer size now %d bytes\n", oldbufsize); |
89 | LOG (llevDebug, "Socket buffer size now %d bytes\n", oldbufsize); |
82 | #endif |
90 | #endif |
83 | |
91 | |
84 | ns->faceset = 0; |
92 | faceset = 0; |
85 | ns->facecache = 0; |
93 | facecache = 0; |
86 | ns->image2 = 0; |
94 | image2 = 0; |
87 | ns->sound = 0; |
95 | sound = 0; |
88 | ns->exp64 = 0; |
96 | exp64 = 0; |
89 | ns->monitor_spells = 0; |
97 | monitor_spells = 0; |
90 | ns->mapmode = Map0Cmd; |
98 | mapmode = Map0Cmd; |
91 | ns->darkness = 1; |
99 | darkness = 1; |
92 | ns->status = Ns_Add; |
100 | status = Ns_Add; |
93 | ns->mapx = 11; |
101 | mapx = 11; |
94 | ns->mapy = 11; |
102 | mapy = 11; |
95 | ns->newmapcmd = 0; |
103 | newmapcmd = 0; |
96 | ns->itemcmd = 1; /* Default is version item1 command */ |
104 | itemcmd = 1; /* Default is version item1 command */ |
97 | ns->ext_mapinfos = 0; /*extendedmapinfo datas */ |
105 | ext_mapinfos = 0; /*extendedmapinfo datas */ |
98 | ns->EMI_smooth = 0; |
106 | EMI_smooth = 0; |
99 | ns->look_position = 0; |
107 | look_position = 0; |
100 | ns->update_look = 0; |
108 | update_look = 0; |
101 | ns->has_readable_type = 0; |
109 | has_readable_type = 0; |
102 | ns->supported_readables = 0; |
110 | supported_readables = 0; |
103 | ns->monitor_spells = 0; |
111 | monitor_spells = 0; |
104 | ns->mapinfocmd = 0; |
112 | mapinfocmd = 0; |
105 | ns->extcmd = 0; |
113 | extcmd = 0; |
106 | ns->extmap = 0; |
114 | extmap = 0; |
107 | |
115 | |
108 | /* we should really do some checking here - if total clients overflows |
116 | /* we should really do some checking here - if total clients overflows |
109 | * we need to do something more intelligent, because client id's will start |
117 | * we need to do something more intelligent, because client id's will start |
110 | * duplicating (not likely in normal cases, but malicous attacks that |
118 | * duplicating (not likely in normal cases, but malicous attacks that |
111 | * just open and close connections could get this total up. |
119 | * just open and close connections could get this total up. |
112 | */ |
120 | */ |
113 | ns->inbuf_len = 0; |
121 | inbuf_len = 0; |
114 | |
122 | |
115 | /* Basic initialization. Needed because we do a check in |
123 | /* Basic initialization. Needed because we do a check in |
116 | * HandleClient for oldsocketmode without checking the |
124 | * HandleClient for oldsocketmode without checking the |
117 | * length of data. |
125 | * length of data. |
118 | */ |
126 | */ |
119 | memset (&ns->lastmap, 0, sizeof (struct Map)); |
127 | memset (&lastmap, 0, sizeof (struct Map)); |
120 | memset (ns->faces_sent, 0, ns->faces_sent_len * sizeof (*ns->faces_sent)); |
128 | memset (faces_sent, 0, faces_sent_len * sizeof (*faces_sent)); |
121 | memset (&ns->anims_sent, 0, sizeof (ns->anims_sent)); |
129 | memset (&anims_sent, 0, sizeof (anims_sent)); |
122 | memset (&ns->stats, 0, sizeof (struct statsinfo)); |
130 | memset (&stats, 0, sizeof (struct statsinfo)); |
123 | /* Do this so we don't send a face command for the client for |
131 | /* Do this so we don't send a face command for the client for |
124 | * this face. Face 0 is sent to the client to say clear |
132 | * this face. Face 0 is sent to the client to say clear |
125 | * face information. |
133 | * face information. |
126 | */ |
134 | */ |
127 | ns->faces_sent[0] = NS_FACESENT_FACE; |
135 | faces_sent[0] = NS_FACESENT_FACE; |
128 | |
136 | |
129 | ns->outputbuffer.start = 0; |
137 | outputbuffer.start = 0; |
130 | ns->outputbuffer.len = 0; |
138 | outputbuffer.len = 0; |
131 | ns->can_write = 1; |
139 | can_write = 1; |
132 | ns->password_fails = 0; |
140 | password_fails = 0; |
133 | |
141 | |
134 | ns->current_map = 0; |
142 | current_map = 0; |
135 | ns->current_x = 0; |
143 | current_x = 0; |
136 | ns->current_y = 0; |
144 | current_y = 0; |
137 | ns->client[0] = 0; |
145 | client[0] = 0; |
138 | ns->buggy_mapscroll = 0; |
146 | buggy_mapscroll = 0; |
139 | |
147 | |
140 | ns->sent_scroll = 0; |
148 | sent_scroll = 0; |
141 | ns->host = strdup_local (from_ip); |
149 | host = strdup_local (from_ip); |
142 | |
150 | |
143 | { |
151 | { |
144 | packet sl; |
152 | packet sl; |
145 | |
|
|
146 | sl.printf ("version %d %d %s\n", VERSION_CS, VERSION_SC, VERSION_INFO); |
153 | sl.printf ("version %d %d %s\n", VERSION_CS, VERSION_SC, VERSION_INFO); |
147 | Send_With_Handling (ns, &sl); |
154 | send_packet (sl); |
148 | } |
155 | } |
149 | |
156 | |
150 | #ifdef CS_LOGSTATS |
|
|
151 | if (socket_info.nconns > cst_tot.max_conn) |
157 | if (socket_info.nconns > cst_tot.max_conn) |
152 | cst_tot.max_conn = socket_info.nconns; |
158 | cst_tot.max_conn = socket_info.nconns; |
153 | if (socket_info.nconns > cst_lst.max_conn) |
159 | if (socket_info.nconns > cst_lst.max_conn) |
154 | cst_lst.max_conn = socket_info.nconns; |
160 | cst_lst.max_conn = socket_info.nconns; |
155 | #endif |
|
|
156 | } |
161 | } |
157 | |
162 | |
158 | |
163 | |
159 | /** This sets up the socket and reads all the image information into memory. */ |
164 | /** This sets up the socket and reads all the image information into memory. */ |
160 | void |
165 | void |
… | |
… | |
168 | |
173 | |
169 | socket_info.timeout.tv_sec = 0; |
174 | socket_info.timeout.tv_sec = 0; |
170 | socket_info.timeout.tv_usec = 0; |
175 | socket_info.timeout.tv_usec = 0; |
171 | socket_info.nconns = 0; |
176 | socket_info.nconns = 0; |
172 | |
177 | |
173 | #ifdef CS_LOGSTATS |
|
|
174 | memset (&cst_tot, 0, sizeof (CS_Stats)); |
178 | memset (&cst_tot, 0, sizeof (CS_Stats)); |
175 | memset (&cst_lst, 0, sizeof (CS_Stats)); |
179 | memset (&cst_lst, 0, sizeof (CS_Stats)); |
176 | cst_tot.time_start = time (NULL); |
180 | cst_tot.time_start = time (NULL); |
177 | cst_lst.time_start = time (NULL); |
181 | cst_lst.time_start = time (NULL); |
178 | #endif |
|
|
179 | |
182 | |
180 | LOG (llevDebug, "Initialize new client/server data\n"); |
183 | LOG (llevDebug, "Initialize new client/server data\n"); |
181 | socket_info.nconns = 1; |
184 | socket_info.nconns = 1; |
182 | init_sockets = (NewSocket *) malloc (sizeof (NewSocket)); |
185 | init_sockets = (client_socket *) malloc (sizeof (client_socket)); |
183 | init_sockets[0].faces_sent = NULL; /* unused */ |
186 | init_sockets[0].faces_sent = NULL; /* unused */ |
184 | socket_info.allocated_sockets = 1; |
187 | socket_info.allocated_sockets = 1; |
185 | |
188 | |
186 | protox = getprotobyname ("tcp"); |
189 | protox = getprotobyname ("tcp"); |
187 | if (protox == NULL) |
190 | if (protox == NULL) |
… | |
… | |
253 | * might be associated with the socket. It is up to the caller to |
256 | * might be associated with the socket. It is up to the caller to |
254 | * update the list |
257 | * update the list |
255 | */ |
258 | */ |
256 | |
259 | |
257 | void |
260 | void |
258 | free_newsocket (NewSocket *ns) |
261 | free_newsocket (client_socket *ns) |
259 | { |
262 | { |
260 | close (ns->fd); |
263 | close (ns->fd); |
261 | |
264 | |
262 | if (ns->stats.range) |
265 | if (ns->stats.range) |
263 | free (ns->stats.range); |
266 | free (ns->stats.range); |