Пример #1
0
int acl_sane_socketpair(int domain, int type, int protocol, ACL_SOCKET result[2])
{
	ACL_SOCKET listener = acl_inet_listen("127.0.0.1:0", 1, ACL_BLOCKING);
	char addr[64];

	(void) domain;

	result[0] = ACL_SOCKET_INVALID;
	result[1] = ACL_SOCKET_INVALID;

	if (listener  == ACL_SOCKET_INVALID) {
		acl_msg_error("%s(%d), %s: listen error %s",
			__FILE__, __LINE__, __FUNCTION__, acl_last_serror());
		return -1;
	}

	acl_tcp_set_nodelay(listener);
	if (acl_getsockname(listener, addr, sizeof(addr)) < 0) {
		acl_msg_error("%s(%d), %s: getoskname error %s",
			__FILE__, __LINE__, __FUNCTION__, acl_last_serror());
		acl_socket_close(listener);
		return -1;
	}

	result[0] = acl_inet_connect(addr, ACL_BLOCKING, 0);
	if (result[0] == ACL_SOCKET_INVALID) {
		acl_msg_error("%s(%d), %s: connect %s error %s",
			__FILE__, __LINE__, __FUNCTION__, addr, acl_last_serror());
		acl_socket_close(listener);
		return -1;
	}

	result[1] = acl_inet_accept(listener);

	acl_socket_close(listener);

	if (result[1] == ACL_SOCKET_INVALID) {
		acl_msg_error("%s(%d), %s: accept error %s",
			__FILE__, __LINE__, __FUNCTION__, acl_last_serror());
		acl_socket_close(result[0]);
		result[0] = ACL_SOCKET_INVALID;
		return -1;
	}

	acl_tcp_set_nodelay(result[0]);
	acl_tcp_set_nodelay(result[1]);
	return 0;
}
Пример #2
0
stream_hook* stream::setup_hook(stream_hook* hook)
{
	if (stream_ == NULL)
	{
		logger_error("stream_ null");
		return NULL;
	}

	stream_hook* old_hook = hook_;

	if (stream_->type == ACL_VSTREAM_TYPE_FILE)
	{
		ACL_FSTREAM_RD_FN read_fn = stream_->fread_fn;
		ACL_FSTREAM_WR_FN write_fn = stream_->fwrite_fn;

		stream_->fread_fn = fread_hook;
		stream_->fwrite_fn = fsend_hook;
		acl_vstream_add_object(stream_, HOOK_KEY, this);

		if (hook->open(stream_) == false)
		{
			// 如果打开失败,则恢复

			stream_->fread_fn = read_fn;
			stream_->fwrite_fn = write_fn;
			acl_vstream_del_object(stream_, HOOK_KEY);
			return hook;
		}
	}
	else
	{
		ACL_VSTREAM_RD_FN read_fn = stream_->read_fn;
		ACL_VSTREAM_WR_FN write_fn = stream_->write_fn;

		stream_->read_fn = read_hook;
		stream_->write_fn = send_hook;
		acl_vstream_add_object(stream_, HOOK_KEY, this);

		acl_tcp_set_nodelay(ACL_VSTREAM_SOCK(stream_));

		if (hook->open(stream_) == false)
		{
			// 如果打开失败,则恢复

			stream_->read_fn = read_fn;
			stream_->write_fn = write_fn;
			acl_vstream_del_object(stream_, HOOK_KEY);
			return hook;
		}
	}

	hook_ = hook;
	return old_hook;
}
Пример #3
0
static void run_server(const char *addr)
{
    ACL_VSTREAM *sstream = acl_vstream_listen(addr, 128);
    acl_pthread_pool_t *pool;
    CONN *conn;
    acl_pthread_t tid;
    acl_pthread_attr_t attr;
    ACL_VSTREAM *client;

    if (sstream == NULL) {
        acl_msg_error("listen %s error(%s)", addr, acl_last_serror());
        return;
    }

    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

    printf("listening on %s ...\n", addr);
    pool = acl_thread_pool_create(10, 10);
    while (1) {
        acl_mem_slice_delay_destroy();
        if (acl_read_wait(ACL_VSTREAM_SOCK(sstream), 5) == -1)
            continue;
        client = acl_vstream_accept(sstream, NULL, 0);
        if (client == NULL) {
            acl_msg_error("accept error(%s)", acl_last_serror());
            break;
        }
        acl_tcp_set_nodelay(ACL_VSTREAM_SOCK(client));
        conn = acl_mycalloc(1, sizeof(CONN));
        conn->stream = client;

        if (0)
            thread_run(conn);
        else if (1)
            acl_pthread_create(&tid, &attr, thread_main, conn);
        else
            acl_pthread_pool_add(pool, thread_run, conn);
    }

    acl_vstream_close(sstream);
}
Пример #4
0
bool ssl_aio_stream::ssl_client_init()
{
#ifdef HAS_POLARSSL
	ACL_VSTREAM* stream = get_vstream();
	acl_assert(stream);

	// 0. Initialize the RNG and the session data
	havege_init((havege_state*) hs_);

	int   ret;
	if ((ret = ssl_init((ssl_context*) ssl_)) != 0)
	{
		logger_error("failed, ssl_init returned %d", ret);
		return false;
	}

	ssl_set_endpoint((ssl_context*) ssl_, SSL_IS_CLIENT);
	ssl_set_authmode((ssl_context*) ssl_, SSL_VERIFY_NONE);

	ssl_set_rng((ssl_context*) ssl_, ::havege_random, hs_);
	//ssl_set_dbg((ssl_context*) ssl_, my_debug, stdout);
	ssl_set_bio((ssl_context*) ssl_, __sock_read, this, __sock_send, this);

	const int* cipher_suites = ssl_list_ciphersuites();
	if (cipher_suites == NULL)
	{
		logger_error("ssl_list_ciphersuites null");
		return false;
	}

	ssl_set_ciphersuites((ssl_context*) ssl_, cipher_suites);
	ssl_set_session((ssl_context*) ssl_, (ssl_session*) ssn_);

	acl_vstream_ctl(stream,
		ACL_VSTREAM_CTL_READ_FN, __ssl_read,
		ACL_VSTREAM_CTL_WRITE_FN, __ssl_send,
		ACL_VSTREAM_CTL_CTX, this,
		ACL_VSTREAM_CTL_END);
	acl_tcp_set_nodelay(ACL_VSTREAM_SOCK(stream));
#endif
	return true;
}
Пример #5
0
socket_stream* server_socket::accept(int timeout /* = 0 */)
{
	if (fd_ == ACL_SOCKET_INVALID)
	{
		logger_error("server socket not opened!");
		return NULL;
	}

	if (block_ && timeout > 0)
	{
		if (acl_read_wait(fd_, timeout) == -1)
			return NULL;
	}

	ACL_SOCKET fd = acl_accept(fd_, NULL, 0, NULL);
	if (fd == ACL_SOCKET_INVALID)
	{
		if (block_)
			logger_error("accept error %s", last_serror());
		else if (last_error() != ACL_EAGAIN
			&& last_error() != ACL_EWOULDBLOCK)
		{
			logger_error("accept error %s", last_serror());
		}
		return NULL;
	}

	socket_stream* client = new socket_stream();
	if (client->open(fd) == false)
	{
		logger_error("create socket_stream error!");
		return NULL;
	}

	if (!unix_sock_)
		acl_tcp_set_nodelay(fd);

	return client;
}
Пример #6
0
bool socket_stream::open_ssl_client(void)
{
	if (stream_ == NULL)
	{
		logger_error("stream_ null");
		return false;
	}

#ifdef HAS_POLARSSL
	// 如果打开已经是 SSL 模式的流,则直接返回
	if (ssl_ != NULL)
	{
		acl_assert(ssn_);
		acl_assert(hs_);
		return true;
	}

	ssl_ = acl_mycalloc(1, sizeof(ssl_context));
	ssn_ = acl_mycalloc(1, sizeof(ssl_session));
	hs_  = acl_mymalloc(sizeof(havege_state));

	// Initialize the RNG and the session data
	::havege_init((havege_state*) hs_);

	int   ret;

	// Setup stuff
	if ((ret = ssl_init((ssl_context*) ssl_)) != 0)
	{
		logger_error("failed, ssl_init returned %d", ret);
		return false;
	}

	ssl_set_endpoint((ssl_context*) ssl_, SSL_IS_CLIENT);
	ssl_set_authmode((ssl_context*) ssl_, SSL_VERIFY_NONE);

	ssl_set_rng((ssl_context*) ssl_, havege_random, hs_);
	//ssl_set_dbg(ssl_, my_debug, stdout);
	ssl_set_bio((ssl_context*) ssl_, sock_read, this, sock_send, this);

	const int* cipher_suites = ssl_list_ciphersuites();
	if (cipher_suites == NULL)
	{
		logger_error("ssl_list_ciphersuites null");
		return false;
	}

	ssl_set_ciphersuites((ssl_context*) ssl_, cipher_suites);
	ssl_set_session((ssl_context*) ssl_, (ssl_session*) ssn_);

	acl_vstream_ctl(stream_,
		ACL_VSTREAM_CTL_READ_FN, ssl_read,
		ACL_VSTREAM_CTL_WRITE_FN, ssl_send,
		ACL_VSTREAM_CTL_CTX, this,
		ACL_VSTREAM_CTL_END);
	acl_tcp_set_nodelay(ACL_VSTREAM_SOCK(stream_));

	// Handshake
	while((ret = ssl_handshake((ssl_context*) ssl_)) != 0)
	{
		if (ret != POLARSSL_ERR_NET_WANT_READ
			&& ret != POLARSSL_ERR_NET_WANT_WRITE)
		{
			logger_error("ssl_handshake failed: 0x%x", ret);
			return false;
		}
	}

	return true;
#else
	logger_error("define HAS_POLARSSL first!");
	return false;
#endif
}
Пример #7
0
static void run_one(TLS_APPL_STATE *client_tls_ctx)
{
	ACL_VSTREAM *client;
	TLS_SESS_STATE *client_sess_ctx;
	TLS_CLIENT_START_PROPS tls_props;
	char  buf[4096];
	int   i, ret;
	time_t last, now;

	int   tls_level = 2;
	char *tls_nexthop = "test.com.cn";
	char *host = "test.com.cn";
	char *namaddrport = "test.com.cn";
	char *serverid = "service:addr:port:helo";
	char *tls_protocols = SSL_TXT_TLSV1;
	char *tls_grade = "low";  /* high, medium, low, export, null */
	char *tls_exclusions = "";
	ACL_ARGV *tls_matchargv = 0;

	client = acl_vstream_connect(serv_addr, ACL_BLOCKING, 20, 30, 8192);
	if (client == NULL) {
		printf("connect %s error(%s)\n", serv_addr, acl_last_serror());
		return;
	}

	acl_tcp_set_nodelay(ACL_VSTREAM_SOCK(client));

#if 0
	client_sess_ctx = TLS_CLIENT_START(&tls_props,
			ctx = client_tls_ctx,
			stream = client,
			log_level = var_client_tls_loglevel,
			timeout = var_client_starttls_tmout,
			tls_level = tls_level,
			nexthop = tls_nexthop,
			host = host,
			namaddr = namaddrport,
			serverid = serverid,
			protocols = tls_protocols,
			cipher_grade = tls_grade,
			cipher_exclusions = tls_exclusions,
			matchargv = tls_matchargv,
			fpt_dgst = var_client_tls_fpt_dgst);
#else
	tls_props.ctx = client_tls_ctx;
	tls_props.stream = client;
	tls_props.log_level = var_client_tls_loglevel;
	tls_props.timeout = var_client_starttls_tmout;
	tls_props.tls_level = tls_level;
	tls_props.nexthop = tls_nexthop;
	tls_props.host = host;
	tls_props.namaddr = namaddrport;
	tls_props.serverid = serverid;
	tls_props.protocols = tls_protocols;
	tls_props.cipher_grade = tls_grade;
	tls_props.cipher_exclusions = tls_exclusions;
	tls_props.matchargv = tls_matchargv;
	tls_props.fpt_dgst = var_client_tls_fpt_dgst;

	client_sess_ctx = tls_client_start(&tls_props);
#endif

	if (client_sess_ctx == NULL) {
		printf("TLS_CLIENT_START error\n");
		acl_vstream_close(client);
		return;
	}

	if (tls_level >= TLS_LEV_VERIFY) {
		if (!TLS_CERT_IS_TRUSTED(client_sess_ctx)) {
			printf("Server certificate not trusted\n");
		}
	}

	if (tls_level > TLS_LEV_ENCRYPT) {
		if (!TLS_CERT_IS_MATCHED(client_sess_ctx)) {
			printf("Server certificate not verified\n");
		}
	}

	time(&last);
	i = 0;
	while (1) {
		ret = acl_vstream_fprintf(client, "hello world\n");
		if (ret == ACL_VSTREAM_EOF)
			goto END;
		ret = acl_vstream_gets(client, buf, sizeof(buf));
		if (ret == ACL_VSTREAM_EOF)
			goto END;
		break;
		i++;
		if (i % 50000 == 0) {
			time(&now);
			printf("client: i=%d, time=%ld\n", i, now - last);
			last = now;
		}
	}

if (0)
{
	if (acl_vstream_writen(client, request, strlen(request)) == ACL_VSTREAM_EOF)
		printf("write request error\n");
	else {
		while (1) {
			if (acl_vstream_gets_nonl(client, buf, sizeof(buf)) == ACL_VSTREAM_EOF)
				break;
			/*
			printf("%s\n", buf);
			*/
		}
		/*
		printf("gets respond over now\n");
		*/
	}
}

END:
	tls_client_stop(client_tls_ctx, client, var_client_starttls_tmout, 0, client_sess_ctx);
	acl_vstream_close(client);
}