public MsForward(byte[] buf, int start, int end) : base(buf, start, end) { addr = new byte[_length - 3]; Buffer.BlockCopy(buf, start + 3, addr, 0, _length - 3); msg = MsMessage.Parse(buf, start + _length, end); }
private void ReceiveCallback(IAsyncResult ar) { if (_udp == null || _udp.Client == null) { return; } IPEndPoint re = new IPEndPoint(IPAddress.Any, 0); Byte[] buf = null; try { buf = _udp.EndReceive(ar, ref re); byte[] addr = re.Address.GetAddressBytes(); if (!_myIps.Any(z => addr.SequenceEqual(z))) { if (buf.Length > 1) { var mt = (MsMessageType)(buf[0] > 1 ? buf[1] : buf[3]); if ((mt != MsMessageType.CONNECT && mt != MsMessageType.SEARCHGW) || _whiteList.Any(z => z.Check(addr))) { //_inBuf.Enqueue(new Tuple<byte[],byte[]>(addr, buf)); _pl.ProcessInPacket(this, addr, buf, 0, buf.Length); } else if (_pl.verbose) { var msg = MsMessage.Parse(buf, 0, buf.Length); if (msg != null) { Log.Debug("restricted {0}: {1} {2}", this.Addr2If(addr), BitConverter.ToString(buf), msg.ToString()); } } } } } catch (ObjectDisposedException) { return; } catch (Exception ex) { Log.Error("ReceiveCallback({0}, {1}) - {2}", re, buf == null ? "null" : BitConverter.ToString(buf), ex.ToString()); } if (_udp != null && _udp.Client != null) { _udp.BeginReceive(new AsyncCallback(ReceiveCallback), null); } }
internal bool ProcessInPacket(IMsGate gate, byte[] addr, byte[] buf, int start, int end) { var msg = MsMessage.Parse(buf, start, end); if (msg == null) { if (verbose) { Log.Warning("r {0}: {1} bad message", gate.Addr2If(addr), BitConverter.ToString(buf, start, end - start)); } return(false); } if (msg.MsgTyp == MsMessageType.ADVERTISE || msg.MsgTyp == MsMessageType.GWINFO) { return(true); } if (verbose) { Log.Debug("r {0}: {1} {2}", gate.Addr2If(addr), BitConverter.ToString(buf, start, end - start), msg.ToString()); } if (msg.MsgTyp == MsMessageType.SEARCHGW) { if ((msg as MsSearchGW).radius == 0 || (msg as MsSearchGW).radius == gate.gwRadius) { gate.SendGw((MsDevice)null, new MsGwInfo(gate.gwIdx)); } return(true); } if (msg.MsgTyp == MsMessageType.DHCP_REQ) { var dr = msg as MsDhcpReq; if ((dr.radius == 0 || dr.radius == 1)) { List <byte> ackAddr = new List <byte>(); byte[] respPrev = null; foreach (byte hLen in dr.hLen) { if (hLen == 0) { continue; } else if (hLen <= 8) { byte[] resp; if (respPrev != null && respPrev.Length == hLen) { resp = respPrev; } else { resp = new byte[hLen]; for (int i = 0; i < 5; i++) { for (int j = 0; j < resp.Length; j++) { resp[j] = (byte)_rand.Next(j == 0 ? 4 : 0, (i < 3 && hLen == 1) ? 31 : (j == 0 ? 254 : 255)); } if (!_devs.Any(z => z.gwIdx == gate.gwIdx && z.CheckAddr(resp))) { break; } else if (i == 4) { for (int j = 0; j < resp.Length; j++) { resp[j] = 0xFF; } } } respPrev = resp; } ackAddr.AddRange(resp); } else { if (verbose) { Log.Warning("r {0}: {1} DhcpReq.hLen is too high", gate.Addr2If(addr), BitConverter.ToString(buf, start, end - start)); } ackAddr = null; break; } } if (ackAddr != null) { gate.SendGw((MsDevice)null, new MsDhcpAck(gate.gwIdx, dr.xId, ackAddr.ToArray())); } } return(true); } if (msg.MsgTyp == MsMessageType.CONNECT) { var cm = msg as MsConnect; MsDevice dev = _devs.FirstOrDefault(z => z.owner != null && z.owner.name == cm.ClientId); if (dev == null) { var dt = Topic.root.Get("/dev/" + cm.ClientId, true, _owner); dev = new MsDevice(this, dt); _devs.Add(dev); dt.SetAttribute(Topic.Attribute.Readonly); dt.SetField("editor", "MsStatus", _owner); dt.SetField("cctor.MqsDev", string.Empty, _owner); } dev._gate = gate; dev.addr = addr; dev.Connect(cm); foreach (var dub in _devs.Where(z => z != dev && z.CheckAddr(addr) && z._gate == gate).ToArray()) { dub.addr = null; dub._gate = null; dub.state = State.Disconnected; } } else { MsDevice dev = _devs.FirstOrDefault(z => z.addr != null && z.addr.SequenceEqual(addr) && z._gate == gate); if (dev != null && (dev.state != State.Disconnected && dev.state != State.Lost)) { dev.ProcessInPacket(msg); } else { if (verbose) { if (dev == null || dev.owner == null) { Log.Debug("{0} unknown device", gate.Addr2If(addr)); } else { Log.Debug("{0} inactive device: {1}", gate.Addr2If(addr), dev.owner.path); } } gate.SendGw(addr, new MsDisconnect()); } } return(true); }