dns_masterold.c

来自「C实现的MUD,对大家基本入门网络游戏很有帮助!」· C语言 代码 · 共 721 行 · 第 1/2 页

C
721
字号
// Ported to ES2 mudlib by Annihilator@ES2#include <mudlib.h>#include <socket_err.h>#include <net/config.h>#include <net/daemons.h>#include <net/dns.h>#include <net/socket.h>#include <net/services.h>#include <net/macros.h>#define DEBUG#define STD_SERVICE ({ "mail", "finger", "rwho_q", "tell", "gwizmsg" })#define MY_LOG_FILE "dns_master"inherit F_DBASE;private int my_port, socket_id;private mapping muds;private mapping mud_svc;private mapping this_host;private mixed * bootsrv;private int bootsrv_retry;private int seq_ctr;private mapping seq_entries;#ifdef DEBUG#  define debug(x) if(monitor) message("diagnostic", (x), monitor)static object monitor = 0;#else#  define debug(x)#endifint startup_udp();void send_udp(string host, int port, string msg);void read_callback(int sock, string msg, string addr);string start_message();private string *muds_ip, *muds_port, *muds_name;int check_mud(string ip, string port, string name);void init_database();void refresh_database();void do_pings();void set_mud_info(string name, mapping junk);void zap_mud_info(string name, mapping junk);void support_q_callback(mapping info);private void query_services(string mud, string address, string port, string tcp);int query_service_method(string mud, string service);mapping query_mud_info(string name);string get_host_name(string alias);int get_mudresource(string mud, string resource);int dns_mudp(string name);mapping query_muds();mapping query_svc();varargs int idx_request(function f);void sequence_callback(int idx, mixed param);void sequence_clean_up();#ifdef DEBUGmixed * query_bootsrv();void dump_sequencer();void set_monitor(object ob);object query_monitor();#endifprivate void restore_euid();void aux_log(string file, string entry);void aux_warning(string warning);private void log(string entry);void resolve_callback(string address, string my_ip, int key);int startup_udp(){	int err_no;		if (socket_id)	return 0;		socket_id = socket_create(DATAGRAM, "read_callback", "close_callback");		if (socket_id < 0)	{		log("Failed to acquire socket.\n");		return 0;	}	err_no = socket_bind(socket_id, my_port);	while( err_no == EEADDRINUSE )	{		my_port++;		err_no = socket_bind(socket_id, my_port);	}	if( err_no <= 0 )	{		log( sprintf("Failed to bind socket of UDP services, error = %d.\n", err_no));		socket_close(socket_id);		return 0;	}	return 1;}void send_udp(string host, int port, string msg){	int sock;		if (!ACCESS_CHECK(previous_object())&&	file_name(previous_object())[0..strlen(AUX_PATH) - 1] != AUX_PATH)	return;		if(sscanf(msg,"||TIME:%*s")==0)	msg=replace_string(msg,"||NAME:",	"||TIME:"+ctime(time())+"||NAME:",1);		if(sscanf(msg,"||USERS:%*s")==0)	msg=replace_string(msg,"||NAME:",	"||USERS:"+sizeof(users())+"||NAME:",1);	debug("DNS: Sending " + msg);	sock = socket_create(DATAGRAM, "read_callback", "close_callback");		if (sock <= 0)	{		log("Failed to open socket to " + host + " " + port + "\n");		return;	}	socket_write(sock, msg, host + " " + port);	socket_close(sock);}void read_callback(int sock, string msg, string addr){	string func, rest="", *bits, name, arg;	mapping args;	int i;		debug("DNS: Got " + msg);	if( !sscanf(msg, "@@@%s||%s@@@%*s", func, rest))	{		if (!sscanf(msg, "@@@%s@@@%*s", func))		return;		rest = "";	}	sscanf(addr, "%s %*s", addr);	if(strlen(rest)<2) 	return;		bits = explode(rest, "||");	args = allocate_mapping(sizeof(bits)+3);		i = sizeof(bits);	while (i--)	if (bits[i] && sscanf(bits[i], "%s:%s", name, arg) == 2)	args[name] = arg;	args["HOSTADDRESS"] = addr;		if (args["NAME"])	{		args["NAME"]= htonn(args["NAME"]);		args["ALIAS"] = htonn(args["NAME"]);	}	if(!check_mud(addr,"",""))	{		return;	}	if (mapp(muds[args["NAME"]]))	muds[args["NAME"]][DNS_NO_CONTACT] = 0;	debug("DNS: got message "+mapp(muds[args["NAME"]])+	" "+args["NAME"]+"\n");		if (mapp(muds[args["NAME"]]))	{		if(!undefinedp(args["TIME"]) && args["TIME"])		muds[args["NAME"]]+=(["TIME":args["TIME"]]);				if(!undefinedp(args["USERS"]) && args["USERS"])		muds[args["NAME"]]+=(["USERS":args["USERS"]]);	}	if (file_size(AUX_PATH + func + ".c") > 0)	(AUX_PATH + func)->incoming_request(args);}int query_udp_port(){	return my_port;}string query_mud_name(){	return INTERMUD_MUD_NAME;}void send_shutdown(){	string *mud_names;	int i;		if(!muds || sizeof(muds)==0)	return;		mud_names = keys(muds);	i = sizeof(mud_names);	while (i--)	SHUTDOWN->send_shutdown(muds[mud_names[i]]["HOSTADDRESS"],	muds[mud_names[i]]["PORTUDP"]);	socket_close(socket_id);	CHANNEL_D->do_channel(this_object(), "sys", "送出网路关闭讯息。\n");}string start_message(){	return sprintf( "||MUDNAME:%s||NAME:%s||VERSION:%s||MUDLIB:%s||HOST:%s||PORT:%d"	"||PORTUDP:%d||TCP:%s",	MUD_NAME, Mud_name(),	MUDLIB_VERSION,	MUDLIB_NAME,	query_host_name(),	mud_port(), my_port,	TCP_SERVICE_LEVEL);}void init_database(){	int i;	string message, *list;		if( MUDLIST_A->query_db_flag() )	{		call_out("refresh_database", REFRESH_INTERVAL);		call_out("sequence_clean_up", 4 * SERVICE_TIMEOUT);		do_pings();		return;	}	message = sprintf("@@@%s%s@@@\n", DNS_STARTUP, start_message());	list = values( LISTNODES );	i = sizeof( list );	while( i-- )	{		sscanf( list[i], "%s %d", bootsrv[0], bootsrv[1] );		send_udp(bootsrv[0], bootsrv[1], message);		MUDLIST_Q->send_mudlist_q(bootsrv[0], bootsrv[1]);	}	call_out("init_database", 60);	return;}void refresh_database(){	int i;	string *list;		while(find_call_out("refresh_database") != -1){ }		call_out("refresh_database", REFRESH_INTERVAL);	list = values( LISTNODES );	i = sizeof( list );	while( i-- )	{		sscanf( list[i], "%s %d", bootsrv[0], bootsrv[1] );		MUDLIST_Q->send_mudlist_q(bootsrv[0], bootsrv[1]);	}}void do_pings(){	int i;	string *mud_names;		if(find_call_out("do_pings") != -1)	return;		call_out("do_pings", PING_INTERVAL);	mud_names = keys(muds);	i = sizeof(mud_names);	while (i--)	{		if(undefinedp(mud_svc[mud_names[i]]))		continue;				muds[mud_names[i]] [DNS_NO_CONTACT]++;		PING_Q->send_ping_q(muds[mud_names[i]]["HOSTADDRESS"],		muds[mud_names[i]]["PORTUDP"]);				if (muds[mud_names[i]][DNS_NO_CONTACT] >= MAX_RETRYS)		zap_mud_info(mud_names[i], 0);	}}void set_mud_info(string name, mapping junk){	string tcp;	int new_mud;	int svc;		if( !(ACCESS_CHECK(previous_object()))&&	file_name(previous_object())[0..strlen(AUX_PATH) - 1] != AUX_PATH)	return;		name = htonn( name );	while( name[strlen(name)-1] == '.' ) name = name[ 0..strlen(name)-2 ];		if (name == mud_nname())	return;		if(undefinedp(junk["PORTUDP"])||	undefinedp(junk["HOSTADDRESS"])||	undefinedp(junk["NAME"]) ||	!check_mud(junk["HOSTADDRESS"], junk["PORTUDP"],junk["NAME"]))	{		return;	}	junk["NAME"] = htonn(junk["NAME"]);	junk["ALIAS"] = nntoh( junk["NAME"] );		if( (undefinedp(muds[name]) ||	undefinedp(muds[name]["TIME"]))&&	!undefinedp(junk["TIME"]) )	CHANNEL_D->do_channel(this_object(), "sys",	junk["MUDNAME"]+"("+junk["NAME"]+")   "+	junk["HOSTADDRESS"]+" "+junk["PORT"]+" 加入互连。");		if (!undefinedp(mud_svc[name]))	{		muds[name] = junk;		return;	}	if (!undefinedp(muds[name]))	this_object()->aux_log("dns_mud_conv", "Udp contact from: "+name+"\n");		if (!junk["TCP"]) junk["TCP"] = TCP_NONE;	muds[name] = junk;	tcp = junk["TCP"];	switch (tcp)	{		case TCP_ALL:		             mud_svc[name] = ([		                               "mail"     :  SVC_TCP,		                               "finger"   :  SVC_TCP | SVC_UDP | SVC_KNOWN,		                               "tell"     :  SVC_TCP | SVC_UDP | SVC_KNOWN,		                               "rwho_q"   :  SVC_UDP,		                               "gwizmsg"  :  SVC_UDP,		                               ]);		             break;		case TCP_ONLY:		              mud_svc[name] = ([		                                "mail"     :  SVC_TCP | SVC_NO_UDP | SVC_KNOWN,		                                "finger"   :  SVC_TCP | SVC_NO_UDP | SVC_KNOWN,		                                "tell"     :  SVC_TCP | SVC_NO_UDP | SVC_KNOWN,		                                "rwho_q"   :  SVC_NO_UDP,		                                "gwizmsg"  :  SVC_NO_UDP,		                                ]);		             break;		case TCP_SOME:		              mud_svc[name] = ([		                                "mail"     :  SVC_UNKNOWN,		                                "finger"   :  SVC_UDP,		                                "tell"     :  SVC_UDP,		                                "rwho_q"   :  SVC_UDP,		                                "gwizmsg"  :  SVC_UDP,		                                ]);		             break;		default:		              mud_svc[name] = ([		                                "mail"     :  SVC_NO_TCP,		                                "finger"   :  SVC_NO_TCP | SVC_UDP | SVC_KNOWN,		                                "tell"     :  SVC_NO_TCP | SVC_UDP | SVC_KNOWN,		                                "rwho_q"   :  SVC_NO_TCP | SVC_UDP | SVC_KNOWN,		                                "gwizmsg"  :  SVC_NO_TCP | SVC_UDP | SVC_KNOWN,		                                ]);		             break;

⌨️ 快捷键说明

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