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

📄 namecachemain.c

📁 p2p类源代码 kadc协议官方源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	signal(sig, SIG_IGN);}#else/* This thread waits for TERM and INT signals, and when   they are found, sets the shutdown_flag */void* sig_handler_th(void* arg) {	DNSIO *pdnsio = glob_pdnsio;	sigset_t signal_set;	int sig;	/* we loop forever (and the main thread does not join() on this thread)	   because under GNU Pth signal blocking doesn't seem to work; a	   signal issued when no sigwait() is waiting for it always terminates	   the process... So we leave this thread to sigwait() till the process'	   exit.	 */	for(;;) {		/* wait for these signal (they are all already blocked) */		sigemptyset(&signal_set);		sigaddset(&signal_set, SIGTERM);		sigaddset(&signal_set, SIGINT);		sigwait(&signal_set, &sig);		/* here we've caught a signal! */		pthread_mutex_lock(&pdnsio->mutex);#ifdef DEBUG		KadC_log("Signal %d caught, shutdown_flag set to 1\n", sig);#endif		pdnsio->shutdown_flag = 1;		pthread_mutex_unlock(&pdnsio->mutex);	}	return NULL;}#endifint main(int ac, char *av[]) {	char *kadcinifile = NULL;	int leafmode = 1;	/* default: leaf mode */	KadC_status kcs;	processing_thread_params ptp = {0};	/* don't forget to init to all 0's... */	pthread_t udprecv;	pthread_t proc;	pthread_t publish;	char c;	DNSIO dnsio = {0};	KadCcontext kcc = {0};	int status;	unsigned long int ip;#ifndef __WIN32__	char *user = NULL;	char *group = NULL;#endif#ifndef OLD_STYLE_SIGNAL	sigset_t signal_set;	pthread_t sig_thread;#endif	KadC_log("namecache - KadC library version: %d.%d.%d\n",		KadC_version.major, KadC_version.minor, KadC_version.patchlevel);	dnsio.mutex = mutex_initializer;	glob_pdnsio = &dnsio;	ptp.cache_maxentries = -1;	dnsio.port = DNS_PORT;	/* default */#ifndef __WIN32__	/* if UNIX */	while( (c = getopt( ac, av, "k:c:t:s:d:li:p:u:g:h")) != EOF ) {#else	while( (c = getopt( ac, av, "k:c:t:s:d:li:p:h")) != EOF ) {#endif		switch(c) {		case 'k':			kadcinifile = optarg;			break;		case 'c':			ptp.cache_maxentries = atoi(optarg);			break;		case 't':			if(ptp.ntlpd >= arraysize(ptp.tlpd)) {				KadC_log("Can't handle more than %d \"-t\" options\n", arraysize(ptp.tlpd));				exit(1);			}			ptp.tlpd[ptp.ntlpd++] = optarg;			break;		case 's':			if(dnsio.nupstream >= arraysize(dnsio.upstream)) {				KadC_log("Can't specify more than %d upstream servers with \"-s\" options\n", arraysize(dnsio.upstream));				exit(1);			}			ip = inet_addr(optarg);			if(ip == -1) {				KadC_log("Invalid IP address %s in \"-s\" option\n", optarg);				exit(1);			}			dnsio.upstream[dnsio.nupstream++] = ntohl(ip);			break;		case 'd':			if(ptp.nmy_pseudo >= arraysize(ptp.my_pseudo)) {				KadC_log("Can't handle more than %d \"-d\" options\n", arraysize(ptp.my_pseudo));				exit(1);			}			ptp.my_pseudo[ptp.nmy_pseudo++] = optarg;			break;/*		case 'l':			leafmode = 1;			break; */		case 'i':				/* IP address to bind to */			ip = inet_addr(optarg);			if(ip == -1) {				KadC_log("Invalid IP address %s in \"-b\" option\n", optarg);				exit(1);			}			dnsio.ip = ntohl(ip);			break;		case 'p':				/* UDP port to bind to */			dnsio.port = atoi(optarg);			break;#ifndef __WIN32__		case 'u':			user = optarg;			break;		case 'g':			group = optarg;			break;#endif		case 'h':		default:			usage(av[0]);			return 1;		}	}	/* a few consistency checks between options: */#if !defined(__WIN32__) && !defined(__CYGWIN__)	if(user != NULL) {		dnsio.uid = user2uid(user);		if(dnsio.uid < 0) {			KadC_log("Could not retrieve the UID of the user %s\n", user);			return 1;		}		dnsio.gid = user2gid(user);		if(dnsio.gid < 0) {			KadC_log("Could not retrieve the GID of the user %s\n", user);			return 1;		}	} else {	/* "-u" option not present: no good if we are root! */		if(we_have_root_privilege()) {	/* ###### FIXME: detect privilege here */			KadC_log("For security reasons, this program must drop root privilege after startup.\n");			KadC_log("Please use the \"-u\" option to define a non-privileged user (e.g., \"-u nobody\")\n");			return 1;		}	}	if(group != NULL) {		dnsio.gid = group2gid(group);		if(dnsio.gid < 0) {			KadC_log("Could not retrieve the GID of the group %s\n", group);			return 1;		}	}#endif	if(kadcinifile == NULL && ptp.ntlpd > 0) {		KadC_log("Can't resolve queries via P2P for the %d pseudo-domains specified with \"-t\" options if a KadC ini file is not specified\n", ptp.ntlpd);		usage(av[0]);		return 1;	}	if(kadcinifile == NULL && ptp.nmy_pseudo != 0) {		KadC_log("Can't publish via P2P with \"-d\" record associating names to IP addresses if a KadC ini file is not specified\n");		usage(av[0]);		return 1;	}	if(ptp.ntlpd == 0 && dnsio.nupstream == 0) {		KadC_log("Can't resolve queries either via DNS or P2P: at least one of -s or -t must be specified.\n");		usage(av[0]);		return 1;	}	if(kadcinifile != NULL && ptp.ntlpd == 0 && ptp.nmy_pseudo == 0) {		KadC_log("Warning: if we neither resolve (-t) nor publish (-p) via P2P, what's the point of specifying \"-k %s\" and running KadC?\n", kadcinifile);	}	if(ptp.cache_maxentries == -1)		ptp.cache_maxentries = 4096;	/* default */	/* if we are under WIN32, this will call WSAStartup() and put in	   place an atexit hook to WSACleanup() */	KadC_init_network();	/* open UDP socket and prepare UDP I/O */	dnsio.fifo = new_queue(8); /* not more than 8 outstanding requests */	assert(dnsio.fifo != NULL);	if(udp_dns_init(&dnsio) < 1) {		KadC_log("dns_udp_recv_thread reports socket error %d\n", dnsio.err);		dnsio.fifo->destroy(dnsio.fifo);		goto exit;	}/* Drop root privileges, if under some flavour of *NIX */#if !defined(__WIN32__) && !defined(__CYGWIN__)	if((status = droppriv(dnsio.uid, dnsio.gid)) != 0) {		KadC_log("FATAL: Couldn't drop root privilege: ");		if(status == -1)			KadC_log("suppl. group IDs reset to non-root GID failed\n");		else if(status == -2)			KadC_log("couldn't change to non-privileged GID %d\n", dnsio.gid);		else if(status == -3)			KadC_log("couldn't change to non-root UID %d\n", dnsio.uid);		else if(status == -4)			KadC_log("once non-root, setuid(0) managed to restore root UID!\n");		exit(1);	}#endif/* Install signal handlers */#ifdef OLD_STYLE_SIGNAL	signal(SIGTERM, sighandler);	/* for the TERM signal (15, default for kill command)...  */	signal(SIGINT, sighandler); 	/* .. the INT signal... (Ctrl-C  hit on keyboard) */#else	/* block signals we'll wait for */	sigemptyset(&signal_set);	sigaddset(&signal_set, SIGTERM);	sigaddset(&signal_set, SIGINT);#ifdef __WIN32__	sigaddset(&signal_set, SIGBREAK);#endif	pthread_sigmask(SIG_BLOCK, &signal_set,	NULL);	/* create the signal handling thread */	pthread_create(&sig_thread, NULL, sig_handler_th, NULL);#endif/* Start KadC engine, if the -k option was present */	if(kadcinifile != NULL) {		kcc = KadC_start(kadcinifile, leafmode, 0);		if(kcc.s != KADC_OK) {			KadC_log("KadC_start(%s, %d) returned error %d:\n",				kadcinifile, leafmode, kcc.s);			KadC_log("%s %s", kcc.errmsg1, kcc.errmsg2);			return 2;		}		KadC_log("Our hash ID: %s ");		KadC_int128flog(stdout, KadC_getourhashID(&kcc));		KadC_log("\nour UDP port: %u, our TCP port: %u\n",		KadC_getourUDPport(&kcc),		KadC_getourTCPport(&kcc));	}	/* spawn the UDP init & listener loop thread */	pthread_create(&udprecv, NULL, dns_udp_recv_thread, &dnsio);	/* go to process requests posted by UDP listener to pdnsio->fifo,	   spawning threads as needed, and send UDP replies with	   sendto() to pdnsio->fd */	ptp.pkcc = &kcc;	ptp.pdnsio = &dnsio;	/* create the pending questions table - ID is significant! */	ptp.pending_q_rbt = rbt_new((rbtcomp *)&DNSpacket_qi_lt, (rbtcomp *)&DNSpacket_qi_eq);	assert(ptp.pending_q_rbt != NULL);	/* create the raw_qa cache. ID is NOT significant */	ptp.cache_q_rbt = rbt_new((rbtcomp *)&DNSpacket_q_lt, (rbtcomp *)&DNSpacket_q_eq);	assert(ptp.cache_q_rbt != NULL);	ptp.mutex = mutex_initializer;	/* start the processing thread, which reads incoming DNS data from FIFO queue */	pthread_create(&proc, NULL, processing_thread, &ptp);	/* start the publishing thread, which every two hours republishes records for our domain names */	pthread_create(&publish, NULL, publishing_thread, &ptp);	ConsoleLoop(&ptp);	KadC_log("Shutting down, please wait...\n");/* sig_thread never returns (see comments in processing_thread() ).#ifndef OLD_STYLE_SIGNAL	pthread_join(sig_thread, NULL);#endif */	pthread_join(publish, NULL);	pthread_join(proc, NULL);	pthread_mutex_destroy(&ptp.mutex);	pthread_join(udprecv, NULL);	pthread_mutex_destroy(&dnsio.mutex);	status = qa_rbt_destroy(ptp.cache_q_rbt, 1);	/* also destroy data */	assert(status == 0);	status = qa_rbt_destroy(ptp.pending_q_rbt, 1);	/* also destroy data */	assert(status == 0);	dnsio.fifo->destroy(dnsio.fifo);	/* destroy queue used to communicate with udprecv */	if(kadcinifile != NULL) {		kcs = KadC_stop(&kcc);		if(kcs != KADC_OK) {			KadC_log("KadC_stop(&kcc) returned error %d:\n", kcc.s);			KadC_log("%s %s", kcc.errmsg1, kcc.errmsg2);			return 3;		}	}exit:	KadC_list_outstanding_mallocs(10);	return 0;}/* converts "4.3.2.1.in-addr.arpa" into the IP address 1.2.3.4 */unsigned long int reverse_inet_addr(char *s) {	unsigned int b1, b2, b3, b4;	char *p;	int n;	if(s == NULL)		return -1;	n = sscanf(s, "%u.%u.%u.%u.in-addr.arpa%s", &b4, &b3, &b2, &b1, p);	if(n<4)		return -1;	if(n == 5 && strcmp(p, ".") != 0)		return -1;	return(b1<<24) + (b2<<16) + (b3<<8) + b4;}/* we are authoritative:   - for PTR queries resolving to an address on some interface;     the proper answer is "cachehost.cachedomain", replied immedately   - for A queries relative to our pseudo-domain     the proper answer is our external IP, replied immediately   - for A queries under some tlpd     the proper answer is a KadC search, replied later */static void ConsoleLoop(processing_thread_params *pptp) {	for(;;){		int sf;		pthread_mutex_lock(&pptp->pdnsio->mutex);	/* \\\\\\ LOCK \\\\\\ */		sf = pptp->pdnsio->shutdown_flag;		pthread_mutex_unlock(&pptp->pdnsio->mutex);	/* ///// UNLOCK ///// */		if(sf)			break;#if 0	/* suppress console input when not in debug mode */		KadCcontext *pkcc = pptp->pkcc;		char line[80];		int linesize = sizeof(line)-1;		char *s;		int fwstatus = KadC_getfwstatus(pkcc);		KadC_log("%4d/%4d%s ",			KadC_getnknodes(pkcc), KadC_getncontacts(pkcc),			(fwstatus>0 ? (fwstatus>1 ? ">" : "]") : "?"));		s = KadC_getsn(line, linesize);		if(s == NULL)			break;#else		/* KadC_log("."); */		millisleep(1000);#endif	}}/* create an entry in the pending queries rbt, unless already there   This is the single point where raw_qa objects are created. They   are then converted in cached qa's in the processing thread by   adding the reply, when it arrives. */static int create_pending_entry(processing_thread_params *pptp, DNSpacket *pdnp, void *threadcode(void *)) {	void *iter;	rbt_StatusEnum rbt_status = rbt_find(pptp->pending_q_rbt, pdnp, &iter);	if(rbt_status == RBT_STATUS_KEY_NOT_FOUND) {		/* this is the only place where a raw_qa is created */		raw_qa *pending_qa = calloc(1, sizeof(raw_qa));		assert(pending_qa != NULL);		pending_qa->q = pdnp;		pending_qa->a = NULL;	/* answer is void, of course */		pending_qa->last_accessed = time(NULL); /* informational, actually unused in pending_q_rbt */		pending_qa->expiry = pending_qa->last_accessed + 300;		pending_qa->being_refreshed = 0;	/* unused in pending_q_rbt */		pending_qa->mutex = mutex_initializer;		pending_qa->pptp = pptp;		rbt_status = rbt_insert(pptp->pending_q_rbt, pending_qa->q, pending_qa, 0);		assert(rbt_status == RBT_STATUS_OK);	/* can't be already there now... */#ifdef VERBOSE_DEBUG			KadC_log("create_pending_entry() created a pending_query entry \n");#endif		if(threadcode != NULL) {#ifdef DEBUG			KadC_log("create_pending_entry() also started a p2pquery thread\n");#endif			pending_qa->isdetached = 1;			pthread_create(&pending_qa->thread, NULL, threadcode, pending_qa);

⌨️ 快捷键说明

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