⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 server.c

📁 打魔兽战网的都知道他是什么
💻 C
📖 第 1 页 / 共 4 页
字号:
		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,__FUNCTION__,"[%d] unable to create new connection (closing connection)",csocket);	    psock_close(csocket);	    return -1;	}		if (conn_add_fdwatch(c, handle_tcp) < 0) {	    eventlog(eventlog_level_error,__FUNCTION__,"[%d] unable to add socket to fdwatch pool (max connections?)",csocket);	    conn_set_state(c,conn_state_destroy);	    return -1;	}	eventlog(eventlog_level_debug,__FUNCTION__,"[%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_wol:	    conn_set_class(c,conn_class_wol);	    conn_set_state(c,conn_state_connected);	    break;	case laddr_type_w3route:		conn_set_class(c,conn_class_w3route);		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: 	    {	/* add a timer to close stale connections */		int delay;		t_timer_data data;		data.p = NULL;		delay = prefs_get_initkill_timer();		if (delay) timerlist_add_timer(c,time(NULL)+delay,conn_shutdown,data);	    }	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;}static int sd_udpinput(t_addr * const curr_laddr, t_laddr_info const * laddr_info, int ssocket, int usocket){    int             err;    psock_t_socklen errlen;    t_packet *      upacket;        err = 0;    errlen = sizeof(err);    if (psock_getsockopt(usocket,PSOCK_SOL_SOCKET,PSOCK_SO_ERROR,&err,&errlen)<0)    {        eventlog(eventlog_level_error,__FUNCTION__,"[%d] unable to read socket error (psock_getsockopt: %s)",usocket,pstrerror(psock_errno()));	return -1;    }    if (errlen && err) /* if it was an error, there is no packet to read */    {	eventlog(eventlog_level_error,__FUNCTION__,"[%d] async UDP socket error notification (psock_getsockopt: %s)",usocket,pstrerror(err));	return -1;    }    if (!(upacket = packet_create(packet_class_udp)))    {	eventlog(eventlog_level_error,__FUNCTION__,"could not allocate raw packet for input");	return -1;    }        {	struct sockaddr_in fromaddr;	psock_t_socklen    fromlen;	int                len;		fromlen = sizeof(fromaddr);	if ((len = psock_recvfrom(usocket,packet_get_raw_data_build(upacket,0),MAX_PACKET_SIZE,0,(struct sockaddr *)&fromaddr,&fromlen))<0)	{	    if (#ifdef PSOCK_EINTR		psock_errno()!=PSOCK_EINTR &&#endif#ifdef PSOCK_EAGAIN		psock_errno()!=PSOCK_EAGAIN &&#endif#ifdef PSOCK_EWOULDBLOCK		psock_errno()!=PSOCK_EWOULDBLOCK &&#endif#ifdef PSOCK_ECONNRESET		psock_errno()!=PSOCK_ECONNRESET &&	/* this is a win2k/winxp issue							 * their socket implementation returns this value							 * although it shouldn't							 */#endif		1)		eventlog(eventlog_level_error,__FUNCTION__,"could not recv UDP datagram (psock_recvfrom: %s)",pstrerror(psock_errno()));	    packet_del_ref(upacket);	    return -1;	}		if (fromaddr.sin_family!=PSOCK_AF_INET)	{	    eventlog(eventlog_level_error,__FUNCTION__,"got UDP datagram with bad address family %d",(int)fromaddr.sin_family);	    packet_del_ref(upacket);	    return -1;	}		packet_set_size(upacket,len);		if (hexstrm)	{	    char tempa[32];	    	    if (!addr_get_addr_str(curr_laddr,tempa,sizeof(tempa)))		strcpy(tempa,"x.x.x.x:x");	    fprintf(hexstrm,"%d: recv class=%s[0x%02x] type=%s[0x%04x] from=%s to=%s length=%u\n",		    usocket,		    packet_get_class_str(upacket),(unsigned int)packet_get_class(upacket),		    packet_get_type_str(upacket,packet_dir_from_client),packet_get_type(upacket),		    addr_num_to_addr_str(ntohl(fromaddr.sin_addr.s_addr),ntohs(fromaddr.sin_port)),		    tempa,		    packet_get_size(upacket));	    hexdump(hexstrm,packet_get_raw_data(upacket,0),packet_get_size(upacket));	}		handle_udp_packet(usocket,ntohl(fromaddr.sin_addr.s_addr),ntohs(fromaddr.sin_port),upacket);	packet_del_ref(upacket);    }        return 0;}static int sd_tcpinput(t_connection * c){    unsigned int currsize;    t_packet *   packet;    int		 csocket = conn_get_socket(c);        currsize = conn_get_in_size(c);    if (!conn_get_in_queue(c))    {	switch (conn_get_class(c))	{	case conn_class_init:	    if (!(packet = packet_create(packet_class_init)))	    {		eventlog(eventlog_level_error,__FUNCTION__,"could not allocate init packet for input");		return -1;	    }	    break;         case conn_class_d2cs_bnetd:            if (!(packet = packet_create(packet_class_d2cs_bnetd)))            {                eventlog(eventlog_level_error,__FUNCTION__,"could not allocate d2cs_bnetd packet");                return -1;            }            break;	case conn_class_bnet:	    if (!(packet = packet_create(packet_class_bnet)))	    {		eventlog(eventlog_level_error,__FUNCTION__,"could not allocate bnet packet for input");		return -1;	    }	    break;	case conn_class_file:	    switch(conn_get_state(c)) {		case conn_state_pending_raw:		    if (!(packet = packet_create(packet_class_raw)))		    {			eventlog(eventlog_level_error,__FUNCTION__,"could not allocate raw packet for input");			return -1;		    }		    packet_set_size(packet, sizeof(t_client_file_req3));		    break;		default:		    if (!(packet = packet_create(packet_class_file)))		    {			eventlog(eventlog_level_error,__FUNCTION__,"could not allocate file packet for input");			return -1;		    }		    break;	    }	    break;	case conn_class_bot:	case conn_class_irc:	case conn_class_wol:	case conn_class_telnet:	    if (!(packet = packet_create(packet_class_raw)))	    {		eventlog(eventlog_level_error,__FUNCTION__,"could not allocate raw packet for input");		return -1;	    }	    packet_set_size(packet,1); /* start by only reading one char */	    break;	case conn_class_w3route:	    if (!(packet = packet_create(packet_class_w3route)))	    {		eventlog(eventlog_level_error,__FUNCTION__,"could not allocate w3route packet for input");		return -1;	    }	    break;		default:	    eventlog(eventlog_level_error,__FUNCTION__,"[%d] connection has bad class (closing connection)",conn_get_socket(c));	    /* marking connection as "destroyed", memory will be freed later */		conn_set_state(c, conn_state_destroy);	    return -2;	}	conn_put_in_queue(c,packet);	currsize = 0;    }        packet = conn_get_in_queue(c);    switch (net_recv_packet(csocket,packet,&currsize))    {    case -1:	eventlog(eventlog_level_debug,__FUNCTION__,"[%d] read FAILED (closing connection)",conn_get_socket(c));	/* marking connection as "destroyed", memory will be freed later */	conn_set_state(c, conn_state_destroy);	return -2;	    case 0: /* still working on it */	/* eventlog(eventlog_level_debug,__FUNCTION__,"[%d] still reading \"%s\" packet (%u of %u bytes so far)",conn_get_socket(c),packet_get_class_str(packet),conn_get_in_size(c),packet_get_size(packet)); */	conn_set_in_size(c,currsize);	break;	    case 1: /* done reading */	switch (conn_get_class(c))	{	case conn_class_bot:	case conn_class_telnet:	    if (currsize<MAX_PACKET_SIZE) /* if we overflow, we can't wait for the end of the line.					     handle_*_packet() should take care of it */	    {		char const * const temp=packet_get_raw_data_const(packet,0);		if ((temp[currsize-1]=='\003')||(temp[currsize-1]=='\004')) {		    /* we have to ignore these special characters, since 		     * some bots even send them after login (eg. UltimateBot)		     */		    currsize--;		    break;	 		}		if (temp[currsize-1]!='\r' && temp[currsize-1]!='\n')		{		    conn_set_in_size(c,currsize);		    packet_set_size(packet,currsize+1);		    break; /* no end of line, get another char */		}	    }	    /* got a complete line or overflow... fall through */		default:	    conn_put_in_queue(c,NULL);	    if (hexstrm)	    {		fprintf(hexstrm,"%d: recv class=%s[0x%02x] type=%s[0x%04x] length=%u\n",			csocket,			packet_get_class_str(packet),(unsigned int)packet_get_class(packet),			packet_get_type_str(packet,packet_dir_from_client),packet_get_type(packet),			packet_get_size(packet));		hexdump(hexstrm,packet_get_raw_data_const(packet,0),packet_get_size(packet));	    }	    	    if (conn_get_class(c)==conn_class_bot ||		conn_get_class(c)==conn_class_telnet) /* NUL terminate the line to make life easier */	    {		char * const temp=packet_get_raw_data(packet,0);				if (temp[currsize-1]=='\r' || temp[currsize-1]=='\n')		    temp[currsize-1] = '\0'; /* have to do it here instead of above so everything						is intact for the hexdump */	    }	    	    {		int ret;				switch (conn_get_class(c))		{		case conn_class_init:		    ret = handle_init_packet(c,packet);		    break;		case conn_class_bnet:		    ret = handle_bnet_packet(c,packet);		    break;		case conn_class_d2cs_bnetd:			ret = handle_d2cs_packet(c,packet);			break;		case conn_class_bot:		    ret = handle_bot_packet(c,packet);		    break;		case conn_class_telnet:		    ret = handle_telnet_packet(c,packet);		    break;		case conn_class_file:		    ret = handle_file_packet(c,packet);		    break;		case conn_class_irc:		case conn_class_wol:		    ret = handle_irc_packet(c,packet);		    break;		case conn_class_w3route:		    ret = handle_w3route_packet(c,packet);		    break;		default:		    eventlog(eventlog_level_error,__FUNCTION__,"[%d] bad packet class %d (closing connection)",conn_get_socket(c),(int)packet_get_class(packet));		    ret = -1;		}		packet_del_ref(packet);		if (ret<0)		{			/* marking connection as "destroyed", memory will be freed later  */			conn_set_state(c, conn_state_destroy);		    return -2;		}	    }	    	    conn_set_in_size(c,0);	}    }    return 0;}static int sd_tcpoutput(t_connection * c){    unsigned int currsize;    unsigned int totsize;    t_packet *   packet;    int		 csocket = conn_get_socket(c);        totsize = 0;    for (;;)    {	currsize = conn_get_out_size(c);        if ((packet = conn_peek_outqueue(c)) == NULL)            return -2;	switch (net_send_packet(csocket,packet,&currsize)) /* avoid warning */	{	case -1:		/* marking connection as "destroyed", memory will be freed later */	    conn_set_state(c, conn_state_destroy);	    return -2;	    	case 0: /* still working on it */	    conn_set_out_size(c,currsize);	    return 0; /* bail out */	    	case 1: /* done sending */	    if (hexstrm)	    {		fprintf(hexstrm,"%d: send class=%s[0x%02x] type=%s[0x%04x] length=%u\n",			csocket,			packet_get_class_str(packet),(unsigned int)packet_get_class(packet),			packet_get_type_str(packet,packet_dir_from_server),packet_get_type(packet),			packet_get_size(packet));		hexdump(hexstrm,packet_get_raw_data(packet,0),packet_get_size(packet));	    }	    packet = conn_pull_outqueue(c);	    packet_del_ref(packet);	    conn_set_out_size(c,0);	    /* stop at about BNETD_MAX_OUTBURST (or until out of packets or EWOULDBLOCK) */	    if (totsize>BNETD_MAX_OUTBURST || !conn_peek_outqueue(c))		return 0;	    totsize += currsize;	    break;	}    }    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -