1/** @addtogroup MCD_MCDIMPL_DAEMON_SRV
2 * @{
3 * @file
4 *
5 * Connection data.
6 *
7 * <!-- Copyright Giesecke & Devrient GmbH 2009 - 2012 -->
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote
18 *    products derived from this software without specific prior
19 *    written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
22 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33#ifndef NETLINKCONNECTION_H_
34#define NETLINKCONNECTION_H_
35
36#include <unistd.h>
37#include <map>
38#include <exception>
39#include <inttypes.h>
40
41#include <sys/types.h>
42#include <sys/socket.h>
43#include <sys/un.h>
44
45#include "Connection.h"
46#include "CMutex.h"
47#include "CSemaphore.h"
48
49/** PID(address) of MC daemon.  */
50#define MC_DAEMON_PID 0xFFFFFFFF
51/** Maximum Netlink payload size
52 * TODO: figure out the best value for this */
53#define MAX_PAYLOAD 1024
54
55#define MC_DAEMON_NETLINK  17
56
57
58class NetlinkConnection;
59
60/**
61 * Hash function for unique ID of a connection.
62 *
63 * @param pid Connection PID
64 * @param seq Connection sequenceMagic
65 *
66 * @return Unique identifier of the connection
67 */
68uint64_t hashConnection(pid_t pid, uint32_t seq);
69
70/** Netlink connection manager interface.
71 * This inteface has to be implemented by the handling server
72 * to ensure connection will be removed from accounting when destroied. */
73class NetlinkConnectionManager
74{
75public:
76    virtual ~NetlinkConnectionManager() {};
77    /**
78     * Retreive connection based on a unique hash.
79     * Search the peer connections hashmap for a hash and return
80     * the associated Connection object
81     *
82     * @param hash The hash to search
83     * @return The NetlinkConnection object if found or NULL if not found
84     */
85    virtual NetlinkConnection *findConnection(
86        uint64_t hash
87    ) = 0;
88
89    /**
90     * Insert a connection in connection lisst
91     * Insert a new connection in the peer connections list. If there
92     * is already such a connection
93     * it will be overriden!
94     *
95     * @param hash The hash to use
96     * @param connection The connection object to insert
97     */
98    virtual void insertConnection(
99        uint64_t hash,
100        NetlinkConnection *connection
101    ) = 0;
102
103    /**
104     * Remove a connection from the peer connections
105     * Remove the connection associated with seq from the peer list.
106     * This doesn't actually free the connection object!
107     * If the hash is invalid nothing happens.
108     *
109     * @param hash The hash hash use
110     */
111    virtual void removeConnection(
112        uint64_t hash
113    ) = 0;
114};
115
116class NetlinkConnection: public Connection
117{
118public:
119    pid_t selfPid; /**< Which PID to use to identify when writing data */
120    pid_t peerPid; /**< Destination PID for sending data */
121    uint32_t sequenceMagic; /**< Random? magic to match requests/answers */
122    uint64_t hash; /**< Unique connection ID, see hashConnection */
123
124    NetlinkConnection(
125        void
126    );
127
128    /**
129     * Connection main constructor
130     *
131     * @param manager Connection manager pointer.
132     * @param socketDescriptor Socket descriptor to use for writing
133     * @param pid Connection PID
134     * @param seq Connection sequence magic number
135     */
136    NetlinkConnection(
137        NetlinkConnectionManager *manager,
138        int   socketDescriptor,
139        uint32_t pid,
140        uint32_t seq
141    );
142
143    virtual ~NetlinkConnection(
144        void
145    );
146
147    /**
148     * Connect to destination.
149     *
150     * @param Destination pointer.
151     * @return true on success.
152     */
153    virtual bool connect(
154        const char *dest
155    );
156
157    /**
158     * Read bytes from the connection(compatiblity method).
159     *
160     * @param buffer    Pointer to destination buffer.
161     * @param len       Number of bytes to read.
162     * @param timeout   Timeout in milliseconds(ignored)
163     * @return Number of bytes read.
164     * @return -1 if select() failed (returned -1)
165     * @return -2 if no data available, i.e. timeout
166     */
167    virtual size_t readData(
168        void      *buffer,
169        uint32_t  len,
170        int32_t   timeout
171    );
172
173    /**
174     * Read bytes from the connection.
175     *
176     * @param buffer    Pointer to destination buffer.
177     * @param len       Number of bytes to read.
178     * @return Number of bytes read.
179     */
180    virtual size_t readData(
181        void       *buffer,
182        uint32_t  len
183    );
184
185    /**
186     * Write bytes to the connection.
187     *
188     * @param buffer    Pointer to source buffer.
189     * @param len       Number of bytes to read.
190     * @return Number of bytes written.
191     */
192    virtual size_t writeData(
193        void      *buffer,
194        uint32_t  len
195    );
196
197    /**
198     * Set the internal data connection.
199     * This method is called by the
200     *
201     * @param nlh    Netlink structure pointing to data.
202     */
203    void handleMessage(
204        struct nlmsghdr *nlh
205    );
206
207private:
208    CMutex dataMutex;
209    CSemaphore dataLeft;
210    struct nlmsghdr *dataMsg; /**< Last message received */
211    uint32_t dataLen; /**< How much connection data is left */
212    uint8_t *dataStart; /**< Start pointer of remaining data */
213    NetlinkConnectionManager *manager; /**< Netlink connection manager(eg. NetlinkServer) */
214};
215
216typedef std::map<uint64_t, NetlinkConnection *>  connectionMap_t;
217
218#endif /* NETLINKCONNECTION_H_ */
219
220/** @} */
221