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 
58 class 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  */
68 uint64_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. */
73 class NetlinkConnectionManager
74 {
75 public:
~NetlinkConnectionManager()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 
116 class NetlinkConnection: public Connection
117 {
118 public:
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 
207 private:
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 
216 typedef std::map<uint64_t, NetlinkConnection *>  connectionMap_t;
217 
218 #endif /* NETLINKCONNECTION_H_ */
219 
220 /** @} */
221