// FinishInitialization status_t PortConnection::FinishInitialization() { // get the down stream channel Channel* channel = DownStreamChannelAt(0); if (!channel) return B_BAD_VALUE; // send the connect reply ConnectReply reply; reply.error = B_OK; reply.upStreamChannels = fUpStreamChannels; reply.downStreamChannels = fDownStreamChannels; status_t error = channel->Send(&reply, sizeof(ConnectReply)); if (error != B_OK) return error; // receive the channel infos int32 allChannels = fUpStreamChannels + fDownStreamChannels; PortChannel::Info* infos = new(std::nothrow) PortChannel::Info[allChannels - 1]; if (!infos) return B_NO_MEMORY; ArrayDeleter<PortChannel::Info> _(infos); error = channel->Receive(infos, sizeof(PortChannel::Info) * (allChannels - 1)); if (error != B_OK) return error; // create the channels for (int32 i = 1; i < allChannels; i++) { // create a channel PortChannel* otherChannel; error = _CreateChannel(&otherChannel, infos + i - 1, true); if (error != B_OK) return error; // add the channel if (i < fUpStreamChannels) // inverse, since we're on server side error = AddDownStreamChannel(otherChannel); else error = AddUpStreamChannel(otherChannel); if (error != B_OK) { delete otherChannel; return error; } } return B_OK; }
// Init (client side) status_t InsecureConnection::Init(const char* parameters) { PRINT(("InsecureConnection::Init\n")); if (!parameters) return B_BAD_VALUE; status_t error = AbstractConnection::Init(); if (error != B_OK) return error; // parse the parameters to get a server name and a port we shall connect to // parameter format is "<server>[:port] [ <up> [ <down> ] ]" char server[256]; uint16 port = kDefaultInsecureConnectionPort; int upStreamChannels = kDefaultUpStreamChannels; int downStreamChannels = kDefaultDownStreamChannels; if (strchr(parameters, ':')) { int result = sscanf(parameters, "%255[^:]:%hu %d %d", server, &port, &upStreamChannels, &downStreamChannels); if (result < 2) return B_BAD_VALUE; } else { int result = sscanf(parameters, "%255[^:] %d %d", server, &upStreamChannels, &downStreamChannels); if (result < 1) return B_BAD_VALUE; } // resolve server address NetAddress netAddress; error = NetAddressResolver().GetHostAddress(server, &netAddress); if (error != B_OK) return error; in_addr serverAddr = netAddress.GetAddress().sin_addr; // open the initial channel Channel* channel; error = _OpenClientChannel(serverAddr, port, &channel); if (error != B_OK) return error; error = AddUpStreamChannel(channel); if (error != B_OK) { delete channel; return error; } // send the server a connect request ConnectRequest request; request.protocolVersion = B_HOST_TO_BENDIAN_INT32(kProtocolVersion); request.serverAddress = serverAddr.s_addr; request.upStreamChannels = B_HOST_TO_BENDIAN_INT32(upStreamChannels); request.downStreamChannels = B_HOST_TO_BENDIAN_INT32(downStreamChannels); error = channel->Send(&request, sizeof(ConnectRequest)); if (error != B_OK) return error; // get the server reply ConnectReply reply; error = channel->Receive(&reply, sizeof(ConnectReply)); if (error != B_OK) return error; error = B_BENDIAN_TO_HOST_INT32(reply.error); if (error != B_OK) return error; upStreamChannels = B_BENDIAN_TO_HOST_INT32(reply.upStreamChannels); downStreamChannels = B_BENDIAN_TO_HOST_INT32(reply.downStreamChannels); port = B_BENDIAN_TO_HOST_INT16(reply.port); // open the remaining channels int32 allChannels = upStreamChannels + downStreamChannels; for (int32 i = 1; i < allChannels; i++) { PRINT((" creating channel %ld\n", i)); // open the channel error = _OpenClientChannel(serverAddr, port, &channel); if (error != B_OK) RETURN_ERROR(error); // add it if (i < upStreamChannels) error = AddUpStreamChannel(channel); else error = AddDownStreamChannel(channel); if (error != B_OK) { delete channel; return error; } } return B_OK; }