コード例 #1
0
ファイル: main.c プロジェクト: Lens-Flare/pwnat2
int do_keepalive(void * param) {
	struct keepalive_param * kp = param;
	pid_t ppid = getppid();
	pk_keepalive_t * pk = make_pk_keepalive(PK_KEEPALIVE);
	
	while (!kill(ppid, 0)) {
		pk_send(*kp->sockfd, pk, 0);
		_sleep(*kp->interval * 5000);
	}
	
	pk->type = PK_EXITING;
	pk_send(*kp->sockfd, pk, 0);
	
	close(*kp->sockfd);
	return 0;
}
コード例 #2
0
ファイル: srvapi.c プロジェクト: tomidelucca/TP1-SO
static void
spawn_worker(Packet * pckt_req)
{
	Packet pckt_ans;

	int pid = fork();
	if (pid == 0) {
		printf("Processing command [%d]...\n", pckt_req->opcode);
		process_request(pckt_req, &pckt_ans);

		sleep(sleep_time);
		pk_send(pckt_req->pid, &pckt_ans, sizeof(pckt_ans));
		printf("Packet sent. [%d byte/s]\n", (int) sizeof(pckt_ans));
		exit(0);
	} else if (pid > 0) {
		// Do nothing, wait not needed because
		// sigaction set for SIGCHILD
	} else {
		// TODO handle error
	}
}
コード例 #3
0
ファイル: main.c プロジェクト: Lens-Flare/pwnat2
int main(int argc, const char * argv[]) {
	struct {
		int verbose, _1_, keepalive, _2_, timeout, _3_;
		char * hostname, * port, * source_type, * source_name;
	} cfg;
	
	struct config_var vars[] = {
//		{"name",			{0, f, r, n},	'-',	"ENV_NAME",				DEFAULT_VALUE,				&my_variable},
		{"verbose",			{0, 1, 0, 0},	'v',	NULL,					(void *)1,					&cfg.verbose},
		{"quiet",			{0, 1, 0, 0},	'q',	NULL,					(void *)-1,					&cfg.verbose},
		{"hostname",		{0, 0, 1, 0},	'h',	"HOSTNAME",				"localhost",				&cfg.hostname},
		{"port",			{0, 0, 1, 0},	'p',	"PORT",					SERVER_PORT,				&cfg.port},
		{"source-type",		{0, 0, 1, 0},	't',	"SOURCE_TYPE",			"file",						&cfg.source_type},
		{"source-name",		{0, 0, 1, 0},	's',	"SOURCE_NAME",			NULL,						&cfg.source_name},
		{"keepalive-int",	{0, 0, 1, 1},	'k',	"KEEPALIVE_INTERVAL",	(void *)300,				&cfg.keepalive},
		{"packet-timeout",	{0, 0, 1, 1},	't',	"PACKET_TIMEOUT",		(void *)DEFAULT_TIMEOUT,	&cfg.timeout}
	};
	
	int sockfd = 0;
	ssize_t retv = 0;
	char buf[256];
	
	pk_keepalive_t * pk = (pk_keepalive_t *)buf;
	pk_advertize_t * ad;
	
	pid_t keepalive_pid = 0;
	struct keepalive_param kp = {&sockfd, &cfg.keepalive};
	
	
	config(argc, argv, sizeof(vars)/sizeof(struct config_var), vars);
	
	ad = (pk_advertize_t *)alloc_packet(PACKET_SIZE_MAX);
	if ((retv = !ad))
		goto exit;
	
	printf("Connecting to %s:%s\n", cfg.hostname, cfg.port);
	if ((retv = connect_socket(cfg.hostname, cfg.port, &sockfd))) {
		fprintf(stderr, "Connection failed\n");
		goto free;
	}
	
	if ((retv = send_handshake(sockfd, cfg.timeout))) {
		fprintf(stderr, "Bad handshake\n");
		goto free;
	}
	
	
	_fork(&keepalive_pid, &do_keepalive, &kp);
	
	
	if (!strcasecmp("file", cfg.source_type)) {
		FILE * file = fopen(cfg.source_name, "r");
		if ((retv = !file)) {
			perror("fopen");
			goto free;
		}
		
		// states:
		//  0 - whitespace before name
		//  1 - name
		//  2 - whitespace between name and port
		//  3 - port
		//  4 - whitespace after port
		char state = 0, name[220], port[7];
		for (int c = 0, i = 0, j = 0; (c = fgetc(file)) > 0;)
			switch (state) {
				case 0: // whitespace before name
					if (c == '#') {
						state = 4;
						break;
					} else if (c <= 0x20 || 0x7F <= c)
						break;
					state = 1;
					i = 0;
					
				case 1: // name
					if ((retv = i >= sizeof(name))) {
						fprintf(stderr, "Names cannot be more than %lu characters\n", sizeof(name) - 1);
						goto fclose;
					} else if (j == 0 && 0x30 <= c && c <= 0x39) {
						// if the first character is a number, interpret it as a port
						port[j++] = c;
						state = 3;
						break;
					} if (0x20 < c && c < 0x7F) {
						name[i++] = c;
						break;
					}
					state = 2;
					
				case 2: // whitespace between name and port
					if (c <= 0x20 || 0x7F <= c)
						break;
					state = 3;
					j = 0;
					
				case 3: // port
					if ((retv = j >= sizeof(port))) {
						fprintf(stderr, "Port number cannot be greater than 65535\n");
						goto fclose;
					} else if (0x30 <= c && c <= 0x39) {
						port[j++] = c;
						state = 3;
						break;
					} else if (0x20 < c && c < 0x7F && c != '#') {
						fprintf(stderr, "Port numbers must be numeric\n");
						goto fclose;
					}
					state = 4;
					
				case 4: // whitespace after port
					if (c == '\n' || c == '\r') {
						name[i] = 0;
						port[j] = 0;
						
						if (i == 0 && j == 0) {
							state = 0;
							break;
						}
						
						int portnum = atoi(port);
						if ((retv = portnum > USHRT_MAX)) {
							fprintf(stderr, "Port number cannot be greater than 65535\n");
							goto fclose;
						}
						
						init_pk_advertize(ad, portnum, name);
						
						if (!*name)
							ad->name.data[0] = '+';
						
						retv = pk_send(sockfd, (pk_keepalive_t *)ad, 0); if ((retv = retv < 0)) goto free;
						
						state = 0;
					}
					break;
					
				default:
					fprintf(stderr, "Internal error\n");
					retv = 1;
					goto fclose;
					break;
			}
		
	fclose:
		fclose(file);
	} else if (!strcasecmp("sqlite", cfg.source_type)) {
		fprintf(stderr, "Using SQLite as a source is currently unsupported\n");
		retv = 1;
		goto free;
	} else {
		fprintf(stderr, "Bad source type %s\n", cfg.source_type);
		retv = 1;
		goto free;
	}
	
free:
	free_packet((pk_keepalive_t *)ad);
	
	while (!retv) {
		retv = pk_recv(sockfd, buf, cfg.timeout, 0);
		
		if (retv <= 0)
			break;
		
		retv = check_version(pk);
	}
	
//close:
	if (sockfd)
		close(sockfd);
	kill(keepalive_pid, SIGTERM);
exit:
	return (int)retv;
}