internal void InvokeReceivedEvent(object sender, DatagramReceiveEventArgs e)
 {
     Interlocked.Add (ref _recvBytes, e.Size);
     Interlocked.Increment (ref _recvDgrams);
     if (Received != null) {
         try {
             Received (sender, e);
         } catch {}
     }
 }
Exemple #2
0
        void Socket_Received(object sender, DatagramReceiveEventArgs e)
        {
            if (!IsActive)
                return;

            MessageType type;
            object obj;
            int tmp;
            uint id = 0;
            try {
                byte[] msg = _key.Decrypt (e.Buffer, 0, e.Size);
                using (MemoryStream strm = new MemoryStream (msg, 0, msg.Length, false)) {
                    if ((tmp = strm.ReadByte ()) < 0)
                        goto MessageError;
                    type = (MessageType)tmp;
                    if (type != MessageType.OneWay) {
                        for (int i = 0; i < 32; i += 8) {
                            if ((tmp = strm.ReadByte ()) < 0)
                                goto MessageError;
                            id |= (uint)(tmp << i);
                        }
                    }
                    obj = _formatter.Deserialize (strm);
                    if (obj == null)
                        goto MessageError;
                }
            } catch {
                goto MessageError;
            }

            if (_nullObject.Equals (obj))
                obj = null;
            string strMsgType = (obj == null ? "null msg" : obj.GetType ().Name);

            switch (type) {
                case MessageType.Request:
                    ThreadTracer.AppendThreadName (" (req: " + strMsgType + ")");
                    InquiredEventArgs args = new InquiredResponseState (obj, e.RemoteEndPoint, id);
                    InvokeInquired (this, args);
                    break;
                case MessageType.Response:
                    InquiredAsyncResultBase ar = RemoveFromRetryList (id, e.RemoteEndPoint);
                    if (ar == null)
                        return;
                    ThreadTracer.AppendThreadName (" (res: " + strMsgType + ", req: "
                        + (ar.Request == null ? "null msg" : ar.Request.GetType ().Name) + ")");
                    ar.Complete (obj, this);
                    InvokeInquirySuccess (this, new InquiredEventArgs (ar.Request, obj, e.RemoteEndPoint, DateTime.Now - ar.TransmitTime, ar.RetryCount));
                    break;
                case MessageType.OneWay:
                    ThreadTracer.AppendThreadName (" (ow: " + strMsgType + ")");
                    InvokeReceived (this, new ReceivedEventArgs (obj, e.RemoteEndPoint));
                    break;
                default:
                    goto MessageError;
            }
            return;

            MessageError:
            return;
        }
Exemple #3
0
 void Socket_Received(object sender, DatagramReceiveEventArgs e)
 {
     switch (e.Buffer[0]) {
         case 0: /* Packet */
             byte[] buf = new byte[5];
             buf[0] = 1;
             Buffer.BlockCopy (e.Buffer, 1, buf, 1, buf.Length - 1); // Copy sequence
             uint rseq = ((uint)buf[1] << 24) | ((uint)buf[2] << 16) | ((uint)buf[3] << 8) | ((uint)buf[4]);
             _sock.SendTo (buf, _remoteEP);
             lock (_recvBuffer) {
                 _lastReceived = DateTime.Now;
                 _recvBuffer.Add (new ReceiveSegment (rseq, e.Buffer.CopyRange (HeaderSize, e.Size - HeaderSize)));
                 _recvWaitHandle.Set ();
             }
             break;
         case 1: /* ACK */
             uint seq = ((uint)e.Buffer[1] << 24) | ((uint)e.Buffer[2] << 16) | ((uint)e.Buffer[3] << 8) | ((uint)e.Buffer[4]);
             lock (_lock) {
                 uint lowest_sendidx = uint.MaxValue, acked_sendidx = 0;
                 int lowest_idx = int.MaxValue, acked_idx = -1;
                 for (int i = 0; i < _sendBuffer.Length; i ++) {
                     if (_sendBuffer[i].State == PacketState.AckWaiting && _sendBuffer[i].Sequence < seq) {
                         if (lowest_sendidx > _sendBuffer[i].RetransmitIndex) {
                             lowest_sendidx = _sendBuffer[i].RetransmitIndex;
                             lowest_idx = i;
                         }
                     }
                 }
                 for (int i = 0; i < _sendBuffer.Length; i ++) {
                     if (_sendBuffer[i].State == PacketState.AckWaiting && _sendBuffer[i].Sequence == seq) {
                         if (_sendBuffer[i].Retries == 0)
                             Update_RTO ((float)(DateTime.Now - _sendBuffer[i].Start).TotalMilliseconds);
                         acked_idx = i;
                         acked_sendidx = _sendBuffer[i].RetransmitIndex;
                         _sendBuffer[i].Reset ();
                         _sendBufferFilled--;
                         _sendWaitHandle.Set ();
                         break;
                     }
                 }
                 if (lowest_idx != int.MaxValue && acked_idx >= 0 && acked_sendidx - lowest_sendidx >= 3) {
                     Packet p = _sendBuffer[lowest_idx];
                     if (p.RTO - p.RTO_Interval + TimeSpan.FromMilliseconds (_rto) <= DateTime.Now) {
                         p.RTO = DateTime.Now;
                         p.RetransmitIndex = acked_sendidx;
                     }
                 }
             }
             break;
     }
 }
