Example #1
0
File: cs.c Project: brho/akaros
static void readipinterfaces(void)
{
	if (myipaddr(ipa, mntpt) != 0)
		ipmove(ipa, IPnoaddr);
	snprintf(ipaddr, sizeof(ipaddr), "%I", ipa);
	if (debug)
		fprintf(stderr, "CS:dns", "ipaddr is %s\n", ipaddr);
}
Example #2
0
void
main(int argc, char *argv[])
{
	int n;
	Biobuf in;
	char *p;
	char *f[4];

	strcpy(mntpt, "/net");
	cfg.inside = 1;

	ARGBEGIN{
	case 'f':
		dbfile = EARGF(usage());
		break;
	case 'r':
		cfg.resolver = 1;
		break;
	case 'x':
		dbfile = "/lib/ndb/external";
		strcpy(mntpt, "/net.alt");
		break;
	default:
		usage();
	}ARGEND

	now = time(nil);
	nowns = nsec();
	dninit();
	fmtinstall('R', prettyrrfmt);
	if(myipaddr(ipaddr, mntpt) < 0)
		sysfatal("can't read my ip address");
	opendatabase();

	if(cfg.resolver)
		squirrelserveraddrs();

	debug = 1;

	if(argc > 0){
		docmd(argc, argv);
		exits(0);
	}

	Binit(&in, 0, OREAD);
	for(print("> "); p = Brdline(&in, '\n'); print("> ")){
		p[Blinelen(&in)-1] = 0;
		n = tokenize(p, f, 3);
		if(n>=1) {
			dnpurge();		/* flush the cache */
			docmd(n, f);
		}
	}
	exits(0);
}
Example #3
0
void
threadmain(int argc, char *argv[])
{
	int n;
	Biobuf in;
	char *p;
	char *f[4];

	strcpy(mntpt, "/net");

	ARGBEGIN{
	case 'r':
		resolver = 1;
		break;
	case 'f':
		dbfile = EARGF(usage());
		break;
	default:
		usage();
	}ARGEND

	now = time(0);
	dninit();
	fmtinstall('R', prettyrrfmt);
	if(myipaddr(ipaddr, mntpt) < 0)
		sysfatal("can't read my ip address");
	opendatabase();

	if(resolver)
		squirrelserveraddrs();

	debug = 1;

	if(argc > 0){
		docmd(argc, argv);
		threadexitsall(0);
	}

	Binit(&in, 0, OREAD);
	for(print("> "); p = Brdline(&in, '\n'); print("> ")){
		p[Blinelen(&in)-1] = 0;
		n = tokenize(p, f, 3);
		if(n<1)
			continue;

		/* flush the cache */
		dnpurge();

		docmd(n, f);

	}
	threadexitsall(0);
}
Example #4
0
/*
 *  Announce on a local port and tell its address to the the remote side
 */
