blob: 5be3f30cd717a7e53075bffe7c04dd2c85f95b5e [file] [log] [blame]
/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
* @{
* @file
*
* Connection data.
*
* Copyright (c) 2013 TRUSTONIC LIMITED
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the TRUSTONIC LIMITED nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef NETLINKCONNECTION_H_
#define NETLINKCONNECTION_H_
#include <unistd.h>
#include <map>
#include <exception>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include "Connection.h"
#include "CMutex.h"
#include "CSemaphore.h"
/** PID(address) of MC daemon. */
#define MC_DAEMON_PID 0xFFFFFFFF
/** Maximum Netlink payload size
* TODO: figure out the best value for this */
#define MAX_PAYLOAD 1024
#define MC_DAEMON_NETLINK 17
class NetlinkConnection;
/**
* Hash function for unique ID of a connection.
*
* @param pid Connection PID
* @param seq Connection sequenceMagic
*
* @return Unique identifier of the connection
*/
uint64_t hashConnection(pid_t pid, uint32_t seq);
/** Netlink connection manager interface.
* This inteface has to be implemented by the handling server
* to ensure connection will be removed from accounting when destroied. */
class NetlinkConnectionManager
{
public:
virtual ~NetlinkConnectionManager() {};
/**
* Retreive connection based on a unique hash.
* Search the peer connections hashmap for a hash and return
* the associated Connection object
*
* @param hash The hash to search
* @return The NetlinkConnection object if found or NULL if not found
*/
virtual NetlinkConnection *findConnection(
uint64_t hash
) = 0;
/**
* Insert a connection in connection lisst
* Insert a new connection in the peer connections list. If there
* is already such a connection
* it will be overriden!
*
* @param hash The hash to use
* @param connection The connection object to insert
*/
virtual void insertConnection(
uint64_t hash,
NetlinkConnection *connection
) = 0;
/**
* Remove a connection from the peer connections
* Remove the connection associated with seq from the peer list.
* This doesn't actually free the connection object!
* If the hash is invalid nothing happens.
*
* @param hash The hash hash use
*/
virtual void removeConnection(
uint64_t hash
) = 0;
};
class NetlinkConnection: public Connection
{
public:
pid_t selfPid; /**< Which PID to use to identify when writing data */
pid_t peerPid; /**< Destination PID for sending data */
uint32_t sequenceMagic; /**< Random? magic to match requests/answers */
uint64_t hash; /**< Unique connection ID, see hashConnection */
NetlinkConnection(
void
);
/**
* Connection main constructor
*
* @param manager Connection manager pointer.
* @param socketDescriptor Socket descriptor to use for writing
* @param pid Connection PID
* @param seq Connection sequence magic number
*/
NetlinkConnection(
NetlinkConnectionManager *manager,
int socketDescriptor,
uint32_t pid,
uint32_t seq
);
virtual ~NetlinkConnection(
void
);
/**
* Connect to destination.
*
* @param Destination pointer.
* @return true on success.
*/
virtual bool connect(
const char *dest
);
/**
* Read bytes from the connection(compatiblity method).
*
* @param buffer Pointer to destination buffer.
* @param len Number of bytes to read.
* @param timeout Timeout in milliseconds(ignored)
* @return Number of bytes read.
* @return -1 if select() failed (returned -1)
* @return -2 if no data available, i.e. timeout
*/
virtual size_t readData(
void *buffer,
uint32_t len,
int32_t timeout
);
/**
* Read bytes from the connection.
*
* @param buffer Pointer to destination buffer.
* @param len Number of bytes to read.
* @return Number of bytes read.
*/
virtual size_t readData(
void *buffer,
uint32_t len
);
/**
* Write bytes to the connection.
*
* @param buffer Pointer to source buffer.
* @param len Number of bytes to read.
* @return Number of bytes written.
*/
virtual size_t writeData(
void *buffer,
uint32_t len
);
/**
* Set the internal data connection.
* This method is called by the
*
* @param nlh Netlink structure pointing to data.
*/
void handleMessage(
struct nlmsghdr *nlh
);
private:
CMutex dataMutex;
CSemaphore dataLeft;
struct nlmsghdr *dataMsg; /**< Last message received */
uint32_t dataLen; /**< How much connection data is left */
uint8_t *dataStart; /**< Start pointer of remaining data */
NetlinkConnectionManager *manager; /**< Netlink connection manager(eg. NetlinkServer) */
};
typedef std::map<uint64_t, NetlinkConnection *> connectionMap_t;
#endif /* NETLINKCONNECTION_H_ */
/** @} */