1 /*
2  *  $Id$
3  *
4  * SocketAPI implementation for the sctplib.
5  * Copyright (C) 1999-2020 by Thomas Dreibholz
6  *
7  * Realized in co-operation between
8  * - Siemens AG
9  * - University of Essen, Institute of Computer Networking Technology
10  * - University of Applied Sciences, Muenster
11  *
12  * Acknowledgement
13  * This work was partially funded by the Bundesministerium fuer Bildung und
14  * Forschung (BMBF) of the Federal Republic of Germany (Foerderkennzeichen 01AK045).
15  * The authors alone are responsible for the contents.
16  *
17  * This program is free software: you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation, either version 3 of the License, or
20  * (at your option) any later version.
21 
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
29  *
30  * Contact: discussion@sctp.de
31  *          dreibh@iem.uni-due.de
32  *          tuexen@fh-muenster.de
33  *
34  * Purpose: Socket Message
35  *
36  */
37 
38 
39 
40 #ifndef TDMESSAGE_H
41 #define TDMESSAGE_H
42 
43 
44 #include "tdsystem.h"
45 #include "socketaddress.h"
46 
47 
48 #include <sys/uio.h>
49 #include <sys/types.h>
50 #include <sys/socket.h>
51 
52 
53 /**
54   * Wrapper for CMSG_SPACE macro.
55   */
56 inline static size_t CSpace(const size_t payloadLength);
57 
58 /**
59   * Wrapper for CMSG_LEN macro.
60   */
61 inline static size_t CLength(const size_t payloadLength);
62 
63 
64 /**
65   * Wrapper for CMSG_DATA macro.
66   */
67 inline static void* CData(cmsghdr* cmsg);
68 
69 /**
70   * Wrapper for CMSG_FIRSTHDR macro.
71   */
72 inline static cmsghdr* CFirstHeader(msghdr* header);
73 
74 /**
75   * Wrapper for CMSG_NXTHDR macro.
76   */
77 inline static cmsghdr* CNextHeader(msghdr* header, const cmsghdr* cmsg);
78 
79 
80 /**
81   * Wrapper for CMSG_DATA macro (constant version).
82   */
83 inline static const void* CData(const cmsghdr* cmsg);
84 
85 /**
86   * Wrapper for CMSG_FIRSTHDR macro (constant version).
87   */
88 inline static const cmsghdr* CFirstHeader(const msghdr* header);
89 
90 /**
91   * Wrapper for CMSG_NXTHDR macro (constant version).
92   */
93 inline static const cmsghdr* CNextHeader(const msghdr* header, const cmsghdr* cmsg);
94 
95 
96 /**
97   * This template class manages manages message structures used by
98   * sendmsg() and recvmsg(). The template parameter gives the size
99   * of the control data block.
100   *
101   * @short   Socket Message
102   * @author  Thomas Dreibholz (dreibh@iem.uni-due.de)
103   * @version 1.0
104   */
105 template<const size_t size> class SocketMessage
106 {
107    // ====== Constructor ====================================================
108    public:
109    /**
110      * Constructor.
111      */
112    inline SocketMessage();
113 
114 
115    // ====== Structure manipulation =========================================
116    /**
117      * Clear structure.
118      */
119    inline void clear();
120 
121    /**
122      * Get address as SocketAddress object. Note: This address has to be freed
123      * using delete operator!
124      *
125      * @return SocketAddress object.
126      */
127    inline SocketAddress* getAddress() const;
128 
129    /**
130      * Set address.
131      *
132      * @param address SocketAddress object.
133      * @param type Address type (AF_UNSPEC to take default from address).
134      */
135    inline void setAddress(const SocketAddress& address,
136                           const integer        family = AF_UNSPEC);
137 
138    /**
139      * Set buffer.
140      *
141      * @param buffer Buffer.
142      * @param bufferSize Size of buffer.
143      */
144    inline void setBuffer(void* buffer, const size_t buffersize);
145 
146    /**
147      * Add control header of given cmsg level and type. Returns NULL,
148      * if there is not enough free space in the control data block.
149      * The new control header is cleared (i.e. all bytes set to 0).
150      *
151      * @param payload Size of payload.
152      * @param level Level (e.g. IPPROTO_SCTP).
153      * @param type Type (e.g. SCTP_INIT).
154      * @return Pointer to begin of *payload* area.
155      */
156    inline void* addHeader(const size_t payloadLength,
157                           const int    level,
158                           const int    type);
159 
160    /**
161      * Get first cmsg header in control block.
162      *
163      * @return First cmsg header or NULL, if there are none.
164      */
165    inline cmsghdr* getFirstHeader();
166 
167    /**
168      * Get next cmsg header in control block.
169      *
170      * @param prev Previous cmsg header.
171      * @return Next cmsg header or NULL, if there are no more.
172      */
173    inline cmsghdr* getNextHeader(cmsghdr* prev);
174 
175    /**
176      * Get flags.
177      *
178      * @return Flags.
179      */
180    inline int getFlags() const;
181 
182    /**
183      * Set flags.
184      *
185      * @param flags Flags.
186      */
187    inline void setFlags(const int flags);
188 
189    // ====== Message structures =============================================
190    /**
191      * msghdr structure.
192      */
193    msghdr Header;
194 
195    /**
196      * Storage for address.
197      */
198    sockaddr_storage Address;
199 
200    /**
201      * iovec structure.
202      */
203    struct iovec IOVector;
204 
205    private:
206    cmsghdr* NextMsg;
207 
208    /**
209      * Control data block, its size is given by the template parameter.
210      */
211    public:
212 #ifdef SOLARIS
213    char Control[_CMSG_DATA_ALIGN(sizeof(struct cmsghdr)) + _CMSG_DATA_ALIGN(size)];
214 #else
215    char Control[CMSG_SPACE(size)];
216 #endif
217 };
218 
219 
220 #include "tdmessage.icc"
221 
222 
223 #endif
224