#include "copyright.h"
#include "config.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/file.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <signal.h>
#include <errno.h>
#include "mudconf.h"
#include "db.h"
#include "file_c.h"
#include "externs.h"
#include "interface.h"
#include "flags.h"
#include "powers.h"
#include "alloc.h"
#include "command.h"
#include "attrs.h"
#include "rbtree.h"
#include "logcache.h"
#include "debug.h"
Include dependency graph for bsd.c:
Go to the source code of this file.
Defines | |
#define | get_tod(x) { (x)->tv_sec = time(NULL); (x)->tv_usec = 0; } |
Functions | |
void | mux_release_socket () |
void | make_nonblocking (int s) |
void | accept_new_connection (int, short, void *) |
DESC * | initializesock (int, struct sockaddr_storage *, int) |
DESC * | new_connection (int) |
int | process_input (DESC *) |
int | desc_cmp (void *vleft, void *vright, void *token) |
void | desc_addhash (DESC *d) |
void | desc_delhash (DESC *d) |
void | bind_descriptor (DESC *d) |
void | release_descriptor (DESC *d) |
void | shutdown_services () |
int | bind_mux_socket (int port) |
int | eradicate_broken_fd (int fd) |
void | accept_client_input (int fd, short event, void *arg) |
void | bsd_write_callback (struct bufferevent *bufev, void *arg) |
void | bsd_read_callback (struct bufferevent *bufev, void *arg) |
void | bsd_error_callback (struct bufferevent *bufev, short whut, void *arg) |
void | runqueues (int fd, short event, void *arg) |
void | shovechars (int port) |
void | shutdownsock (DESC *d, int reason) |
void | make_blocking (int s) |
void | flush_sockets () |
void | close_sockets (int emergency, char *message) |
void | emergency_shutdown (void) |
Variables | |
event | listen_sock_ev |
int | mux_bound_socket = -1 |
int | ndescriptors = 0 |
DESC * | descriptor_list = NULL |
timeval | queue_slice = { 0, 0 } |
event | queue_ev |
timeval last_slice | current_time |
static const char * | disc_reasons [] |
static const char * | disc_messages [] |
int | fcache_conn_c |
void accept_client_input | ( | int | fd, | |
short | event, | |||
void * | arg | |||
) |
Definition at line 294 of file bsd.c.
References bind_descriptor(), DARK, descriptor_data::descriptor, DS_AUTODARK, descriptor_data::flags, Flags, descriptor_data::player, process_input(), release_descriptor(), and s_Flags.
Referenced by initializesock(), load_restart_db(), and load_restart_db_xdr().
00295 { 00296 DESC *connection = (DESC *) arg; 00297 if(connection->descriptor != fd) return; 00298 00299 //dprintk("callback on fd %d DESC %p", fd, arg); 00300 00301 if(connection->flags & DS_AUTODARK) { 00302 connection->flags &= ~DS_AUTODARK; 00303 s_Flags(connection->player, Flags(connection->player) & ~DARK); 00304 } 00305 bind_descriptor(connection); 00306 process_input(connection); 00307 //dprintk("finish on fd %d DESC %p", fd, arg); 00308 release_descriptor(connection); 00309 }
void accept_new_connection | ( | int | , | |
short | , | |||
void * | ||||
) |
Definition at line 388 of file bsd.c.
References statedata::access_list, FC_CONN_SITE, fcache_rawdump(), H_FORBIDDEN, initializesock(), log_error(), LOG_NET, LOG_SECURITY, mudstate, and site_check().
Referenced by shovechars().
00389 { 00390 int newsock, addr_len, len; 00391 char *buff, *buff1; 00392 DESC *d; 00393 struct sockaddr_storage addr; 00394 char addrname[1024]; 00395 char addrport[32]; 00396 00397 00398 addr_len = sizeof(struct sockaddr); 00399 00400 newsock = 00401 accept(sock, (struct sockaddr *) &addr, (unsigned int *) &addr_len); 00402 if(newsock < 0) 00403 return; 00404 00405 getnameinfo((struct sockaddr *) &addr, addr_len, 00406 addrname, 1024, addrport, 32, 00407 NI_NUMERICHOST | NI_NUMERICSERV); 00408 00409 if(site_check(&addr, addr_len, mudstate.access_list) == H_FORBIDDEN) { 00410 log_error(LOG_NET | LOG_SECURITY, "NET", "SITE", 00411 "Connection refused from %s %s.", addrname, addrport); 00412 00413 fcache_rawdump(newsock, FC_CONN_SITE); 00414 shutdown(newsock, 2); 00415 close(newsock); 00416 errno = 0; 00417 d = NULL; 00418 } else { 00419 log_error(LOG_NET, "NET", "CONN", "Connection opened from %s %s.", 00420 addrname, addrport); 00421 00422 d = initializesock(newsock, &addr, addr_len); 00423 } 00424 return; 00425 }
void bind_descriptor | ( | DESC * | d | ) |
Definition at line 131 of file bsd.c.
References descriptor_data::refcount.
Referenced by accept_client_input(), desc_addhash(), initializesock(), and process_input().
00131 { 00132 d->refcount++; 00133 //dprintk("bound desciptor %p, refcount now %d", d, d->refcount); 00134 }
int bind_mux_socket | ( | int | port | ) |
Definition at line 213 of file bsd.c.
References dprintk, and log_perror().
Referenced by shovechars().
00214 { 00215 int s, opt; 00216 struct sockaddr_in server; 00217 00218 s = socket(AF_INET, SOCK_STREAM, 0); 00219 if(s < 0) { 00220 log_perror("NET", "FAIL", NULL, "creating master socket"); 00221 exit(3); 00222 } 00223 opt = 1; 00224 if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, 00225 sizeof(opt)) < 0) { 00226 log_perror("NET", "FAIL", NULL, "setsockopt"); 00227 } 00228 00229 if(fcntl(s, F_SETFD, FD_CLOEXEC) < 0) { 00230 log_perror("LOGCACHE", "FAIL", NULL, 00231 "fcntl(fd, F_SETFD, FD_CLOEXEC)"); 00232 close(s); 00233 abort(); 00234 } 00235 server.sin_family = AF_INET; 00236 server.sin_addr.s_addr = INADDR_ANY; 00237 server.sin_port = htons(port); 00238 if(bind(s, (struct sockaddr *) &server, sizeof(server))) { 00239 log_perror("NET", "FAIL", NULL, "bind"); 00240 close(s); 00241 exit(4); 00242 } 00243 dprintk("connection socket raised and bound, %d", s); 00244 listen(s, 25); 00245 return s; 00246 }
void bsd_error_callback | ( | struct bufferevent * | bufev, | |
short | whut, | |||
void * | arg | |||
) |
Definition at line 319 of file bsd.c.
References dprintk.
Referenced by initializesock(), load_restart_db(), and load_restart_db_xdr().
00320 { 00321 dprintk("error %d", whut); 00322 }
void bsd_read_callback | ( | struct bufferevent * | bufev, | |
void * | arg | |||
) |
Definition at line 315 of file bsd.c.
Referenced by initializesock(), load_restart_db(), and load_restart_db_xdr().
void bsd_write_callback | ( | struct bufferevent * | bufev, | |
void * | arg | |||
) |
Definition at line 311 of file bsd.c.
Referenced by initializesock(), load_restart_db(), and load_restart_db_xdr().
void close_sockets | ( | int | emergency, | |
char * | message | |||
) |
Definition at line 716 of file bsd.c.
References DESC_SAFEITER_ALL, descriptor_data::descriptor, dnschild_kill(), dprintk, listen_sock_ev, log_perror(), mux_bound_socket, descriptor_data::outstanding_dnschild_query, queue_string(), queue_write(), R_GOING_DOWN, shutdownsock(), descriptor_data::sock_buff, and descriptor_data::sock_ev.
Referenced by emergency_shutdown(), and main().
00717 { 00718 DESC *d, *dnext; 00719 00720 DESC_SAFEITER_ALL(d, dnext) { 00721 if(emergency) { 00722 write(d->descriptor, message, strlen(message)); 00723 if(shutdown(d->descriptor, 2) < 0) 00724 log_perror("NET", "FAIL", NULL, "shutdown"); 00725 dprintk("shutting down fd %d", d->descriptor); 00726 dprintk("output evbuffer misalign: %d, totallen: %d, off: %d", 00727 d->sock_buff->output->misalign, 00728 d->sock_buff->output->totallen, 00729 d->sock_buff->output->off); 00730 fsync(d->descriptor); 00731 if(d->outstanding_dnschild_query) 00732 dnschild_kill(d->outstanding_dnschild_query); 00733 d->outstanding_dnschild_query = NULL; 00734 event_loop(EVLOOP_ONCE); 00735 event_del(&d->sock_ev); 00736 bufferevent_free(d->sock_buff); 00737 close(d->descriptor); 00738 } else { 00739 queue_string(d, message); 00740 queue_write(d, "\r\n", 2); 00741 shutdownsock(d, R_GOING_DOWN); 00742 } 00743 } 00744 close(mux_bound_socket); 00745 event_del(&listen_sock_ev); 00746 }
void desc_addhash | ( | DESC * | d | ) |
Definition at line 65 of file bsd.c.
References bind_descriptor(), statedata::desctree, descriptor_data::hashnext, mudstate, descriptor_data::player, rb_find(), and rb_insert().
Referenced by announce_connect(), load_restart_db(), and load_restart_db_xdr().
00066 { 00067 DESC *hdesc; 00068 00069 bind_descriptor(d); 00070 00071 hdesc = (DESC *) rb_find(mudstate.desctree, (void *) d->player); 00072 /* if(!hdesc) { 00073 dprintk("Creating new list root for '%s'(#%d) at %p.", 00074 Name(d->player), d->player, d); 00075 } else { 00076 dprintk("Adding descriptor %p to list root at %p for '%s'(#%d).", 00077 d, hdesc, Name(d->player), d->player); 00078 } 00079 */ 00080 d->hashnext = hdesc; 00081 rb_insert(mudstate.desctree, (void *) d->player, d); 00082 }
int desc_cmp | ( | void * | vleft, | |
void * | vright, | |||
void * | token | |||
) |
void desc_delhash | ( | DESC * | d | ) |
Definition at line 84 of file bsd.c.
References statedata::desctree, descriptor_data::hashnext, log_text(), mudstate, descriptor_data::player, rb_delete(), rb_find(), rb_insert(), and release_descriptor().
Referenced by shutdownsock().
00085 { 00086 char buffer2[4096]; 00087 DESC *hdesc = NULL; 00088 char buffer[4096]; 00089 /* dprintk("removing descriptor %p from list root %p for '%s'(#%d).", d, hdesc, Name(d->player), d->player); */ 00090 hdesc = (DESC *) rb_find(mudstate.desctree, (void *) d->player); 00091 /* dprintk("removing descriptor %p from list root %p for '%s'(#%d).", d, hdesc, Name(d->player), d->player); */ 00092 00093 00094 if(!hdesc) { 00095 snprintf(buffer, 4096, 00096 "desc_delhash: unable to find player(%d)'s descriptors from hashtable.\n", 00097 d->player); 00098 log_text(buffer); 00099 release_descriptor(d); 00100 return; 00101 } 00102 00103 /* dprintk("hdesc: %p, d: %p, hdesc->hashnext: %p, d->hashnext: %p", hdesc, 00104 d, hdesc->hashnext, d->hashnext); 00105 */ 00106 if(hdesc == d && hdesc->hashnext) { 00107 /* dprintk("updating %d to use hashroot %p", d->player, d->hashnext);*/ 00108 rb_insert(mudstate.desctree, (void *) d->player, d->hashnext); 00109 d->hashnext = NULL; 00110 release_descriptor(d); 00111 return; 00112 } else if(hdesc == d) { 00113 /* dprintk("removing %d table", d->player); */ 00114 rb_delete(mudstate.desctree, (void *) d->player); 00115 release_descriptor(d); 00116 return; 00117 } 00118 00119 while(hdesc->hashnext != NULL) { 00120 if(hdesc->hashnext == d) { 00121 hdesc->hashnext = d->hashnext; 00122 break; 00123 } 00124 hdesc = hdesc->hashnext; 00125 } 00126 d->hashnext = NULL; 00127 release_descriptor(d); 00128 return; 00129 }
void emergency_shutdown | ( | void | ) |
Definition at line 748 of file bsd.c.
References close_sockets().
Referenced by do_shutdown().
00748 { 00749 close_sockets(1, (char *) "Going down - Bye.\n"); 00750 }
int eradicate_broken_fd | ( | int | fd | ) |
Definition at line 261 of file bsd.c.
References DESC_SAFEITER_ALL, log_error(), LOG_PROBLEMS, mux_bound_socket, R_SOCKDIED, and shutdownsock().
Referenced by signal_PIPE().
00262 { 00263 struct stat statbuf; 00264 DESC *d, *dtemp; 00265 00266 DESC_SAFEITER_ALL(d, dtemp) { 00267 if((fd && d->descriptor == fd) || 00268 (!fd && fstat(d->descriptor, &statbuf) < 0)) { 00269 /* An invalid player connection... eject, eject, eject. */ 00270 log_error(LOG_PROBLEMS, "ERR", "EBADF", 00271 "Broken descriptor %d for player #%d", d->descriptor, 00272 d->player); 00273 close(d->descriptor); 00274 shutdownsock(d, R_SOCKDIED); 00275 } 00276 } 00277 if(mux_bound_socket != -1 && fstat(mux_bound_socket, &statbuf) < 0) { 00278 log_error(LOG_PROBLEMS, "ERR", "EBADF", 00279 "Broken descriptor on our main port."); 00280 mux_bound_socket = -1; 00281 return -1; 00282 } 00283 #ifdef IPV6_SUPPORT 00284 if(mux_bound_socket6 != -1 && fstat(mux_bound_socket6, &statbuf) < 0) { 00285 log_error(LOG_PROBLEMS, "ERR", "EBADF", 00286 "Broken descriptor for our ipv6 port."); 00287 mux_bound_socket6 = -1; 00288 return -1; 00289 } 00290 #endif 00291 return 0; 00292 }
void flush_sockets | ( | ) |
Definition at line 692 of file bsd.c.
References descriptor_data::chokes, DESC_SAFEITER_ALL, descriptor_data::descriptor, and descriptor_data::sock_buff.
Referenced by raw_broadcast(), and shutdown_services().
00693 { 00694 int null = 0; 00695 DESC *d, *dnext; 00696 DESC_SAFEITER_ALL(d, dnext) { 00697 if(d->chokes) { 00698 #if TCP_CORK 00699 setsockopt(d->descriptor, IPPROTO_TCP, TCP_CORK, &null, 00700 sizeof(null)); 00701 #else 00702 #ifdef TCP_NOPUSH 00703 setsockopt(d->descriptor, IPPROTO_TCP, TCP_NOPUSH, &null, 00704 sizeof(null)); 00705 #endif 00706 #endif 00707 d->chokes = 0; 00708 } 00709 if(d->sock_buff && EVBUFFER_LENGTH(d->sock_buff->output)) { 00710 evbuffer_write(d->sock_buff->output, d->descriptor); 00711 } 00712 fsync(d->descriptor); 00713 } 00714 }
DESC * initializesock | ( | int | , | |
struct sockaddr_storage * | , | |||
int | ||||
) |
Definition at line 548 of file bsd.c.
References accept_client_input(), statedata::access_list, descriptor_data::addr, bind_descriptor(), bsd_error_callback(), bsd_read_callback(), bsd_write_callback(), descriptor_data::chokes, confdata::cmd_quota_max, descriptor_data::command_count, descriptor_data::connected_at, descriptor_data::descriptor, descriptor_list, dnschild_request(), descriptor_data::doing, descriptor_data::flags, descriptor_data::hashnext, descriptor_data::host_info, descriptor_data::hudkey, confdata::idle_timeout, descriptor_data::input, descriptor_data::input_lost, descriptor_data::input_size, descriptor_data::input_tail, descriptor_data::input_tot, descriptor_data::last_time, make_nonblocking(), mudconf, mudstate, ndescriptors, descriptor_data::next, statedata::now, descriptor_data::output_lost, descriptor_data::output_prefix, descriptor_data::output_size, descriptor_data::output_suffix, descriptor_data::output_tot, descriptor_data::outstanding_dnschild_query, descriptor_data::player, descriptor_data::prev, descriptor_data::program_data, descriptor_data::quota, descriptor_data::retries_left, confdata::retry_limit, descriptor_data::saddr, descriptor_data::saddr_len, site_check(), descriptor_data::sock_buff, descriptor_data::sock_ev, statedata::suspect_list, descriptor_data::timeout, descriptor_data::username, and welcome_user().
Referenced by accept_new_connection().
00549 { 00550 DESC *d; 00551 00552 ndescriptors++; 00553 d = malloc(sizeof(DESC)); 00554 memset(d, 0, sizeof(DESC)); 00555 00556 d->descriptor = s; 00557 d->flags = 0; 00558 d->connected_at = mudstate.now; 00559 d->retries_left = mudconf.retry_limit; 00560 d->command_count = 0; 00561 d->timeout = mudconf.idle_timeout; 00562 d->host_info = 00563 site_check(saddr, saddr_len, mudstate.access_list) | 00564 site_check(saddr, saddr_len, mudstate.suspect_list); 00565 d->player = 0; 00566 d->chokes = 0; 00567 d->addr[0] = '\0'; 00568 d->doing[0] = '\0'; 00569 d->hudkey[0] = '\0'; 00570 d->username[0] = '\0'; 00571 make_nonblocking(s); 00572 d->output_prefix = NULL; 00573 d->output_suffix = NULL; 00574 d->output_size = 0; 00575 d->output_tot = 0; 00576 d->output_lost = 0; 00577 d->input_size = 0; 00578 d->input_tot = 0; 00579 d->input_lost = 0; 00580 memset(d->input, 0, sizeof(d->input)); 00581 d->input_tail = 0; 00582 d->quota = mudconf.cmd_quota_max; 00583 d->program_data = NULL; 00584 d->last_time = 0; 00585 memcpy(&d->saddr, saddr, saddr_len); 00586 d->saddr_len = saddr_len; 00587 00588 d->hashnext = NULL; 00589 getnameinfo((struct sockaddr *) saddr, saddr_len, d->addr, 00590 sizeof(d->addr), NULL, 0, NI_NUMERICHOST); 00591 00592 if (descriptor_list) 00593 descriptor_list->prev = d; 00594 d->next = descriptor_list; 00595 d->prev = NULL; 00596 descriptor_list = d; 00597 00598 d->outstanding_dnschild_query = dnschild_request(d); 00599 00600 d->sock_buff = bufferevent_new(d->descriptor, bsd_write_callback, 00601 bsd_read_callback, bsd_error_callback, 00602 NULL); 00603 bufferevent_disable(d->sock_buff, EV_READ); 00604 bufferevent_enable(d->sock_buff, EV_WRITE); 00605 event_set(&d->sock_ev, d->descriptor, EV_READ | EV_PERSIST, 00606 accept_client_input, d); 00607 event_add(&d->sock_ev, NULL); 00608 bind_descriptor(d); 00609 welcome_user(d); 00610 return d; 00611 }
void make_blocking | ( | int | s | ) |
Definition at line 530 of file bsd.c.
References log_perror().
00531 { 00532 long flags = 0; 00533 00534 if(fcntl(s, F_GETFL, &flags) < 0) { 00535 log_perror("NET", "FAIL", "make_blocking", "fcntl F_GETFL"); 00536 } 00537 flags &= ~O_NONBLOCK; 00538 if(fcntl(s, F_SETFL, flags) < 0) { 00539 log_perror("NET", "FAIL", "make_blocking", "fcntl F_SETFL"); 00540 } 00541 flags = 0; 00542 if(setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &flags, sizeof(flags)) < 0) { 00543 log_perror("NET", "FAIL", "make_blocking", "setsockopt NDELAY"); 00544 } 00545 }
void make_nonblocking | ( | int | s | ) |
Definition at line 513 of file bsd.c.
References log_perror().
Referenced by initializesock().
00514 { 00515 long flags = 0; 00516 00517 if(fcntl(s, F_GETFL, &flags) < 0) { 00518 log_perror("NET", "FAIL", "make_nonblocking", "fcntl F_GETFL"); 00519 } 00520 flags |= O_NONBLOCK; 00521 if(fcntl(s, F_SETFL, flags) < 0) { 00522 log_perror("NET", "FAIL", "make_nonblocking", "fcntl F_SETFL"); 00523 } 00524 flags = 1; 00525 if(setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &flags, sizeof(flags)) < 0) { 00526 log_perror("NET", "FAIL", "make_nonblocking", "setsockopt NDELAY"); 00527 } 00528 }
void mux_release_socket | ( | ) |
Definition at line 248 of file bsd.c.
References dprintk, listen_sock_ev, and mux_bound_socket.
Referenced by signal_BUS(), signal_SEGV(), and signal_USR1().
00249 { 00250 dprintk("releasing mux main socket."); 00251 event_del(&listen_sock_ev); 00252 close(mux_bound_socket); 00253 mux_bound_socket = -1; 00254 #ifdef IPV6_SUPPORT 00255 event_del(&listen6_sock_ev); 00256 close(mux_bound_socket6); 00257 mux_bound_socket6 = -1; 00258 #endif 00259 }
DESC* new_connection | ( | int | ) |
int process_input | ( | DESC * | ) |
Definition at line 613 of file bsd.c.
References bind_descriptor(), descriptor_data::descriptor, do_unauth_command(), dprintk, DS_CONNECTED, DS_DEAD, descriptor_data::flags, descriptor_data::input, descriptor_data::input_tail, LBUF_SIZE, Name(), descriptor_data::player, queue_string(), R_QUIT, R_SOCKDIED, run_command(), shutdownsock(), and Wizard.
Referenced by accept_client_input().
00614 { 00615 char buf[LBUF_SIZE]; 00616 int got, in, iter; 00617 char current; 00618 00619 if(d->flags & DS_DEAD) { 00620 dprintk("Bailing on process_input %p %d %s %d", 00621 d, d->descriptor, (d->player?Name(d->player):""), d->player); 00622 return 0; 00623 } 00624 00625 memset(buf, 0, sizeof(buf)); 00626 00627 got = in = read(d->descriptor, buf, (sizeof buf - 1)); 00628 00629 if(got <= 0) { 00630 if(errno == EINTR) 00631 return 1; 00632 else if(errno == EAGAIN) 00633 return 1; 00634 else { 00635 dprintk("error %s (errno %d) read on fd %d descriptor %p %s(%d)\n", 00636 strerror(errno), errno, 00637 d->descriptor, d, (d->player?Name(d->player):""), d->player); 00638 shutdownsock(d, R_SOCKDIED); 00639 return 1; 00640 } 00641 } 00642 00643 bind_descriptor(d); 00644 00645 if(Wizard(d->player) && strncmp("@segfault", buf, 9) == 0) { 00646 queue_string(d, "@segfault failed. (check logfile for reason.)\n"); 00647 *(char *) 0xDEADBEEF = '9'; 00648 } 00649 00650 for(iter = 0; iter < got; iter++) { 00651 current = buf[iter]; 00652 if(current == '\n') { 00653 if(d->flags & DS_CONNECTED) { 00654 //dprintk("authed as %s running command '%s' refcount %d descriptor %p fd %d", Name(d->player), d->input, d->refcount, d, d->descriptor); 00655 run_command(d, (char *)d->input); 00656 } else { 00657 //dprintk("unauth running command '%s' refcount %d descriptor %p fd %d", d->input, d->refcount, 00658 //d, d->descriptor); 00659 if(!do_unauth_command(d, d->input)) { 00660 dprintk("logout on %p fd %d, bailing.", d, d->descriptor); 00661 shutdownsock(d, R_QUIT); 00662 break; 00663 } 00664 } 00665 memset(d->input, 0, sizeof(d->input)); 00666 d->input_tail = 0; 00667 if(d->flags & DS_DEAD) break; 00668 } else if(current == '\b' || current == 0x7f) { 00669 if(current == 127) { 00670 queue_string(d, "\b \b"); 00671 } else { 00672 queue_string(d, " \b"); 00673 } 00674 if(d->input_tail > 0) { 00675 d->input[--d->input_tail] = '\0'; 00676 } 00677 d->input_size--; 00678 } else if(isascii(current) && isprint(current)) { 00679 if(d->input_tail >= sizeof(d->input)) { 00680 continue; 00681 } 00682 d->input[d->input_tail++] = current; 00683 d->input_size++; 00684 } 00685 } 00686 //dprintk("finished %p fd %d", d, d->descriptor); 00687 00688 release_descriptor(d); 00689 return 1; 00690 }
void release_descriptor | ( | DESC * | d | ) |
Definition at line 136 of file bsd.c.
References clearstrings(), DESC_ITER_PLAYER, descriptor_data::descriptor, descriptor_list, dprintk, free_lbuf, freeqs(), MAX_GLOBAL_REGS, ndescriptors, descriptor_data::next, descriptor_data::player, descriptor_data::prev, descriptor_data::program_data, descriptor_data::refcount, descriptor_data::sock_buff, descriptor_data::sock_ev, and prog_data::wait_regs.
Referenced by accept_client_input(), desc_delhash(), and shutdownsock().
00136 { 00137 d->refcount--; 00138 //dprintk("descriptor %p released, refcount now %d", d, d->refcount); 00139 if(d->refcount == 0) { 00140 dprintk("%p destructing", d); 00141 freeqs(d); 00142 00143 if(d->program_data != NULL) { 00144 int num = 0; 00145 DESC *dtemp; 00146 DESC_ITER_PLAYER(d->player, dtemp) num++; 00147 00148 if(num == 0) { 00149 for(int i = 0; i < MAX_GLOBAL_REGS; i++) { 00150 free_lbuf(d->program_data->wait_regs[i]); 00151 } 00152 free(d->program_data); 00153 } 00154 } 00155 clearstrings(d); 00156 if(d->descriptor) { 00157 fsync(d->descriptor); 00158 event_del(&d->sock_ev); 00159 shutdown(d->descriptor, 2); 00160 close(d->descriptor); 00161 } 00162 d->descriptor = 0; 00163 if(d->sock_buff) 00164 bufferevent_free(d->sock_buff); 00165 d->sock_buff = NULL; 00166 00167 /* if(descriptor_list == d) { 00168 descriptor_list = d->next; 00169 } else { 00170 if(!descriptor_list) { 00171 dprintk("Oh sweet jesus, we have major braindamage."); 00172 descriptor_list = d->next; 00173 } else { 00174 DESC *dtemp = descriptor_list; 00175 while(dtemp->next != NULL) { 00176 if(dtemp->next == d) { 00177 dtemp->next = d->next; 00178 break; 00179 } else { 00180 dtemp = dtemp->next; 00181 } 00182 } 00183 } 00184 } 00185 00186 d->next = NULL; 00187 */ 00188 if (d->prev) 00189 d->prev->next = d->next; 00190 else /* d was the first one! */ 00191 descriptor_list = d->next; 00192 if (d->next) 00193 d->next->prev = d->prev; 00194 00195 ndescriptors--; 00196 free(d); 00197 } 00198 }
void runqueues | ( | int | fd, | |
short | event, | |||
void * | arg | |||
) |
Definition at line 334 of file bsd.c.
References current_time, do_top(), dprintk, get_tod, mudconf, confdata::queue_chunk, queue_ev, queue_slice, and update_quotas().
Referenced by shovechars().
00335 { 00336 pid_t pchild; 00337 int status = 0; 00338 event_add(&queue_ev, &queue_slice); 00339 get_tod(¤t_time); 00340 last_slice = update_quotas(last_slice, current_time); 00341 pchild = waitpid(-1, &status, WNOHANG); 00342 if(pchild > 0) { 00343 dprintk("unexpected child %d exited with exit status %d.", pchild, 00344 WEXITSTATUS(status)); 00345 } 00346 if(mudconf.queue_chunk) 00347 do_top(mudconf.queue_chunk); 00348 }
void shovechars | ( | int | port | ) |
Definition at line 350 of file bsd.c.
References accept_new_connection(), bind_mux_socket(), current_time, dprintk, get_tod, listen_sock_ev, mudconf, mux_bound_socket, queue_ev, queue_slice, runqueues(), and confdata::timeslice.
Referenced by main().
00351 { 00352 unsigned int flags; 00353 queue_slice.tv_sec = 0; 00354 queue_slice.tv_usec = mudconf.timeslice * 1000; 00355 00356 dprintk("shovechars starting, sock is %d.", mux_bound_socket); 00357 #ifdef IPV6_SUPPORT 00358 dprintk("shovechars starting, ipv6 sock is %d.", mux_bound_socket); 00359 #endif 00360 00361 if(mux_bound_socket < 0) { 00362 mux_bound_socket = bind_mux_socket(port); 00363 } 00364 event_set(&listen_sock_ev, mux_bound_socket, EV_READ | EV_PERSIST, 00365 accept_new_connection, NULL); 00366 event_add(&listen_sock_ev, NULL); 00367 00368 flags = fcntl(2, F_GETFD, 0); 00369 dprintk("stderr is %x", flags); 00370 #ifdef IPV6_SUPPORT 00371 if(mux_bound_socket6 < 0) { 00372 mux_bound_socket6 = bind_mux6_socket(port); 00373 } 00374 event_set(&listen6_sock_ev, mux_bound_socket6, EV_READ | EV_PERSIST, 00375 accept_new6_connection, NULL); 00376 event_add(&listen6_sock_ev, NULL); 00377 #endif 00378 00379 evtimer_set(&queue_ev, runqueues, NULL); 00380 evtimer_add(&queue_ev, &queue_slice); 00381 00382 get_tod(&last_slice); 00383 get_tod(¤t_time); 00384 00385 event_dispatch(); 00386 }
void shutdown_services | ( | ) |
Definition at line 200 of file bsd.c.
References dnschild_destruct(), flush_sockets(), logcache_destruct(), and sqlchild_destruct().
Referenced by do_restart().
00201 { 00202 dnschild_destruct(); 00203 flush_sockets(); 00204 #ifdef SQL_SUPPORT 00205 sqlchild_destruct(); 00206 #endif 00207 #ifdef ARBITRARY_LOGFILES 00208 logcache_destruct(); 00209 #endif 00210 event_loopexit(NULL); 00211 }
void shutdownsock | ( | DESC * | d, | |
int | reason | |||
) |
Definition at line 460 of file bsd.c.
References descriptor_data::addr, announce_disconnect(), descriptor_data::command_count, descriptor_data::connected_at, decode_flags(), desc_delhash(), descriptor_data::descriptor, disc_messages, disc_reasons, dnschild_kill(), DS_CONNECTED, DS_DEAD, FC_QUIT, fcache_dump(), descriptor_data::flags, Flags, Flags2, Flags3, GOD, Location, LOG_ACCOUNTING, log_error(), LOG_LOGIN, LOG_NET, mudstate, Name(), statedata::now, descriptor_data::outstanding_dnschild_query, Pennies(), descriptor_data::player, R_LOGOUT, and release_descriptor().
Referenced by boot_by_port(), boot_off(), check_connect(), check_idle(), close_sockets(), do_command(), do_unauth_command(), eradicate_broken_fd(), failconn(), load_restart_db(), load_restart_db_xdr(), and process_input().
00461 { 00462 char *buff, *buff2; 00463 time_t now; 00464 int i, num; 00465 DESC *dtemp; 00466 00467 /* dprintk("shutdownsock called on %p %s(#%d) refcount %d", 00468 d, (d->player?Name(d->player):""), d->player, d->refcount); */ 00469 00470 if(d->flags & DS_CONNECTED) { 00471 if(d->outstanding_dnschild_query) 00472 dnschild_kill(d->outstanding_dnschild_query); 00473 00474 /* 00475 * Do the disconnect stuff if we aren't doing a LOGOUT * * * 00476 * * * * (which keeps the connection open so the player can * 00477 * * connect * * * * to a different character). 00478 */ 00479 00480 if(reason != R_LOGOUT) { 00481 fcache_dump(d, FC_QUIT); 00482 } 00483 00484 log_error(LOG_NET | LOG_LOGIN, "NET", "DISC", 00485 "[%d/%s] Logout by %s(#%d), <Reason: %s>", 00486 d->descriptor, d->addr, Name(d->player), d->player, 00487 disc_reasons[reason]); 00488 00489 /* 00490 * If requested, write an accounting record of the form: * * 00491 * * * * * Plyr# Flags Cmds ConnTime Loc Money [Site] 00492 * <DiscRsn> * * * Name 00493 */ 00494 00495 log_error(LOG_ACCOUNTING, "DIS", "ACCT", 00496 "%d %s %d %d %d %d [%s] <%s> %s", 00497 d->player, decode_flags(GOD, Flags(d->player), 00498 Flags2(d->player), 00499 Flags3(d->player)), 00500 d->command_count, mudstate.now - d->connected_at, 00501 Location(d->player), Pennies(d->player), d->addr, 00502 disc_reasons[reason], Name(d->player)); 00503 00504 announce_disconnect(d->player, d, disc_messages[reason]); 00505 desc_delhash(d); 00506 00507 } 00508 d->flags |= DS_DEAD; 00509 release_descriptor(d); 00510 /* dprintk("shutdown."); */ 00511 }
struct timeval last_slice current_time |
DESC* descriptor_list = NULL |
Definition at line 48 of file bsd.c.
Referenced by dump_restart_db(), dump_restart_db_xdr(), initializesock(), load_restart_db(), load_restart_db_xdr(), network_initialize_socket(), and release_descriptor().
const char* disc_messages[] [static] |
Initial value:
{ "unknown", "quit", "timeout", "boot", "netdeath", "shutdown", "badlogin", "nologins", "logout" }
Definition at line 448 of file bsd.c.
Referenced by shutdownsock().
const char* disc_reasons[] [static] |
Initial value:
{ "Unspecified", "Quit", "Inactivity Timeout", "Booted", "Remote Close or Net Failure", "Game Shutdown", "Login Retry Limit", "Logins Disabled", "Logout (Connection Not Dropped)", "Too Many Connected Players" }
Definition at line 431 of file bsd.c.
Referenced by shutdownsock().
int fcache_conn_c |
struct event listen_sock_ev |
Definition at line 37 of file bsd.c.
Referenced by close_sockets(), mux_release_socket(), and shovechars().
int mux_bound_socket = -1 |
Definition at line 42 of file bsd.c.
Referenced by close_sockets(), eradicate_broken_fd(), mux_release_socket(), and shovechars().
int ndescriptors = 0 |
struct event queue_ev |
struct timeval queue_slice = { 0, 0 } |