示例#1
0
//---------------------------------------------------------------------
// itm_socket_bind
//---------------------------------------------------------------------
static int itm_socket_bind(int fd, struct sockaddr *addr,  int addrlen)
{
	int start_port = -1;
	int index;
	int iter;

	struct sockaddr_in *address4 = (struct sockaddr_in*)addr;
#ifdef AF_INET6
	struct sockaddr_in6 *address6 = (struct sockaddr_in6*)addr;
#endif

	if (addrlen <= 20) {
		start_port = ntohs(address4->sin_port);
	}
#ifdef AF_INET6
	else {
		start_port = ntohs(address6->sin6_port);
	}
#endif

	if (start_port < 0) {
		return -10;
	}

	index = start_port;

	for (iter = 0; iter < 65536; iter++) {
		if (addrlen <= 20) {
			address4->sin_port = htons((unsigned short)index);	
		}
	#ifdef AF_INET6
		else {
			address6->sin6_port = htons((unsigned short)index);
		}
	#endif
		if (apr_bind(fd, addr, addrlen) == 0) {
			return 0;
		}
		if (itm_autoport == 0) break;
		if (++index >= 65535) {
			index = start_port;
		}
	}

	return -20;
}
示例#2
0
static apr_status_t rfc1413_connect(apr_socket_t **newsock, conn_rec *conn,
                                    server_rec *srv)
{
    apr_status_t rv;
    apr_sockaddr_t *localsa, *destsa;

    if ((rv = apr_sockaddr_info_get(&localsa, conn->local_ip, APR_UNSPEC, 
                              0, /* ephemeral port */
                              0, conn->pool)) != APR_SUCCESS) {
        /* This should not fail since we have a numeric address string
         * as the host. */
        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, srv,
                     "rfc1413: apr_sockaddr_info_get(%s) failed",
                     conn->local_ip);
        return rv;
    }
    
    if ((rv = apr_sockaddr_info_get(&destsa, conn->remote_ip, 
                              localsa->family, /* has to match */
                              RFC1413_PORT, 0, conn->pool)) != APR_SUCCESS) {
        /* This should not fail since we have a numeric address string
         * as the host. */
        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, srv,
                     "rfc1413: apr_sockaddr_info_get(%s) failed",
                     conn->remote_ip);
        return rv;
    }

    if ((rv = apr_socket_create(newsock, 
                                localsa->family, /* has to match */
                                SOCK_STREAM, conn->pool)) != APR_SUCCESS) {
	ap_log_error(APLOG_MARK, APLOG_CRIT, rv, srv,
                     "rfc1413: error creating query socket");
        return rv;
    }

    if ((rv = apr_socket_timeout_set(*newsock, apr_time_from_sec(ap_rfc1413_timeout)))
            != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_CRIT, rv, srv,
                     "rfc1413: error setting query socket timeout");
        apr_socket_close(*newsock);
        return rv;
    }

/*
 * Bind the local and remote ends of the query socket to the same
 * IP addresses as the connection under investigation. We go
 * through all this trouble because the local or remote system
 * might have more than one network address. The RFC1413 etc.
 * client sends only port numbers; the server takes the IP
 * addresses from the query socket.
 */

    if ((rv = apr_bind(*newsock, localsa)) != APR_SUCCESS) {
	ap_log_error(APLOG_MARK, APLOG_CRIT, rv, srv,
                     "rfc1413: Error binding query socket to local port");
        apr_socket_close(*newsock);
	return rv;
    }

