Пример #1
0
int fd_collection::addpipe(int fdrd, int fdwr)
{
	fdcoll_logfunc("fdrd=%d, fdwr=%d", fdrd, fdwr);

	if (!is_valid_fd(fdrd) || !is_valid_fd(fdwr))
		return -1;

	lock();

	// Sanity check to remove any old objects using the same fd!!
	socket_fd_api* p_fdrd_api_obj = get_sockfd(fdrd);
	BULLSEYE_EXCLUDE_BLOCK_START
	if (p_fdrd_api_obj) {
		fdcoll_logwarn("[fd=%d] Deleting old duplicate object (%p)", fdrd, p_fdrd_api_obj);
		unlock();
		handle_close(fdrd, true);
		lock();
	}
	BULLSEYE_EXCLUDE_BLOCK_END
	socket_fd_api* p_fdwr_api_obj = get_sockfd(fdwr);
	BULLSEYE_EXCLUDE_BLOCK_START
	if (p_fdwr_api_obj) {
		fdcoll_logwarn("[fd=%d] Deleting old duplicate object (%p)", fdwr, p_fdwr_api_obj);
		unlock();
		handle_close(fdwr, true);
		lock();
	}
	BULLSEYE_EXCLUDE_BLOCK_END

	unlock();
	p_fdrd_api_obj = new pipeinfo(fdrd);
	p_fdwr_api_obj = new pipeinfo(fdwr);
	lock();

	BULLSEYE_EXCLUDE_BLOCK_START
	if (p_fdrd_api_obj == NULL) {
		fdcoll_logpanic("[fd=%d] Failed creating new pipeinfo (%m)", fdrd);
	}
	if (p_fdwr_api_obj == NULL) {
		fdcoll_logpanic("[fd=%d] Failed creating new pipeinfo (%m)", fdwr);
	}
	BULLSEYE_EXCLUDE_BLOCK_END

	m_p_sockfd_map[fdrd] = p_fdrd_api_obj;
	m_p_sockfd_map[fdwr] = p_fdwr_api_obj;

	unlock();

	return 0;
}
Пример #2
0
			void run()
			{ 
				while(1)
				{
					int fd_client;
					get_sockfd(fd_client);
					handle_chat(fd_client);
				}
			}
