示例#1
0
        //internal void SendErrorResponseToRegisterReq(RegisterRequestPacket req, IPEndPoint requesterEndpoint,
        //    ConnectionToNeighbor neighbor, bool alreadyRepliedWithNPA, DrpResponderStatusCode errorCode)
        //{
        //    WriteToLog_routing_higherLevelDetail($"routing failed, executing SendErrorResponseToRegisterReq()", req, neighbor?.LocalDrpPeer);
        //    if (alreadyRepliedWithNPA)
        //    {
        //        // send ack1
        //        _ = RespondToSourcePeerWithAck1_Error(requesterEndpoint, req, neighbor, errorCode);
        //    }
        //    else
        //    {
        //        // send NPACK
        //        SendNeighborPeerAckResponseToRegisterReq(req, requesterEndpoint, NextHopResponseOrFailureCode.failure_routeIsUnavailable, neighbor);
        //    }
        //}

        internal void SendNeighborPeerAckResponseToRegisterAck1(RegisterAck1Packet ack1, ConnectionToNeighbor neighbor)
        {
            var npAck = new NeighborPeerAckPacket
            {
                ReqP2pSeq16  = ack1.ReqP2pSeq16,
                ResponseCode = ResponseOrFailureCode.accepted
            };

            npAck.NeighborToken32 = neighbor.RemoteNeighborToken32;
            npAck.NeighborHMAC    = neighbor.GetNeighborHMAC(w => npAck.GetSignedFieldsForNeighborHMAC(w, ack1.GetSignedFieldsForNeighborHMAC));
            var npAckUdpData = npAck.Encode(false);

            RespondToRequestAndRetransmissions(ack1.DecodedUdpPayloadData, npAckUdpData, neighbor.RemoteEndpoint);
        }
示例#2
0
        void SendNeighborPeerAckResponseToCfm(InviteConfirmationPacket cfm, ConnectionToNeighbor neighbor)
        {
            var npAck = new NeighborPeerAckPacket
            {
                ReqP2pSeq16  = cfm.ReqP2pSeq16,
                ResponseCode = ResponseOrFailureCode.accepted
            };

            npAck.NeighborToken32 = neighbor.RemoteNeighborToken32;
            npAck.NeighborHMAC    = neighbor.GetNeighborHMAC(w => npAck.GetSignedFieldsForNeighborHMAC(w, cfm.GetSignedFieldsForNeighborHMAC));
            var npAckUdpData = npAck.Encode(false);

            Engine.RespondToRequestAndRetransmissions(cfm.DecodedUdpPayloadData, npAckUdpData, neighbor.RemoteEndpoint);
        }
示例#3
0
        void SendNeighborPeerAckResponseToRegisterCfm(RegisterConfirmationPacket cfm, IPEndPoint remoteEndpoint, ConnectionToNeighbor neighbor)
        {
            var npAck = new NeighborPeerAckPacket
            {
                ReqP2pSeq16  = cfm.ReqP2pSeq16,
                ResponseCode = ResponseOrFailureCode.accepted
            };

            if (cfm.AtoEP == false)
            {
                npAck.NeighborToken32 = neighbor.RemoteNeighborToken32;
                npAck.NeighborHMAC    = neighbor.GetNeighborHMAC(w => npAck.GetSignedFieldsForNeighborHMAC(w, cfm.GetSignedFieldsForNeighborHMAC));
            }
            var npAckUdpData = npAck.Encode(cfm.AtoEP);

            RespondToRequestAndRetransmissions(cfm.DecodedUdpPayloadData, npAckUdpData, remoteEndpoint);
        }
        /// <param name="waitNhaFromNeighborNullable">is used to verify NPACK.NeighborHMAC</param>
        internal async Task <NeighborPeerAckPacket> OptionallySendUdpRequestAsync_Retransmit_WaitForNeighborPeerAck(string completionActionVisibleId, byte[] requestPacketDataNullable, IPEndPoint responderEndpoint,
                                                                                                                    RequestP2pSequenceNumber16 reqP2pSeq16, ConnectionToNeighbor waitNhaFromNeighborNullable = null, Action <BinaryWriter> npaRequestFieldsForNeighborHmacNullable = null)
        {
            var npaScanner = NeighborPeerAckPacket.GetScanner(reqP2pSeq16, waitNhaFromNeighborNullable, npaRequestFieldsForNeighborHmacNullable);

            if (WriteToLog_udp_deepDetail_enabled)
            {
                WriteToLog_udp_deepDetail($"waiting for NPACK, scanner: {MiscProcedures.ByteArrayToString(npaScanner.ResponseFirstBytes)} npaSeq={reqP2pSeq16}");
            }
            var nextHopResponsePacketData = await SendUdpRequestAsync_Retransmit(
                new PendingLowLevelUdpRequest(completionActionVisibleId, responderEndpoint,
                                              npaScanner,
                                              DateTimeNowUtc, Configuration.UdpLowLevelRequests_ExpirationTimeoutS,
                                              requestPacketDataNullable,
                                              Configuration.UdpLowLevelRequests_InitialRetransmissionTimeoutS, Configuration.UdpLowLevelRequests_RetransmissionTimeoutIncrement
                                              ));

            if (nextHopResponsePacketData == null)
            {
                string desc = "no NPACK response to DRP request '";
                if (requestPacketDataNullable != null)
                {
                    desc += (PacketTypes)requestPacketDataNullable[0];
                }
                desc += $"' - timeout expired ({Configuration.UdpLowLevelRequests_ExpirationTimeoutS}s) completionAction={completionActionVisibleId}";
                if (waitNhaFromNeighborNullable != null)
                {
                    desc += $", neighbor={waitNhaFromNeighborNullable}";
                }
                throw new DrpTimeoutException(desc);
            }

            var nextHopResponsePacket = new NeighborPeerAckPacket(nextHopResponsePacketData);

            if (nextHopResponsePacket.ResponseCode != ResponseOrFailureCode.accepted)
            {
                if (WriteToLog_udp_deepDetail_enabled)
                {
                    WriteToLog_udp_deepDetail($"got NPACK with {nextHopResponsePacket.ResponseCode} throwing exception");
                }
                throw new RequestRejectedException(nextHopResponsePacket.ResponseCode);
            }
            return(nextHopResponsePacket);
        }
