Exemplo n.º 1
0
void csocket::connect(const sockaddrunion& su)
{
	if(is_sock_err(::connect(sd, &su.s, get_addrlen(su)))) {
		// EINPROGRESS just means socket is non-blocking and requires TCP handshake, not really an error
		if(sock_err::get_last() != sock_err::einprogress)
			throw e_check_sock_err("connect()", true);
	}
}
Exemplo n.º 2
0
size_t send_rv(ssize_t bytes, const char* fn)
{
	if(is_sock_err(bytes)) {
		if(sock_err_is_wouldblock(sock_err::get_last()))
			return 0;
		else
			throw e_check_sock_err(fn, true);
	}
	return bytes;
}
Exemplo n.º 3
0
void network_init()
{
#ifdef WINSOCK
	dout() << "network_init: doing WSAStartup()";
	WSADATA not_interested;
	int rv = WSAStartup(MAKEWORD(2,2), &not_interested);
	if(rv != 0) {
		eout() << "WSAStartup failed: " << get_windows_errorstr(rv);
		throw e_check_sock_err("WSAStartup failed", true);
	}
#endif
}
Exemplo n.º 4
0
size_t recv_rv(ssize_t bytes, size_t len, const char* fn)
{
	if(is_sock_err(bytes)) {
		if(sock_err_is_wouldblock(sock_err::get_last()))
			return 0;
		else
			throw e_check_sock_err(fn, true);
	}
	if(bytes == 0 && len != 0)
		sock_err::set_last(sock_err::enotconn);
	return bytes;
}
Exemplo n.º 5
0
bool tuntap::send_packet(dbuf &buf, size_t len)
{
#ifdef WINDOWS
	if(sent_sync || HasOverlappedIoCompleted(&send_overlapped)) {
		std::swap(buf, send_buf);
		if(buf.size() < send_buf.size())
			buf.resize(send_buf.size());
		do_write(len);
		return true;
	}
	// else previous async send has not completed
	return false; 
#else
	ssize_t nwritten = write(fd, buf, len);
	if(nwritten > 0)
		return true;
	if(errno == EWOULDBLOCK || errno == EAGAIN)
		return false;
	throw e_check_sock_err("write to tuntap failed", true);
#endif
}
Exemplo n.º 6
0
size_t tuntap::recv_packet(dbuf &buf)
{
#ifdef WINDOWS
	// interesting possible trouble: if async read fails then obviously want to retry, but then how to avoid busy looping?
		// -> maybe do the retry but also then throw exception to indicate the failure
		// this means that before throw the buffers have to be swapped back so that non-error previous read is not lost
	if(received_sync > 0) {
		DWORD bytes_read = received_sync;
		std::swap(buf, recv_buf);
		if(buf.size() < recv_buf.size())
			buf.resize(recv_buf.size());
		do_read();
		return bytes_read;
	} else if(HasOverlappedIoCompleted(&recv_overlapped)) {
		DWORD bytes_read;
		if(GetOverlappedResult(fd, &recv_overlapped, &bytes_read, FALSE) == FALSE) {
#warning fixme GetLastError, throw exception
			// GetLastError should not be ERROR_IO_INCOMPLETE because otherwise HasOverlappedIoCompleted should have been false
		}
		std::swap(buf, recv_buf);
		if(buf.size() < recv_buf.size())
			buf.resize(recv_buf.size());
		do_read();
		return bytes_read;
	}
	// else async read is still in progress, no data to return yet
	return 0;
#else
	ssize_t nread = read(fd, buf, buf.size());
	if(nread >= 0)
		return nread;
	if(errno == EWOULDBLOCK || errno == EAGAIN)
		return 0;
	throw e_check_sock_err("read from tuntap failed", true);
#endif	
}