static int
port(void)
{
	char buf[256];
	int n, fd;
	char *ptr;
	uchar ipaddr[IPaddrlen];
	int port;

	/* get a channel to listen on, let kernel pick the port number */
	sprint(buf, "%s!*!0", net);
	listenfd = announce(buf, netdir);
	if(listenfd < 0)
		return seterr("can't announce");

	/* get the local address and port number */
	sprint(buf, "%s/local", netdir);
	fd = open(buf, OREAD);
	if(fd < 0)
		return seterr("opening %s: %r", buf);
	n = read(fd, buf, sizeof(buf)-1);
	close(fd);
	if(n <= 0)
		return seterr("opening %s/local: %r", netdir);
	buf[n] = 0;
	ptr = strchr(buf, ' ');
	if(ptr)
		*ptr = 0;
	ptr = strchr(buf, '!')+1;
	port = atoi(ptr);

	memset(ipaddr, 0, IPaddrlen);
	if (*net){
		strcpy(buf, net);
		ptr = strchr(buf +1, '/');
		if (ptr)
			*ptr = 0;
		myipaddr(ipaddr, buf);
	}

	/* tell remote side */
	sprint(buf, "PORT %d,%d,%d,%d,%d,%d", ipaddr[IPv4off+0], ipaddr[IPv4off+1],
		ipaddr[IPv4off+2], ipaddr[IPv4off+3], port>>8, port&0xff);
	sendrequest(buf, nil);
	if(getreply(&ctlin, msg, sizeof(msg), 0) != Success)
		return seterr(msg);
	return 0;
}
Example #5
0
void
main(int argc, char *argv[])
{
	int len, rcode;
	char tname[32];
	char *err, *ext = "";
	unsigned char buf[64*1024], callip[IPaddrlen];
	DNSmsg reqmsg, repmsg;
	Request req;

	alarm(2*60*1000);
	cfg.cachedb = 1;
	ARGBEGIN{
	case 'd':
		debug++;
		break;
	case 'f':
		dbfile = EARGF(usage());
		break;
	case 'r':
		cfg.resolver = 1;
		break;
	case 'R':
		norecursion = 1;
		break;
	case 'x':
		ext = EARGF(usage());
		break;
	default:
		usage();
		break;
	}ARGEND

	if(debug < 2)
		debug = 0;

	if(argc > 0)
		getcaller(argv[0]);

	cfg.inside = 1;
	dninit();

	snprint(mntpt, sizeof mntpt, "/net%s", ext);
	if(myipaddr(ipaddr, mntpt) < 0)
		sysfatal("can't read my ip address");
	dnslog("dnstcp call from %s to %I", caller, ipaddr);
	memset(callip, 0, sizeof callip);
	parseip(callip, caller);

	db2cache(1);

	memset(&req, 0, sizeof req);
	setjmp(req.mret);
	req.isslave = 0;
	procsetname("main loop");

	/* loop on requests */
	for(;; putactivity(0)){
		now = time(nil);
		memset(&repmsg, 0, sizeof repmsg);
		len = readmsg(0, buf, sizeof buf);
		if(len <= 0)
			break;

		getactivity(&req, 0);
		req.aborttime = timems() + S2MS(15*Min);
		rcode = 0;
		memset(&reqmsg, 0, sizeof reqmsg);
		err = convM2DNS(buf, len, &reqmsg, &rcode);
		if(err){
			dnslog("server: input error: %s from %s", err, caller);
			free(err);
			break;
		}
		if (rcode == 0) {
			if(reqmsg.qdcount < 1){
				dnslog("server: no questions from %s", caller);
				break;
			} else if(reqmsg.flags & Fresp){
				dnslog("server: reply not request from %s",
					caller);
				break;
			} else if((reqmsg.flags & Omask) != Oquery){
				dnslog("server: op %d from %s",
					reqmsg.flags & Omask, caller);
				break;
			}
		}
		if(debug)
			dnslog("[%d] %d: serve (%s) %d %s %s",
				getpid(), req.id, caller,
				reqmsg.id, reqmsg.qd->owner->name,
				rrname(reqmsg.qd->type, tname, sizeof tname));

		/* loop through each question */
		while(reqmsg.qd)
			if(reqmsg.qd->type == Taxfr)
				dnzone(&reqmsg, &repmsg, &req);
			else {
				dnserver(&reqmsg, &repmsg, &req, callip, rcode);
				reply(1, &repmsg, &req);
				rrfreelist(repmsg.qd);
				rrfreelist(repmsg.an);
				rrfreelist(repmsg.ns);
				rrfreelist(repmsg.ar);
			}
		rrfreelist(reqmsg.qd);		/* qd will be nil */
		rrfreelist(reqmsg.an);
		rrfreelist(reqmsg.ns);
		rrfreelist(reqmsg.ar);

		if(req.isslave){
			putactivity(0);
			_exits(0);
		}
	}
	refreshmain(mntpt);
}
Example #6
0
void
main(int argc, char *argv[])
{
	uchar buf[8*1024], *p;
	char addr[128], dir[40], ldir[40], *s;
	int cmd, fd, cfd, n;
	NetConnInfo *nc;

	fmtinstall('I', eipfmt);

	setnetmtpt(inside, sizeof(inside), 0);
	setnetmtpt(outside, sizeof(outside), 0);
	ARGBEGIN {
	case 'x':
		setnetmtpt(inside, sizeof(inside), ARGF());
		break;
	case 'o':
		setnetmtpt(outside, sizeof(outside), ARGF());
		break;
	} ARGEND;

	/* ver+cmd or ver+nmethod */
	if(readn(0, buf, 2) != 2)
		return;
	socksver = buf[0];
	if(socksver < 4)
		return;
	if(socksver > 5)
		socksver = 5;

	if(socksver == 4){
		/* port+ip4 */
		if(readn(0, buf+2, 2+4) != 2+4)
			return;
		/* +user\0 */
		for(p = buf+2+2+4;; p++){
			if(p >= buf+sizeof(buf))
				return;
			if(read(0, p, 1) != 1)
				return;
			if(*p == 0)
				break;
		}
		/* socks 4a dom hack */
		if((buf[4] | buf[5] | buf[6]) == 0 && buf[7]){
			/* +dom\0 */
			for(++p;; p++){
				if(p >= buf+sizeof(buf))
					return;
				if(read(0, p, 1) != 1)
					return;
				if(*p == 0)
					break;
			}
		}
	} else {
		/* nmethod */
		if((n = buf[1]) > 0)
			if(readn(0, buf+2, n) != n)
				return;

		/* ver+method */
		buf[0] = socksver;
		buf[1] = 0x00;	/* no authentication required */
		if(write(1, buf, 2) != 2)
			return;

		/* ver+cmd+res+atyp */
		if(readn(0, buf, 4) != 4)
			return;
		switch(buf[3]){
		default:
			return;
		case 0x01:	/* +ipv4 */
			if(readn(0, buf+4, 4+2) != 4+2)
				return;
			break;
		case 0x03:	/* +len+dom[len] */
			if(readn(0, buf+4, 1) != 1)
				return;
			if((n = buf[4]) == 0)
				return;
			if(readn(0, buf+5, n+2) != n+2)
				return;
			break;
		case 0x04:	/* +ipv6 */
			if(readn(0, buf+4, 16+2) != 16+2)
				return;
			break;
		}
	}

	dir[0] = 0;
	fd = cfd = -1;
	cmd = buf[1];
	switch(cmd){
	case 0x01:	/* CONNECT */
		snprint(addr, sizeof(addr), "%s/tcp", outside);
		if((s = addr2str(addr, buf)) == nil)
			break;
		alarm(30000);
		fd = dial(s, 0, dir, &cfd);
		alarm(0);
		break;
	case 0x02:	/* BIND */
		if(myipaddr(buf, outside) < 0)
			break;
		snprint(addr, sizeof(addr), "%s/tcp!%I!0", outside, buf);
		fd = announce(addr, dir);
		break;
	case 0x03:	/* UDP */
		if(myipaddr(buf, inside) < 0)
			break;
		snprint(addr, sizeof(addr), "%s/udp!%I!0", inside, buf);
		fd = announce(addr, dir);
		break;
	}

Reply:
	/* reply */
	buf[1] = sockerr(fd < 0);			/* status */
	if(socksver == 4){
		buf[0] = 0x00;				/* vc */
		if(fd < 0){
			memset(buf+2, 0, 2+4);
			write(1, buf, 2+2+4);
			return;
		}
	} else {
		buf[0] = socksver;			/* ver */
		buf[2] = 0x00;				/* res */
		if(fd < 0){
			buf[3] = 0x01;			/* atyp */
			memset(buf+4, 0, 4+2);
			write(1, buf, 4+4+2);
			return;
		}
	}
	if((nc = getnetconninfo(dir, cfd)) == nil)
		return;
	if((n = str2addr((cmd & 0x100) ? nc->raddr : nc->laddr, buf)) <= 0)
		return;
	if(write(1, buf, n) != n)
		return;

	switch(cmd){
	default:
		return;
	case 0x01:	/* CONNECT */
		break;
	case 0x02:	/* BIND */
		cfd = listen(dir, ldir);
		close(fd);
		fd = -1;
		if(cfd >= 0){
			strcpy(dir, ldir);
			fd = accept(cfd, dir);
		}
		cmd |= 0x100;
		goto Reply;
	case 0x102:
		break;		
	case 0x03:	/* UDP */
		if(udprelay(fd, dir) == 0)
			while(read(0, buf, sizeof(buf)) > 0)
				;
		goto Hangup;
	}
	
	/* relay data */
	switch(rfork(RFMEM|RFPROC|RFFDG|RFNOWAIT)){
	case -1:
		return;
	case 0:
		dup(fd, 0);
		break;
	default:
		dup(fd, 1);
	}
	while((n = read(0, buf, sizeof(buf))) > 0)
		if(write(1, buf, n) != n)
			break;
Hangup:
	if(cfd >= 0)
		hangup(cfd);
	postnote(PNGROUP, getpid(), "kill");
}
Example #7
0
void
main(int argc, char *argv[])
{
	int kid, pid;
	char servefile[Maxpath], ext[Maxpath];
	Dir *dir;

	setnetmtpt(mntpt, sizeof mntpt, nil);
	ext[0] = 0;
	ARGBEGIN{
	case 'a':
		maxage = atol(EARGF(usage()));
		if (maxage <= 0)
			maxage = Defmaxage;
		break;
	case 'd':
		debug = 1;
		traceactivity = 1;
		break;
	case 'f':
		dbfile = EARGF(usage());
		break;
	case 'F':
		cfg.justforw = cfg.resolver = 1;
		break;
	case 'n':
		sendnotifies = 1;
		break;
	case 'N':
		target = atol(EARGF(usage()));
		if (target < 1000)
			target = 1000;
		break;
	case 'o':
		cfg.straddle = 1;	/* straddle inside & outside networks */
		break;
	case 'r':
		cfg.resolver = 1;
		break;
	case 'R':
		norecursion = 1;
		break;
	case 's':
		cfg.serve = 1;		/* serve network */
		cfg.cachedb = 1;
		break;
	case 't':
		testing = 1;
		break;
	case 'T':
		addforwtarg(EARGF(usage()));
		break;
	case 'x':
		setnetmtpt(mntpt, sizeof mntpt, EARGF(usage()));
		setext(ext, sizeof ext, mntpt);
		break;
	case 'z':
		zonerefreshprogram = EARGF(usage());
		break;
	default:
		usage();
		break;
	}ARGEND
	if(argc != 0)
		usage();

	if(testing)
		mainmem->flags |= POOL_NOREUSE | POOL_ANTAGONISM;
	mainmem->flags |= POOL_ANTAGONISM;
	rfork(RFREND|RFNOTEG);

	cfg.inside = (*mntpt == '\0' || strcmp(mntpt, "/net") == 0);

	/* start syslog before we fork */
	fmtinstall('F', fcallfmt);
	dninit();
	/* this really shouldn't be fatal */
	if(myipaddr(ipaddr, mntpt) < 0)
		sysfatal("can't read my ip address");
	dnslog("starting %s%sdns %s%s%son %I's %s",
		(cfg.straddle? "straddling ": ""),
		(cfg.cachedb? "caching ": ""),
		(cfg.serve?   "udp server ": ""),
		(cfg.justforw? "forwarding-only ": ""),
		(cfg.resolver? "resolver ": ""), ipaddr, mntpt);

	opendatabase();
	now = time(nil);		/* open time files before we fork */
	nowns = nsec();

	snprint(servefile, sizeof servefile, "#s/dns%s", ext);
	dir = dirstat(servefile);
	if (dir)
		sysfatal("%s exists; another dns instance is running",
			servefile);
	free(dir);

	/* don't unmount here; could deadlock */
//	while (unmount(servefile, mntpt) >= 0)
//		;
	mountinit(servefile, mntpt);	/* forks, parent exits */

	srand(now*getpid());
	db2cache(1);
//	dnageallnever();

	if (cfg.straddle && !seerootns())
		dnslog("straddle server misconfigured; can't resolve root name servers");
	/*
	 * fork without sharing heap.
	 * parent waits around for child to die, then forks & restarts.
	 * child may spawn udp server, notify procs, etc.; when it gets too
	 * big or too old, it kills itself and any children.
	 *
	 * /srv/dns remains open and valid, but /net/dns was only mounted in
	 * a child's separate namespace from 9p service, to avoid a deadlock
	 * from serving our own namespace, so we must remount it upon restart,
	 * in a separate process and namespace.
	 */
	for (;;) {
		start = time(nil);
		/* don't unmount here; could deadlock */
//		unmount(servefile, mntpt);
		kid = rfork(RFPROC|RFFDG|RFNOTEG|RFNAMEG);
		switch (kid) {
		case -1:
			sysfatal("fork failed: %r");
		case 0:
			if(cfg.serve)
				dnudpserver(mntpt);
			if(sendnotifies)
				notifyproc();
			io();		/* serve 9p; return implies restart */
			_exits("restart");
		}
		sleep(1000);	/* wait for 9p service to start */
		justremount(servefile, mntpt);
		while ((pid = waitpid()) != kid && pid != -1)
			continue;
		dnslog("restarting");
	}
}
Example #8
0
void
threadmain(int argc, char *argv[])
{
	int serveudp, servetcp;
	char *service;

	serveudp = 0;
	servetcp = 0;
	service = "dns";
	ARGBEGIN{
	case 'd':
		debug = 1;
		traceactivity = 1;
		break;
	case 'f':
		dbfile = EARGF(usage());
		break;
	case 'x':
		service = EARGF(usage());
		break;
	case 'r':
		resolver = 1;
		break;
	case 's':
		serveudp = 1;
		cachedb = 1;
		break;
	case 't':
		servetcp = 1;
		cachedb = 1;
		break;
	case 'a':
		maxage = atoi(EARGF(usage()));
		break;
	case 'z':
		zonerefreshprogram = EARGF(usage());
		break;
	case 'n':
		sendnotifies = 1;
		break;
	case 'U':
		udpaddr = estrdup(netmkaddr(EARGF(usage()), "udp", "domain"));
		break;
	case 'T':
		tcpaddr = estrdup(netmkaddr(EARGF(usage()), "tcp", "domain"));
		break;
	default:
		usage();
	}ARGEND
	
	if(argc)
		usage();
	if(serveudp && servetcp)
		checkaddress();

	rfork(RFNOTEG);

	/* start syslog before we fork */
	fmtinstall('F', fcallfmt);
	dninit();
	if(myipaddr(ipaddr, mntpt) < 0)
		sysfatal("can't read my ip address");

	syslog(0, logfile, "starting dns on %I", ipaddr);

	opendatabase();

	mountinit(service);

	now = time(0);
	srand(now*getpid());
	db2cache(1);

	if(serveudp)
		proccreate(dnudpserver, nil, STACK);
	if(servetcp)
		proccreate(dntcpserver, nil, STACK);
	if(sendnotifies)
		proccreate(notifyproc, nil, STACK);

	io();
}