… | |
… | |
41 | #include <sys/time.h> |
41 | #include <sys/time.h> |
42 | #include <sys/socket.h> |
42 | #include <sys/socket.h> |
43 | #include <netinet/in.h> |
43 | #include <netinet/in.h> |
44 | #include <netdb.h> |
44 | #include <netdb.h> |
45 | |
45 | |
46 | #ifdef HAVE_UNISTD_H |
|
|
47 | # include <unistd.h> |
46 | #include <unistd.h> |
48 | #endif |
|
|
49 | |
|
|
50 | #ifdef HAVE_ARPA_INET_H |
|
|
51 | # include <arpa/inet.h> |
47 | #include <arpa/inet.h> |
52 | #endif |
|
|
53 | |
48 | |
54 | #include <loader.h> |
49 | #include <loader.h> |
55 | #include <newserver.h> |
50 | #include <newserver.h> |
56 | |
51 | |
57 | /***************************************************************************** |
52 | /***************************************************************************** |
… | |
… | |
275 | next_packet: |
270 | next_packet: |
276 | ; |
271 | ; |
277 | } |
272 | } |
278 | } |
273 | } |
279 | |
274 | |
280 | |
|
|
281 | /***************************************************************************** |
|
|
282 | * |
|
|
283 | * Low level socket looping - select calls and watchdog udp packet |
|
|
284 | * sending. |
|
|
285 | * |
|
|
286 | ******************************************************************************/ |
|
|
287 | |
|
|
288 | #ifdef WATCHDOG |
|
|
289 | |
|
|
290 | /** |
|
|
291 | * Tell watchdog that we are still alive |
|
|
292 | * |
|
|
293 | * I put the function here since we should hopefully already be getting |
|
|
294 | * all the needed include files for socket support |
|
|
295 | */ |
|
|
296 | |
|
|
297 | void |
|
|
298 | watchdog (void) |
|
|
299 | { |
|
|
300 | static int fd = -1; |
|
|
301 | static struct sockaddr_in insock; |
|
|
302 | |
|
|
303 | if (fd == -1) |
|
|
304 | { |
|
|
305 | struct protoent *protoent; |
|
|
306 | |
|
|
307 | if ((protoent = getprotobyname ("udp")) == NULL || (fd = socket (PF_INET, SOCK_DGRAM, protoent->p_proto)) == -1) |
|
|
308 | { |
|
|
309 | return; |
|
|
310 | } |
|
|
311 | insock.sin_family = AF_INET; |
|
|
312 | insock.sin_port = htons ((unsigned short) 13325); |
|
|
313 | insock.sin_addr.s_addr = inet_addr ("127.0.0.1"); |
|
|
314 | } |
|
|
315 | sendto (fd, (void *) &fd, 1, 0, (struct sockaddr *) &insock, sizeof (insock)); |
|
|
316 | } |
|
|
317 | #endif |
|
|
318 | |
|
|
319 | void |
275 | void |
320 | flush_sockets (void) |
276 | flush_sockets (void) |
321 | { |
277 | { |
322 | player *pl; |
278 | for (sockvec::iterator i = client_sockets.begin (); i != client_sockets.end (); ++i) |
323 | |
|
|
324 | for (pl = first_player; pl != NULL; pl = pl->next) |
|
|
325 | if (pl->socket->status != Ns_Dead) |
279 | if ((*i)->status != Ns_Dead) |
326 | Socket_Flush (pl->socket); |
280 | (*i)->flush (); |
327 | } |
281 | } |
328 | |
282 | |
329 | /** |
283 | /** |
330 | * This checks the sockets for input, does the right thing. |
284 | * This checks the sockets for input, does the right thing. |
331 | * |
285 | * |
… | |
… | |
335 | */ |
289 | */ |
336 | void |
290 | void |
337 | doeric_server (void) |
291 | doeric_server (void) |
338 | { |
292 | { |
339 | int i, pollret; |
293 | int i, pollret; |
340 | fd_set tmp_read, tmp_write; |
294 | fd_set tmp_read; |
341 | struct sockaddr_in addr; |
295 | struct sockaddr_in addr; |
342 | socklen_t addrlen = sizeof (struct sockaddr); |
296 | socklen_t addrlen = sizeof (struct sockaddr); |
343 | player *pl, *next; |
297 | player *pl, *next; |
344 | int maxfd = 0; |
298 | int maxfd = 0; |
345 | |
299 | |
… | |
… | |
373 | |
327 | |
374 | pl = npl; |
328 | pl = npl; |
375 | } |
329 | } |
376 | |
330 | |
377 | FD_ZERO (&tmp_read); |
331 | FD_ZERO (&tmp_read); |
378 | FD_ZERO (&tmp_write); |
|
|
379 | |
332 | |
380 | for (sockvec::iterator i = client_sockets.begin (); i != client_sockets.end (); ) |
333 | for (sockvec::iterator i = client_sockets.begin (); i != client_sockets.end (); ) |
381 | { |
334 | { |
382 | client_socket *s = *i; |
335 | client_socket *s = *i; |
383 | |
336 | |
… | |
… | |
390 | { |
343 | { |
391 | if (s->fd > maxfd) maxfd = s->fd; |
344 | if (s->fd > maxfd) maxfd = s->fd; |
392 | |
345 | |
393 | FD_SET (s->fd, &tmp_read); |
346 | FD_SET (s->fd, &tmp_read); |
394 | |
347 | |
395 | if (s->outputbuffer.len) |
|
|
396 | FD_SET (s->fd, &tmp_write); |
|
|
397 | |
|
|
398 | ++i; |
348 | ++i; |
399 | } |
349 | } |
400 | } |
350 | } |
401 | |
351 | |
402 | struct timeval timeout; |
352 | struct timeval timeout; |
403 | |
353 | |
404 | timeout.tv_sec = 0; |
354 | timeout.tv_sec = 0; |
405 | timeout.tv_usec = 0; |
355 | timeout.tv_usec = 0; |
406 | |
356 | |
407 | pollret = select (maxfd + 1, |
357 | pollret = select (maxfd + 1, |
408 | &tmp_read, &tmp_write, 0, |
358 | &tmp_read, 0, 0, |
409 | &timeout); |
359 | &timeout); |
410 | |
360 | |
411 | if (pollret == -1) |
361 | if (pollret == -1) |
412 | { |
362 | { |
413 | LOG (llevError, "select failed: %s\n", strerror (errno)); |
363 | LOG (llevError, "select failed: %s\n", strerror (errno)); |
… | |
… | |
419 | /* Check for any input on the sockets */ |
369 | /* Check for any input on the sockets */ |
420 | for (sockvec::iterator i = client_sockets.begin (); i != client_sockets.end (); ++i) |
370 | for (sockvec::iterator i = client_sockets.begin (); i != client_sockets.end (); ++i) |
421 | { |
371 | { |
422 | client_socket *s = *i; |
372 | client_socket *s = *i; |
423 | player *pl = s->pl; |
373 | player *pl = s->pl; |
424 | |
|
|
425 | //TODO: writing should be independent of tick |
|
|
426 | if (FD_ISSET (s->fd, &tmp_write)) |
|
|
427 | { |
|
|
428 | s->can_write = 1; |
|
|
429 | write_socket_buffer (s); |
|
|
430 | } |
|
|
431 | |
374 | |
432 | //TODO: disassociate handleclient from socket readin |
375 | //TODO: disassociate handleclient from socket readin |
433 | if (s->inbuf_len || FD_ISSET (s->fd, &tmp_read)) |
376 | if (s->inbuf_len || FD_ISSET (s->fd, &tmp_read)) |
434 | HandleClient (s, pl); |
377 | HandleClient (s, pl); |
435 | |
378 | |