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: SCTP Association
35  *
36  */
37 
38 #ifndef SCTPASSOCIATION_H
39 #define SCTPASSOCIATION_H
40 
41 
42 #include "tdsystem.h"
43 #include "condition.h"
44 #include "internetaddress.h"
45 #include "sctpsocket.h"
46 #include "sctpnotificationqueue.h"
47 
48 #include <sctp.h>
49 
50 
51 class SCTPSocket;
52 
53 
54 /**
55   * This structure contains defaults for an association.
56   */
57 struct AssocIODefaults
58 {
59    /**
60      * Default stream ID.
61      */
62    unsigned short StreamID;
63 
64    /**
65      * Default protocol ID.
66      */
67    unsigned int ProtoID;
68 
69    /**
70      * Default time to live.
71      */
72    unsigned int TimeToLive;
73 
74    /**
75      * Default conext.
76      */
77    unsigned int Context;
78 };
79 
80 
81 
82 /**
83   * This class manages a SCTP assocation. Note: The constructor is protected,
84   * a SCTP assocation can be created from an SCTP socket using associate() or
85   * accept().
86   *
87   * @short   SCTP Association
88   * @author  Thomas Dreibholz (dreibh@iem.uni-due.de)
89   * @version 1.0
90   *
91   * @see SCTPSocket
92   * @see SCTPSocket#associate
93   * @see SCTPSocket#accept
94   */
95 class SCTPAssociation
96 {
97    // ====== Friend classes =================================================
98    friend class SCTPSocket;
99    friend class SCTPConnectionlessSocket;
100    friend class SCTPSocketMaster;
101 
102 
103    // ====== Destructor =====================================================
104    public:
105    /**
106      * Destructor.
107      */
108    ~SCTPAssociation();
109 
110 
111    // ====== Association functions ==========================================
112    /**
113      * Get internal association ID.
114      *
115      * @return Association ID.
116      */
117    inline unsigned int getID() const;
118 
119    /**
120      * Get local addresses.
121      *
122      * @param addressArray Reference to store NULL-terminated array of local addresses. The addresses are allocated automatically and have to be freed using deleteAddressList().
123      * @return true, if addressEntries are sufficient; false otherwise.
124      *
125      * @see SocketAddress#deleteAddressList
126      */
127    bool getLocalAddresses(SocketAddress**& addressArray);
128 
129    /**
130      * Get remote addresses.
131      *
132      * @param addressArray Reference to store NULL-terminated array of local addresses. The addresses are allocated automatically and have to be freed using deleteAddressList().
133      * @return true, if addressEntries are sufficient; false otherwise.
134      *
135      * @see SocketAddress#deleteAddressList
136      */
137    bool getRemoteAddresses(SocketAddress**& addressArray);
138 
139 
140    /**
141      * Receive data.
142      *
143      * @param buffer Buffer to store data to.
144      * @param bufferSize Size of data buffer; this will be overwritten with actual size of data content.
145      * @param flags Flags; this will be overwritten with actual reception flags.
146      * @param streamID Variable to store stream ID to.
147      * @param protoID Variable to store protocol ID to.
148      * @param ssn Variable to store SSN to.
149      * @param tsn Variable to store TSN to.
150      * @return error code (0 for success).
151      */
152    int receive(char*           buffer,
153                size_t&         bufferSize,
154                int&            flags,
155                unsigned short& streamID,
156                unsigned int&   protoID,
157                uint16_t&       ssn,
158                uint32_t&       tsn);
159 
160    /**
161      * Receive data.
162      *
163      * @param buffer Buffer to store data to.
164      * @param bufferSize Size of data buffer; this will be overwritten with actual size of data content.
165      * @param flags Flags; this will be overwritten with actual reception flags.
166      * @param streamID Variable to store stream ID to.
167      * @param protoID Variable to store protocol ID to.
168      * @param ssn Variable to store SSN to.
169      * @param tsn Variable to store TSN to.
170      * @param address Reference to store the destination addresses to. The address is allocated automatically and has to be freed using delete operator. Set NULL to skip creation of the address.
171      * @return error code (0 for success).
172      */
173    int receiveFrom(char*           buffer,
174                    size_t&         bufferSize,
175                    int&            flags,
176                    unsigned short& streamID,
177                    unsigned int&   protoID,
178                    uint16_t&       ssn,
179                    uint32_t&       tsn,
180                    SocketAddress** address);
181 
182 
183    /**
184      * Send data.
185      *
186      * @param buffer Data to be sent.
187      * @param length Length of data to be sent.
188      * @param flags Flags.
189      * @param streamID Stream ID.
190      * @param protoID Protocol ID.
191      * @param timeToLive Time to live in milliseconds.
192      * @param useDefaults true to use defaults for Stream ID, Protocol ID and TTL; false to use given values.
193      * @return error code (0 for success).
194      */
195    inline int send(const char*          buffer,
196                    const size_t         length,
197                    const int            flags,
198                    const unsigned short streamID,
199                    const unsigned int   protoID,
200                    const unsigned int   timeToLive,
201                    const bool           useDefaults);
202 
203    /**
204      * Send data via path given by address.
205      *
206      * @param buffer Data to be sent.
207      * @param length Length of data to be sent.
208      * @param flags Flags.
209      * @param streamID Stream ID.
210      * @param protoID Protocol ID.
211      * @param timeToLive Time to live in milliseconds.
212      * @param useDefaults true to use defaults for Stream ID, Protocol ID and TTL; false to use given values.
213      * @param pathDestinationAddress Destination address of path to send data via.
214      * @return error code (0 for success).
215      */
216    int sendTo(const char*          buffer,
217               const size_t         length,
218               const int            flags,
219               const unsigned short streamID,
220               const unsigned int   protoID,
221               const unsigned int   timeToLive,
222               const bool           useDefaults,
223               const SocketAddress* pathDestinationAddress);
224 
225    /**
226      * Shutdown.
227      */
228    void shutdown();
229 
230    /**
231      * Abort.
232      */
233    void abort();
234 
235 
236    // ====== Check, if there is new data to read ============================
237    /**
238      * Check, if queue has data to read for given flags.
239      *
240      * @return true if queue has data; false otherwise.
241      */
242    bool hasData();
243 
244 
245    // ====== Notification flags =============================================
246    /**
247      * Get notification flags.
248      *
249      * @return Notification flags.
250      */
251    inline unsigned int getNotificationFlags() const;
252 
253    /**
254      * Get notification flags.
255      *
256      * @param notificationFlags Notification flags.
257      */
258    inline void setNotificationFlags(const unsigned int notificationFlags);
259 
260 
261    // ====== Association parameters =========================================
262    /**
263      * Get association defaults.
264      *
265      * @param defaults Reference to store association defaults to.
266      */
267    void getAssocIODefaults(struct AssocIODefaults& defaults);
268 
269     /**
270      * Set association defaults.
271      *
272      * @param defaults Association defaults.
273      */
274    void setAssocIODefaults(const struct AssocIODefaults& defaults);
275 
276    /**
277      * Set stream default timeouts.
278      * @param timeout Timeout in milliseconds.
279      * @param start First stream ID to set timeout for.
280      * @param start Last stream ID to set timeout for.
281      * @return true, if timeout has been updated; false otherwise.
282      */
283    bool setDefaultStreamTimeouts(const unsigned int   timeout,
284                                  const unsigned short start,
285                                  const unsigned short end);
286 
287    /**
288      * Get stream default timeout.
289      *
290      * @param streamID Stream ID to get timeout for.
291      * @param timeout Reference to store timeout.
292      * @return true, if timeout has been found; false otherwise.
293      */
294    bool getDefaultStreamTimeout(const unsigned short streamID, unsigned int& timeout);
295 
296    /**
297      * Get association parameters.
298      *
299      * @param assocStatus Reference to store association parameters.
300      * @return true, if successful; false otherwise.
301      */
302    bool getAssocStatus(SCTP_Association_Status& assocStatus);
303 
304    /**
305      * Set association parameters.
306      *
307      * @param assocStatus Association parameters.
308      * @return true, if successful; false otherwise.
309      */
310    bool setAssocStatus(const SCTP_Association_Status& assocStatus);
311 
312 
313    // ====== Path parameters ================================================
314    /**
315      * Get path parameters.
316      *
317      * @param address Address to get path parameters for.
318      * @param pathParameters Reference to store path parameters.
319      * @return true, if successful; false otherwise.
320      */
321    bool getPathParameters(const SocketAddress* address,
322                           SCTP_PathStatus&     pathParameters);
323 
324    /**
325      * Set path parameters.
326      *
327      * @param address Address to set path parameters for.
328      * @param pathParameters Path parameters.
329      * @return true, if successful; false otherwise.
330      */
331    bool setPathParameters(const SocketAddress*   address,
332                           const SCTP_PathStatus& pathParameters);
333 
334    /**
335      * Get primary address.
336      *
337      * @return Primary address. This address has to be deleted after usage.
338      */
339    SocketAddress* getPrimaryAddress();
340 
341    /**
342      * Set primary address of given association.
343      *
344      * @param primary Primary address.
345      * @return true for success; false otherwise.
346      */
347    bool setPrimary(const SocketAddress& primary);
348 
349    /**
350      * Set peer primary address of given association.
351      *
352      * @param primary Peer primary address.
353      * @return true for success; false otherwise.
354      */
355    bool setPeerPrimary(const SocketAddress& primary);
356 
357    /**
358      * Add address to given association.
359      *
360      * @param addAddress Address to be added.
361      * @return true for success; false otherwise.
362      */
363    bool addAddress(const SocketAddress& addAddress);
364 
365    /**
366      * Delete address from given association.
367      *
368      * @param delAddress Address to be deleted.
369      * @return true for success; false otherwise.
370      */
371    bool deleteAddress(const SocketAddress& delAddress);
372 
373 
374    // ====== Other parameters ===============================================
375    /**
376      * Get send buffer size.
377      *
378      * @param Send buffer size (-1 in case of error).
379      */
380    ssize_t getSendBuffer();
381 
382    /**
383      * Set send buffer size.
384      *
385      * @param size Send buffer size.
386      */
387    bool setSendBuffer(const size_t size);
388 
389    /**
390      * Get receive buffer size.
391      *
392      * @param Receive buffer size (-1 in case of error).
393      */
394    ssize_t getReceiveBuffer();
395 
396    /**
397      * Set receive buffer size.
398      *
399      * @param size Receive buffer size.
400      */
401    bool setReceiveBuffer(const size_t size);
402 
403    /**
404      * Get traffic class.
405      *
406      * @param streamID Stream ID (default: 0).
407      * @return Traffic class (-1 in case of error).
408      */
409    int getTrafficClass(const int streamID = 0);
410 
411    /**
412      * Set traffic class.
413      *
414      * @param trafficClass Traffic class.
415      * @param streamID Stream ID (-1 for all streams, default).
416      */
417    bool setTrafficClass(const card8 trafficClass,
418                         const int   streamID = -1);
419 
420    /**
421      * Get pointer to update condition.
422      *
423      * @param type Update condition type.
424      * @return Update condition.
425      */
426    inline Condition* getUpdateCondition(const UpdateConditionType type);
427 
428 
429    // ====== Protected data =================================================
430    protected:
431    SCTPAssociation(SCTPSocket*        socket,
432                    const unsigned int associationID,
433                    const unsigned int notificationFlags,
434                    const bool         udpLike);
435 
436 
437    // ====== Private data ===================================================
438    private:
439    bool sendPreEstablishmentPackets();
440 
441    SCTPSocket*           Socket;
442    SCTPNotificationQueue InQueue;
443    Condition             EstablishCondition;
444    Condition             ShutdownCompleteCondition;
445    Condition             ReadyForTransmit;
446    Condition             ReadUpdateCondition;
447    Condition             WriteUpdateCondition;
448    Condition             ExceptUpdateCondition;
449 
450    card64                LastUsage;
451    cardinal              UseCount;
452 
453    unsigned int          AssociationID;
454    unsigned int          NotificationFlags;
455    AssocIODefaults       Defaults;
456 
457    struct StreamDefaultTimeout {
458       bool         Valid;
459       unsigned int Timeout;
460    };
461    StreamDefaultTimeout*   StreamDefaultTimeoutArray;
462    unsigned int            StreamDefaultTimeoutCount;
463 
464    bool                    CommunicationUpNotification;
465    bool                    CommunicationLostNotification;
466    bool                    ShutdownCompleteNotification;
467    bool                    IsShuttingDown;
468 
469    bool                    ReadReady;
470    bool                    WriteReady;
471    bool                    HasException;
472 
473    bool                    RTOMaxIsInitTimeout;
474    unsigned int            InitTimeout;
475    unsigned int            RTOMax;
476 
477    struct PreEstablishmentPacket {
478       PreEstablishmentPacket* Next;
479       unsigned int            Flags;
480       uint32_t                ProtoID;
481       uint16_t                StreamID;
482       unsigned int            TimeToLive;
483       size_t                  Length;
484       char*                   Data;
485    };
486    PreEstablishmentPacket* FirstPreEstablishmentPacket;
487    PreEstablishmentPacket* LastPreEstablishmentPacket;
488    SocketAddress**         PreEstablishmentAddressList;
489 
490    bool                    PeeledOff;
491 };
492 
493 
494 #include "sctpassociation.icc"
495 
496 
497 #endif
498