// Start sending single message to client which token belongs to. public void Send(Message message, HostAsyncUserToken token) { byte[] messageToSend = WoxalizerAdapter.SerializeToXml(message); Logger.WriteStr(" The message to be send: " + utf8.GetString(messageToSend)); // encrypt message byte[] encryptedMsgData = EncryptionAdapter.Encrypt(messageToSend); SendMessage(token, encryptedMsgData); }
private void OnReceiveCompleted(HostCustomEventArgs args) { if (args.Result is RequestMessage) { ProcessReceivedMessageRequest(args); } else if (args.Result is ResponseMessage) { ProcessReceivedMessageResponse(args); } else if (args.Result == null) { // someone disconnected if (args.Token == _console) { Logger.WriteStr("- Console disconnected."); _console = null; } else { Logger.WriteStr("- " + args.Token.Agent.Name + " disconnected."); // mark it offline lock (AgentListLock) { _agents[args.Token.Agent.ID].Agent.Status = (int)EAgentStatus.Offline; } if (_console != null) { //Console is connected so we should send update var update = new AgentStatusUpdate { status = (int)EAgentStatus.Offline }; var updateMessage = new ResponseMessage() { Response = update, AgentId = args.Token.Agent.ID }; _server.Send(updateMessage, _console); } } } else { Logger.WriteStr(" ERROR: Cannot determinate Message type!"); } }
private void LoadAgentsList() { var agentlist = (List <Agent>)WoxalizerAdapter.LoadFromFile(AgentsFile); if (agentlist != null) { Logger.WriteStr("Loaded known agents:"); foreach (Agent agent in agentlist) { // change status to Offline agent.Status = (int)EAgentStatus.Offline; //add to List var token = new HostAsyncUserToken(); token.Agent = agent; _agents.Add(agent.ID, token); Logger.WriteStr(" < #" + agent.ID + ": " + agent.Name + " >"); } } }
// Transfers AcceptArgs to another SocketAsyncEventArgs object from the pool, and begins to receive data. private void ProcessAccept(SocketAsyncEventArgs args) { if (args.SocketError != SocketError.Success) { Logger.WriteStr("Error while processing accept."); StartAccept(null, args.UserToken as Action <HostCustomEventArgs>); //start new Accept socket return; } Logger.WriteStr("Client connection accepted. Processing Accept from client " + args.AcceptSocket.RemoteEndPoint); // Get Arg from the Pool, for recieving SocketAsyncEventArgs readEventArgs = _argsReadWritePool.Pop(); if (readEventArgs != null) { // create user's token var token = new HostAsyncUserToken(); readEventArgs.UserToken = token; token.Callback = args.UserToken as Action <HostCustomEventArgs>; // store this object in token for fast reusing token.readEventArgs = readEventArgs; // Get the socket for the accepted client connection and put it into the readEventArg object user token token.Socket = args.AcceptSocket; readEventArgs.AcceptSocket = args.AcceptSocket; // Get another Arg from the Pool, for sending. SocketAsyncEventArgs writeEventArgs = _argsReadWritePool.Pop(); if (writeEventArgs != null) { // point it's UserToken to the same token writeEventArgs.UserToken = token; writeEventArgs.AcceptSocket = args.AcceptSocket; // Link writeEventArgs to readEventArgs in the token token.writeEventArgs = writeEventArgs; // Initialize agent's data/info holder token.Agent = new Agent(); // Start timer that sends keep-alive messages token.KeepAliveTimer = new KeepAliveTimer(token); token.KeepAliveTimer.Elapsed += SendKeepAlive; // As soon as the client is connected, post a receive to the connection, to get client's identification info WaitForReceiveMessage(readEventArgs); } else { Logger.WriteStr("WARNING: There is no more SocketAsyncEventArgs available in write pool! Cannot continue. Close connection."); CloseConnection(args); } } else { Logger.WriteStr("WARNING: There is no more SocketAsyncEventArgs available in read pool! Cannot continue. Close connection."); // increase maxNumberConnectedClients simaphore back because it has been decreased in StartAccept _maxNumberConnectedClients.Release(); } // Accept the next connection request. We'll reuse Accept SocketAsyncEventArgs object. args.AcceptSocket = null; StartAccept(args, args.UserToken as Action <HostCustomEventArgs>); }
private void ProcessReceivedMessageRequest(HostCustomEventArgs args) { //server recieves requests only from Console! var message = (RequestMessage)args.Result; if (_console == null) { _console = args.Token; } if (message.Request is ListAgentsRequest) { // send all agents list to console (icluding static agent info: name, ip, OS, etc...) var agentsResponse = new ListAgentsResponse() { Agents = new List <Agent>() }; for (var i = 0; i < _agents.Count; i++) { agentsResponse.Agents.Add(_agents[i].Agent); } var responseMessage = new ResponseMessage() { UniqueID = message.UniqueID, Response = agentsResponse }; _server.Send(responseMessage, args.Token); } else if (message.Request is WakeOnLanRequest) { Agent targetAgent = _agents[message.AgentId].Agent; string targetIp = targetAgent.Data.IpConfig.IpAddress; string targetMask = targetAgent.Data.IpConfig.NetMask; Logger.WriteStr("Recieved command to wake up agent " + targetAgent.Name); bool notFound = true; //look for client on the same subnet with target, which has Online status for (var i = 0; i < _agents.Count; i++) { //exclude itself if (message.AgentId != i) { var agentToken = _agents[i]; if (NetworkHelper.IsOnSameNetwork(agentToken.Agent.Data.IpConfig.IpAddress, agentToken.Agent.Data.IpConfig.NetMask, targetIp, targetMask) && agentToken.Agent.Status == (int)EAgentStatus.Online) { // send original message with MAC address to the found agent _server.Send(message, agentToken); notFound = false; // exit loop break; } } } if (notFound) // there is no agent in the same subnet with target agent { Logger.WriteStr("Cannot wake up " + targetAgent.Name + " because there is no agent in the same subnet."); // send unsuccessfull message back to console var response = new WakeOnLanResponse(false, ((WakeOnLanRequest)message.Request).RunId); var responseMessage = new ResponseMessage() { Response = response, AgentId = message.AgentId }; _server.Send(responseMessage, _console); } } else if (message.Request is BulkStaticRequest) { //retrieve from local "database": it will speed up response. //(this data is not changes at least untill agent reconnects) var agentToken = _agents[message.AgentId]; if (agentToken.Agent.Data.IpConfig != null && agentToken.Agent.Data.OS != null) { var response = new BulkStaticResponse() { IpConf = agentToken.Agent.Data.IpConfig, OsInfo = agentToken.Agent.Data.OS }; var responseMessage = new ResponseMessage() { Response = response, AgentId = message.AgentId }; _server.Send(responseMessage, args.Token); } else { // nas no reqired info, so send request to client _server.Send(message, agentToken); } } else { //match agent by agentId and redirect received Message Request to it, if it still is connected var agentToken = _agents[message.AgentId]; if (agentToken.Socket != null) { // redirect to agent _server.Send(message, agentToken); } else { // Agent is not connected so send update to console if (_console != null) { var update = new AgentStatusUpdate { status = (int)EAgentStatus.Offline }; var updateMessage = new ResponseMessage() { Response = update, AgentId = message.AgentId }; _server.Send(updateMessage, _console); } } } }