xref: /haiku/src/add-ons/kernel/file_systems/netfs/shared/InsecureConnection.cpp (revision ebb21bd1486152acf792f4b069339d14ef6e1896)
15a1d355fSStephan Aßmus // InsecureConnection.cpp
25a1d355fSStephan Aßmus 
35a1d355fSStephan Aßmus // TODO: Asynchronous connecting on client side?
45a1d355fSStephan Aßmus 
55a1d355fSStephan Aßmus #include <new>
65a1d355fSStephan Aßmus 
75a1d355fSStephan Aßmus #include <errno.h>
85a1d355fSStephan Aßmus #include <netdb.h>
95a1d355fSStephan Aßmus #include <stdio.h>
105a1d355fSStephan Aßmus #include <string.h>
115a1d355fSStephan Aßmus #include <unistd.h>
125a1d355fSStephan Aßmus 
135a1d355fSStephan Aßmus #include <ByteOrder.h>
145a1d355fSStephan Aßmus 
155a1d355fSStephan Aßmus #include "Compatibility.h"
165a1d355fSStephan Aßmus #include "DebugSupport.h"
175a1d355fSStephan Aßmus #include "InsecureChannel.h"
185a1d355fSStephan Aßmus #include "InsecureConnection.h"
195a1d355fSStephan Aßmus #include "NetAddress.h"
205a1d355fSStephan Aßmus #include "NetFSDefs.h"
215a1d355fSStephan Aßmus 
225a1d355fSStephan Aßmus namespace InsecureConnectionDefs {
235a1d355fSStephan Aßmus 
245a1d355fSStephan Aßmus const int32 kProtocolVersion = 1;
255a1d355fSStephan Aßmus 
265a1d355fSStephan Aßmus const bigtime_t kAcceptingTimeout = 10000000;	// 10 s
275a1d355fSStephan Aßmus 
285a1d355fSStephan Aßmus // number of client up/down stream channels
295a1d355fSStephan Aßmus const int32 kMinUpStreamChannels		= 1;
305a1d355fSStephan Aßmus const int32 kMaxUpStreamChannels		= 10;
315a1d355fSStephan Aßmus const int32 kDefaultUpStreamChannels	= 5;
325a1d355fSStephan Aßmus const int32 kMinDownStreamChannels		= 1;
335a1d355fSStephan Aßmus const int32 kMaxDownStreamChannels		= 5;
345a1d355fSStephan Aßmus const int32 kDefaultDownStreamChannels	= 1;
355a1d355fSStephan Aßmus 
365a1d355fSStephan Aßmus } // namespace InsecureConnectionDefs
375a1d355fSStephan Aßmus 
385a1d355fSStephan Aßmus using namespace InsecureConnectionDefs;
395a1d355fSStephan Aßmus 
405a1d355fSStephan Aßmus // SocketCloser
415a1d355fSStephan Aßmus struct SocketCloser {
SocketCloserSocketCloser425a1d355fSStephan Aßmus 	SocketCloser(int fd) : fFD(fd) {}
~SocketCloserSocketCloser435a1d355fSStephan Aßmus 	~SocketCloser()
445a1d355fSStephan Aßmus 	{
455a1d355fSStephan Aßmus 		if (fFD >= 0)
465a1d355fSStephan Aßmus 			closesocket(fFD);
475a1d355fSStephan Aßmus 	}
485a1d355fSStephan Aßmus 
DetachSocketCloser495a1d355fSStephan Aßmus 	int Detach()
505a1d355fSStephan Aßmus 	{
515a1d355fSStephan Aßmus 		int fd = fFD;
525a1d355fSStephan Aßmus 		fFD = -1;
535a1d355fSStephan Aßmus 		return fd;
545a1d355fSStephan Aßmus 	}
555a1d355fSStephan Aßmus 
565a1d355fSStephan Aßmus private:
575a1d355fSStephan Aßmus 	int	fFD;
585a1d355fSStephan Aßmus };
595a1d355fSStephan Aßmus 
605a1d355fSStephan Aßmus 
615a1d355fSStephan Aßmus // #pragma mark -
625a1d355fSStephan Aßmus // #pragma mark ----- InsecureConnection -----
635a1d355fSStephan Aßmus 
645a1d355fSStephan Aßmus // constructor
InsecureConnection()655a1d355fSStephan Aßmus InsecureConnection::InsecureConnection()
665a1d355fSStephan Aßmus {
675a1d355fSStephan Aßmus }
685a1d355fSStephan Aßmus 
695a1d355fSStephan Aßmus // destructor
~InsecureConnection()705a1d355fSStephan Aßmus InsecureConnection::~InsecureConnection()
715a1d355fSStephan Aßmus {
725a1d355fSStephan Aßmus }
735a1d355fSStephan Aßmus 
745a1d355fSStephan Aßmus // Init (server side)
755a1d355fSStephan Aßmus status_t
Init(int fd)765a1d355fSStephan Aßmus InsecureConnection::Init(int fd)
775a1d355fSStephan Aßmus {
785a1d355fSStephan Aßmus 	status_t error = AbstractConnection::Init();
795a1d355fSStephan Aßmus 	if (error != B_OK) {
805a1d355fSStephan Aßmus 		closesocket(fd);
815a1d355fSStephan Aßmus 		return error;
825a1d355fSStephan Aßmus 	}
835a1d355fSStephan Aßmus 	// create the initial channel
845a1d355fSStephan Aßmus 	Channel* channel = new(std::nothrow) InsecureChannel(fd);
855a1d355fSStephan Aßmus 	if (!channel) {
865a1d355fSStephan Aßmus 		closesocket(fd);
875a1d355fSStephan Aßmus 		return B_NO_MEMORY;
885a1d355fSStephan Aßmus 	}
895a1d355fSStephan Aßmus 	// add it
905a1d355fSStephan Aßmus 	error = AddDownStreamChannel(channel);
915a1d355fSStephan Aßmus 	if (error != B_OK) {
925a1d355fSStephan Aßmus 		delete channel;
935a1d355fSStephan Aßmus 		return error;
945a1d355fSStephan Aßmus 	}
955a1d355fSStephan Aßmus 	return B_OK;
965a1d355fSStephan Aßmus }
975a1d355fSStephan Aßmus 
985a1d355fSStephan Aßmus // Init (client side)
995a1d355fSStephan Aßmus status_t
Init(const char * parameters)1005a1d355fSStephan Aßmus InsecureConnection::Init(const char* parameters)
1015a1d355fSStephan Aßmus {
1025a1d355fSStephan Aßmus PRINT(("InsecureConnection::Init\n"));
1035a1d355fSStephan Aßmus 	if (!parameters)
1045a1d355fSStephan Aßmus 		return B_BAD_VALUE;
1055a1d355fSStephan Aßmus 	status_t error = AbstractConnection::Init();
1065a1d355fSStephan Aßmus 	if (error != B_OK)
1075a1d355fSStephan Aßmus 		return error;
1085a1d355fSStephan Aßmus 	// parse the parameters to get a server name and a port we shall connect to
1095a1d355fSStephan Aßmus 	// parameter format is "<server>[:port] [ <up> [ <down> ] ]"
1105a1d355fSStephan Aßmus 	char server[256];
1115a1d355fSStephan Aßmus 	uint16 port = kDefaultInsecureConnectionPort;
1125a1d355fSStephan Aßmus 	int upStreamChannels = kDefaultUpStreamChannels;
1135a1d355fSStephan Aßmus 	int downStreamChannels = kDefaultDownStreamChannels;
1145a1d355fSStephan Aßmus 	if (strchr(parameters, ':')) {
1155a1d355fSStephan Aßmus 		int result = sscanf(parameters, "%255[^:]:%hu %d %d", server, &port,
1165a1d355fSStephan Aßmus 			&upStreamChannels, &downStreamChannels);
1175a1d355fSStephan Aßmus 		if (result < 2)
1185a1d355fSStephan Aßmus 			return B_BAD_VALUE;
1195a1d355fSStephan Aßmus 	} else {
1205a1d355fSStephan Aßmus 		int result = sscanf(parameters, "%255[^:] %d %d", server,
1215a1d355fSStephan Aßmus 			&upStreamChannels, &downStreamChannels);
1225a1d355fSStephan Aßmus 		if (result < 1)
1235a1d355fSStephan Aßmus 			return B_BAD_VALUE;
1245a1d355fSStephan Aßmus 	}
1255a1d355fSStephan Aßmus 	// resolve server address
1265a1d355fSStephan Aßmus 	NetAddress netAddress;
1275a1d355fSStephan Aßmus 	error = NetAddressResolver().GetHostAddress(server, &netAddress);
1285a1d355fSStephan Aßmus 	if (error != B_OK)
1295a1d355fSStephan Aßmus 		return error;
1305a1d355fSStephan Aßmus 	in_addr serverAddr = netAddress.GetAddress().sin_addr;
1315a1d355fSStephan Aßmus 	// open the initial channel
1325a1d355fSStephan Aßmus 	Channel* channel;
1335a1d355fSStephan Aßmus 	error = _OpenClientChannel(serverAddr, port, &channel);
1345a1d355fSStephan Aßmus 	if (error != B_OK)
1355a1d355fSStephan Aßmus 		return error;
1365a1d355fSStephan Aßmus 	error = AddUpStreamChannel(channel);
1375a1d355fSStephan Aßmus 	if (error != B_OK) {
1385a1d355fSStephan Aßmus 		delete channel;
1395a1d355fSStephan Aßmus 		return error;
1405a1d355fSStephan Aßmus 	}
1415a1d355fSStephan Aßmus 	// send the server a connect request
1425a1d355fSStephan Aßmus 	ConnectRequest request;
1435a1d355fSStephan Aßmus 	request.protocolVersion = B_HOST_TO_BENDIAN_INT32(kProtocolVersion);
1445a1d355fSStephan Aßmus 	request.serverAddress = serverAddr.s_addr;
1455a1d355fSStephan Aßmus 	request.upStreamChannels = B_HOST_TO_BENDIAN_INT32(upStreamChannels);
1465a1d355fSStephan Aßmus 	request.downStreamChannels = B_HOST_TO_BENDIAN_INT32(downStreamChannels);
1475a1d355fSStephan Aßmus 	error = channel->Send(&request, sizeof(ConnectRequest));
1485a1d355fSStephan Aßmus 	if (error != B_OK)
1495a1d355fSStephan Aßmus 		return error;
1505a1d355fSStephan Aßmus 	// get the server reply
1515a1d355fSStephan Aßmus 	ConnectReply reply;
1525a1d355fSStephan Aßmus 	error = channel->Receive(&reply, sizeof(ConnectReply));
1535a1d355fSStephan Aßmus 	if (error != B_OK)
1545a1d355fSStephan Aßmus 		return error;
1555a1d355fSStephan Aßmus 	error = B_BENDIAN_TO_HOST_INT32(reply.error);
1565a1d355fSStephan Aßmus 	if (error != B_OK)
1575a1d355fSStephan Aßmus 		return error;
1585a1d355fSStephan Aßmus 	upStreamChannels = B_BENDIAN_TO_HOST_INT32(reply.upStreamChannels);
1595a1d355fSStephan Aßmus 	downStreamChannels = B_BENDIAN_TO_HOST_INT32(reply.downStreamChannels);
1605a1d355fSStephan Aßmus 	port = B_BENDIAN_TO_HOST_INT16(reply.port);
1615a1d355fSStephan Aßmus 	// open the remaining channels
1625a1d355fSStephan Aßmus 	int32 allChannels = upStreamChannels + downStreamChannels;
1635a1d355fSStephan Aßmus 	for (int32 i = 1; i < allChannels; i++) {
164*ebb21bd1SMurai Takashi 		PRINT("  creating channel %" B_PRId32 "\n", i);
1655a1d355fSStephan Aßmus 		// open the channel
1665a1d355fSStephan Aßmus 		error = _OpenClientChannel(serverAddr, port, &channel);
1675a1d355fSStephan Aßmus 		if (error != B_OK)
1685a1d355fSStephan Aßmus 			RETURN_ERROR(error);
1695a1d355fSStephan Aßmus 		// add it
1705a1d355fSStephan Aßmus 		if (i < upStreamChannels)
1715a1d355fSStephan Aßmus 			error = AddUpStreamChannel(channel);
1725a1d355fSStephan Aßmus 		else
1735a1d355fSStephan Aßmus 			error = AddDownStreamChannel(channel);
1745a1d355fSStephan Aßmus 		if (error != B_OK) {
1755a1d355fSStephan Aßmus 			delete channel;
1765a1d355fSStephan Aßmus 			return error;
1775a1d355fSStephan Aßmus 		}
1785a1d355fSStephan Aßmus 	}
1795a1d355fSStephan Aßmus 	return B_OK;
1805a1d355fSStephan Aßmus }
1815a1d355fSStephan Aßmus 
1825a1d355fSStephan Aßmus // FinishInitialization
1835a1d355fSStephan Aßmus status_t
FinishInitialization()1845a1d355fSStephan Aßmus InsecureConnection::FinishInitialization()
1855a1d355fSStephan Aßmus {
1865a1d355fSStephan Aßmus PRINT(("InsecureConnection::FinishInitialization()\n"));
1875a1d355fSStephan Aßmus 	// get the down stream channel
1885a1d355fSStephan Aßmus 	InsecureChannel* channel
1895a1d355fSStephan Aßmus 		= dynamic_cast<InsecureChannel*>(DownStreamChannelAt(0));
1905a1d355fSStephan Aßmus 	if (!channel)
1915a1d355fSStephan Aßmus 		return B_BAD_VALUE;
1925a1d355fSStephan Aßmus 	// receive the connect request
1935a1d355fSStephan Aßmus 	ConnectRequest request;
1945a1d355fSStephan Aßmus 	status_t error = channel->Receive(&request, sizeof(ConnectRequest));
1955a1d355fSStephan Aßmus 	if (error != B_OK)
1965a1d355fSStephan Aßmus 		return error;
1975a1d355fSStephan Aßmus 	// check the protocol version
1985a1d355fSStephan Aßmus 	int32 protocolVersion = B_BENDIAN_TO_HOST_INT32(request.protocolVersion);
1995a1d355fSStephan Aßmus 	if (protocolVersion != kProtocolVersion) {
2005a1d355fSStephan Aßmus 		_SendErrorReply(channel, B_ERROR);
2015a1d355fSStephan Aßmus 		return B_ERROR;
2025a1d355fSStephan Aßmus 	}
2035a1d355fSStephan Aßmus 	// get our address (we need it for binding)
2045a1d355fSStephan Aßmus 	in_addr serverAddr;
2055a1d355fSStephan Aßmus 	serverAddr.s_addr = request.serverAddress;
2065a1d355fSStephan Aßmus 	// check number of up and down stream channels
2075a1d355fSStephan Aßmus 	int32 upStreamChannels = B_BENDIAN_TO_HOST_INT32(request.upStreamChannels);
2085a1d355fSStephan Aßmus 	int32 downStreamChannels = B_BENDIAN_TO_HOST_INT32(
2095a1d355fSStephan Aßmus 		request.downStreamChannels);
2105a1d355fSStephan Aßmus 	if (upStreamChannels < kMinUpStreamChannels)
2115a1d355fSStephan Aßmus 		upStreamChannels = kMinUpStreamChannels;
2125a1d355fSStephan Aßmus 	else if (upStreamChannels > kMaxUpStreamChannels)
2135a1d355fSStephan Aßmus 		upStreamChannels = kMaxUpStreamChannels;
2145a1d355fSStephan Aßmus 	if (downStreamChannels < kMinDownStreamChannels)
2155a1d355fSStephan Aßmus 		downStreamChannels = kMinDownStreamChannels;
2165a1d355fSStephan Aßmus 	else if (downStreamChannels > kMaxDownStreamChannels)
2175a1d355fSStephan Aßmus 		downStreamChannels = kMaxDownStreamChannels;
2185a1d355fSStephan Aßmus 	// due to a bug on BONE we have a maximum of 2 working connections
2195a1d355fSStephan Aßmus 	// accepted on one listener socket.
2205a1d355fSStephan Aßmus 	NetAddress peerAddress;
2215a1d355fSStephan Aßmus 	if (channel->GetPeerAddress(&peerAddress) == B_OK
2225a1d355fSStephan Aßmus 		&& peerAddress.IsLocal()) {
2235a1d355fSStephan Aßmus 		upStreamChannels = 1;
2245a1d355fSStephan Aßmus 		if (downStreamChannels > 2)
2255a1d355fSStephan Aßmus 			downStreamChannels = 2;
2265a1d355fSStephan Aßmus 	}
2275a1d355fSStephan Aßmus 	int32 allChannels = upStreamChannels + downStreamChannels;
2285a1d355fSStephan Aßmus 	// create a listener socket
2295a1d355fSStephan Aßmus 	int fd = socket(AF_INET, SOCK_STREAM, 0);
2305a1d355fSStephan Aßmus 	if (fd < 0) {
2315a1d355fSStephan Aßmus 		error = errno;
2325a1d355fSStephan Aßmus 		_SendErrorReply(channel, error);
2335a1d355fSStephan Aßmus 		return error;
2345a1d355fSStephan Aßmus 	}
2355a1d355fSStephan Aßmus 	SocketCloser _(fd);
2365a1d355fSStephan Aßmus 	// bind it to some port
2375a1d355fSStephan Aßmus 	sockaddr_in addr;
2385a1d355fSStephan Aßmus 	addr.sin_family = AF_INET;
2395a1d355fSStephan Aßmus 	addr.sin_port = 0;
2405a1d355fSStephan Aßmus 	addr.sin_addr = serverAddr;
2415a1d355fSStephan Aßmus 	if (bind(fd, (sockaddr*)&addr, sizeof(addr)) < 0) {
2425a1d355fSStephan Aßmus 		error = errno;
2435a1d355fSStephan Aßmus 		_SendErrorReply(channel, error);
2445a1d355fSStephan Aßmus 		return error;
2455a1d355fSStephan Aßmus 	}
2465a1d355fSStephan Aßmus 	// get the port
2475a1d355fSStephan Aßmus 	socklen_t addrSize = sizeof(addr);
2485a1d355fSStephan Aßmus 	if (getsockname(fd, (sockaddr*)&addr, &addrSize) < 0) {
2495a1d355fSStephan Aßmus 		error = errno;
2505a1d355fSStephan Aßmus 		_SendErrorReply(channel, error);
2515a1d355fSStephan Aßmus 		return error;
2525a1d355fSStephan Aßmus 	}
2535a1d355fSStephan Aßmus 	// set socket to non-blocking
2545a1d355fSStephan Aßmus 	int dontBlock = 1;
2555a1d355fSStephan Aßmus 	if (setsockopt(fd, SOL_SOCKET, SO_NONBLOCK, &dontBlock, sizeof(int)) < 0) {
2565a1d355fSStephan Aßmus 		error = errno;
2575a1d355fSStephan Aßmus 		_SendErrorReply(channel, error);
2585a1d355fSStephan Aßmus 		return error;
2595a1d355fSStephan Aßmus 	}
2605a1d355fSStephan Aßmus 	// start listening
2615a1d355fSStephan Aßmus 	if (listen(fd, allChannels - 1) < 0) {
2625a1d355fSStephan Aßmus 		error = errno;
2635a1d355fSStephan Aßmus 		_SendErrorReply(channel, error);
2645a1d355fSStephan Aßmus 		return error;
2655a1d355fSStephan Aßmus 	}
2665a1d355fSStephan Aßmus 	// send the reply
2675a1d355fSStephan Aßmus 	ConnectReply reply;
2685a1d355fSStephan Aßmus 	reply.error = B_HOST_TO_BENDIAN_INT32(B_OK);
2695a1d355fSStephan Aßmus 	reply.upStreamChannels = B_HOST_TO_BENDIAN_INT32(upStreamChannels);
2705a1d355fSStephan Aßmus 	reply.downStreamChannels = B_HOST_TO_BENDIAN_INT32(downStreamChannels);
2715a1d355fSStephan Aßmus 	reply.port = addr.sin_port;
2725a1d355fSStephan Aßmus 	error = channel->Send(&reply, sizeof(ConnectReply));
2735a1d355fSStephan Aßmus 	if (error != B_OK)
2745a1d355fSStephan Aßmus 		return error;
2755a1d355fSStephan Aßmus 	// start accepting
2765a1d355fSStephan Aßmus 	bigtime_t startAccepting = system_time();
2775a1d355fSStephan Aßmus 	for (int32 i = 1; i < allChannels; ) {
2785a1d355fSStephan Aßmus 		// accept a connection
2795a1d355fSStephan Aßmus 		int channelFD = accept(fd, NULL, 0);
2805a1d355fSStephan Aßmus 		if (channelFD < 0) {
2815a1d355fSStephan Aßmus 			error = errno;
2825a1d355fSStephan Aßmus 			if (error == B_INTERRUPTED) {
2835a1d355fSStephan Aßmus 				error = B_OK;
2845a1d355fSStephan Aßmus 				continue;
2855a1d355fSStephan Aßmus 			}
2865a1d355fSStephan Aßmus 			if (error == B_WOULD_BLOCK) {
2875a1d355fSStephan Aßmus 				bigtime_t now = system_time();
2885a1d355fSStephan Aßmus 				if (now - startAccepting > kAcceptingTimeout)
2895a1d355fSStephan Aßmus 					RETURN_ERROR(B_TIMED_OUT);
2905a1d355fSStephan Aßmus 				snooze(10000);
2915a1d355fSStephan Aßmus 				continue;
2925a1d355fSStephan Aßmus 			}
2935a1d355fSStephan Aßmus 			RETURN_ERROR(error);
2945a1d355fSStephan Aßmus 		}
295*ebb21bd1SMurai Takashi 		PRINT("  accepting channel %" B_PRId32 "\n", i);
2965a1d355fSStephan Aßmus 		// create a channel
2975a1d355fSStephan Aßmus 		channel = new(std::nothrow) InsecureChannel(channelFD);
2985a1d355fSStephan Aßmus 		if (!channel) {
2995a1d355fSStephan Aßmus 			closesocket(channelFD);
3005a1d355fSStephan Aßmus 			return B_NO_MEMORY;
3015a1d355fSStephan Aßmus 		}
3025a1d355fSStephan Aßmus 		// add it
3035a1d355fSStephan Aßmus 		if (i < upStreamChannels)	// inverse, since we are on server side
3045a1d355fSStephan Aßmus 			error = AddDownStreamChannel(channel);
3055a1d355fSStephan Aßmus 		else
3065a1d355fSStephan Aßmus 			error = AddUpStreamChannel(channel);
3075a1d355fSStephan Aßmus 		if (error != B_OK) {
3085a1d355fSStephan Aßmus 			delete channel;
3095a1d355fSStephan Aßmus 			return error;
3105a1d355fSStephan Aßmus 		}
3115a1d355fSStephan Aßmus 		i++;
3125a1d355fSStephan Aßmus 		startAccepting = system_time();
3135a1d355fSStephan Aßmus 	}
3145a1d355fSStephan Aßmus 	return B_OK;
3155a1d355fSStephan Aßmus }
3165a1d355fSStephan Aßmus 
3175a1d355fSStephan Aßmus // _OpenClientChannel
3185a1d355fSStephan Aßmus status_t
_OpenClientChannel(in_addr serverAddr,uint16 port,Channel ** _channel)3195a1d355fSStephan Aßmus InsecureConnection::_OpenClientChannel(in_addr serverAddr, uint16 port,
3205a1d355fSStephan Aßmus 	Channel** _channel)
3215a1d355fSStephan Aßmus {
3225a1d355fSStephan Aßmus 	// create a socket
3235a1d355fSStephan Aßmus 	int fd = socket(AF_INET, SOCK_STREAM, 0);
3245a1d355fSStephan Aßmus 	if (fd < 0)
3255a1d355fSStephan Aßmus 		return errno;
3265a1d355fSStephan Aßmus 	// connect
3275a1d355fSStephan Aßmus 	sockaddr_in addr;
3285a1d355fSStephan Aßmus 	addr.sin_family = AF_INET;
3295a1d355fSStephan Aßmus 	addr.sin_port = htons(port);
3305a1d355fSStephan Aßmus 	addr.sin_addr = serverAddr;
3315a1d355fSStephan Aßmus 	if (connect(fd, (sockaddr*)&addr, sizeof(addr)) < 0) {
3325a1d355fSStephan Aßmus 		status_t error = errno;
3335a1d355fSStephan Aßmus 		closesocket(fd);
3345a1d355fSStephan Aßmus 		RETURN_ERROR(error);
3355a1d355fSStephan Aßmus 	}
3365a1d355fSStephan Aßmus 	// create the channel
3375a1d355fSStephan Aßmus 	Channel* channel = new(std::nothrow) InsecureChannel(fd);
3385a1d355fSStephan Aßmus 	if (!channel) {
3395a1d355fSStephan Aßmus 		closesocket(fd);
3405a1d355fSStephan Aßmus 		return B_NO_MEMORY;
3415a1d355fSStephan Aßmus 	}
3425a1d355fSStephan Aßmus 	*_channel = channel;
3435a1d355fSStephan Aßmus 	return B_OK;
3445a1d355fSStephan Aßmus }
3455a1d355fSStephan Aßmus 
3465a1d355fSStephan Aßmus // _SendErrorReply
3475a1d355fSStephan Aßmus status_t
_SendErrorReply(Channel * channel,status_t error)3485a1d355fSStephan Aßmus InsecureConnection::_SendErrorReply(Channel* channel, status_t error)
3495a1d355fSStephan Aßmus {
3505a1d355fSStephan Aßmus 	ConnectReply reply;
3515a1d355fSStephan Aßmus 	reply.error = B_HOST_TO_BENDIAN_INT32(error);
3525a1d355fSStephan Aßmus 	return channel->Send(&reply, sizeof(ConnectReply));
3535a1d355fSStephan Aßmus }
3545a1d355fSStephan Aßmus 
355