Beispiel #1
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;
        }
Beispiel #2
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();
            }
        }