… | |
… | |
275 | next_packet: |
275 | next_packet: |
276 | ; |
276 | ; |
277 | } |
277 | } |
278 | } |
278 | } |
279 | |
279 | |
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 |
280 | void |
320 | flush_sockets (void) |
281 | flush_sockets (void) |
321 | { |
282 | { |
322 | player *pl; |
283 | 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) |
284 | if ((*i)->status != Ns_Dead) |
326 | Socket_Flush (pl->socket); |
285 | (*i)->flush (); |
327 | } |
286 | } |
328 | |
287 | |
329 | /** |
288 | /** |
330 | * This checks the sockets for input, does the right thing. |
289 | * This checks the sockets for input, does the right thing. |
331 | * |
290 | * |
… | |
… | |
335 | */ |
294 | */ |
336 | void |
295 | void |
337 | doeric_server (void) |
296 | doeric_server (void) |
338 | { |
297 | { |
339 | int i, pollret; |
298 | int i, pollret; |
340 | fd_set tmp_read, tmp_write; |
299 | fd_set tmp_read; |
341 | struct sockaddr_in addr; |
300 | struct sockaddr_in addr; |
342 | socklen_t addrlen = sizeof (struct sockaddr); |
301 | socklen_t addrlen = sizeof (struct sockaddr); |
343 | player *pl, *next; |
302 | player *pl, *next; |
344 | int maxfd = 0; |
303 | int maxfd = 0; |
345 | |
304 | |
… | |
… | |
373 | |
332 | |
374 | pl = npl; |
333 | pl = npl; |
375 | } |
334 | } |
376 | |
335 | |
377 | FD_ZERO (&tmp_read); |
336 | FD_ZERO (&tmp_read); |
378 | FD_ZERO (&tmp_write); |
|
|
379 | |
337 | |
380 | for (sockvec::iterator i = client_sockets.begin (); i != client_sockets.end (); ) |
338 | for (sockvec::iterator i = client_sockets.begin (); i != client_sockets.end (); ) |
381 | { |
339 | { |
382 | client_socket *s = *i; |
340 | client_socket *s = *i; |
383 | |
341 | |
… | |
… | |
390 | { |
348 | { |
391 | if (s->fd > maxfd) maxfd = s->fd; |
349 | if (s->fd > maxfd) maxfd = s->fd; |
392 | |
350 | |
393 | FD_SET (s->fd, &tmp_read); |
351 | FD_SET (s->fd, &tmp_read); |
394 | |
352 | |
395 | if (s->outputbuffer.len) |
|
|
396 | FD_SET (s->fd, &tmp_write); |
|
|
397 | |
|
|
398 | ++i; |
353 | ++i; |
399 | } |
354 | } |
400 | } |
355 | } |
401 | |
356 | |
402 | struct timeval timeout; |
357 | struct timeval timeout; |
403 | |
358 | |
404 | timeout.tv_sec = 0; |
359 | timeout.tv_sec = 0; |
405 | timeout.tv_usec = 0; |
360 | timeout.tv_usec = 0; |
406 | |
361 | |
407 | pollret = select (maxfd + 1, |
362 | pollret = select (maxfd + 1, |
408 | &tmp_read, &tmp_write, 0, |
363 | &tmp_read, 0, 0, |
409 | &timeout); |
364 | &timeout); |
410 | |
365 | |
411 | if (pollret == -1) |
366 | if (pollret == -1) |
412 | { |
367 | { |
413 | LOG (llevError, "select failed: %s\n", strerror (errno)); |
368 | LOG (llevError, "select failed: %s\n", strerror (errno)); |
… | |
… | |
419 | /* Check for any input on the sockets */ |
374 | /* Check for any input on the sockets */ |
420 | for (sockvec::iterator i = client_sockets.begin (); i != client_sockets.end (); ++i) |
375 | for (sockvec::iterator i = client_sockets.begin (); i != client_sockets.end (); ++i) |
421 | { |
376 | { |
422 | client_socket *s = *i; |
377 | client_socket *s = *i; |
423 | player *pl = s->pl; |
378 | 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 | |
379 | |
432 | //TODO: disassociate handleclient from socket readin |
380 | //TODO: disassociate handleclient from socket readin |
433 | if (s->inbuf_len || FD_ISSET (s->fd, &tmp_read)) |
381 | if (s->inbuf_len || FD_ISSET (s->fd, &tmp_read)) |
434 | HandleClient (s, pl); |
382 | HandleClient (s, pl); |
435 | |
383 | |