📄 transports.cxx
字号:
H323TransportTCP::H323TransportTCP(H323EndPoint & end) : H323TransportIP(end, H323ListenerTCP::DefaultSignalPort){ h245listener = NULL;}H323TransportTCP::~H323TransportTCP(){ delete h245listener; // Delete and H245 listener that may be present}BOOL H323TransportTCP::OnOpen(){ PIPSocket * socket = (PIPSocket *)GetReadChannel(); // Get name of the remote computer for information purposes if (!socket->GetPeerAddress(remoteAddress, remotePort)) return FALSE; // get local address of incoming socket to ensure that multi-homed machines // use a NIC address that is guaranteed to be addressable to destination if (!socket->GetLocalAddress(localAddress, localPort)) return FALSE;#ifdef __BEOS__ return TRUE;#else socket->SetOption(TCP_NODELAY, 1, IPPROTO_TCP); // make sure do not lose outgoing packets on close const linger ling = { 1, 3 }; return socket->SetOption(SO_LINGER, &ling, sizeof(ling));#endif}BOOL H323TransportTCP::SetRemoteAddress(const H323TransportAddress & address){ return address.GetIpAndPort(remoteAddress, remotePort, "tcp");}BOOL H323TransportTCP::ReadPDU(PBYTEArray & pdu){ // Make sure is a RFC1006 TPKT switch (ReadChar()) { case 3 : // Only support version 3 break; default : // Unknown version number lastError = Miscellaneous; osError = 0x10000; // Do case for read error case -1 : return FALSE; } // Save timeout PTimeInterval oldTimeout = GetReadTimeout(); // Should get all of PDU in 5 seconds or something is seriously wrong, SetReadTimeout(5000); // Get TPKT length BYTE header[3]; BOOL ok = ReadBlock(header, sizeof(header)); if (ok) { PINDEX packetLength = ((header[1] << 8)|header[2]) - 4; ok = ReadBlock(pdu.GetPointer(packetLength), packetLength); } SetReadTimeout(oldTimeout); return ok;}BOOL H323TransportTCP::WritePDU(const PBYTEArray & pdu){ // We copy the data into a new buffer so we can do a single write call. This // is necessary as we have disabled the Nagle TCP delay algorithm to improve // network performance. int packetLength = pdu.GetSize() + 4; // Send RFC1006 TPKT length PBYTEArray tpkt(packetLength); tpkt[0] = 3; tpkt[1] = 0; tpkt[2] = (BYTE)(packetLength >> 8); tpkt[3] = (BYTE)packetLength; memcpy(tpkt.GetPointer()+4, (const BYTE *)pdu, pdu.GetSize()); return Write((const BYTE *)tpkt, packetLength);}BOOL H323TransportTCP::Connect(){ PTCPSocket * socket = new PTCPSocket(remotePort); readChannel = writeChannel = socket; PTRACE(3, "TCP\tStarting connection to " << remoteAddress << ':' << remotePort); if (!socket->Connect(remoteAddress)) { PTRACE(1, "TCP\tCould not connect to " << remoteAddress << ':' << remotePort << ' ' << socket->GetErrorText()); osError = socket->GetErrorNumber(); lastError = socket->GetErrorCode(); readChannel = writeChannel = NULL; delete socket; return FALSE; } readChannel = writeChannel = NULL; if (!Open(socket)) return FALSE; PTRACE(1, "TCP\tStarted connection to " << remoteAddress << ':' << remotePort << " (if=" << localAddress << ':' << localPort << ')'); return TRUE;}BOOL H323TransportTCP::CreateControlChannel(H323Connection & connection, H323Transport * & transport){ // construct H245 socket PTCPSocket * socket = new PTCPSocket; if (!socket->Listen()) { PTRACE(1, "H225\tTCP Listen for H245 failed: " << socket->GetErrorText()); delete socket; return FALSE; } PTRACE(3, "H225\tTCP Listen for H245 on " << localAddress << ':' << socket->GetPort()); // Make H323 Connect PDU H323SignalPDU connectPDU; connectPDU.BuildConnect(connection, localAddress, socket->GetPort()); // Send H323 Connect PDU if (!connection.WriteSignalPDU(connectPDU)) { delete socket; return FALSE; } H323TransportTCP * tcpTransport = new H323TransportTCP(endpoint); tcpTransport->h245listener = socket; transport = tcpTransport; new H245TransportThread(endpoint, connection, *tcpTransport); return TRUE;}BOOL H323TransportTCP::AcceptControlChannel(H323Connection & connection){ if (IsOpen()) return TRUE; if (h245listener == NULL) { PAssertAlways(PLogicError); return FALSE; } PTRACE(3, "H245\tTCP Accept wait"); PTCPSocket * h245Socket = new PTCPSocket; h245listener->SetReadTimeout(30000); // Wait 30 seconds for remote H245 connect if (h245Socket->Accept(*h245listener)) return Open(h245Socket); PTRACE(1, "H225\tAccept for H245 failed: " << h245Socket->GetErrorText()); delete h245Socket; connection.ClearCall(H323Connection::EndedByTransportFail); return FALSE;}/////////////////////////////////////////////////////////////////////////////H323TransportUDP::H323TransportUDP(H323EndPoint & end, PIPSocket::Address binding) : H323TransportIP(end, DefaultRasPort){ PUDPSocket * udp = new PUDPSocket; PTRACE(3, "UDP\tBinding to interface: " << binding); udp->Listen(binding); Open(udp); localAddress = binding; localPort = udp->GetPort();}H323TransportUDP::~H323TransportUDP(){ Close();}BOOL H323TransportUDP::SetRemoteAddress(const H323TransportAddress & address){ return address.GetIpAndPort(remoteAddress, remotePort, "udp");}BOOL H323TransportUDP::Connect(){ if (remoteAddress == 0 || remotePort == 0) return FALSE; PUDPSocket * socket = (PUDPSocket *)GetReadChannel(); socket->SetSendAddress(remoteAddress, remotePort); return TRUE;}BOOL H323TransportUDP::ReadPDU(PBYTEArray & pdu){ if (!Read(pdu.GetPointer(10000), 10000)) { pdu.SetSize(0); return FALSE; } pdu.SetSize(GetLastReadCount()); return TRUE;}BOOL H323TransportUDP::WritePDU(const PBYTEArray & pdu){ return Write((const BYTE *)pdu, pdu.GetSize());}BOOL H323TransportUDP::DiscoverGatekeeper(H323Gatekeeper & gk, H323RasPDU & request, const H323TransportAddress & address){ PTRACE(3, "H225\tStarted gatekeeper discovery of \"" << address << '"'); // Skip over the H323Transport::Close to make sure PUDPSocket is deleted. PIndirectChannel::Close(); remoteAddress = 0; remotePort = 0; PIPSocket::Address destAddr = INADDR_BROADCAST; WORD destPort = DefaultRasPort; if (!address) { if (!address.GetIpAndPort(destAddr, destPort, "udp")) { PTRACE(2, "RAS\tError decoding address"); return FALSE; } } PIPSocket::Address originalLocalAddress = localAddress; WORD originalLocalPort = localPort; PIPSocket::InterfaceTable interfaces; // See if prebound to interface, only use that if so if (localAddress != INADDR_ANY) { PTRACE(3, "RAS\tGatekeeper discovery on pre-bound interface: " << localAddress); interfaces.Append(new PIPSocket::InterfaceEntry("", localAddress, "")); } else if (!PIPSocket::GetInterfaceTable(interfaces)) { PTRACE(3, "RAS\tNo interfaces on system!"); interfaces.Append(new PIPSocket::InterfaceEntry("", localAddress, "")); } PSocketList sockets; PSocket::SelectList selection; PINDEX i; for (i = 0; i < interfaces.GetSize(); i++) { localAddress = interfaces[i].GetAddress(); if (localAddress == 0 || localAddress == PIPSocket::Address()) continue; // Check for already have had that IP address. PINDEX j; for (j = 0; j < i; j++) { if (localAddress == interfaces[j].GetAddress()) break; } if (j < i) continue; PUDPSocket * socket = new PUDPSocket; sockets.Append(socket); if (!socket->Listen(localAddress)) { PTRACE(2, "RAS\tError on discover request listen: " << socket->GetErrorText()); return FALSE; } localPort = socket->GetPort(); PTRACE(3, "RAS\tGatekeeper discovery on interface: " << localAddress << ':' << localPort);#ifndef __BEOS__ if (destAddr == INADDR_BROADCAST) { if (!socket->SetOption(SO_BROADCAST, 1)) { PTRACE(2, "RAS\tError allowing broadcast: " << socket->GetErrorText()); return FALSE; } }#else PTRACE(2, "RAS\tBroadcast option under BeOS is not implemented yet");#endif // Adjust the PD to reflect the interface we are writing to. H225_GatekeeperRequest & grq = request; SetUpTransportPDU(grq.m_rasAddress, TRUE); socket->SetSendAddress(destAddr, destPort); writeChannel = socket; if (request.Write(*this)) selection.Append(socket); else PTRACE(2, "RAS\tError writing discovery PDU: " << socket->GetErrorText()); writeChannel = NULL;#ifndef __BEOS__ if (destAddr == INADDR_BROADCAST) socket->SetOption(SO_BROADCAST, 0);#endif } if (PSocket::Select(selection, endpoint.GetGatekeeperRequestTimeout()) != NoError) { PTRACE(3, "RAS\tError on discover request select"); return FALSE; } SetReadTimeout(0); for (i = 0; i < selection.GetSize(); i++) { readChannel = &selection[i]; H323RasPDU response; if (!response.Read(*this)) { PTRACE(3, "RAS\tError on discover request read: " << readChannel->GetErrorText()); readChannel = NULL; return FALSE; } do { if (gk.HandleRasPDU(response)) { PUDPSocket * socket = (PUDPSocket *)readChannel; readChannel = NULL; Open(socket); sockets.DisallowDeleteObjects(); sockets.Remove(socket); sockets.AllowDeleteObjects(); WORD dummyPort; socket->GetLastReceiveAddress(remoteAddress, dummyPort); socket->SetSendAddress(remoteAddress, remotePort); socket->GetLocalAddress(localAddress, localPort); PTRACE(2, "RAS\tGatekeeper discovered at: " << remoteAddress << ':' << remotePort << " (if=" << localAddress << ':' << localPort << ')'); return TRUE; } } while (response.Read(*this)); } PTRACE(2, "RAS\tGatekeeper discovery failed"); localAddress = originalLocalAddress; localPort = originalLocalPort; readChannel = NULL; return FALSE;}/////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -