コード例 #1
0
ファイル: server.c プロジェクト: friederschueler/pvpgn
static int server_listen(void)
{
	t_addr		* curr_laddr;
	t_addr_data	laddr_data;
	int		sock;

	if (!(server_listen_addrs=addrlist_create(prefs_get_servaddrs(),INADDR_ANY,D2CS_SERVER_PORT))) {
		eventlog(eventlog_level_error,__FUNCTION__,"error create listening address list");
		return -1;
	}
	BEGIN_LIST_TRAVERSE_DATA(server_listen_addrs,curr_laddr)
	{
		sock=net_listen(addr_get_ip(curr_laddr),addr_get_port(curr_laddr),PSOCK_SOCK_STREAM);
		if (sock<0) {
			eventlog(eventlog_level_error,__FUNCTION__,"error listen socket");
			return -1;
		}

		if (psock_ctl(sock,PSOCK_NONBLOCK)<0) {
			eventlog(eventlog_level_error,__FUNCTION__,"error set listen socket in non-blocking mode");
		}

		laddr_data.i = sock;
		addr_set_data(curr_laddr,laddr_data);

		if (fdwatch_add_fd(sock, fdwatch_type_read, d2cs_server_handle_accept, curr_laddr)<0) {
		    eventlog(eventlog_level_error,__FUNCTION__,"error adding socket %d to fdwatch pool (max sockets?)",sock);
		    psock_close(sock);
		    return -1;
		}

		eventlog(eventlog_level_info,__FUNCTION__,"listen on %s", addr_num_to_addr_str(addr_get_ip(curr_laddr),addr_get_port(curr_laddr)));
	}
コード例 #2
0
ファイル: trans.cpp プロジェクト: AleXoundOS/pvpgn
	extern int trans_net(unsigned int clientaddr, unsigned int *addr, unsigned short *port)
	{
		t_elem const *curr;
		t_trans	 *entry;
		char	 temp1[32];
		char         temp2[32];
		char         temp3[32];
		char	 temp4[32];

#ifdef DEBUG_TRANS
		eventlog(eventlog_level_debug, __FUNCTION__, "checking %s for client %s ...",
			addr_num_to_addr_str(*addr, *port),
			addr_num_to_ip_str(clientaddr));
#endif

		if (trans_head) {
			LIST_TRAVERSE_CONST(trans_head, curr)
			{
				if (!(entry = (t_trans*)elem_get_data(curr))) {
					eventlog(eventlog_level_error, __FUNCTION__, "found NULL entry in list");
					continue;
				}

#ifdef DEBUG_TRANS
				eventlog(eventlog_level_debug, __FUNCTION__, "against entry -> %s output %s network %s",
					addr_get_addr_str(entry->input, temp1, sizeof(temp1)),
					addr_get_addr_str(entry->output, temp2, sizeof(temp2)),
					netaddr_get_addr_str(entry->network, temp3, sizeof(temp3)));
#endif
				if (addr_get_ip(entry->input) != *addr || addr_get_port(entry->input) != *port) {
#ifdef DEBUG_TRANS
					eventlog(eventlog_level_debug, __FUNCTION__, "entry does match input address");
#endif
					continue;
				}
				if (netaddr_contains_addr_num(entry->network, clientaddr) == 0) {
#ifdef DEBUG_TRANS
					eventlog(eventlog_level_debug, __FUNCTION__, "client is not in the correct network");
#endif
					continue;
				}
#ifdef DEBUG_TRANS
				eventlog(eventlog_level_debug, __FUNCTION__, "%s translated to %s",
					addr_num_to_addr_str(*addr, *port),
					addr_get_addr_str(entry->output, temp4, sizeof(temp4)));
#endif
				*addr = addr_get_ip(entry->output);
				*port = addr_get_port(entry->output);
				return 1; /* match found in list */
			}
		}
#ifdef DEBUG_TRANS
		eventlog(eventlog_level_debug, __FUNCTION__, "no match found for %s (not translated)",
			addr_num_to_addr_str(*addr, *port));
#endif
		return 0; /* no match found in list */
	}
コード例 #3
0
ファイル: zip_addr.c プロジェクト: zhiyuan2007/anyhost
int
addr_compare(const addr_t *src, const addr_t *dst)
{
    char ip1[MAX_IP_STR_LEN];
    char ip2[MAX_IP_STR_LEN];
    int ret;

    addr_get_ip(src, ip1);
    addr_get_ip(dst, ip2);

    if (strcmp(ip1, ip2) == 0)
        ret = true;
    else
        ret = false;

    return ret;
}
コード例 #4
0
ファイル: zip_addr.c プロジェクト: zhiyuan2007/anyhost
bool
addr_is_loopback(const addr_t *addr)
{
    static const char *IPV4_LOOPBACK = "127.0.0.1";
    static const char *IPV6_LOOPBACK = "0:0:0:0:0:0:0:1";
    static const char *IPV6_LOOPBACK_SIMPLE = "::1";
    char ip[MAX_IP_STR_LEN];
    addr_get_ip(addr, ip);
    if (addr_get_type(addr) == ADDR_IPV4)
        return strcmp(ip, IPV4_LOOPBACK) == 0;
    else
        return strcmp(ip, IPV6_LOOPBACK) == 0 || strcmp(ip, IPV6_LOOPBACK_SIMPLE) == 0;
}
コード例 #5
0
ファイル: server.c プロジェクト: Danteoriginal/bnetd
static int server_listen(void)
{
	t_addr		* curr_laddr;
	t_addr_data	laddr_data;
	int		sock;

	if (!(server_listen_addrs=addrlist_create(prefs_get_servaddrs(),INADDR_ANY,D2CS_SERVER_PORT))) {
		log_error("error create listening address list");
		return -1;
	}
	BEGIN_LIST_TRAVERSE_DATA(server_listen_addrs,curr_laddr)
	{
		sock=net_listen(addr_get_ip(curr_laddr),addr_get_port(curr_laddr),PSOCK_SOCK_STREAM);
		if (sock<0) {
			log_error("error listen socket");
			return -1;
		} 
		log_info("listen on %s", addr_num_to_addr_str(addr_get_ip(curr_laddr),addr_get_port(curr_laddr)));
		if (psock_ctl(sock,PSOCK_NONBLOCK)<0) {
			log_error("error set listen socket in non-blocking mode");
		}
		laddr_data.p=(void *)sock;
		addr_set_data(curr_laddr,laddr_data);
	}
コード例 #6
0
ファイル: realm.c プロジェクト: BackupTheBerlios/pvpgn
t_list * realmlist_load(char const * filename)
{
    FILE *          fp;
    unsigned int    line;
    unsigned int    pos;
    unsigned int    len;
    t_addr *        raddr;
    char *          temp, *temp2;
    char *          buff;
    char *          name;
    char *          desc;
    t_realm *       realm;
    t_list *        list_head = NULL;
    
    if (!filename)
    {
        eventlog(eventlog_level_error,__FUNCTION__,"got NULL filename");
        return NULL;
    }
    
    if (!(fp = fopen(filename,"r")))
    {
        eventlog(eventlog_level_error,__FUNCTION__,"could not open realm file \"%s\" for reading (fopen: %s)",filename,pstrerror(errno));
        return NULL;
    }
    
    list_head = list_create();

    for (line=1; (buff = file_get_line(fp)); line++)
    {
        for (pos=0; buff[pos]=='\t' || buff[pos]==' '; pos++);
        if (buff[pos]=='\0' || buff[pos]=='#')
        {
            continue;
        }
        if ((temp = strrchr(buff,'#')))
        {
	    unsigned int endpos;
	    
            *temp = '\0';
	    len = strlen(buff)+1;
            for (endpos=len-1;  buff[endpos]=='\t' || buff[endpos]==' '; endpos--);
            buff[endpos+1] = '\0';
        }
        
	/* skip any separators */
	for (temp = buff; *temp && (*temp == ' ' || *temp == '\t');temp++);
	if (*temp != '"') {
	    eventlog(eventlog_level_error,__FUNCTION__,"malformed line %u in file \"%s\" (no realmname)",line,filename);
	    continue;
	}
	
	temp2 = temp + 1;
	/* find the next " */
	for (temp = temp2; *temp && *temp != '"';temp++);
	if (*temp != '"' || temp == temp2) {
	    eventlog(eventlog_level_error,__FUNCTION__,"malformed line %u in file \"%s\" (no realmname)",line,filename);
	    continue;
	}
	
	/* save the realmname */
	*temp = '\0';
        name = xstrdup(temp2);
	
	/* eventlog(eventlog_level_trace, __FUNCTION__,"found realmname: %s",name); */

	/* skip any separators */
	for(temp = temp + 1; *temp && (*temp == '\t' || *temp == ' ');temp++);
	
	if (*temp == '"') { /* we have realm description */
	    temp2 = temp + 1;
	    /* find the next " */
	    for(temp = temp2;*temp && *temp != '"';temp++);
	    if (*temp != '"' || temp == temp2) {
		eventlog(eventlog_level_error,__FUNCTION__,"malformed line %u in file \"%s\" (no valid description)",line,filename);
		xfree(name);
		continue;
	    }
	    
	    /* save the description */
	    *temp = '\0';
    	    desc = xstrdup(temp2);
	    
	    /* eventlog(eventlog_level_trace, __FUNCTION__,"found realm desc: %s",desc); */

	    /* skip any separators */
	    for(temp = temp + 1; *temp && (*temp == ' ' || *temp == '\t');temp++);
	} else desc = xstrdup("\0");

	temp2 = temp;
	/* find out where address ends */
	for(temp = temp2 + 1; *temp && *temp != ' ' && *temp != '\t';temp++);

	if (*temp) *temp++ = '\0'; /* if is not the end of the file, end addr and move forward */

	/* eventlog(eventlog_level_trace, __FUNCTION__,"found realm ip: %s",temp2); */

	if (!(raddr = addr_create_str(temp2,0,BNETD_REALM_PORT))) /* 0 means "this computer" */ {
	    eventlog(eventlog_level_error,__FUNCTION__,"invalid address value for field 3 on line %u in file \"%s\"",line,filename);
	    xfree(name);
	    xfree(desc);
	    continue;
	}
	
	if (!(realm = realm_create(name,desc,addr_get_ip(raddr),addr_get_port(raddr))))
	{
	    eventlog(eventlog_level_error,__FUNCTION__,"could not create realm");
	    addr_destroy(raddr);
	    xfree(name);
	    xfree(desc);
	    continue;
	}

	addr_destroy(raddr);
	xfree(name);
	xfree(desc);
	
	list_prepend_data(list_head,realm);
    }
    file_get_line(NULL); // clear file_get_line buffer
    if (fclose(fp)<0)
	eventlog(eventlog_level_error,__FUNCTION__,"could not close realm file \"%s\" after reading (fclose: %s)",filename,pstrerror(errno));
    return list_head;
}
コード例 #7
0
ファイル: tracker.cpp プロジェクト: DizKragnet/pvpgn
extern int tracker_send_report(t_addrlist const * laddrs)
{
    t_addr const *     addrl;
    t_elem const *     currl;
    t_addr const *     addrt;
    t_elem const *     currt;
    t_trackpacket      packet;
    struct utsname     utsbuf;
    struct sockaddr_in tempaddr;
    t_laddr_info *     laddr_info;
    char               tempa[64];
    char               tempb[64];

    if (addrlist_get_length(track_servers)>0)
    {
        std::memset(&packet,0,sizeof(packet));
	bn_short_nset(&packet.packet_version,(unsigned short)TRACK_VERSION);
	/* packet.port is set below */
	bn_int_nset(&packet.flags, 0);
	std::strncpy((char *)packet.server_location,
		prefs_get_location(),
		sizeof(packet.server_location));
	bn_byte_set(&packet.server_location[sizeof(packet.server_location)-1],'\0');
	std::strncpy((char *)packet.software,
		PVPGN_SOFTWARE,
		sizeof(packet.software));
	bn_byte_set(&packet.software[sizeof(packet.software)-1],'\0');
	std::strncpy((char *)packet.version,
		PVPGN_VERSION,
		sizeof(packet.version));
	bn_byte_set(&packet.version[sizeof(packet.version)-1],'\0');
	std::strncpy((char *)packet.server_desc,
		prefs_get_description(),
		sizeof(packet.server_desc));
	bn_byte_set(&packet.server_desc[sizeof(packet.server_desc)-1],'\0');
	std::strncpy((char *)packet.server_url,
		prefs_get_url(),
		sizeof(packet.server_url));
	bn_byte_set(&packet.server_url[sizeof(packet.server_url)-1],'\0');
	std::strncpy((char *)packet.contact_name,
		prefs_get_contact_name(),
		sizeof(packet.contact_name));
	bn_byte_set(&packet.contact_name[sizeof(packet.contact_name)-1],'\0');
	std::strncpy((char *)packet.contact_email,
		prefs_get_contact_email(),
		sizeof(packet.contact_email));
	bn_byte_set(&packet.contact_email[sizeof(packet.contact_email)-1],'\0');
	bn_int_nset(&packet.users,connlist_login_get_length());
	bn_int_nset(&packet.channels,channellist_get_length());
	bn_int_nset(&packet.games,gamelist_get_length());
	bn_int_nset(&packet.uptime,server_get_uptime());
	bn_int_nset(&packet.total_logins,connlist_total_logins());
	bn_int_nset(&packet.total_games,gamelist_total_games());

	if (uname(&utsbuf)<0)
	{
	    eventlog(eventlog_level_warn,__FUNCTION__,"could not get platform info (uname: %s)",pstrerror(errno));
	    std::strncpy((char *)packet.platform,"",sizeof(packet.platform));
	}
	else
	{
	    std::strncpy((char *)packet.platform,
		    utsbuf.sysname,
		    sizeof(packet.platform));
	    bn_byte_set(&packet.platform[sizeof(packet.platform)-1],'\0');
	}

	LIST_TRAVERSE_CONST(laddrs,currl)
	{
	    addrl = (t_addr*)elem_get_data(currl);

	    if (!(laddr_info = (t_laddr_info*)addr_get_data(addrl).p))
	    {
		eventlog(eventlog_level_error,__FUNCTION__,"address data is NULL");
		continue;
	    }
	    if (laddr_info->type!=laddr_type_bnet)
		continue; /* don't report IRC, telnet, and other non-game ports */

	    bn_short_nset(&packet.port,addr_get_port(addrl));

	    LIST_TRAVERSE_CONST(track_servers,currt)
	    {
		addrt = (t_addr*)elem_get_data(currt);

		std::memset(&tempaddr,0,sizeof(tempaddr));
		tempaddr.sin_family = PSOCK_AF_INET;
		tempaddr.sin_port = htons(addr_get_port(addrt));
		tempaddr.sin_addr.s_addr = htonl(addr_get_ip(addrt));

		if (!addr_get_addr_str(addrl,tempa,sizeof(tempa)))
		    std::strcpy(tempa,"x.x.x.x:x");
		if (!addr_get_addr_str(addrt,tempb,sizeof(tempb)))
		    std::strcpy(tempa,"x.x.x.x:x");
		/* eventlog(eventlog_level_debug,__FUNCTION__,"sending tracking info from %s to %s",tempa,tempb); */

		if (psock_sendto(laddr_info->usocket,&packet,sizeof(packet),0,(struct sockaddr *)&tempaddr,(psock_t_socklen)sizeof(tempaddr))<0)
		    eventlog(eventlog_level_warn,__FUNCTION__,"could not send tracking information from %s to %s (psock_sendto: %s)",tempa,tempb,pstrerror(errno));
	    }
コード例 #8
0
ファイル: dbserver.c プロジェクト: DizKragnet/pvpgn
/* FIXME: No it doesn't!  pcAddress is not ever referenced in this
 * function.
 * CreepLord: Fixed much better way (will accept dns hostnames)
 */
int dbs_server_init(void)
{
	int sd;
	struct sockaddr_in sinInterface;
	int val;
	t_addr	* servaddr;
		
	dbs_server_connection_list=list_create();

	if (d2dbs_d2ladder_init()==-1)
	{
		eventlog(eventlog_level_error,__FUNCTION__,"d2ladder_init() failed");
		return -1;
	}

	if (cl_init(DEFAULT_HASHTBL_LEN, DEFAULT_GS_MAX)==-1)
	{
		eventlog(eventlog_level_error,__FUNCTION__,"cl_init() failed");
		return -1;
	}

	if (psock_init()<0)
	{
		eventlog(eventlog_level_error,__FUNCTION__,"psock_init() failed");
		return -1;
	}
	
	sd = psock_socket(PSOCK_PF_INET, PSOCK_SOCK_STREAM, PSOCK_IPPROTO_TCP);
	if (sd==-1)
	{
		eventlog(eventlog_level_error,__FUNCTION__,"psock_socket() failed : %s",strerror(psock_errno()));
		return -1;
	}

	val = 1;
	if (psock_setsockopt(sd, PSOCK_SOL_SOCKET, PSOCK_SO_REUSEADDR, &val, sizeof(val)) < 0)
	{
		eventlog(eventlog_level_error,__FUNCTION__,"psock_setsockopt() failed : %s",strerror(psock_errno()));
	}

        if (!(servaddr=addr_create_str(d2dbs_prefs_get_servaddrs(),INADDR_ANY,DEFAULT_LISTEN_PORT)))
	{
		eventlog(eventlog_level_error,__FUNCTION__,"could not get servaddr");
		return -1;
	}
	
	sinInterface.sin_family = PSOCK_AF_INET;
	sinInterface.sin_addr.s_addr = htonl(addr_get_ip(servaddr));
	sinInterface.sin_port = htons(addr_get_port(servaddr));
	if (psock_bind(sd, (struct sockaddr*)&sinInterface, (psock_t_socklen)sizeof(struct sockaddr_in)) < 0)
	{
		eventlog(eventlog_level_error,__FUNCTION__,"psock_bind() failed : %s",strerror(psock_errno()));
		return -1;
	}
	if (psock_listen(sd, LISTEN_QUEUE) < 0)
	{
		eventlog(eventlog_level_error,__FUNCTION__,"psock_listen() failed : %s",strerror(psock_errno()));
		return -1;
	}
	addr_destroy(servaddr);
	return sd;
}
コード例 #9
0
ファイル: realm.c プロジェクト: cooljeanius/bnetd
extern int realmlist_create(char const * filename)
{
    FILE *          fp;
    unsigned int    line;
    unsigned int    pos;
    unsigned int    len;
    t_addr *        raddr;
    char *          temp;
    char *          buff;
    char *          name;
    char *          desc;
    char *          addr;
    t_realm *       realm;

    if (!filename)
    {
        eventlog(eventlog_level_error,"realmlist_create","got NULL filename");
        return -1;
    }

    if (!(realmlist_head = list_create()))
    {
        eventlog(eventlog_level_error,"realmlist_create","could not create list");
        return -1;
    }

    if (!(fp = fopen(filename,"r")))
    {
        eventlog(eventlog_level_error,"realmlist_create","could not open realm file \"%s\" for reading (fopen: %s)",filename,strerror(errno));
	list_destroy(realmlist_head);
	realmlist_head = NULL;
        return -1;
    }

    for (line=1; (buff = file_get_line(fp)); line++)
    {
        for (pos=0; buff[pos]=='\t' || buff[pos]==' '; pos++);
        if (buff[pos]=='\0' || buff[pos]=='#')
        {
            free(buff);
            continue;
        }
        if ((temp = strrchr(buff,'#')))
        {
	    unsigned int endpos;

            *temp = '\0';
	    len = strlen(buff)+1;
            for (endpos=len-1;  buff[endpos]=='\t' || buff[endpos]==' '; endpos--);
            buff[endpos+1] = '\0';
        }
        len = strlen(buff)+1;

        if (!(name = malloc(len)))
        {
            eventlog(eventlog_level_error,"realmlist_create","could not allocate memory for name");
            free(buff);
            continue;
        }
        if (!(desc = malloc(len)))
        {
            eventlog(eventlog_level_error,"realmlist_create","could not allocate memory for desc");
            free(name);
            free(buff);
            continue;
        }
        if (!(addr = malloc(len)))
        {
            eventlog(eventlog_level_error,"realmlist_create","could not allocate memory for desc");
            free(desc);
            free(name);
            free(buff);
            continue;
        }

	if (sscanf(buff," \"%[^\"]\" \"%[^\"]\" %s",name,desc,addr)!=3)
	{
	    if (sscanf(buff," \"%[^\"]\" \"\" %s",name,addr)==2)
		desc[0] = '\0';
	    else
	    {
		eventlog(eventlog_level_error,"realmlist_create","malformed line %u in file \"%s\"",line,filename);
		free(addr);
		free(desc);
         	free(name);
		free(buff);
		continue;
	    }
	}

	free(buff);

	if (!(raddr = addr_create_str(addr,0,BNETD_REALM_PORT))) /* 0 means "this computer" */
	{
	    eventlog(eventlog_level_error,"realmlist_create","invalid address value for field 3 on line %u in file \"%s\"",line,filename);
	    free(addr);
	    free(desc);
	    free(name);
	    continue;
	}

	free(addr);

	if (!(realm = realm_create(name,desc,addr_get_ip(raddr),addr_get_port(raddr))))
	{
	    eventlog(eventlog_level_error,"realmlist_create","could not create realm");
	    addr_destroy(raddr);
	    free(desc);
	    free(name);
	    continue;
	}

	addr_destroy(raddr);
        free(desc);
	free(name);

	if (list_prepend_data(realmlist_head,realm)<0)
	{
	    eventlog(eventlog_level_error,"realmlist_create","could not prepend realm");
	    realm_destroy(realm);
	    continue;
	}
    }
    if (fclose(fp)<0)
	eventlog(eventlog_level_error,"realmlist_create","could not close realm file \"%s\" after reading (fclose: %s)",filename,strerror(errno));
    return 0;
}
コード例 #10
0
ファイル: zipper.c プロジェクト: zhiyuan2007/anyhost
static void
handle_dns_query(const uint8_t *raw_data,
                 uint16_t data_len,
                 socket_t *client_socket,
                 const addr_t *client_addr,
                 void *arg)
{
    //header is 12 octets, wire name is 1 octets,
    //class is 2 octets, type is 2 octets
    if (data_len < 12 + 4 + 1)
    {
        log_warning(QUERY_LOG, "get invalid query package\n");
        return;
    }

    if (dns_header_get_opt(raw_data) != QUERY_STAND)
    {
        log_warning(QUERY_LOG, "get non-query package\n");
        return;
    }

    zipper_t *zipper = (zipper_t *)arg;

    query_session_t *session = memorypool_alloc_node(zipper->query_session_pool_);
    if (session == NULL)
    {
        log_warning(QUERY_LOG, "no memory left to handle more query\n");
        return;
    }

    memcpy(session->query_raw_data_, raw_data, data_len);
    session->query_data_len_ = data_len;
    session->zipper_ = zipper;
    session->client_socket_ = *client_socket;
    session->client_addr_ = *client_addr;

    char ip_addr_str[MAX_IP_STR_LEN];
    addr_get_ip(client_addr, ip_addr_str);
    log_debug(QUERY_LOG, "get query from ip [%s]\n", ip_addr_str);

    session->location_info_ = ipstore_get_location_use_int(zipper->ip_store_,
                                                 addr_get_v4_addr(client_addr));
    if (!session->location_info_)
    {
        log_warning(QUERY_LOG, "get ip failed\n");
        goto BAD_QUERY;
    }

    buffer_t buf;
    buffer_create_from(&buf, (void *)(raw_data + 12), data_len - 12 - 4);
    session->query_wire_name_ = wire_name_from_wire(&buf);
    if (session->query_wire_name_)
    {
        buffer_t name_buf;
        char str_name[MAX_DOMAIN_NAME_LEN] = {0};
        buffer_create_from(&name_buf, str_name, MAX_DOMAIN_NAME_LEN);
        wire_name_to_text(session->query_wire_name_, &name_buf); 
        log_debug(QUERY_LOG, "handle query name [%s]\n", str_name);
                                                
        char view_name[MAX_VIEW_NAME_LEN];
        rule_store_get_view(zipper->rule_store_, session->query_wire_name_,
                                                 session->location_info_, view_name);
        query_named_with_view(view_name, session); 
        wire_name_delete(session->query_wire_name_);
    }
    else
    {
        wire_name_delete(session->query_wire_name_);
        log_warning(QUERY_LOG, "get invalid query name\n");
        goto BAD_QUERY;
    }
    return;

BAD_QUERY:
    memorypool_free_node(zipper->query_session_pool_, session);
}
コード例 #11
0
ファイル: gametrans.c プロジェクト: cooljeanius/bnetd
extern void gametrans_net(unsigned int vaddr, unsigned short vport, unsigned int laddr, unsigned short lport, unsigned int * addr, unsigned short * port)
{
  const t_elem *curr;
  t_gametrans *entry;
#ifdef DEBUGGAMETRANS
  char temp1[32];
  char temp2[32];
  char temp3[32];
  char temp4[32];
#endif

#ifdef DEBUGGAMETRANS
  eventlog(eventlog_level_debug,"gametrans_net","checking client %s (viewer on %s connected to %s)...",
	   addr_num_to_addr_str(*addr,*port),
	   addr_num_to_addr_str(vaddr,vport),
	   addr_num_to_addr_str(laddr,lport));
#else
  (void)vport;
#endif
  if (gametrans_head)
  {
    LIST_TRAVERSE_CONST(gametrans_head,curr)
    {
      if (!(entry = elem_get_data(curr)))
      {
	eventlog(eventlog_level_error,"gametrans_net","found NULL entry in list");
	continue;
      }

#ifdef DEBUGGAMETRANS
      eventlog(eventlog_level_debug,"gametrans_net","against entry viewerint=%s client=%s output=%s viewerex=%s",
	       addr_get_addr_str(entry->viewer,temp1,sizeof(temp1)),
	       addr_get_addr_str(entry->client,temp2,sizeof(temp2)),
	       addr_get_addr_str(entry->output,temp3,sizeof(temp3)),
	       netaddr_get_addr_str(entry->exclude,temp4,sizeof(temp4)));
#endif

      if (addr_get_ip(entry->viewer)!=0 && addr_get_ip(entry->viewer)!=laddr)
      {
#ifdef DEBUGGAMETRANS
	eventlog(eventlog_level_debug,"gametrans_net","viewer is not on right interface IP");
#endif
	continue;
      }
      if (addr_get_port(entry->viewer)!=0 && addr_get_port(entry->viewer)!=lport)
      {
#ifdef DEBUGGAMETRANS
	eventlog(eventlog_level_debug,"gametrans_net","view is not on right interface port");
#endif
	continue;
      }

      if (addr_get_ip(entry->client)!=0 && addr_get_ip(entry->client)!=*addr)
      {
#ifdef DEBUGGAMETRANS
	eventlog(eventlog_level_debug,"gametrans_net","client is not on the right IP");
#endif
	continue;
      }
      if (addr_get_port(entry->client)!=0 && addr_get_port(entry->client)!=*port)
      {
#ifdef DEBUGGAMETRANS
	eventlog(eventlog_level_debug,"gametrans_net","client is not on the right port");
#endif
	continue;
      }

      if (netaddr_contains_addr_num(entry->exclude,vaddr)==1)
      {
#ifdef DEBUGGAMETRANS
	eventlog(eventlog_level_debug,"gametrans_net","viewer is in the excluded network");
#endif
	continue;
      }

      *addr = addr_get_ip(entry->output);
      *port = addr_get_port(entry->output);

#ifdef DEBUGGAMETRANS
      eventlog(eventlog_level_debug,"gametrans_net","did translation");
#endif

      return;
    }
  }
}
コード例 #12
0
ファイル: server.c プロジェクト: cooljeanius/bnetd
static int sd_accept(t_addr const * curr_laddr, t_laddr_info const * laddr_info, int ssocket, int usocket)
{
    char               tempa[32];
    int                csocket;
    struct sockaddr_in caddr;
    psock_t_socklen    caddr_len;
    unsigned int       raddr;
    unsigned short     rport;

    if (!addr_get_addr_str(curr_laddr,tempa,sizeof(tempa)))
	strcpy(tempa,"x.x.x.x:x");

    /* accept the connection */
    memset(&caddr,0,sizeof(caddr)); /* not sure if this is needed... modern systems are ok anyway */
    caddr_len = sizeof(caddr);
    if ((csocket = psock_accept(ssocket,(struct sockaddr *)&caddr,&caddr_len))<0)
    {
	/* BSD, POSIX error for aborted connections, SYSV often uses EAGAIN or EPROTO */
	if (
#ifdef PSOCK_EWOULDBLOCK
	    psock_errno()==PSOCK_EWOULDBLOCK ||
#endif
#ifdef PSOCK_ECONNABORTED
	    psock_errno()==PSOCK_ECONNABORTED ||
#endif
#ifdef PSOCK_EPROTO
	    psock_errno()==PSOCK_EPROTO ||
#endif
	    0)
	    eventlog(eventlog_level_error,"sd_accept","client aborted connection on %s (psock_accept: %s)",tempa,strerror(psock_errno()));
	else /* EAGAIN can mean out of resources _or_ connection aborted :( */
	    if (
#ifdef PSOCK_EINTR
		psock_errno()!=PSOCK_EINTR &&
#endif
		1)
		eventlog(eventlog_level_error,"sd_accept","could not accept new connection on %s (psock_accept: %s)",tempa,strerror(psock_errno()));
	return -1;
    }

#ifdef HAVE_POLL
    if (csocket>=BNETD_MAX_SOCKETS) /* This check is a bit too strict (csocket is probably
                                     * greater than the number of connections) but this makes
                                     * life easier later.
                                     */
    {
	eventlog(eventlog_level_error,"sd_accept","csocket is beyond range allowed by BNETD_MAX_SOCKETS for poll() (%d>=%d)",csocket,BNETD_MAX_SOCKETS);
	psock_close(csocket);
	return -1;
    }
#else
# ifdef FD_SETSIZE
    if (csocket>=FD_SETSIZE) /* fd_set size is determined at compile time */
    {
	eventlog(eventlog_level_error,"sd_accept","csocket is beyond range allowed by FD_SETSIZE for select() (%d>=%d)",csocket,FD_SETSIZE);
	psock_close(csocket);
	return -1;
    }
# endif
#endif
    if (ipbanlist_check(inet_ntoa(caddr.sin_addr))!=0)
    {
	eventlog(eventlog_level_info,"sd_accept","[%d] connection from banned address %s denied (closing connection)",csocket,inet_ntoa(caddr.sin_addr));
	psock_close(csocket);
	return -1;
    }

    eventlog(eventlog_level_info,"sd_accept","[%d] accepted connection from %s on %s",csocket,addr_num_to_addr_str(ntohl(caddr.sin_addr.s_addr),ntohs(caddr.sin_port)),tempa);

    if (prefs_get_use_keepalive())
    {
	int val=1;

	if (psock_setsockopt(csocket,PSOCK_SOL_SOCKET,PSOCK_SO_KEEPALIVE,&val,(psock_t_socklen)sizeof(val))<0)
	    eventlog(eventlog_level_error,"sd_accept","[%d] could not set socket option SO_KEEPALIVE (psock_setsockopt: %s)",csocket,strerror(psock_errno()));
	/* not a fatal error */
    }

    {
	struct sockaddr_in rsaddr;
	psock_t_socklen    rlen;

	memset(&rsaddr,0,sizeof(rsaddr)); /* not sure if this is needed... modern systems are ok anyway */
	rlen = sizeof(rsaddr);
	if (psock_getsockname(csocket,(struct sockaddr *)&rsaddr,&rlen)<0)
	{
	    eventlog(eventlog_level_error,"sd_accept","[%d] unable to determine real local port (psock_getsockname: %s)",csocket,strerror(psock_errno()));
	    /* not a fatal error */
	    raddr = addr_get_ip(curr_laddr);
	    rport = addr_get_port(curr_laddr);
	}
	else
	{
	    if (rsaddr.sin_family!=PSOCK_AF_INET)
	    {
		eventlog(eventlog_level_error,"sd_accept","local address returned with bad address family %d",(int)rsaddr.sin_family);
		/* not a fatal error */
		raddr = addr_get_ip(curr_laddr);
		rport = addr_get_port(curr_laddr);
	    }
	    else
	    {
		raddr = ntohl(rsaddr.sin_addr.s_addr);
		rport = ntohs(rsaddr.sin_port);
	    }
	}
    }

    if (psock_ctl(csocket,PSOCK_NONBLOCK)<0)
    {
	eventlog(eventlog_level_error,"sd_accept","[%d] could not set TCP socket to non-blocking mode (closing connection) (psock_ctl: %s)",csocket,strerror(psock_errno()));
	psock_close(csocket);
	return -1;
    }

    {
	t_connection * c;

	if (!(c = conn_create(csocket,usocket,raddr,rport,addr_get_ip(curr_laddr),addr_get_port(curr_laddr),ntohl(caddr.sin_addr.s_addr),ntohs(caddr.sin_port))))
	{
	    eventlog(eventlog_level_error,"sd_accept","[%d] unable to create new connection (closing connection)",csocket);
	    psock_close(csocket);
	    return -1;
	}

	eventlog(eventlog_level_debug,"sd_accept","[%d] client connected to a %s listening address",csocket,laddr_type_get_str(laddr_info->type));
	switch (laddr_info->type)
	{
	case laddr_type_irc:
	    conn_set_class(c,conn_class_irc);
	    conn_set_state(c,conn_state_connected);
	    break;
	case laddr_type_telnet:
	    conn_set_class(c,conn_class_telnet);
	    conn_set_state(c,conn_state_connected);
	    break;
	case laddr_type_bnet:
	default:
	    /* We have to wait for an initial "magic" byte on bnet connections to
             * tell us exactly what connection class we are dealing with.
             */
	    break;
	}
    }

    return 0;
}