示例#5
0
        internal void SendNeighborPeerAck(ResponseOrFailureCode responseCode)
        {
            var npAck = new NeighborPeerAckPacket
            {
                ReqP2pSeq16  = ReqP2pSeq16,
                ResponseCode = responseCode
            };

            if (ReceivedFromNeighborNullable != null)
            {
                npAck.NeighborToken32 = ReceivedFromNeighborNullable.RemoteNeighborToken32;
                npAck.NeighborHMAC    = ReceivedFromNeighborNullable.GetNeighborHMAC(w => npAck.GetSignedFieldsForNeighborHMAC(w, GetSignedFieldsForNeighborHMAC));
            }

            var npAckUdpData = npAck.Encode(ReceivedFromNeighborNullable == null);

            _engine.RespondToRequestAndRetransmissions(RequestUdpPayloadData, npAckUdpData, ReceivedFromEndpoint);
            _repliedWithNPA = true;
        }
示例#6
0
        public async Task <byte[]> SendRequestAsync(string completionActionVisibleId)
        {
            // wait for NPACK (-accepted or -failure)
            _logger.WriteToLog_detail($"[{completionActionVisibleId}] >> SendRequestAsync() _requestUdpData={MiscProcedures.GetArrayHashCodeString(_requestUdpData)}");
            await _engine.OptionallySendUdpRequestAsync_Retransmit_WaitForNeighborPeerAck(completionActionVisibleId + "_first_npack", _requestUdpData, _destinationEndpoint, _sentReqP2pSeq16);

            // wait for ACK1 OR FAILURE
            await Task.WhenAny(
                WaitForAck1Async(completionActionVisibleId + "_ack1"),
                WaitForFailureAsync(completionActionVisibleId + "_failure")
                );

            if (_pendingAck1Request != null)
            {
                _engine.CancelPendingRequest(_pendingAck1Request);
                _pendingAck1Request = null;
            }
            if (_pendingFailureRequest != null)
            {
                _engine.CancelPendingRequest(_pendingFailureRequest);
                _pendingFailureRequest = null;
            }


            if (_waitForAck1Completed)
            {
                if (Ack1UdpData == null)
                {
                    ThrowTimeoutException(completionActionVisibleId);
                }
                _logger.WriteToLog_detail($"received ACK1");
                return(Ack1UdpData);
            }
            else if (_waitForFailureCompleted)
            {
                if (_failureUdpData == null)
                {
                    ThrowTimeoutException(completionActionVisibleId);
                }
                _logger.WriteToLog_detail($"received FAILURE");
                var failure = FailurePacket.DecodeAndOptionallyVerify(_failureUdpData, _sentReqP2pSeq16);

                if (_failureUdpData != null)
                {
                    // send NPACK to FAILURE
                    var npAckToFailure = new NeighborPeerAckPacket
                    {
                        ReqP2pSeq16  = _sentReqP2pSeq16,
                        ResponseCode = ResponseOrFailureCode.accepted
                    };
                    if (_destinationNeighborNullable != null)
                    {
                        npAckToFailure.NeighborToken32 = _destinationNeighborNullable.RemoteNeighborToken32;
                        npAckToFailure.NeighborHMAC    = _destinationNeighborNullable.GetNeighborHMAC(w => npAckToFailure.GetSignedFieldsForNeighborHMAC(w, failure.GetSignedFieldsForNeighborHMAC));
                    }

                    var npAckToFailureUdpData = npAckToFailure.Encode(_destinationNeighborNullable == null);

                    _engine.RespondToRequestAndRetransmissions(_failureUdpData, npAckToFailureUdpData, _destinationEndpoint);
                }

                throw new RequestRejectedException(failure.ResponseCode);
            }
            else
            {
                throw new InvalidOperationException();
            }
        }