// Queue an item for immediate sending on the wire // This method is called from the ISenderChannels internal void QueueSendMessage(NetOutgoingMessage om, int seqNr) { m_peer.VerifyNetworkThread(); int sz = om.GetEncodedSize(); if (sz > m_currentMTU) { m_peer.LogWarning("Message larger than MTU! Fragmentation must have failed!"); } if (m_sendBufferWritePtr + sz > m_currentMTU) { bool connReset; // TODO: handle connection reset NetException.Assert(m_sendBufferWritePtr > 0 && m_sendBufferNumMessages > 0); // or else the message should have been fragmented earlier m_peer.SendPacket(m_sendBufferWritePtr, m_remoteEndpoint, m_sendBufferNumMessages, out connReset); m_statistics.PacketSent(m_sendBufferWritePtr, m_sendBufferNumMessages); m_sendBufferWritePtr = 0; m_sendBufferNumMessages = 0; } m_sendBufferWritePtr = om.Encode(m_peer.m_sendBuffer, m_sendBufferWritePtr, seqNr); m_sendBufferNumMessages++; NetException.Assert(m_sendBufferWritePtr > 0, "Encoded zero size message?"); NetException.Assert(m_sendBufferNumMessages > 0); }
/// <summary> /// Add a forwarding rule to the router using UPnP /// </summary> public bool ForwardPort(int port, string description) { if (m_serviceUrl == null) { return(false); } IPAddress mask; var client = NetUtility.GetMyAddress(out mask); try { XmlDocument xdoc = SOAPRequest(m_serviceUrl, "<u:AddPortMapping xmlns:u=\"urn:schemas-upnp-org:service:WANIPConnection:1\">" + "<NewRemoteHost></NewRemoteHost><NewExternalPort>" + port.ToString() + "</NewExternalPort>" + "<NewProtocol>" + ProtocolType.Udp.ToString().ToUpper() + "</NewProtocol>" + "<NewInternalPort>" + port.ToString() + "</NewInternalPort>" + "<NewInternalClient>" + client.ToString() + "</NewInternalClient>" + "<NewEnabled>1</NewEnabled>" + "<NewPortMappingDescription>" + description + "</NewPortMappingDescription>" + "<NewLeaseDuration>0</NewLeaseDuration>" + "</u:AddPortMapping>", "AddPortMapping"); m_peer.LogDebug("Sent UPnP port forward request"); System.Threading.Thread.Sleep(50); } catch (Exception ex) { m_peer.LogWarning("UPnP port forward failed: " + ex.Message); return(false); } return(true); }
/// <summary> /// Add a forwarding rule to the router using UPnP /// </summary> /// <param name="externalPort">The external, WAN facing, port</param> /// <param name="description">A description for the port forwarding rule</param> /// <param name="internalPort">The port on the client machine to send traffic to</param> public bool ForwardPort(int externalPort, string description, int internalPort = 0) { if (!CheckAvailability()) { return(false); } IPAddress mask; var client = NetUtility.GetMyAddress(out mask); if (client == null) { return(false); } if (internalPort == 0) { internalPort = externalPort; } try { SOAPRequest(m_serviceUrl, "<u:AddPortMapping xmlns:u=\"urn:schemas-upnp-org:service:" + m_serviceName + ":1\">" + "<NewRemoteHost></NewRemoteHost>" + "<NewExternalPort>" + externalPort.ToString() + "</NewExternalPort>" + "<NewProtocol>" + ProtocolType.Udp.ToString().ToUpper(System.Globalization.CultureInfo.InvariantCulture) + "</NewProtocol>" + "<NewInternalPort>" + internalPort.ToString() + "</NewInternalPort>" + "<NewInternalClient>" + client.ToString() + "</NewInternalClient>" + "<NewEnabled>1</NewEnabled>" + "<NewPortMappingDescription>" + description + "</NewPortMappingDescription>" + "<NewLeaseDuration>0</NewLeaseDuration>" + "</u:AddPortMapping>", "AddPortMapping"); m_peer.LogDebug("Sent UPnP port forward request"); NetUtility.Sleep(50); } catch (Exception ex) { m_peer.LogWarning("UPnP port forward failed: " + ex.Message); return(false); } return(true); }
// received a library message while Connected internal void ReceivedLibraryMessage(NetMessageType tp, int ptr, int payloadLength) { m_peer.VerifyNetworkThread(); float now = (float)NetTime.Now; switch (tp) { case NetMessageType.Connect: m_peer.LogDebug("Received handshake message (" + tp + ") despite connection being in place"); break; case NetMessageType.ConnectResponse: // handshake message must have been lost HandleConnectResponse(now, tp, ptr, payloadLength); break; case NetMessageType.ConnectionEstablished: // do nothing, all's well break; case NetMessageType.LibraryError: m_peer.ThrowOrLog("LibraryError received by ReceivedLibraryMessage; this usually indicates a malformed message"); break; case NetMessageType.Disconnect: NetIncomingMessage msg = m_peer.SetupReadHelperMessage(ptr, payloadLength); m_disconnectRequested = true; m_disconnectMessage = msg.ReadString(); m_disconnectReqSendBye = false; //ExecuteDisconnect(msg.ReadString(), false); break; case NetMessageType.Acknowledge: for (int i = 0; i < payloadLength; i += 3) { NetMessageType acktp = (NetMessageType)m_peer.m_receiveBuffer[ptr++]; // netmessagetype int seqNr = m_peer.m_receiveBuffer[ptr++]; seqNr |= (m_peer.m_receiveBuffer[ptr++] << 8); // need to enqueue this and handle it in the netconnection heartbeat; so be able to send resends together with normal sends m_queuedIncomingAcks.Enqueue(new NetTuple <NetMessageType, int>(acktp, seqNr)); } break; case NetMessageType.Ping: int pingNr = m_peer.m_receiveBuffer[ptr++]; SendPong(pingNr); break; case NetMessageType.Pong: NetIncomingMessage pmsg = m_peer.SetupReadHelperMessage(ptr, payloadLength); int pongNr = pmsg.ReadByte(); float remoteSendTime = pmsg.ReadSingle(); ReceivedPong(now, pongNr, remoteSendTime); break; case NetMessageType.ExpandMTURequest: SendMTUSuccess(payloadLength); break; case NetMessageType.ExpandMTUSuccess: if (m_peer.Configuration.AutoExpandMTU == false) { m_peer.LogDebug("Received ExpandMTURequest altho AutoExpandMTU is turned off!"); break; } NetIncomingMessage emsg = m_peer.SetupReadHelperMessage(ptr, payloadLength); int size = emsg.ReadInt32(); HandleExpandMTUSuccess(now, size); break; case NetMessageType.NatIntroduction: // Unusual situation where server is actually already known, but got a nat introduction - oh well, lets handle it as usual m_peer.HandleNatIntroduction(ptr); break; default: m_peer.LogWarning("Connection received unhandled library message: " + tp); break; } }