Beispiel #1
0
int32 network_addlistener(bool v6,  const char *addr,  uint16 port)
{
	SESSION *s;
	int optval, fd;

#if !defined(ENABLE_IPV6)
	if(v6 == true) {
		ShowError(read_message("Source.common.network_addlistener"), (v6==true?'t':'f'),  addr, port);
		return -1;
	}
#endif


#ifdef ENABLE_IPV6
	if(v6 == true)
		fd = socket(AF_INET6, SOCK_STREAM, 0);
	else
#endif
		fd = socket(AF_INET, SOCK_STREAM, 0);

	// Error?
	if(fd == -1) {
		ShowError(read_message("Source.common.network_addlistener2"), (v6==true?'t':'f'),  addr, port,    errno, strerror(errno));
		return -1;
	}

	// Too many connections?
	if(fd >= MAXCONN) {
		ShowError(read_message("Source.common.network_addlistener3"), (v6==true?'t':'f'),  addr, port, MAXCONN);
		close(fd);
		return -1;
	}


	s = &g_Session[fd];
	if(s->type != NST_FREE) { // additional checks.. :)
		ShowError(read_message("Source.common.network_addlistener4"), (v6==true?'t':'f'),  addr, port, fd);
		close(fd);
		return -1;
	}


	// Fill ip addr structs
#ifdef ENABLE_IPV6
	if(v6 == true) {
		memset(&s->addr.v6, 0x00, sizeof(s->addr.v6));
		s->addr.v6.sin6_family = AF_INET6;
		s->addr.v6.sin6_port = htons(port);
		if(inet_pton(AF_INET6, addr, &s->addr.v6.sin6_addr) != 1) {
			ShowError(read_message("Source.common.network_addlistener5"), (v6==true?'t':'f'),  addr, port);
			close(fd);
			return -1;
		}

	} else {
#endif
		memset(&s->addr.v4, 0x00, sizeof(s->addr.v4));
		s->addr.v4.sin_family = AF_INET;
		s->addr.v4.sin_port = htons(port);
		s->addr.v4.sin_addr.s_addr = inet_addr(addr);
#ifdef ENABLE_IPV6
	}
#endif


	// if OS has support for SO_REUSEADDR, apply the flag
	// so the address could be used when there're still time_wait sockets outstanding from previous application run.
#ifdef SO_REUSEADDR
	optval=1;
	setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
#endif

	// Bind
#ifdef ENABLE_IPV6
	if(v6 == true) {
		if(bind(fd, (struct sockaddr *)&s->addr.v6,  sizeof(s->addr.v6)) == -1) {
			ShowError(read_message("Source.common.add_listener6"), (v6==true?'t':'f'),  addr, port, errno, strerror(errno));
			close(fd);
			return -1;
		}
	} else {
#endif
		if(bind(fd, (struct sockaddr *)&s->addr.v4,  sizeof(s->addr.v4)) == -1) {
			ShowError(read_message("Source.common.add_listener6"), (v6==true?'t':'f'),  addr, port, errno, strerror(errno));
			close(fd);
			return -1;
		}
#ifdef ENABLE_IPV6
	}
#endif

	if(listen(fd, l_ListenBacklog) == -1) {
		ShowError(read_message("Source.common.add_listener7"), (v6==true?'t':'f'),  addr, port, errno, strerror(errno));
		close(fd);
		return -1;
	}


	// Set to nonblock!
	if(_setnonblock(fd) == false) {
		ShowError(read_message("Source.common.addlistener8"), (v6==true?'t':'f'),  addr, port, errno, strerror(errno));
		close(fd);
		return -1;
	}


	// Rgister @ evdp.
	if(evdp_addlistener(fd, &s->evdp_data) != true) {
		ShowError(read_message("Source.common.addlistener9"), (v6==true?'t':'f'),  addr, port);
		close(fd);
		return -1;
	}


	// Apply flags on Session array for this conneciton.
	if(v6 == true)  s->v6 = true;
	else            s->v6 = false;

	s->type = NST_LISTENER;
	s->onRecv = _network_accept;

	ShowStatus(read_message("Source.common.add_listener10"), addr, port, (v6==true ? "(ipv6)":"(ipv4)"));

	return fd;
}//end: network_addlistener()
Beispiel #2
0
int32 network_addlistener(bool v6,  const char *addr,  uint16 port){
	SESSION *s;
	int optval, fd;

#if !defined(ENABLE_IPV6)
	if(v6 == true){
		 ShowError("network_addlistener(%c, '%s', %u):  this release has no IPV6 support.\n",  (v6==true?'t':'f'),  addr, port);
		 return -1;
	}
#endif


#ifdef ENABLE_IPV6
	if(v6 == true)
		fd = socket(AF_INET6, SOCK_STREAM, 0);
	else
#endif
		fd = socket(AF_INET, SOCK_STREAM, 0);

	// Error?
	if(fd == -1){
		ShowError("network_addlistener(%c, '%s', %u):  socket() failed (errno: %u / %s)\n",  (v6==true?'t':'f'),  addr, port,    errno, strerror(errno));
		return -1;
	}
	
	// Too many connections?
	if(fd >= MAXCONN){
		ShowError("network_addlistener(%c, '%s', %u):  cannot create listener, exceeds more than supported connections (%u).\n", (v6==true?'t':'f'),  addr, port, MAXCONN);
		close(fd);
		return -1;
	}
	
	
	s = &g_Session[fd];
	if(s->type != NST_FREE){ // additional checks.. :)
			ShowError("network_addlistener(%c, '%s', %u): failed, got fd #%u which is already in use in local session table?!\n", (v6==true?'t':'f'),  addr, port, fd);
			close(fd);
			return -1;
	}
	
	
	// Fill ip addr structs
#ifdef ENABLE_IPV6
	if(v6 == true){
		memset(&s->addr.v6, 0x00, sizeof(s->addr.v6));
		s->addr.v6.sin6_family = AF_INET6;
		s->addr.v6.sin6_port = htons(port);
		if(inet_pton(AF_INET6, addr, &s->addr.v6.sin6_addr) != 1){
			ShowError("network_addlistener(%c, '%s', %u): failed to parse the given IPV6 address.\n",  (v6==true?'t':'f'),  addr, port);
			close(fd);
			return -1;
		}
		
	}else{
#endif
		memset(&s->addr.v4, 0x00, sizeof(s->addr.v4));
		s->addr.v4.sin_family = AF_INET;
		s->addr.v4.sin_port = htons(port);
		s->addr.v4.sin_addr.s_addr = inet_addr(addr);
#ifdef ENABLE_IPV6
	}
#endif
		 

	// if OS has support for SO_REUSEADDR, apply the flag
	// so the address could be used when there're still time_wait sockets outstanding from previous application run.
#ifdef SO_REUSEADDR
	optval=1;
	setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
#endif

	// Bind
#ifdef ENABLE_IPV6
	if(v6 == true){
		if( bind(fd, (struct sockaddr*)&s->addr.v6,  sizeof(s->addr.v6)) == -1) {
			ShowError("network_addlistener(%c, '%s', %u): bind failed (errno: %u / %s)\n",  (v6==true?'t':'f'),  addr, port, errno, strerror(errno));
			close(fd);
			return -1;
		}
	}else{
#endif
		if( bind(fd, (struct sockaddr*)&s->addr.v4,  sizeof(s->addr.v4)) == -1) {
            ShowError("network_addlistener(%c, '%s', %u): bind failed (errno: %u / %s)\n",  (v6==true?'t':'f'),  addr, port, errno, strerror(errno));
			close(fd);
			return -1;
		}		
#ifdef ENABLE_IPV6
	}
#endif

	if( listen(fd, l_ListenBacklog) == -1){
		ShowError("network_addlistener(%c, '%s', %u): listen failed (errno: %u / %s)\n",  (v6==true?'t':'f'),  addr, port, errno, strerror(errno));
		close(fd);
		return -1;
	}
		

	// Set to nonblock!
	if(_setnonblock(fd) == false){
		ShowError("network_addlistener(%c, '%s', %u): cannot set to nonblock (errno: %u / %s)\n",  (v6==true?'t':'f'),  addr, port, errno, strerror(errno));
		close(fd);
		return -1;
	}	


	// Rgister @ evdp.
	if( evdp_addlistener(fd, &s->evdp_data) != true){
		ShowError("network_addlistener(%c, '%s', %u): eventdispatcher subsystem returned an error.\n",  (v6==true?'t':'f'),  addr, port);
		close(fd);
		return -1;
	}
	
	
	// Apply flags on Session array for this conneciton.
	if(v6 == true)	s->v6 = true;
	else			s->v6 = false;
	
	s->type = NST_LISTENER;
	s->onRecv = _network_accept;

	ShowStatus("Added Listener on '%s':%u\n", addr, port, (v6==true ? "(ipv6)":"(ipv4)") );

	return fd;
}//end: network_addlistener()