Ejemplo n.º 1
0
/* Initialise the UDP socket and router worker thread.
 * Aborts on failure.
*/
void router_init(void)
{
	/* Event object used for notification of new packets and exit signal. */
	
	if((router_event = WSACreateEvent()) == WSA_INVALID_EVENT)
	{
		log_printf(LOG_ERROR, "Error creating WSA event object: %s", w32_error(WSAGetLastError()));
		abort();
	}
	
	if(ipx_use_pcap)
	{
		if((private_socket = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
		{
			log_printf(LOG_ERROR, "Error creating retransmit socket: %s", w32_error(WSAGetLastError()));
			abort();
		}
		
		struct sockaddr_in addr;
		addr.sin_family      = AF_INET;
		addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
		addr.sin_port        = htons(0);
		
		if(bind(private_socket, (struct sockaddr*)(&addr), sizeof(addr)) == -1)
		{
			log_printf(LOG_ERROR, "Error binding retransmit socket: %s", w32_error(WSAGetLastError()));
			abort();
		}
	}
	else{
		_init_socket(&shared_socket, main_config.udp_port, TRUE);
		_init_socket(&private_socket, 0, FALSE);
	}
	
	router_running = true;
	
	if(!(router_thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(&router_main), NULL, 0, NULL)))
	{
		log_printf(LOG_ERROR, "Cannot create router worker thread: %s", w32_error(GetLastError()));
		abort();
	}
}
Ejemplo n.º 2
0
acceptor::acc_impl::acc_impl(const char* port) noexcept(false)
{
	_listen_socket = INVALID_SOCKET;
	_result = NULL;

	ZeroMemory(&_hints, sizeof(_hints));
	_hints.ai_family = AF_INET;
	_hints.ai_socktype = SOCK_STREAM;
	_hints.ai_protocol = IPPROTO_TCP;
	_hints.ai_flags = AI_PASSIVE;

	error_code err = _init_socket(port);
	if (err != error_code::NO_ERR) throw tool::exception(err);
}
Ejemplo n.º 3
0
int cnn_start(struct connection_info *ci, bool join) {
	_init_socket(ci);

	ci->is_running = 1;

	if (0 != pthread_create(&ci->tid, NULL, _working, ci)) {
		log_fatal("failed to create thread");

		return 1;
	}

	if (join) {
		if (pthread_join(ci->tid, NULL)) {
			log_fatal("failed to wait the thread");

			return 2;
		}
	}

	return 0;
}
Ejemplo n.º 4
0
static void *_working(void *arg) {
	pthread_detach(pthread_self());

	__lock;
	_connection_num++;
	__unlock;

	struct connection_info *ci = (struct connection_info *) arg;
	ci->is_connected = 0;

	struct sockaddr_in server_addr;
	bzero(&server_addr, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = htons(ci->port);

	if (0 == inet_aton(ci->ip, &server_addr.sin_addr)) {
		log_fatal("failed to initialize socket ip");
		exit(1);
	}

	while (ci->is_running) {
		int ret = connect(ci->socket, (struct sockaddr *) &server_addr,
				sizeof(server_addr));

		if (0 == ret) {
			ci->callback_funs.on_connected(ci->id);
			ci->is_connected = 1;
		} else if (0 > ret && EINPROGRESS != errno) {
			log_info("failed to connect to destination");
			goo_sleep(ci->reconnect_interval, 0);
			_fini_socket(ci);
			_init_socket(ci);

			continue;
		}

		ci->needs_reconnect = 0;
		struct epoll_event events[EPOLL_EVENT_NUM];
		int ret_fds = 0;

		while (ci->is_running && !ci->needs_reconnect) {
			ret_fds = epoll_wait(ci->epoll_container, events, EPOLL_EVENT_NUM,
					ci->reconnect_interval);

			if (-1 == ret_fds) {
				switch (errno) {
				case EBADF:
					log_fatal("failed to call epoll_wait - EBADF");
					exit(1);
				case EFAULT:
					log_fatal("failed to call epoll_wait - EFAULT");
					exit(1);
				case EINTR:
					continue;
				case EINVAL:
					log_fatal("failed to call epoll_wait - EINVAL");
					exit(1);
				default:
					log_fatal("failed to call epoll_wait - Unknown");
					exit(1);
				}
			}

			int i = 0;

			for (; i < ret_fds; i++) {
				if ((events[i].events & EPOLLERR) && EINPROGRESS != errno) {
					ci->is_connected = 0;
					ci->needs_reconnect = 1;
					ci->callback_funs.on_error(ci->id, errno, strerror(errno));
					goo_sleep(ci->reconnect_interval, 0);
					_fini_socket(ci);
					_init_socket(ci);
					break;
				}

				if (events[i].events & EPOLLRDHUP) {
					ci->is_connected = 0;
					ci->needs_reconnect = 1;
					ci->callback_funs.on_closed(ci->id);
					goo_sleep(ci->reconnect_interval, 0);
					_fini_socket(ci);
					_init_socket(ci);
					break;
				}

				if (events[i].events & EPOLLOUT) {
					if (!ci->is_connected) {
						ci->is_connected = 1;
						ci->callback_funs.on_connected(ci->id);
						continue;
					}
				}

				if (events[i].events & EPOLLIN) {
					unsigned char buffer[RECEIVE_BUFFER_SIZE];
					int offset = 0;

					for (;;) {
						unsigned char tmp_buf[512];
						int len = recv(events[i].data.fd, tmp_buf, 512, 0);

						if (0 < len) { // read data from socket buffer
							if (len + offset > RECEIVE_BUFFER_SIZE) {
								log_fatal("the socket receiving buffer is too "
										"small");
								exit(1);
							}

							memcpy(buffer + offset, tmp_buf, len);
							offset += len;
						} else if (0 > len) {
							if (EAGAIN == errno || EWOULDBLOCK == errno) {
								// socket read buffer is empty
								if (0 < offset) {
									buffer[offset] = 0;
									ci->callback_funs.on_received(ci->id,
											buffer, offset);
									offset = 0;
								}
							} else {
								// error happened
							}

							break;
						} else {
							// the socket has been closed
							break;
						}
					}
				}
			}
		}
	}

	ci->is_connected = 0;
	ci->callback_funs.on_closed(ci->id);
	_fini_socket(ci);

	__lock;
	_connection_num--;
	__unlock;

	ci->tid = 0;

	return NULL;
}