Пример #3
0
int fd_collection::add_cq_channel_fd(int cq_ch_fd, ring* p_ring)
{
	fdcoll_logfunc("cq_ch_fd=%d", cq_ch_fd);

	if (!is_valid_fd(cq_ch_fd))
		return -1;

	lock();

	epfd_info* p_fd_info = get_epfd(cq_ch_fd);
	BULLSEYE_EXCLUDE_BLOCK_START
	if (p_fd_info) {
		fdcoll_logwarn("[fd=%d] Deleting old duplicate sockinfo object (%p)", cq_ch_fd, p_fd_info);
		unlock();
		handle_close(cq_ch_fd, true);
		lock();
	}
	BULLSEYE_EXCLUDE_BLOCK_END

	// Sanity check to remove any old objects using the same fd!!
	socket_fd_api* p_cq_ch_fd_api_obj = get_sockfd(cq_ch_fd);
	BULLSEYE_EXCLUDE_BLOCK_START
	if (p_cq_ch_fd_api_obj) {
		fdcoll_logwarn("[fd=%d] Deleting old duplicate object (%p)", cq_ch_fd, p_cq_ch_fd_api_obj);
		unlock();
		handle_close(cq_ch_fd, true);
		lock();
	}
	BULLSEYE_EXCLUDE_BLOCK_END

	// Check if cq_channel_info was already created
	cq_channel_info* p_cq_ch_info = get_cq_channel_fd(cq_ch_fd);
	BULLSEYE_EXCLUDE_BLOCK_START
	if (p_cq_ch_info) {
		fdcoll_logwarn("cq channel fd already exists in fd_collection");
		m_p_cq_channel_map[cq_ch_fd] = NULL;
		delete p_cq_ch_info;
		p_cq_ch_info = NULL;
	}
	BULLSEYE_EXCLUDE_BLOCK_END

	unlock();
	p_cq_ch_info = new cq_channel_info(p_ring);
	lock();

	BULLSEYE_EXCLUDE_BLOCK_START
	if (p_cq_ch_info == NULL) {
		fdcoll_logpanic("[fd=%d] Failed creating new cq_channel_info (%m)", cq_ch_fd);
	}
	BULLSEYE_EXCLUDE_BLOCK_END
	m_p_cq_channel_map[cq_ch_fd] = p_cq_ch_info;

	unlock();

	return 0;
}
Пример #4
0
void private_chat(sLoginInfo *send, int newfd)
{
	char dest[BUF_SIZE] = {0};
	char no_user_online[] = {"user on online!"};
	
	if(get_sockfd(send->login_name) == OK)
		write(newfd, no_user_online, strlen(no_user_online)+1);//error newfd
	else
	//	format_buf(dest,send->buf, newfd);
		;
		write(newfd, dest, strlen(dest)+1);//error newfd
}
Пример #5
0
//Triggers connection close of all handled fds.
//This is important for TCP connection which needs some time to terminate the connection,
//before the connection can be finally and properly closed.
void fd_collection::prepare_to_close()
{
	lock();
	for (int fd = 0; fd < m_n_fd_map_size; ++fd) {
		if (m_p_sockfd_map[fd]) {
			if(!g_is_forked_child) {
				socket_fd_api *p_sfd_api = get_sockfd(fd);
				if (p_sfd_api) {
					p_sfd_api->prepare_to_close(true);
				}
			}
		}
	}
	unlock();
}
Пример #6
0
int fd_collection::del_sockfd(int fd, bool b_cleanup /*=false*/)
{
	int ret_val = -1;
	socket_fd_api *p_sfd_api;

	p_sfd_api = get_sockfd(fd);

	if (p_sfd_api) {
		//TCP socket need some timer to before it can be deleted,
		//in order to gracefuly terminate TCP connection
		//so we have to stages:
		//1. Prepare to close: kikstarts TCP connection termination
		//2. Socket deletion when TCP connection == CLOSED
		if (p_sfd_api->prepare_to_close()) {
			//the socket is already closable
			ret_val = del(fd, b_cleanup, m_p_sockfd_map);
		}
		else {
			lock();
			//The socket is not ready for close.
			//Delete it from fd_col and add it to pending_to_remove list.
			//This socket will be handled and destroyed now by fd_col.
			//This will be done from fd_col timer handler.
			if (m_p_sockfd_map[fd] == p_sfd_api) {
				m_p_sockfd_map[fd] = NULL;
				m_pendig_to_remove_lst.push_front(p_sfd_api);
			}

			if (m_pendig_to_remove_lst.size() == 1) {
				//Activate timer
				try {
					m_timer_handle = g_p_event_handler_manager->register_timer_event(250, this, PERIODIC_TIMER, 0);
				} catch (vma_exception &error) {
	  				fdcoll_logdbg("recovering from %s", error.what());
					unlock();
	  				return -1;
				}
			}
			unlock();
			ret_val = 0;
		}
	}

	return ret_val;
}
Пример #7
0
void fd_collection::statistics_print_helper(int fd, vlog_levels_t log_level)
{
	socket_fd_api* socket_fd;
	epfd_info* epoll_fd;

	if ((socket_fd = get_sockfd(fd))) {
		vlog_printf(log_level, "==================== SOCKET FD ===================\n");
		socket_fd->statistics_print(log_level);
		goto found_fd;
	}
	if ((epoll_fd = get_epfd(fd))) {
		vlog_printf(log_level, "==================== EPOLL FD ====================\n");
		epoll_fd->statistics_print(log_level);
		goto found_fd;
	}

	return;

found_fd:

	vlog_printf(log_level, "==================================================\n");
}
Пример #8
0
int fd_collection::addsocket(int fd, int domain, int type, bool check_offload /*= false*/)
{
	transport_t transport;
	const int SOCK_TYPE_MASK = 0xf;
	int sock_type = type & SOCK_TYPE_MASK;
	int sock_flags = type & ~SOCK_TYPE_MASK;

	if (check_offload && !create_offloaded_sockets()) {
		fdcoll_logdbg("socket [fd=%d, domain=%d, type=%d] is not offloaded by thread rules or by VMA_OFFLOADED_SOCKETS", fd, domain, type);
		return -1;
	}

	// IPV4 domain only (at least today)
	if (domain != AF_INET)
		return -1;

	fdcoll_logfunc("fd=%d", fd);

	if (!is_valid_fd(fd))
		return -1;

	lock();

	// Sanity check to remove any old sockinfo object using the same fd!!
	socket_fd_api* p_sfd_api_obj = get_sockfd(fd);
	BULLSEYE_EXCLUDE_BLOCK_START
	if (p_sfd_api_obj) {
		fdcoll_logwarn("[fd=%d] Deleting old duplicate sockinfo object (%p)", fd, p_sfd_api_obj);
		unlock();
		handle_close(fd);
		lock();
	}
	BULLSEYE_EXCLUDE_BLOCK_END

	unlock();
	try {
		switch (sock_type) {
			case SOCK_DGRAM:
			{	transport = __vma_match_by_program(PROTO_UDP, safe_mce_sys().app_id);
				if (transport == TRANS_OS) {
					fdcoll_logdbg("All UDP rules are consistent and instructing to use OS. TRANSPORT: OS");
					return -1;
				}
				fdcoll_logdbg("UDP rules are either not consistent or instructing to use VMA. TRANSPORT: VMA");
				p_sfd_api_obj = new sockinfo_udp(fd);
				break;
			}
			case SOCK_STREAM:
			{
				transport = __vma_match_by_program(PROTO_TCP, safe_mce_sys().app_id);
				if (transport == TRANS_OS) {
					fdcoll_logdbg("All TCP rules are consistent and instructing to use OS.transport == USE_OS");
					return -1;
				}
				fdcoll_logdbg("TCP rules are either not consistent or instructing to use VMA.transport == USE_VMA");
				p_sfd_api_obj = new sockinfo_tcp(fd);
				break;
			}
			default:
				fdcoll_logdbg("unsupported socket type=%d", sock_type);
				return -1;
		}
	} catch (vma_exception& e) {
	  fdcoll_logdbg("recovering from %s", e.what());
	  return -1;
	}
	lock();

	BULLSEYE_EXCLUDE_BLOCK_START
	if (p_sfd_api_obj == NULL) {
		fdcoll_logpanic("[fd=%d] Failed creating new sockinfo (%m)", fd);
	}
	BULLSEYE_EXCLUDE_BLOCK_END

	if (sock_flags) {
		if (sock_flags & SOCK_NONBLOCK)
			p_sfd_api_obj->fcntl(F_SETFL, O_NONBLOCK);
		if (sock_flags & SOCK_CLOEXEC)
			p_sfd_api_obj->fcntl(F_SETFD, FD_CLOEXEC);
	}

	m_p_sockfd_map[fd] = p_sfd_api_obj;

	unlock();

	return fd;
}
Пример #9
0
void fd_collection::clear()
{
	int fd;

	fdcoll_logfunc("");

	if (!m_p_sockfd_map)
		return;

	lock();

	if (m_timer_handle) {
		g_p_event_handler_manager->unregister_timer_event(this, m_timer_handle);
		m_timer_handle = 0;
	}

	//internal thread should be already dead and these sockets should have been deleted through the internal thread.
	sock_fd_api_list_t::iterator itr;
	for (itr = m_pendig_to_remove_lst.begin(); itr != m_pendig_to_remove_lst.end(); itr++) {
		(*itr)->force_close();
	}

	// Clean up all left overs sockinfo
	for (fd = 0; fd < m_n_fd_map_size; ++fd) {
		if (m_p_sockfd_map[fd]) {
			if(!g_is_forked_child) {
				socket_fd_api *p_sfd_api = get_sockfd(fd);
				if (p_sfd_api) {
					p_sfd_api->statistics_print();
					p_sfd_api->destructor_helper();
				}
			}
	/**** Problem here - if one sockinfo is in a blocked call rx()/tx() then this will block too!!!
	 * also - statistics_print() and destructor_helper() should not be called in two lines above, because they are called from the dtor
			delete m_p_sockfd_map[fd];
	*/
			m_p_sockfd_map[fd] = NULL;
			fdcoll_logdbg("destroyed fd=%d", fd);
		}

		if (m_p_epfd_map[fd]) {
			epfd_info *p_epfd = get_epfd(fd);
			if (p_epfd) {
				delete p_epfd;
			}
			m_p_epfd_map[fd] = NULL;
			fdcoll_logdbg("destroyed epfd=%d", fd);
		}

		if (m_p_cq_channel_map[fd]) {
			cq_channel_info *p_cq_ch_info = get_cq_channel_fd(fd);
			if (p_cq_ch_info) {
				delete p_cq_ch_info;
			}
			m_p_cq_channel_map[fd] = NULL;
			fdcoll_logdbg("destroyed cq_channel_fd=%d", fd);
		}

		if (m_p_tap_map[fd]) {
			m_p_tap_map[fd] = NULL;
			fdcoll_logdbg("destroyed tapfd=%d", fd);
		}
	}

	unlock();
	fdcoll_logfunc("done");
}