dns_mastergold.c
来自「C实现的MUD,对大家基本入门网络游戏很有帮助!」· C语言 代码 · 共 887 行 · 第 1/2 页
C
887 行
"tell" : SVC_UDP, "rwho_q" : SVC_UDP, "gwizmsg" : SVC_UDP, ]); break; default: // TCP_NONE 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; } // switch (tcp) // handle service information if (tcp != TCP_ONLY) query_services(name, junk["HOSTADDRESS"], junk["PORTUDP"], tcp);}// deletes an entry for a mudvoid zap_mud_info(string name, mapping junk){ // check permissions if( !previous_object() || !ACCESS_CHECK(previous_object()) || file_name(previous_object())[0..strlen(AUX_PATH) - 1] != AUX_PATH) return; // delete the entry map_delete(muds, name); // wipe the service information map_delete(mud_svc, name);}// This is called when we get a service response from the other endvoid support_q_callback(mapping info){ string cmd; string mud; // check permission if (!ACCESS_CHECK(previous_object())) return; // check the reply is valid - note that if info is 0 it is possible // this is the result of a tiemout, but as muds are only queried // once, and the default is unknown, we dont have a problem. if (!info || !info["CMD"] || !info["NAME"] || !strlen(info["CMD"]) || !strlen(info["NAME"])) return; mud = htonn( info["NAME"] ); if (undefinedp(muds[mud])) return; if (undefinedp(mud_svc[mud])) mud_svc[mud] = ([]); if(!info["SUPPORTED"] && !info["NOTSUPPORTED"]) return; // mesed up packet if (info["CMD"] == "tcp") { cmd = info["PARAM"]; // if udp is known then we know the whole status if (mud_svc[mud][cmd] & (SVC_UDP | SVC_NO_UDP)) mud_svc[mud][cmd] |= SVC_KNOWN; if (info["SUPPORTED"]) { mud_svc[mud][cmd] |= SVC_TCP; mud_svc[mud][cmd] &= ~SVC_NO_TCP; } else { mud_svc[mud][cmd] |= SVC_NO_TCP; mud_svc[mud][cmd] &= ~SVC_TCP; // if they don't support something tcp, we check udp if(!(mud_svc[mud][cmd] & SVC_KNOWN)) SUPPORT_Q->send_support_q(muds[mud]["HOSTADDRESS"], muds[mud]["PORTUDP"], info["PARAM"]); } } // if (info["CMD"] == "tcp") else { cmd = info["CMD"]; // if tcp is known then we know the whole status if (mud_svc[mud][cmd] & (SVC_TCP | SVC_NO_TCP)) mud_svc[mud][cmd] |= SVC_KNOWN; if (info["SUPPORTED"]) { mud_svc[mud][cmd] |= SVC_UDP; mud_svc[mud][cmd] &= ~SVC_NO_UDP; } else { mud_svc[mud][cmd] |= SVC_NO_UDP; mud_svc[mud][cmd] &= ~SVC_UDP; // if they don't support something udp, we check tcp if(!(mud_svc[mud][cmd] & SVC_KNOWN)) SUPPORT_Q->send_support_q(muds[mud]["HOSTADDRESS"], muds[mud]["PORTUDP"], "tcp", info["CMD"]); } } // if (info["CMD"] == "tcp") return;}// This queries a mud just added to the database for its supported services// What is queries for is dependant on config.hprivate voidquery_services(string mud, string address, string port, string tcp){#ifdef PREF_MAIL if (!(mud_svc[mud]["mail"] & SVC_KNOWN)) {#if PREF_MAIL & SVC_TCP if (tcp == TCP_SOME && !(mud_svc[mud]["mail"] & (SVC_TCP | SVC_NO_TCP))) SUPPORT_Q->send_support_q(address, port, "tcp", "mail");#elif PREF_MAIL & SVC_UDP if (!(mud_svc[mud]["mail"] & (SVC_UDP | SVC_NO_UDP))) SUPPORT_Q->send_support_q(address, port, "mail");#endif }#endif // PREF_MAIL#ifdef PREF_FINGER if (!(mud_svc[mud]["finger"] & SVC_KNOWN)) {#if PREF_FINGER & SVC_TCP if (tcp == TCP_SOME && !(mud_svc[mud]["finger"] & (SVC_TCP | SVC_NO_TCP))) SUPPORT_Q->send_support_q(address, port, "tcp", "finger");#endif }#endif // PREF_FINGER#ifdef PREF_TELL if (!(mud_svc[mud]["tell"] & SVC_KNOWN)) {#if PREF_TELL & SVC_TCP if (tcp == TCP_SOME && !(mud_svc[mud]["tell"] & (SVC_TCP | SVC_NO_TCP))) SUPPORT_Q->send_support_q(address, port, "tcp", "tell");#endif }#endif // PREF_TELL return;}/*---------------------------------------------------------------------------- * Name server functions */// this is used by the internet communication front ends. It return// flags representing whether a service is supported or not.int query_service_method(string mud, string service){ mud = htonn(mud); // do we know about the mud if (undefinedp(muds[mud])) return SVC_UNKNOWN; // if we have an entry, but no service entry, it is a static mud if (undefinedp(mud_svc[mud])) return SVC_TCP | SVC_NO_UDP | SVC_KNOWN; // if we have an entry for the mud, do we know what the service is ? if (undefinedp(mud_svc[mud][service])) { // if it is a standard service we try to find out if(member_array(service, STD_SERVICE) != -1) query_services(mud, muds[mud]["HOSTADDRESS"], muds[mud]["PORTUDP"], muds[mud]["TCP"]); return SVC_UNKNOWN; } return mud_svc[mud][service];}mapping query_svc_entry(string mud){// if (ACCESS_CHECK(previous_object())) return mud_svc[mud];}string get_host_name(string name){ name = htonn(name); if (name == mud_nname()) return this_host["HOSTADDRESS"]; if (undefinedp(muds[name])) return 0; return muds[name]["HOSTADDRESS"];}mapping query_mud_info(string name){ name = htonn(name); if(name == mud_nname()) return this_host + ([ "TIME" : ctime(time()) ]); return muds[name];}// this returns '1' if the mud is in the dns, or if it is usint dns_mudp(string name){ name = htonn( name ); return undefinedp(mud_svc[name]) ? (name == mud_nname() ? 1 : 0) : 1;}// returns all the muds in the databasesmapping query_muds(){// if (ACCESS_CHECK(previous_object())) return muds + ([ mud_nname():this_host + ([ "TIME":ctime(time()) ]) + (["USERS":sprintf("%d",sizeof(users())) ]) ]);}// returns the services mappingmapping query_svc(){// if (ACCESS_CHECK(previous_object())) return mud_svc;}// ----------------------------------------------------------------------------// service sequencing functions//// this is a potential security nightmare, be careful what euid the object// has when it calls the function// ----------------------------------------------------------------------------// register a function in the sequencervarargs int idx_request(function f){ if (file_name(previous_object())[0..strlen(AUX_PATH) - 1] != AUX_PATH) return 0; seq_ctr++; seq_entries[seq_ctr] = ({ geteuid(previous_object()), f, time() }); return seq_ctr;}// call a function in the sequencervoid idx_callback(int idx, mixed param){ mixed *entry; if (!ACCESS_CHECK(previous_object())) return; if (undefinedp(seq_entries[idx])) return; entry = seq_entries[idx]; map_delete(seq_entries, idx); seteuid(entry[0]); (*entry[1]) (param); restore_euid();}// remove timed out entriesvoid sequence_clean_up(){ int i, now; int *indexes; if(find_call_out("sequence_clean_up") != -1) return; indexes = keys(seq_entries); now = time(); i = sizeof(indexes); while (i--) if( now - seq_entries[indexes[i]][2] > SERVICE_TIMEOUT ) { seteuid(seq_entries[indexes[i]][0]); (*seq_entries[indexes[i]][1]) (0); restore_euid(); map_delete( seq_entries, indexes[i] ); } call_out("sequence_clean_up", SEQ_CLEAN_INTERVAL);}/*---------------------------------------------------------------------------- * general debugging stuff */#ifdef DEBUGmixed *query_bootsrv(){ return bootsrv;}void dump_sequencer(){ printf("counter: %d\n\n%O\n", seq_ctr, seq_entries);}void dump_svc(){ printf("%O\n", mud_svc);}void dump_mud_keys(){ printf("%O\n", keys(muds));}void dump_svc_keys(){ printf("%O\n", keys(mud_svc));}void set_monitor(object ob){ string euid;/* euid = geteuid(previous_object()); if (!euid || !member_group(euid, "admin") && !member_group(euid, "socket")) return;*/ monitor = ob;}objectquery_monitor(){ return monitor;}#endif // DEBUG/*---------------------------------------------------------------------------- * some misc functions */// Not really used yetprivate void restore_euid(){ seteuid(ROOT_UID);}// Logging functions// This one is for log entries from the auxiliariesvoidaux_log(string file, string entry){ if(!ACCESS_CHECK(previous_object())) return; restore_euid(); log_file(file, sprintf("%s: %s\n", ctime(time()), entry));}// This one is for warnings from the auxiliariesvoidaux_warning(string warning){ if(!ACCESS_CHECK(previous_object())) return; log("dns_warning: "+warning);}// This is for internal useprivate voidlog(string entry){ log_file(MY_LOG_FILE, sprintf("%s: %s\n", ctime(time()), entry));}// Used to find the ip number of the host we are onvoid resolve_callback(string address, string my_ip, int key){/* if(previous_object()) return;*/ this_host["HOSTADDRESS"] = my_ip;}// ----------------------------------------------------------------------------// This starts us all off// ----------------------------------------------------------------------------void create(){ restore_euid(); set("channel_id", "网路精灵"); // find out which port we are on my_port = SRVC_PORT_UDP(mud_port()); // initialise global mud info variables muds = allocate_mapping(MUDS_ALLOC); mud_svc = allocate_mapping(MUDS_ALLOC); // initialise the sequencing variables seq_ctr = 0; seq_entries = ([]); // set the bootserver default bootsrv = MUDLIST_DNS; bootsrv_retry = 0; // tell the mudlist_a daemon that we have cleared the database MUDLIST_A->clear_db_flag(); // set up our own info this_host = ([ "MUDNAME" : CHINESE_MUD_NAME, // add by ken@XAJH 1997-10-18 "NAME" : Mud_name(), "ALIAS" : Mud_name(), "DRIVER" : __VERSION__, // add by ken@XAJH 1998-05-28 "MUDLIB" : MUDLIB_NAME, "VERSION" : MUDLIB_VERSION, "HOST" : query_host_name(), "HOSTADDRESS" : 0, // set in resolve_callback() "PORT" : "" + mud_port(), "PORTUDP" : "" + my_port, "ADMIN" : MUD_ADMIN, "HTTP" : MUD_WEB, "ENCODING" : MUDLIB_ENCODING, // add by ken@XAJH 1998-05-28 "TIME" : ctime(time()), "TCP" : TCP_SERVICE_LEVEL, "USERS" : sprintf("%d",sizeof(users())), ]); resolve(query_host_name(), "resolve_callback"); // initialise the udp socket, if successful start the database system if (startup_udp()) init_database(); CHANNEL_D->do_channel(this_object(), "sys", "MUD 互联核心 DNS_MASTER 已经启动。 \n");}void remove(){ send_shutdown();}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?