📄 server.c
字号:
/* not reached */}void server_check_and_fix_hostname(char const * sname){ int ok = 1; char * tn = (char *)sname; char * sn = (char *)sname; if (!isalnum((int)*sn)) { eventlog(eventlog_level_error,__FUNCTION__,"hostname contains invalid first symbol (must be alphanumeric)"); *tn='a'; } tn++; sn++; for (;*sn!='\0';sn++) { if (isalnum((int)*sn) || *sn=='-' || *sn=='.') { *tn=*sn; tn++; } else ok = 0; } *tn='\0'; if (!ok) eventlog(eventlog_level_error,__FUNCTION__,"hostname contains invalid symbol(s) (must be alphanumeric, '-' or '.') - skipped those symbols");}extern void server_set_hostname(void){ char temp[250]; char const * hn;#ifdef HAVE_GETHOSTBYNAME struct hostent * hp;#endif if (server_hostname) { xfree((void *)server_hostname); /* avoid warning */ server_hostname = NULL; } hn = prefs_get_hostname(); if ((!hn)||(hn[0]=='\0')) { if (gethostname(temp,sizeof(temp))<0) {#ifdef WIN32 sprintf(temp,"localhost");#else eventlog(eventlog_level_error,__FUNCTION__,"could not get hostname: %s",pstrerror(errno)); return;#endif }#ifdef HAVE_GETHOSTBYNAME hp = gethostbyname(temp); if (!hp || !hp->h_name) {#endif server_hostname = xstrdup(temp);#ifdef HAVE_GETHOSTBYNAME } else { int i=0; if (strchr(hp->h_name,'.')) /* Default name is already a FQDN */ server_hostname = xstrdup(hp->h_name); /* ... if not we have to examine the aliases */ while (!server_hostname && hp->h_aliases && hp->h_aliases[i]) { if (strchr(hp->h_aliases[i],'.')) server_hostname = xstrdup(hp->h_aliases[i]); i++; } if (!server_hostname) /* Fall back to default name which might not be a FQDN */ server_hostname = xstrdup(hp->h_name); }#endif } else { server_hostname = xstrdup(hn); } server_check_and_fix_hostname(server_hostname); eventlog(eventlog_level_info,__FUNCTION__,"set hostname to \"%s\"",server_hostname);}extern char const * server_get_hostname(void){ if (!server_hostname) return "(null)"; /* avoid crashes */ else return server_hostname;}extern void server_clear_hostname(void){ if (server_hostname) { xfree((void *)server_hostname); /* avoid warning */ server_hostname = NULL; }}static int handle_accept(void *data, t_fdwatch_type rw){ t_laddr_info *laddr_info = addr_get_data((t_addr *)data).p; return sd_accept((t_addr *)data, laddr_info, laddr_info->ssocket, laddr_info->usocket);}static int handle_udp(void *data, t_fdwatch_type rw){ t_laddr_info *laddr_info = addr_get_data((t_addr *)data).p; return sd_udpinput((t_addr *)data, laddr_info, laddr_info->ssocket, laddr_info->usocket);}static int handle_tcp(void *data, t_fdwatch_type rw){ switch(rw) { case fdwatch_type_read: return sd_tcpinput((t_connection *)data); case fdwatch_type_write: return sd_tcpoutput((t_connection *)data); default: return -1; }}static int _setup_add_addrs(t_addrlist **pladdrs, const char *str, unsigned int defaddr, unsigned short defport, t_laddr_type type){ t_addr * curr_laddr; t_addr_data laddr_data; t_laddr_info * laddr_info; t_elem const * acurr; if (*pladdrs == NULL) { *pladdrs = addrlist_create(str, defaddr, defport); if (*pladdrs == NULL) return -1; } else if (addrlist_append(*pladdrs, str, defaddr, defport)) return -1; /* Mark all these laddrs for being classic Battle.net service */ LIST_TRAVERSE_CONST(*pladdrs,acurr) { curr_laddr = elem_get_data(acurr); if (addr_get_data(curr_laddr).p) continue; laddr_info = xmalloc(sizeof(t_laddr_info)); laddr_info->usocket = -1; laddr_info->ssocket = -1; laddr_info->type = type; laddr_data.p = laddr_info; if (addr_set_data(curr_laddr,laddr_data)<0) { eventlog(eventlog_level_error, __FUNCTION__,"could not set address data"); if (laddr_info->usocket!=-1) { psock_close(laddr_info->usocket); laddr_info->usocket = -1; } if (laddr_info->ssocket!=-1) { psock_close(laddr_info->ssocket); laddr_info->ssocket = -1; } return -1; } } return 0;}static int _set_reuseaddr(int sock){ int val = 1; return psock_setsockopt(sock,PSOCK_SOL_SOCKET,PSOCK_SO_REUSEADDR,&val,(psock_t_socklen)sizeof(int));}static int _bind_socket(int sock, unsigned addr, short port){ struct sockaddr_in saddr; memset(&saddr,0,sizeof(saddr)); saddr.sin_family = PSOCK_AF_INET; saddr.sin_port = htons(port); saddr.sin_addr.s_addr = htonl(addr); return psock_bind(sock,(struct sockaddr *)&saddr,(psock_t_socklen)sizeof(saddr));}static int _setup_listensock(t_addrlist *laddrs){ t_addr * curr_laddr; t_laddr_info * laddr_info; t_elem const * acurr; char tempa[32]; int fidx; LIST_TRAVERSE_CONST(laddrs,acurr) { curr_laddr = elem_get_data(acurr); if (!(laddr_info = addr_get_data(curr_laddr).p)) { eventlog(eventlog_level_error, __FUNCTION__, "NULL address info"); goto err; } if (!addr_get_addr_str(curr_laddr,tempa,sizeof(tempa))) strcpy(tempa,"x.x.x.x:x"); laddr_info->ssocket = psock_socket(PSOCK_PF_INET,PSOCK_SOCK_STREAM,PSOCK_IPPROTO_TCP); if (laddr_info->ssocket<0) { eventlog(eventlog_level_error, __FUNCTION__, "could not create a %s listening socket (psock_socket: %s)",laddr_type_get_str(laddr_info->type),pstrerror(psock_errno())); goto err; } if (_set_reuseaddr(laddr_info->ssocket)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not set option SO_REUSEADDR on %s socket %d (psock_setsockopt: %s)",laddr_type_get_str(laddr_info->type),laddr_info->ssocket,pstrerror(psock_errno())); /* not a fatal error... */ if (_bind_socket(laddr_info->ssocket,addr_get_ip(curr_laddr),addr_get_port(curr_laddr))<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not bind %s socket to address %s TCP (psock_bind: %s)",laddr_type_get_str(laddr_info->type),tempa,pstrerror(psock_errno())); goto errsock; } /* tell socket to listen for connections */ if (psock_listen(laddr_info->ssocket,LISTEN_QUEUE)<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not set %s socket %d to listen (psock_listen: %s)",laddr_type_get_str(laddr_info->type),laddr_info->ssocket,pstrerror(psock_errno())); goto errsock; } if (psock_ctl(laddr_info->ssocket,PSOCK_NONBLOCK)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not set %s TCP listen socket to non-blocking mode (psock_ctl: %s)",laddr_type_get_str(laddr_info->type),pstrerror(psock_errno())); /* index not stored persisently because we dont need to refer to it later */ fidx = fdwatch_add_fd(laddr_info->ssocket, fdwatch_type_read, handle_accept, curr_laddr); if (fidx < 0) { eventlog(eventlog_level_error, __FUNCTION__, "could not add listening socket %d to fdwatch pool (max sockets?)",laddr_info->ssocket); goto errsock; } eventlog(eventlog_level_info,__FUNCTION__,"listening for %s connections on %s TCP",laddr_type_get_str(laddr_info->type),tempa); if (laddr_info->type==laddr_type_bnet) { laddr_info->usocket = psock_socket(PSOCK_PF_INET,PSOCK_SOCK_DGRAM,PSOCK_IPPROTO_UDP); if (laddr_info->usocket<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not create UDP socket (psock_socket: %s)",pstrerror(psock_errno())); goto errfdw; } if (_set_reuseaddr(laddr_info->usocket)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not set option SO_REUSEADDR on %s socket %d (psock_setsockopt: %s)",laddr_type_get_str(laddr_info->type),laddr_info->usocket,pstrerror(psock_errno())); /* not a fatal error... */ if (_bind_socket(laddr_info->usocket,addr_get_ip(curr_laddr),addr_get_port(curr_laddr))<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not bind %s socket to address %s UDP (psock_bind: %s)",laddr_type_get_str(laddr_info->type),tempa,pstrerror(psock_errno())); goto errusock; } if (psock_ctl(laddr_info->usocket,PSOCK_NONBLOCK)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not set %s UDP socket to non-blocking mode (psock_ctl: %s)",laddr_type_get_str(laddr_info->type),pstrerror(psock_errno())); /* index ignored because we never need it after this */ if (fdwatch_add_fd(laddr_info->usocket, fdwatch_type_read, handle_udp, curr_laddr) < 0) { eventlog(eventlog_level_error, __FUNCTION__, "could not add listening socket %d to fdwatch pool (max sockets?)",laddr_info->usocket); goto errusock; } } } return 0;errusock: psock_close(laddr_info->usocket); laddr_info->usocket = -1;errfdw: fdwatch_del_fd(fidx);errsock: psock_close(laddr_info->ssocket); laddr_info->ssocket = -1;err: return -1;}#ifdef DO_POSIXSIGstatic sigset_t block_set;static sigset_t save_set;static int _setup_posixsig(void){ if (sigemptyset(&save_set)<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not initialize signal set (sigemptyset: %s)",pstrerror(errno)); return -1; } if (sigemptyset(&block_set)<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not initialize signal set (sigemptyset: %s)",pstrerror(errno)); return -1; } if (sigaddset(&block_set,SIGINT)<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not add signal to set (sigemptyset: %s)",pstrerror(errno)); return -1; } if (sigaddset(&block_set,SIGHUP)<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not add signal to set (sigemptyset: %s)",pstrerror(errno)); return -1; } if (sigaddset(&block_set,SIGTERM)<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not add signal to set (sigemptyset: %s)",pstrerror(errno)); return -1; } if (sigaddset(&block_set,SIGUSR1)<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not add signal to set (sigemptyset: %s)",pstrerror(errno)); return -1; } if (sigaddset(&block_set,SIGUSR2)<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not add signal to set (sigemptyset: %s)",pstrerror(errno)); return -1; } if (sigaddset(&block_set,SIGALRM)<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not add signal to set (sigemptyset: %s)",pstrerror(errno)); return -1; } { struct sigaction quit_action; struct sigaction restart_action; struct sigaction save_action; struct sigaction pipe_action;#ifdef HAVE_SETITIMER struct sigaction timer_action;#endif struct sigaction forced_quit_action; quit_action.sa_handler = quit_sig_handle; if (sigemptyset(&quit_action.sa_mask)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not initialize signal set (sigemptyset: %s)",pstrerror(errno)); quit_action.sa_flags = SA_RESTART; restart_action.sa_handler = restart_sig_handle; if (sigemptyset(&restart_action.sa_mask)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not initialize signal set (sigemptyset: %s)",pstrerror(errno)); restart_action.sa_flags = SA_RESTART; save_action.sa_handler = save_sig_handle; if (sigemptyset(&save_action.sa_mask)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not initialize signal set (sigemptyset: %s)",pstrerror(errno)); save_action.sa_flags = SA_RESTART; pipe_action.sa_handler = pipe_sig_handle; if (sigemptyset(&pipe_action.sa_mask)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not initialize signal set (sigemptyset: %s)",pstrerror(errno)); pipe_action.sa_flags = SA_RESTART;#ifdef HAVE_SETITIMER timer_action.sa_handler = timer_sig_handle; if (sigemptyset(&timer_action.sa_mask)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not initialize signal set (sigemptyset: %s)",pstrerror(errno)); timer_action.sa_flags = SA_RESTART;#endif /* HAVE_SETITIMER */ forced_quit_action.sa_handler = forced_quit_sig_handle; if (sigemptyset(&forced_quit_action.sa_mask)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not initialize signal set (sigemptyset: %s)",pstrerror(errno)); forced_quit_action.sa_flags = SA_RESTART; if (sigaction(SIGINT,&quit_action,NULL)<0) /* control-c */ eventlog(eventlog_level_error,__FUNCTION__,"could not set SIGINT signal handler (sigaction: %s)",pstrerror(errno)); if (sigaction(SIGHUP,&restart_action,NULL)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not set SIGHUP signal handler (sigaction: %s)",pstrerror(errno)); if (sigaction(SIGTERM,&quit_action,NULL)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not set SIGTERM signal handler (sigaction: %s)",pstrerror(errno)); if (sigaction(SIGUSR1,&save_action,NULL)<0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -