cacert, cert, key)) == NULL)
cacert, cert, key, cipher_list, out_state)) == NULL)
int main(int argc, char *argv[]){	unsigned int loop;	int newfd;	tunala_world_t world;	tunala_item_t *t_item;	unsigned char *proxy_ip;	unsigned short proxy_port;	/* Overridables */	const char *proxyhost = def_proxyhost;	const char *listenhost = def_listenhost;	unsigned int max_tunnels = def_max_tunnels;	const char *cacert = def_cacert;	const char *cert = def_cert;	const char *key = def_key;	const char *engine_id = def_engine_id;	int server_mode = def_server_mode;/* Parse command-line arguments */next_arg:	argc--; argv++;	if(argc > 0) {		if(strcmp(*argv, "-listen") == 0) {			if(argc < 2)				return usage("-listen requires an argument", 0);			argc--; argv++;			listenhost = *argv;			goto next_arg;		} else if(strcmp(*argv, "-proxy") == 0) {			if(argc < 2)				return usage("-proxy requires an argument", 0);			argc--; argv++;			proxyhost = *argv;			goto next_arg;		} else if(strcmp(*argv, "-maxtunnels") == 0) {			if(argc < 2)				return usage("-maxtunnels requires an argument", 0);			argc--; argv++;			if(!parse_max_tunnels(*argv, &max_tunnels))				return 1;			goto next_arg;		} else if(strcmp(*argv, "-cacert") == 0) {			if(argc < 2)				return usage("-cacert requires an argument", 0);			argc--; argv++;			if(strcmp(*argv, "NULL") == 0)				cacert = NULL;			else				cacert = *argv;			goto next_arg;		} else if(strcmp(*argv, "-cert") == 0) {			if(argc < 2)				return usage("-cert requires an argument", 0);			argc--; argv++;			if(strcmp(*argv, "NULL") == 0)				cert = NULL;			else				cert = *argv;			goto next_arg;		} else if(strcmp(*argv, "-key") == 0) {			if(argc < 2)				return usage("-key requires an argument", 0);			argc--; argv++;			if(strcmp(*argv, "NULL") == 0)				key = NULL;			else				key = *argv;			goto next_arg;		} else if(strcmp(*argv, "-engine") == 0) {			if(argc < 2)				return usage("-engine requires an argument", 0);			argc--; argv++;			engine_id = *argv;			goto next_arg;		} else if(strcmp(*argv, "-server") == 0) {			if(argc < 2)				return usage("-server requires an argument", 0);			argc--; argv++;			if(!parse_server_mode(*argv, &server_mode))				return 1;			goto next_arg;		} else if((strcmp(*argv, "-h") == 0) ||				(strcmp(*argv, "-help") == 0) ||				(strcmp(*argv, "-?") == 0)) {			fprintf(stderr, "%s\n", helpstring);			return 0;		} else			return usage(*argv, 1);	}	/* Initialise network stuff */	if(!ip_initialise())		return err_str0("ip_initialise failed");	err_str0("ip_initialise succeeded");	/* Create the SSL_CTX */	if((world.ssl_ctx = initialise_ssl_ctx(server_mode, engine_id,			cacert, cert, key)) == NULL)		return err_str1("initialise_ssl_ctx(engine_id=%s) failed",			(engine_id == NULL) ? "NULL" : engine_id);	err_str1("initialise_ssl_ctx(engine_id=%s) succeeded",			(engine_id == NULL) ? "NULL" : engine_id);	/* Create the listener */	if((world.listen_fd = ip_create_listener(listenhost)) == -1)		return err_str1("ip_create_listener(%s) failed", listenhost);	err_str1("ip_create_listener(%s) succeeded", listenhost);	if(!ip_parse_address(proxyhost, &proxy_ip, &proxy_port, 0))		return err_str1("ip_parse_address(%s) failed", proxyhost);	err_str1("ip_parse_address(%s) succeeded", proxyhost);	fprintf(stderr, "Info - proxying to %d.%d.%d.%d:%d\n",			(int)proxy_ip[0], (int)proxy_ip[1],			(int)proxy_ip[2], (int)proxy_ip[3], (int)proxy_port);	fprintf(stderr, "Info - set maxtunnels to %d\n", (int)max_tunnels);	fprintf(stderr, "Info - set to operate as an SSL %s\n",			(server_mode ? "server" : "client"));	/* Initialise the rest of the stuff */	world.tunnels_used = world.tunnels_size = 0;	world.tunnels = NULL;	world.server_mode = server_mode;	selector_init(&world.selector);/* We're ready to loop */main_loop:	/* Should we listen for *new* tunnels? */	if(world.tunnels_used < max_tunnels)		selector_add_listener(&world.selector, world.listen_fd);	/* We should add in our existing tunnels */	for(loop = 0; loop < world.tunnels_used; loop++)		selector_add_tunala(&world.selector, world.tunnels + loop);	/* Now do the select */	switch(selector_select(&world.selector)) {	case -1:		fprintf(stderr, "selector_select returned a badness error.\n");		abort();	case 0:		fprintf(stderr, "Warn, selector_select returned 0 - signal??\n");		goto main_loop;	default:		break;	}	/* Accept new connection if we should and can */	if((world.tunnels_used < max_tunnels) && (selector_get_listener(					&world.selector, world.listen_fd,					&newfd) == 1)) {		/* We have a new connection */		if(!tunala_world_new_item(&world, newfd,					proxy_ip, proxy_port)) {			fprintf(stderr, "tunala_world_new_item failed\n");			abort();		}		fprintf(stderr, "Info, new tunnel opened, now up to %d\n",				world.tunnels_used);	}	/* Give each tunnel its moment, note the while loop is because it makes	 * the logic easier than with "for" to deal with an array that may shift	 * because of deletes. */	loop = 0;	t_item = world.tunnels;	while(loop < world.tunnels_used) {		if(!tunala_item_io(&world.selector, t_item)) {			/* We're closing whether for reasons of an error or a			 * natural close. Don't increment loop or t_item because			 * the next item is moving to us! */			tunala_world_del_item(&world, loop);			fprintf(stderr, "Info, tunnel closed, down to %d\n",					world.tunnels_used);		}		else {			/* Move to the next item */			loop++;			t_item++;		}	}	goto main_loop;	/* Should never get here */	abort();	return 1;}