Exemple #4
0
        void InvokeThread(object o)
        {
            int idx = (int)o;

            while (_active) {
                _invokeStartHandles[idx].WaitOne ();
                if (!_active) return;

                while (true) {
                    int i = Interlocked.Increment (ref _dgramListIndex);
                    if (i >= _dgramList.Count)
                        break;
                    DatagramInfo dgram = _dgramList[i];
                    if (IsLossPacket (dgram.SourceEndPoint, dgram.DestinationEndPoint))
                        continue;
                    VirtualNetworkNode node;
                    if (!_mapping.TryGetValue (dgram.DestinationEndPoint, out node)) {
                        Interlocked.Increment (ref _noDestPackets);
                        continue;
                    }

                    int jitter = (int)((DateTime.Now.Subtract (dgram.StartDateTime) - dgram.ExpectedDelay).TotalMilliseconds);
                    lock (_jitterLock) {
                        _jitterSD.AddSample (jitter);
                        Interlocked.Increment (ref _packets);
                    }

                    if (dgram.Datagram != null) {
                        DatagramReceiveEventArgs eventArgs = new DatagramReceiveEventArgs (dgram.Datagram, dgram.Datagram.Length, dgram.SourceEndPoint);
                        node.DatagramSocket.InvokeReceivedEvent (node.DatagramSocket, eventArgs);
                        Interlocked.Add (ref _totalTraffic, dgram.Datagram.Length);
                    } else {
                        node.MessagingSocket.Deliver (dgram.SourceEndPoint, dgram.Message);
                    }
                }
                _invokeEndHandles[idx].Set ();
            }
        }
Exemple #5
0
 public InvokeHelper(UdpSocket sock, DatagramReceiveEventArgs e)
 {
     _sock = sock;
     _e = e;
 }
Exemple #6
0
 static void ReceiveThread()
 {
     List<Socket> list = new List<Socket> ();
     byte[] recvBuffer = new byte[MAX_DATAGRAM_SIZE];
     while (true) {
         list.Clear ();
         lock (_sockets) {
             if (_sockets.Count == 0) {
                 _receiveThread = null;
                 return;
             }
             list.AddRange (_sockets);
         }
         Socket.Select (list, null, null, 1 * 1000000);
         lock (_sockets) {
             for (int i = 0; i < list.Count; i ++) {
                 UdpSocket usock;
                 if (!_socketMap.TryGetValue (list[i], out usock)) {
                     continue;
                 }
                 if (usock.Received == null) {
                     continue;
                 }
                 try {
                     EndPoint remoteEP = new IPEndPoint (usock._receiveAdrs, 0);
                     int receiveSize = usock._sock.ReceiveFrom (recvBuffer, 0, recvBuffer.Length, SocketFlags.None, ref remoteEP);
                     IPEndPoint remoteIPEP = (IPEndPoint)remoteEP;
     #if !DEBUG
                     if (remoteIPEP.Port == usock._bindPort && usock._loopbackAdrs.Equals (remoteIPEP.Address)) {
                         IPAddress new_adrs = usock._pubIpVotingBox.CurrentPublicIPAddress;
                         if (usock._noneAdrs.Equals (new_adrs))
                             continue; // パブリックIPが決定していないときはそのパケットを破棄
                         remoteEP = new IPEndPoint (new_adrs, remoteIPEP.Port);
                     }
                     else if (IPAddressUtility.IsPrivate (remoteIPEP.Address)) {
                         // リリースビルド時はプライベートアドレスからのパケットを破棄
                         continue;
                     }
     #endif
                     usock._recvBytes += receiveSize;
                     usock._recvDgrams ++;
                     ushort ver = (ushort)((recvBuffer[0] << 8) | recvBuffer[1]);
                     if (ver != ProtocolVersion.Version)
                         continue; // drop
                     byte[] recvData = new byte[receiveSize - usock._header_size];
                     Buffer.BlockCopy (recvBuffer, usock._header_size, recvData, 0, recvData.Length);
                     IPAddress adrs = new IPAddress (recvBuffer.CopyRange (2, usock._header_size - 2));
                     usock._pubIpVotingBox.Vote ((IPEndPoint)remoteEP, adrs);
                     DatagramReceiveEventArgs e = new DatagramReceiveEventArgs (recvData, recvData.Length, remoteEP);
                     ThreadTracer.QueueToThreadPool (new InvokeHelper (usock, e).Invoke, "Handling Received UDP Datagram");
                 } catch {}
             }
         }
     }
 }