/*
 * errors from connect usually imply the remote machine doesn't support
 * the service; don't log such an error
 */
    if ((rv = apr_connect(*newsock, destsa)) != APR_SUCCESS) {
        apr_socket_close(*newsock);
        return rv;
    }

    return APR_SUCCESS;
}
示例#3
0
文件: beos.c 项目: kheradmand/Break
int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
{
    int remaining_threads_to_start, i,j;
    apr_status_t rv;
    ap_listen_rec *lr;    
    pconf = _pconf;
    ap_server_conf = s;

    /* Increase the available pool of fd's.  This code from
     * Joe Kloss <*****@*****.**>
     */
    if( FD_SETSIZE > 128 && (i = _kset_fd_limit_( 128 )) < 0 ){
        ap_log_error(APLOG_MARK, APLOG_ERR, i, s,
            "could not set FD_SETSIZE (_kset_fd_limit_ failed)");
    }

    /* BeOS R5 doesn't support pipes on select() calls, so we use a 
       UDP socket as these are supported in both R5 and BONE.  If we only cared
       about BONE we'd use a pipe, but there it is.
       As we have UDP support in APR, now use the APR functions and check all the
       return values...
      */
    if (apr_sockaddr_info_get(&udp_sa, "127.0.0.1", APR_UNSPEC, 7772, 0, _pconf)
        != APR_SUCCESS){
        ap_log_error(APLOG_MARK, APLOG_ALERT, errno, s,
            "couldn't create control socket information, shutting down");
        return 1;
    }
    if (apr_socket_create(&udp_sock, udp_sa->family, SOCK_DGRAM,
                      _pconf) != APR_SUCCESS){
        ap_log_error(APLOG_MARK, APLOG_ALERT, errno, s,
            "couldn't create control socket, shutting down");
        return 1;
    }
    if (apr_bind(udp_sock, udp_sa) != APR_SUCCESS){
        ap_log_error(APLOG_MARK, APLOG_ALERT, errno, s,
            "couldn't bind UDP socket!");
        return 1;
    }
 
    if ((num_listening_sockets = ap_setup_listeners(ap_server_conf)) < 1) {
        ap_log_error(APLOG_MARK, APLOG_ALERT, 0, s,
            "no listening sockets available, shutting down");
        return 1;
    }

    ap_log_pid(pconf, ap_pid_fname);

    /*
     * Create our locks... 
     */
    
    /* accept_mutex
     * used to lock around select so we only have one thread
     * in select at a time
     */
    rv = apr_thread_mutex_create(&accept_mutex, 0, pconf);
    if (rv != APR_SUCCESS) {
        /* tsch tsch, can't have more than one thread in the accept loop
           at a time so we need to fall on our sword... */
        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
                     "Couldn't create accept lock");
        return 1;
    }

    /* worker_thread_count_mutex
     * locks the worker_thread_count so we have ana ccurate count...
     */
    rv = apr_thread_mutex_create(&worker_thread_count_mutex, 0, pconf);
    if (rv != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s,
                     "Couldn't create worker thread count lock");
        return 1;
    }

    /*
     * Startup/shutdown... 
     */
    
    if (!is_graceful) {
        /* setup the scoreboard shared memory */
        if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
            return 1;
        }

        for (i = 0; i < HARD_SERVER_LIMIT; i++) {
            ap_scoreboard_image->parent[i].pid = 0;
            for (j = 0;j < HARD_THREAD_LIMIT; j++)
                ap_scoreboard_image->servers[i][j].tid = 0;
        }
    }

    if (HARD_SERVER_LIMIT == 1)
        ap_scoreboard_image->parent[0].pid = getpid();

    set_signals();

    /* Sanity checks to avoid thrashing... */
    if (max_spare_threads < min_spare_threads )
        max_spare_threads = min_spare_threads;

    /* If we're doing a graceful_restart then we're going to see a lot
     * of threads exiting immediately when we get into the main loop
     * below (because we just sent them AP_SIG_GRACEFUL).  This happens 
     * pretty rapidly... and for each one that exits we'll start a new one 
     * until we reach at least threads_min_free.  But we may be permitted to
     * start more than that, so we'll just keep track of how many we're
     * supposed to start up without the 1 second penalty between each fork.
     */
    remaining_threads_to_start = ap_threads_to_start;
    /* sanity check on the number to start... */
    if (remaining_threads_to_start > ap_thread_limit) {
	    remaining_threads_to_start = ap_thread_limit;
    }

    /* setup the child pool to use for the workers.  Each worker creates
     * a seperate pool of its own to use.
     */
    apr_pool_create(&pchild, pconf);

    /* Now that we have the child pool (pchild) we can allocate
     * the listenfds and creat the pollset...
     */
    listening_sockets = apr_palloc(pchild,
       sizeof(*listening_sockets) * (num_listening_sockets + 1));

    listening_sockets[0] = udp_sock;
    for (lr = ap_listeners, i = 1; i <= num_listening_sockets; lr = lr->next, ++i)
	    listening_sockets[i]=lr->sd;

    /* we assume all goes OK...hmm might want to check that! */
    /* if we're in one_process mode we don't want to start threads
     * do we??
     */
    if (!is_graceful && !one_process) {
	    startup_threads(remaining_threads_to_start);
	    remaining_threads_to_start = 0;
    }
    else {
	    /* give the system some time to recover before kicking into
	     * exponential mode */
        hold_off_on_exponential_spawning = 10;
    }

    /*
     * record that we've entered the world !
     */
    ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
		"%s configured -- resuming normal operations",
		ap_get_server_version());

    ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,
		"Server built: %s", ap_get_server_built());

    restart_pending = shutdown_pending = 0;

    /*
     * main_loop until it's all over
     */
    if (!one_process) {
        server_main_loop(remaining_threads_to_start);
    
        tell_workers_to_exit(); /* if we get here we're exiting... */
        sleep(1); /* give them a brief chance to exit */
    } else {
        proc_info *my_info = (proc_info *)malloc(sizeof(proc_info));
        my_info->slot = 0;
        apr_pool_create(&my_info->tpool, pchild);
        worker_thread(my_info);
    }
        
    /* close the UDP socket we've been using... */
    apr_socket_close(listening_sockets[0]);

    if ((one_process || shutdown_pending) && !child_fatal) {
        const char *pidfile = NULL;
        pidfile = ap_server_root_relative (pconf, ap_pid_fname);
        if ( pidfile != NULL && unlink(pidfile) == 0)
            ap_log_error(APLOG_MARK, APLOG_INFO, 0, ap_server_conf,
                         "removed PID file %s (pid=%ld)", pidfile, 
                         (long)getpid());
    }

    if (one_process) {
        return 1;
    }
        
    /*
     * If we get here we're shutting down...
     */
    if (shutdown_pending) {
        /* Time to gracefully shut down:
         * Kill child processes, tell them to call child_exit, etc...
         */
        if (beosd_killpg(getpgrp(), SIGTERM) < 0)
            ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
             "killpg SIGTERM");
      
        /* use ap_reclaim_child_processes starting with SIGTERM */
        ap_reclaim_child_processes(1);

        if (!child_fatal) {         /* already recorded */
            /* record the shutdown in the log */
            ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
                         "caught SIGTERM, shutting down");
        }
    
        return 1;
    }

    /* we've been told to restart */
    signal(SIGHUP, SIG_IGN);

    if (is_graceful) {
        ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
		    AP_SIG_GRACEFUL_STRING " received.  Doing graceful restart");
    }
    else {
        /* Kill 'em all.  Since the child acts the same on the parents SIGTERM 
         * and a SIGHUP, we may as well use the same signal, because some user
         * pthreads are stealing signals from us left and right.
         */
	    
        ap_reclaim_child_processes(1);		/* Start with SIGTERM */
	    ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf,
		    "SIGHUP received.  Attempting to restart");
    }
    
    /* just before we go, tidy up the locks we've created to prevent a 
     * potential leak of semaphores... */
    apr_thread_mutex_destroy(worker_thread_count_mutex);
    apr_thread_mutex_destroy(accept_mutex);
    
    return 0;
}
示例#4
0
//---------------------------------------------------------------------
// itm_socket_create
//---------------------------------------------------------------------
static int itm_socket_create(void)
{
	unsigned long noblock1 = 1, noblock2 = 1, noblock3 = 1;
	unsigned long reuseaddr = 0;
	unsigned long reuseport = 0;
	unsigned long buffer1 = 0;
	unsigned long buffer2 = 0;
	struct sockaddr_in host_outer4;
	struct sockaddr_in host_inner4;
	struct sockaddr_in host_dgram4;
#ifdef AF_INET6
	struct sockaddr_in6 host_outer6;
	struct sockaddr_in6 host_inner6;
	struct sockaddr_in6 host_dgram6;
#endif

	itm_socket_release();

	itm_outer_sock4 = apr_socket(PF_INET, SOCK_STREAM, 0);
	if (itm_outer_sock4 < 0) return -1;
	itm_inner_sock4 = apr_socket(PF_INET, SOCK_STREAM, 0);
	if (itm_inner_sock4 < 0) {
		itm_socket_release();
		return -1;
	}
	itm_dgram_sock4 = apr_socket(PF_INET, SOCK_DGRAM, 0);
	if (itm_dgram_sock4 < 0) {
		itm_socket_release();
		return -2;
	}

	apr_enable(itm_outer_sock4, APR_CLOEXEC);
	apr_enable(itm_inner_sock4, APR_CLOEXEC);
	apr_enable(itm_dgram_sock4, APR_CLOEXEC);

	memset(&host_outer4, 0, sizeof(host_outer4));
	memset(&host_inner4, 0, sizeof(host_inner4));
	memset(&host_dgram4, 0, sizeof(host_dgram4));

	// 配置套接字监听地址
	host_outer4.sin_addr.s_addr = 0;
	host_inner4.sin_addr.s_addr = itm_inner_addr4;
	host_dgram4.sin_addr.s_addr = 0;
	host_outer4.sin_port = htons((short)itm_outer_port4);
	host_inner4.sin_port = htons((short)itm_inner_port4);
	host_dgram4.sin_port = htons((short)itm_dgram_port4);
	host_outer4.sin_family = PF_INET;
	host_inner4.sin_family = PF_INET;
	host_dgram4.sin_family = PF_INET;

	// 设置套接字参数
	apr_ioctl(itm_outer_sock4, FIONBIO, &noblock1);
	apr_ioctl(itm_inner_sock4, FIONBIO, &noblock2);
	apr_ioctl(itm_dgram_sock4, FIONBIO, &noblock3);
	
	// 地址复用
	if (itm_reuseaddr == 0) {
	#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
		reuseaddr = 0;
	#else
		reuseaddr = 1;
	#endif
	}
	else {
		reuseaddr = (itm_reuseaddr == 1)? 1 : 0;
	}

	// 端口复用
	reuseport = (itm_reuseport == 1)? 1 : 0;

	apr_setsockopt(itm_outer_sock4, SOL_SOCKET, SO_REUSEADDR, (char*)&reuseaddr, sizeof(reuseaddr));
	apr_setsockopt(itm_inner_sock4, SOL_SOCKET, SO_REUSEADDR, (char*)&reuseaddr, sizeof(reuseaddr));
	apr_setsockopt(itm_dgram_sock4, SOL_SOCKET, SO_REUSEADDR, (char*)&reuseaddr, sizeof(reuseaddr));

#ifdef SO_REUSEPORT
	apr_setsockopt(itm_outer_sock4, SOL_SOCKET, SO_REUSEPORT, (char*)&reuseport, sizeof(reuseport));
	apr_setsockopt(itm_inner_sock4, SOL_SOCKET, SO_REUSEPORT, (char*)&reuseport, sizeof(reuseport));
	apr_setsockopt(itm_dgram_sock4, SOL_SOCKET, SO_REUSEPORT, (char*)&reuseport, sizeof(reuseport));
#endif

	buffer1 = itm_dgram_blimit;
	buffer2 = itm_dgram_blimit;

	if (itm_dgram_blimit > 0) {
		apr_setsockopt(itm_dgram_sock4, SOL_SOCKET, SO_RCVBUF, (char*)&buffer1, sizeof(buffer1));
		apr_setsockopt(itm_dgram_sock4, SOL_SOCKET, SO_SNDBUF, (char*)&buffer2, sizeof(buffer2));
	}

	// 绑定本地套接字
	if (apr_bind(itm_outer_sock4, (struct sockaddr*)&host_outer4, 0) ||
		apr_bind(itm_inner_sock4, (struct sockaddr*)&host_inner4, 0) ||
		apr_bind(itm_dgram_sock4, (struct sockaddr*)&host_dgram4, 0)) {
		itm_socket_release();
		return -3;
	}

	// 初始化 WIN32的 RESET修复
	if (apr_win32_init(itm_dgram_sock4)) {
		itm_socket_release();
		return -4;
	}

	// 数据流监听开始
	if (apr_listen(itm_outer_sock4, itm_backlog) || 
		apr_listen(itm_inner_sock4, itm_backlog)) {
		itm_socket_release();
		return -5;
	}

	apr_sockname(itm_outer_sock4, (struct sockaddr*)&host_outer4, NULL);
	apr_sockname(itm_inner_sock4, (struct sockaddr*)&host_inner4, NULL);
	apr_sockname(itm_dgram_sock4, (struct sockaddr*)&host_dgram4, NULL);

	itm_outer_port4 = htons(host_outer4.sin_port);
	itm_inner_port4 = htons(host_inner4.sin_port);
	itm_dgram_port4 = htons(host_dgram4.sin_port);

	itmd_outer4.fd = itm_outer_sock4;
	itmd_inner4.fd = itm_inner_sock4;
	itmd_dgram4.fd = itm_dgram_sock4;

	itmd_outer4.mode = ITMD_OUTER_HOST4;
	itmd_inner4.mode = ITMD_INNER_HOST4;
	itmd_dgram4.mode = ITMD_DGRAM_HOST4;
	itmd_dgram4.mask = 0;

#ifdef AF_INET6
	memset(&host_outer6, 0, sizeof(host_outer6));
	memset(&host_inner6, 0, sizeof(host_inner6));
	memset(&host_dgram6, 0, sizeof(host_dgram6));

	// 配置套接字监听地址
	memcpy(&host_inner6.sin6_addr.s6_addr, itm_inner_addr6, 16);
	host_outer6.sin6_port = htons((short)itm_outer_port6);
	host_inner6.sin6_port = htons((short)itm_inner_port6);
	host_dgram6.sin6_port = htons((short)itm_dgram_port6);
	host_outer6.sin6_family = AF_INET6;
	host_inner6.sin6_family = AF_INET6;
	host_dgram6.sin6_family = AF_INET6;

	// 如果 IPv6外部端口允许
	if (itm_outer_port6 >= 0) {
		unsigned long noblock4 = 1;
		unsigned long enable4 = 1;
		int size4 = sizeof(struct sockaddr_in6);

		itm_outer_sock6 = apr_socket(AF_INET6, SOCK_STREAM, 0);

		if (itm_outer_sock6 < 0) {
			itm_socket_release();
			return -10;
		}

	#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
		apr_setsockopt(itm_outer_sock6, IPPROTO_IPV6, IPV6_V6ONLY,
			(const char*)&enable4, sizeof(enable4));
	#endif

		apr_ioctl(itm_outer_sock6, FIONBIO, &noblock4);

		apr_setsockopt(itm_outer_sock6, SOL_SOCKET, SO_REUSEADDR, 
			(char*)&reuseaddr, sizeof(reuseaddr));

	#ifdef SO_REUSEPORT
		apr_setsockopt(itm_outer_sock6, SOL_SOCKET, SO_REUSEPORT, 
			(char*)&reuseport, sizeof(reuseport));
	#endif

		apr_enable(itm_outer_sock6, APR_CLOEXEC);

		if (apr_bind(itm_outer_sock6, (struct sockaddr*)&host_outer6, 
			sizeof(host_outer6))) {
			itm_socket_release();
			return -12;
		}

		if (apr_listen(itm_outer_sock6, itm_backlog)) {
			itm_socket_release();
			return -13;
		}

		apr_sockname(itm_outer_sock6, (struct sockaddr*)&host_outer6, &size4);
		itm_outer_port6 = htons(host_outer6.sin6_port);
		enable4 = enable4 + 5;
	}

	// 如果 IPv6内部端口允许
	if (itm_inner_port6 >= 0) {
		unsigned long noblock5 = 1;
		unsigned long enable5 = 1;
		int size5 = sizeof(struct sockaddr_in6);

		itm_inner_sock6 = apr_socket(AF_INET6, SOCK_STREAM, 0);

		if (itm_inner_sock6 < 0) {
			itm_socket_release();
			return -14;
		}

	#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
		apr_setsockopt(itm_inner_sock6, IPPROTO_IPV6, IPV6_V6ONLY,
			(const char*)&enable5, sizeof(enable5));
	#endif

		apr_ioctl(itm_inner_sock6, FIONBIO, &noblock5);

		apr_setsockopt(itm_inner_sock6, SOL_SOCKET, SO_REUSEADDR, 
				(char*)&reuseaddr, sizeof(reuseaddr));
	
	#ifdef SO_REUSEPORT
		apr_setsockopt(itm_inner_sock6, SOL_SOCKET, SO_REUSEPORT, 
				(char*)&reuseport, sizeof(reuseport));
	#endif

		apr_enable(itm_inner_sock6, APR_CLOEXEC);

		if (apr_bind(itm_inner_sock6, (struct sockaddr*)&host_inner6, 
			sizeof(host_inner6))) {
			itm_socket_release();
			return -15;
		}

		if (apr_listen(itm_inner_sock6, itm_backlog)) {
			itm_socket_release();
			return -16;
		}

		apr_sockname(itm_inner_sock6, (struct sockaddr*)&host_inner6, &size5);
		itm_inner_port6 = htons(host_inner6.sin6_port);
		enable5 = enable5 + 5;
	}

	// 如果 IPv6数据报端口允许
	if (itm_dgram_port6 >= 0) {
		unsigned long noblock6 = 1;
		unsigned long enable6 = 1;
		int size6 = sizeof(struct sockaddr_in6);

		itm_dgram_sock6 = apr_socket(AF_INET6, SOCK_DGRAM, 0);

		if (itm_dgram_sock6 < 0) {
			itm_socket_release();
			return -17;
		}

	#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
		apr_setsockopt(itm_dgram_sock6, IPPROTO_IPV6, IPV6_V6ONLY,
			(const char*)&enable6, sizeof(enable6));
	#endif

		apr_ioctl(itm_dgram_sock6, FIONBIO, &noblock6);

		apr_setsockopt(itm_dgram_sock6, SOL_SOCKET, SO_REUSEADDR, 
			(char*)&reuseaddr, sizeof(reuseaddr));

	#ifdef SO_REUSEPORT
		apr_setsockopt(itm_dgram_sock6, SOL_SOCKET, SO_REUSEPORT, 
			(char*)&reuseport, sizeof(reuseport));
	#endif

		buffer1 = itm_dgram_blimit;
		buffer2 = itm_dgram_blimit;

		if (itm_dgram_blimit > 0) {
			apr_setsockopt(itm_dgram_sock6, SOL_SOCKET, SO_RCVBUF, 
				(char*)&buffer1, sizeof(buffer1));
			apr_setsockopt(itm_dgram_sock6, SOL_SOCKET, SO_SNDBUF,
				(char*)&buffer2, sizeof(buffer2));
		}

		apr_enable(itm_dgram_sock6, APR_CLOEXEC);

		if (apr_bind(itm_dgram_sock6, (struct sockaddr*)&host_dgram6, 
			sizeof(host_dgram6))) {
			itm_socket_release();
			return -18;
		}

		// 初始化 WIN32的 RESET修复
		if (apr_win32_init(itm_dgram_sock6)) {
			itm_socket_release();
			return -19;
		}

		apr_sockname(itm_dgram_sock6, (struct sockaddr*)&host_dgram6, &size6);
		itm_dgram_port6 = htons(host_dgram6.sin6_port);
		enable6 = enable6 + 5;
	}

	itmd_outer6.fd = itm_outer_sock6;
	itmd_inner6.fd = itm_inner_sock6;
	itmd_dgram6.fd = itm_dgram_sock6;

	itmd_outer6.mode = ITMD_OUTER_HOST6;
	itmd_inner6.mode = ITMD_INNER_HOST6;
	itmd_dgram6.mode = ITMD_DGRAM_HOST6;
	itmd_dgram6.mask = 0;

#endif

	#ifdef __unix
	signal(SIGPIPE, SIG_IGN);
	#endif
	
	reuseport = reuseport + 10;

	return 0;
}