/** * Sends an answer to a proxied packet back to the original host. * Retrieves the RadiusProxyConnection object from the cache employing * the Proxy-State attribute. * @param packet packet to be sent back * @param remote the server the packet arrived from * @throws IOException */ protected void proxyPacketReceived(RadiusPacket packet, IPEndPoint remote) { // retrieve my Proxy-State attribute (the last) IList <RadiusAttribute> proxyStates = packet.GetAttributes(33); if (proxyStates == null || proxyStates.Count == 0) { throw new RadiusException("Proxy packet without Proxy-State attribute"); } RadiusAttribute proxyState = proxyStates[proxyStates.Count - 1]; // retrieve Proxy connection from cache string state = BitConverter.ToString(proxyState.Data); var proxyConnection = (RadiusProxyConnection)proxyConnections[state]; proxyConnections.Remove(state); if (proxyConnection == null) { logger.Warn("received packet on Proxy port without saved Proxy connection - duplicate?"); return; } // retrieve client RadiusEndpoint client = proxyConnection.RadiusClient; if (logger.IsInfoEnabled) { logger.Info("received Proxy packet: " + packet); logger.Info("forward packet to " + client.EndpointAddress + " with secret " + client.SharedSecret); } // remove only own Proxy-State (last attribute) packet.RemoveLastAttribute(33); // re-encode answer packet with authenticator of the original packet var answer = new RadiusPacket(packet.Type, packet.Identifier, packet.Attributes); byte[] datagram = MakeDatagramPacket(answer, client.SharedSecret, proxyConnection.Packet); // send back using correct socket UdpClient socket = proxyConnection.Port == AuthPort?GetAuthSocket() : GetAcctSocket(); socket.Send(datagram, datagram.Length, remote); }