Ejemplo n.º 1
0
		/* FIXME: we should save client ipaddr into c->ipaddr after accept */
		static int dbs_verify_ipaddr(char const * addrlist, t_d2dbs_connection * c)
		{
			char			* adlist;
			char			* s, *temp;
			t_elem			* elem;
			t_d2dbs_connection	* tempc;
			unsigned int		valid;
			unsigned int		resolveipaddr;

			adlist = xstrdup(addrlist);
			temp = adlist;
			valid = 0;
			while ((s = strsep(&temp, ","))) {
				host_lookup(s, &resolveipaddr);
				if (resolveipaddr == 0) continue;

				if (c->ipaddr == resolveipaddr) {
					valid = 1;
					break;
				}
			}
			xfree(adlist);
			if (valid) {
				eventlog(eventlog_level_info, __FUNCTION__, "ip address %s is valid", addr_num_to_ip_str(c->ipaddr));
				LIST_TRAVERSE(dbs_server_connection_list, elem)
				{
					if (!(tempc = (t_d2dbs_connection*)elem_get_data(elem))) continue;
					if (tempc != c && tempc->ipaddr == c->ipaddr) {
						eventlog(eventlog_level_info, __FUNCTION__, "destroying previous connection %d", tempc->serverid);
						dbs_server_shutdown_connection(tempc);
						list_remove_elem(dbs_server_connection_list, &elem);
					}
				}
				c->verified = 1;
				return 0;
			}
			else {
Ejemplo n.º 2
0
void dbs_server_loop(int lsocket)
{
	struct sockaddr_in sinRemote;
	int sd ;
	fd_set ReadFDs, WriteFDs, ExceptFDs;
	t_elem * elem;
	t_d2dbs_connection* it;
	BOOL bOK ;
	const char* pcErrorType ;
	struct timeval         tv;
	int highest_fd;
	psock_t_socklen nAddrSize = sizeof(sinRemote);
	
	while (1) {
#ifdef WIN32
		if (g_ServiceStatus<0 && kbhit() && getch()=='q')
			d2dbs_signal_quit_wrapper();
		
		if (g_ServiceStatus == 0) d2dbs_signal_quit_wrapper();
		
		while (g_ServiceStatus == 2) Sleep(1000);
#endif
		if (d2dbs_handle_signal()<0) break;
		dbs_handle_timed_events();
		highest_fd=dbs_server_setup_fdsets(&ReadFDs, &WriteFDs, &ExceptFDs, lsocket);

		tv.tv_sec  = 0;
		tv.tv_usec = SELECT_TIME_OUT;
		switch (psock_select(highest_fd+1, &ReadFDs, &WriteFDs, &ExceptFDs, &tv) ) {
			case -1:
				eventlog(eventlog_level_error,__FUNCTION__,"psock_select() failed : %s",strerror(psock_errno()));
				continue;
			case 0:
				continue;
			default:
				break;
		}

		if (PSOCK_FD_ISSET(lsocket, &ReadFDs)) {
			sd = psock_accept(lsocket, (struct sockaddr*)&sinRemote, &nAddrSize);
			if (sd == -1) {
				eventlog(eventlog_level_error,__FUNCTION__,"psock_accept() failed : %s",strerror(psock_errno()));
				return;
			}
			
			eventlog(eventlog_level_info,__FUNCTION__,"accepted connection from %s:%d , socket %d .",
				inet_ntoa(sinRemote.sin_addr) , ntohs(sinRemote.sin_port), sd);
			eventlog_step(prefs_get_logfile_gs(),eventlog_level_info,__FUNCTION__,"accepted connection from %s:%d , socket %d .",
				inet_ntoa(sinRemote.sin_addr) , ntohs(sinRemote.sin_port), sd);
			setsockopt_keepalive(sd);
			dbs_server_list_add_socket(sd, ntohl(sinRemote.sin_addr.s_addr));
			if (psock_ctl(sd,PSOCK_NONBLOCK)<0) {
				eventlog(eventlog_level_error,__FUNCTION__,"could not set TCP socket [%d] to non-blocking mode (closing connection) (psock_ctl: %s)", sd,strerror(psock_errno()));
				psock_close(sd);
			}
		} else if (PSOCK_FD_ISSET(lsocket, &ExceptFDs)) {
			eventlog(eventlog_level_error,__FUNCTION__,"exception on listening socket");
			/* FIXME: exceptions are not errors with TCP, they are out-of-band data */
			return;
		}
		
		LIST_TRAVERSE(dbs_server_connection_list,elem)
		{
			bOK = TRUE;
			pcErrorType = 0;
			
			if (!(it=elem_get_data(elem))) continue;
			if (PSOCK_FD_ISSET(it->sd, &ExceptFDs)) {
				bOK = FALSE;
				pcErrorType = "General socket error"; /* FIXME: no no no no no */
				PSOCK_FD_CLR(it->sd, &ExceptFDs);
			} else {
				
				if (PSOCK_FD_ISSET(it->sd, &ReadFDs)) {
					bOK = dbs_server_read_data(it);
					pcErrorType = "Read error";
					PSOCK_FD_CLR(it->sd, &ReadFDs);
				}
				
				if (PSOCK_FD_ISSET(it->sd, &WriteFDs)) {
					bOK = dbs_server_write_data(it);
					pcErrorType = "Write error";
					PSOCK_FD_CLR(it->sd, &WriteFDs);
				}
			}
			
			if (!bOK) {
				int	err;
				psock_t_socklen	errlen;
				
				err = 0;
				errlen = sizeof(err);
				if (psock_getsockopt(it->sd, PSOCK_SOL_SOCKET, PSOCK_SO_ERROR, &err, &errlen)==0) {
					if (errlen && err!=0) {
						eventlog(eventlog_level_error,__FUNCTION__,"data socket error : %s",strerror(err));
					}
				}
				dbs_server_shutdown_connection(it);
				list_remove_elem(dbs_server_connection_list,&elem);
			} else {
				if (dbs_packet_handle(it)==-1) {
					eventlog(eventlog_level_error,__FUNCTION__,"dbs_packet_handle() failed");
					dbs_server_shutdown_connection(it);
					list_remove_elem(dbs_server_connection_list,&elem);
				}
			}
		}
	}