/// <summary> /// Processes incomming initial packet and creates or halts a connection. /// </summary> /// <param name="packet">Initial Packet</param> /// <param name="endPoint">Peer's endpoint</param> /// <returns></returns> private QuicConnection ProcessInitialPacket(Packet packet, IPEndPoint endPoint) { QuicConnection result = null; byte[] data; // Unsupported version. Version negotiation packet is sent only on initial connection. All other packets are dropped. (5.2.2 / 16th draft) if (packet.Version != QuicVersion.CurrentVersion || !QuicVersion.SupportedVersions.Contains(packet.Version)) { var vnp = _packetCreator.CreateVersionNegotiationPacket(); data = vnp.Encode(); _client.Send(data, data.Length, endPoint); return(null); } if (!(packet is InitialPacket cast)) { throw new ArgumentNullException(nameof(cast)); } var ip = _packetCreator.CreateInitialPacket(0, cast.SourceConnectionId); // Protocol violation if the initial packet is smaller than the PMTU. (pt. 14 / 16th draft) if (cast.Encode().Length < QuicSettings.Pmtu) { ip.AttachFrame(new ConnectionCloseFrame(ErrorCode.PROTOCOL_VIOLATION, "PMTU have not been reached.")); } else if (ConnectionPool.AddConnection(new ConnectionData(_pwt, cast.SourceConnectionId, 0), out var availableConnectionId)) { // Tell the peer the available connection id ip.SourceConnectionId = (byte)availableConnectionId; // We're including the maximum possible stream id during the connection handshake. (4.5 / 16th draft) ip.AttachFrame(new MaxStreamsFrame(QuicSettings.MaximumStreamId, StreamType.ServerBidirectional)); // Set the return result result = ConnectionPool.Find(availableConnectionId); } else { // Not accepting connections. Send initial packet with CONNECTION_CLOSE frame. // TODO: Buffering. The server might buffer incomming 0-RTT packets in anticipation of late delivery InitialPacket. // Maximum buffer size should be set in QuicSettings. ip.AttachFrame(new ConnectionCloseFrame(ErrorCode.SERVER_BUSY, "The server is too busy to process your request.")); } data = ip.Encode(); var dataSent = _client.Send(data, data.Length, endPoint); if (dataSent > 0) { return(result); } return(null); }
/// <summary> /// Processes incomming initial packet and creates or halts a connection. /// </summary> /// <param name="packet">Initial Packet</param> /// <param name="endPoint">Peer's endpoint</param> /// <returns></returns> private QuicConnection ProcessInitialPacket(Packet packet, IPEndPoint endPoint) { QuicConnection result = null; UInt64 availableConnectionId; byte[] data; // Unsupported version. Version negotiation packet is sent only on initial connection. All other packets are dropped. (5.2.2 / 16th draft) if (packet.Version != QuicVersion.CurrentVersion || !QuicVersion.SupportedVersions.Contains(packet.Version)) { VersionNegotiationPacket vnp = _packetCreator.CreateVersionNegotiationPacket(); data = vnp.Encode(); _client.Send(data, data.Length, endPoint); return(null); } InitialPacket cast = packet as InitialPacket; InitialPacket ip = _packetCreator.CreateInitialPacket(0, cast.SourceConnectionId); // Protocol violation if the initial packet is smaller than the PMTU. (pt. 14 / 16th draft) if (cast.Encode().Length < QuicSettings.PMTU) { ip.AttachFrame(new ConnectionCloseFrame(ErrorCode.PROTOCOL_VIOLATION, 0x00, ErrorConstants.PMTUNotReached)); } else if (ConnectionPool.AddConnection(new ConnectionData(new PacketWireTransfer(_client, endPoint), cast.SourceConnectionId, 0), out availableConnectionId) == true) { // Tell the peer the available connection id ip.SourceConnectionId = (byte)availableConnectionId; // We're including the maximum possible stream id during the connection handshake. (4.5 / 16th draft) ip.AttachFrame(new MaxStreamsFrame(QuicSettings.MaximumStreamId, StreamType.ServerBidirectional)); // Set the return result result = ConnectionPool.Find(availableConnectionId); } else { // Not accepting connections. Send initial packet with CONNECTION_CLOSE frame. // TODO: Buffering. The server might buffer incomming 0-RTT packets in anticipation of late delivery InitialPacket. // Maximum buffer size should be set in QuicSettings. ip.AttachFrame(new ConnectionCloseFrame(ErrorCode.CONNECTION_REFUSED, 0x00, ErrorConstants.ServerTooBusy)); } data = ip.Encode(); int dataSent = _client.Send(data, data.Length, endPoint); if (dataSent > 0) { return(result); } return(null); }
private void ProcessInitialPacket(Packet packet, IPEndPoint endPoint) { UInt32 availableConnectionId; byte[] data; // Unsupported version. Version negotiation packet is sent only on initial connection. All other packets are dropped. (5.2.2 / 16th draft) if (packet.Version != QuicVersion.CurrentVersion || !QuicVersion.SupportedVersions.Contains(packet.Version)) { VersionNegotiationPacket vnp = _packetCreator.CreateVersionNegotiationPacket(); data = vnp.Encode(); _client.Send(data, data.Length, endPoint); return; } InitialPacket cast = packet as InitialPacket; InitialPacket ip = _packetCreator.CreateInitialPacket(0, cast.SourceConnectionId); // Protocol violation if the initial packet is smaller than the PMTU. (pt. 14 / 16th draft) if (cast.Encode().Length < QuicSettings.PMTU) { ip.AttachFrame(new ConnectionCloseFrame(ErrorCode.PROTOCOL_VIOLATION, "PMTU have not been reached.")); } else if (ConnectionPool.AddConnection(cast.SourceConnectionId, out availableConnectionId) == true) { // Tell the peer the available connection id ip.SourceConnectionId = (byte)availableConnectionId; // We're including the maximum possible stream id during the connection handshake. (4.5 / 16th draft) ip.AttachFrame(new MaxStreamsFrame(QuicSettings.MaximumStreamId, StreamType.ServerBidirectional)); } else { // Not accepting connections. Send initial packet with CONNECTION_CLOSE frame. // TODO: Buffering. The server might buffer incomming 0-RTT packets in anticipation of late delivery InitialPacket. // Maximum buffer size should be set in QuicSettings. ip.AttachFrame(new ConnectionCloseFrame(ErrorCode.SERVER_BUSY, "The server is too busy to process your request.")); } data = ip.Encode(); int dataSent = _client.Send(data, data.Length, endPoint); if (dataSent > 0) { // Create a QuicContext to represent the connected client. QuicContext context = new QuicContext(_client, endPoint); ConnectionPool.AttachContext(ip.SourceConnectionId, context); OnClientConnected?.Invoke(context); } }
//Should be called after connections list is finished public void constructServiceConnections() { foreach (ServiceNodeScript node in connectedServiceComponents) { //Check if Arrow already exists IDPair pair = new IDPair(this.GetInstanceID(), node.GetInstanceID()); GameObject connectionGO = connectionPool.getConnection(pair); if (connectionGO == null) { connectionGO = Instantiate(connectionPrefab, transform.position, Quaternion.identity); connectionGO.name = "Connection To " + node.gameObject.name; #region adjust transform Vector3 dirVec = node.transform.position - transform.position; dirVec.y = 0; float distance = dirVec.magnitude; Vector3 newScale = new Vector3(distance, GlobalVar.serviceNodeSize * 0.25f, GlobalVar.serviceNodeSize * 0.25f); connectionGO.transform.localScale = newScale; connectionGO.transform.position += new Vector3(distance / 2f, 0, 0); connectionGO.transform.parent = rotPivot.transform; float angle = Vector3.Angle(Vector3.right, dirVec / distance); Vector3 cross = Vector3.Cross(Vector3.right, dirVec / distance); if (cross.y < 0) { angle = -angle; } rotPivot.transform.Rotate(Vector3.up, angle); connectionGO.transform.parent = null; connectionGO.transform.parent = transform; rotPivot.transform.Rotate(Vector3.up, -angle); #endregion connectionGO.SetActive(false); connectionPool.AddConnection(pair, connectionGO); } connections.Add(connectionGO); GameObject.Destroy(rotPivot); } }
public void constructConnectionArrows() { //Construct new Arrows int cc = 0; foreach (DependencyDock otherDock in connectedDocks) { //Check if Arrow already exists IDPair pair = new IDPair(this.GetInstanceID(), otherDock.GetInstanceID()); GameObject connectionArrow = connectionPool.GetConnection(pair); if (connectionArrow == null) { GameObject arrowBody; if (dockType == DockType.Import) { arrowBody = Instantiate(importArrowPrefab, transform.position, Quaternion.identity); //var renderer = arrowBody.GetComponent<MeshRenderer>(); //renderer.sharedMaterial = VisualizationLoader.Instance.ImportArrowMaterial; } else { arrowBody = Instantiate(exportArrowPrefab, transform.position, Quaternion.identity); //var renderer = arrowBody.GetComponent<MeshRenderer>(); //renderer.sharedMaterial = VisualizationLoader.Instance.ExportArrowMaterial; } GameObject arrowHead = Instantiate(arrowHeadPrefab, transform.position, Quaternion.identity); //var headRenderer = arrowBody.GetComponent<MeshRenderer>(); //headRenderer.sharedMaterial = VisualizationLoader.Instance.ArrowHeadMaterial; connectionArrow = new GameObject(); connectionArrow.name = "Connection from " + gameObject.name + " to " + otherDock.gameObject.name; connectionArrow.gameObject.AddComponent <DependencyArrow>(); arrowHead.name = connectionArrow.name + "_ArrowHead"; arrowBody.name = connectionArrow.name + "_ArrowBody"; connectionArrow.transform.parent = dependencyContainer.transform; arrowHead.transform.parent = connectionArrow.transform; arrowHead.transform.localPosition = Vector3.zero; arrowBody.transform.parent = connectionArrow.transform; arrowBody.transform.localPosition = Vector3.zero; connectionArrow.transform.localScale = Vector3.one; connectionArrow.transform.rotation = Quaternion.identity; #region adjust transform Vector3 dockLocalPos = transform.localPosition; Vector3 otherDockLocalPos = otherDock.transform.localPosition; Vector3 islandPos = transform.parent.localPosition; Vector3 otherIslandPos = otherDock.transform.parent.localPosition; Vector3 dockPos = islandPos + dockLocalPos; Vector3 otherDockPos = otherIslandPos + otherDockLocalPos; Vector3 direction = otherDockPos - dockPos; direction.y = 0.0f; double distance = direction.magnitude; Vector3 connectionArrowPos = dockPos + (direction / 2); connectionArrow.transform.localPosition = connectionArrowPos; double angle = Vector3.Angle(Vector3.right, direction.normalized); Vector3 cross = Vector3.Cross(Vector3.right, direction.normalized); if (cross.y < 0) { angle = -angle; } connectionArrow.transform.localRotation = Quaternion.Euler(0, (float)angle, 0); float sDWidth = gameObject.GetComponent <Collider>().bounds.extents.magnitude; float tDWidth = otherDock.gameObject.GetComponent <Collider>().bounds.extents.magnitude; float cumulativeWidth = (sDWidth + tDWidth) * 30; float conLength = ((float)distance - cumulativeWidth) - 0.5f; Vector3 arrowBodyScale = new Vector3(conLength, conLength, arrowBody.transform.localScale.z); arrowBody.transform.localScale = arrowBodyScale; float maxHeight = Mathf.Max(gameObject.GetComponent <Collider>().bounds.extents.y, otherDock.gameObject.GetComponent <Collider>().bounds.extents.y); connectionArrow.transform.localPosition += new Vector3(0, maxHeight + cumulativeWidth + 0.7f, 0); #region Arrowhead arrowBodyScale.x = 0.02f * 30f * dockWeights[cc]; arrowBodyScale.y = 0.01f; arrowHead.transform.localScale = arrowBodyScale; if (dockType == DockType.Import) { arrowHead.transform.localPosition += new Vector3(-conLength * 0.5f, 0f, 0f); arrowHead.transform.localEulerAngles = new Vector3(0f, 180f, -39f); } else { arrowHead.transform.localPosition += new Vector3(conLength * 0.5f, 0f, 0f); arrowHead.transform.localEulerAngles = new Vector3(0f, 0f, -39f); } #endregion #endregion //connectionArrow.AddComponent<ObjectStateSynchronizer>().SyncTransform = true; //arrowhead.addcomponent<objectstatesynchronizer>().synctransform = true; //arrowbody.addcomponent<objectstatesynchronizer>().synctransform = true; connectionPool.AddConnection(pair, connectionArrow); connectionArrow.SetActive(false); } connectionArrows.Add(connectionArrow); cc++; } }
public void constructConnectionArrows() { //Construct new Arrows int cc = 0; foreach (DependencyDock dock in connectedDocks) { //Check if Arrow already exists IDPair pair = new IDPair(this.GetInstanceID(), dock.GetInstanceID()); GameObject conArrow = connectionPool.getConnection(pair); if (conArrow == null) { GameObject arrowBody; if (dockType == DockType.ImportDock) { arrowBody = Instantiate(importArrowPrefab, transform.position, Quaternion.identity); } else { arrowBody = Instantiate(exportArrowPrefab, transform.position, Quaternion.identity); } GameObject arrowHead = Instantiate(arrowHeadPrefab, transform.position, Quaternion.identity); conArrow = new GameObject(); conArrow.name = "Connection To " + dock.gameObject.name; #region adjust transform Vector3 dirVec = dock.transform.position - transform.position; dirVec.y = 0; float distance = dirVec.magnitude; float sDWidth = gameObject.GetComponent <Collider>().bounds.extents.x; float tDWidth = dock.gameObject.GetComponent <Collider>().bounds.extents.x;; float aWidth = GlobalVar.depArrowWidth * dockWeights[cc]; float connectionLength = distance - (sDWidth + tDWidth); Vector3 newScale = new Vector3(connectionLength, connectionLength, GlobalVar.depArrowWidth * dockWeights[cc]); arrowBody.transform.localScale = newScale; #region Arrowhead newScale.x = GlobalVar.depArrowWidth * dockWeights[cc]; newScale.y = 1f; arrowHead.transform.localScale = newScale; if (dockType == DockType.ImportDock) { arrowHead.transform.position += new Vector3(-connectionLength * 0.5f, 0f, 0f); arrowHead.transform.localEulerAngles = new Vector3(0f, 180f, -39f); } else { arrowHead.transform.position += new Vector3(connectionLength * 0.5f, 0f, 0f); arrowHead.transform.localEulerAngles = new Vector3(0f, 0f, -39f); } arrowHead.transform.parent = conArrow.transform; #endregion arrowBody.transform.parent = conArrow.transform; float maxHeight = Mathf.Max(gameObject.GetComponent <Collider>().bounds.extents.y, dock.gameObject.GetComponent <Collider>().bounds.extents.y); conArrow.transform.position += new Vector3((connectionLength / 2f), maxHeight, 0); conArrow.transform.parent = rotPivot.transform; float angle = Vector3.Angle(Vector3.right, dirVec / distance); Vector3 cross = Vector3.Cross(Vector3.right, dirVec / distance); if (cross.y < 0) { angle = -angle; } rotPivot.transform.Rotate(Vector3.up, angle); conArrow.transform.parent = null; conArrow.transform.parent = dependencyContainer.transform; rotPivot.transform.Rotate(Vector3.up, -angle); #endregion conArrow.SetActive(false); connectionPool.AddConnection(pair, conArrow); } connectionArrows.Add(conArrow); cc++; } }