1 /* $Id$ 2 * -------------------------------------------------------------------------- 3 * 4 * //===== //===== ===//=== //===// // // //===// 5 * // // // // // // // // // 6 * //====// // // //===// // // //===<< 7 * // // // // // // // // 8 * ======// //===== // // //===== // //===// 9 * 10 * -------------- An SCTP implementation according to RFC 4960 -------------- 11 * 12 * Copyright (C) 2000 by Siemens AG, Munich, Germany. 13 * Copyright (C) 2001-2004 Andreas Jungmaier 14 * Copyright (C) 2004-2019 Thomas Dreibholz 15 * 16 * Acknowledgements: 17 * Realized in co-operation between Siemens AG and the University of 18 * Duisburg-Essen, Institute for Experimental Mathematics, Computer 19 * Networking Technology group. 20 * This work was partially funded by the Bundesministerium fuer Bildung und 21 * Forschung (BMBF) of the Federal Republic of Germany 22 * (Förderkennzeichen 01AK045). 23 * The authors alone are responsible for the contents. 24 * 25 * This library is free software: you can redistribute it and/or modify it 26 * under the terms of the GNU Lesser General Public License as published by 27 * the Free Software Foundation, either version 2.1 of the License, or 28 * (at your option) any later version. 29 * 30 * This library is distributed in the hope that it will be useful, 31 * but WITHOUT ANY WARRANTY; without even the implied warranty of 32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 33 * GNU General Public License for more details. 34 * 35 * You should have received a copy of the GNU Lesser General Public License 36 * along with this program. If not, see <http://www.gnu.org/licenses/>. 37 * 38 * Contact: sctp-discussion@sctp.de 39 * dreibh@iem.uni-due.de 40 * tuexen@fh-muenster.de 41 * andreas.jungmaier@web.de 42 */ 43 44 #ifndef GLOBALS_H 45 #define GLOBALS_H 46 47 #ifdef HAVE_CONFIG_H 48 #include <config.h> 49 #endif 50 51 52 #include <stdio.h> 53 #include <glib.h> 54 #include <string.h> 55 #include <stdlib.h> 56 57 58 #ifdef STDC_HEADERS 59 #ifdef HAVE_SYS_TIME_H 60 #include <sys/time.h> 61 #ifdef TIME_WITH_SYS_TIME 62 #include <time.h> 63 #endif 64 #endif 65 #ifdef HAVE_UNISTD_H 66 #include <unistd.h> 67 #endif 68 #endif 69 70 #ifdef WIN32 71 #include <winsock2.h> 72 #include <time.h> 73 #endif 74 75 #ifdef FreeBSD 76 #include <netinet/in_systm.h> 77 #include <sys/types.h> 78 #endif 79 80 #ifdef SOLARIS 81 #include <netinet/in_systm.h> 82 #include <stdarg.h> 83 #endif 84 85 86 /* turn on Posix 1g for compatible cmsg structure */ 87 /* #ifdef USE_RFC2292BIS 88 #define _XPG4_2 89 #endif 90 */ 91 92 #ifndef WIN32 93 #include <sys/socket.h> 94 #include <netinet/in.h> 95 #endif 96 97 #include "messages.h" 98 99 /* timer granularity in millliseconds..... */ 100 #define GRANULARITY 1 101 102 /* Define a protocol id to be used in the IP Header..... */ 103 #ifndef IPPROTO_SCTP 104 #define IPPROTO_SCTP 132 105 #endif 106 107 /** this parameter specifies the maximum number of addresses that an endpoint may have */ 108 #define MAX_NUM_ADDRESSES 32 109 110 111 #define SECRET_KEYSIZE 4096 112 #define KEY_INIT 0 113 #ifndef KEY_READ 114 #define KEY_READ 1 115 #endif 116 #define MAX_DEST 16 117 118 119 /* Definition of levels for the logging of events */ 120 #define ByteString_log_ 0 /* set to != 0 if byte string logging should be done */ 121 122 #define VVERBOSE 6 /* very verbose logging of events */ 123 #define VERBOSE 5 /* more verbose logging of events */ 124 #define INTERNAL_EVENT_0 4 /* pure execution flow trace */ 125 #define INTERNAL_EVENT_1 3 /* important internal events */ 126 #define EXTERNAL_EVENT 2 /* for events from ULP, peer or Timers */ 127 #define EXTERNAL_EVENT_X 1 /* for unexpected external events from ULP, peer or Timers */ 128 129 130 #define Current_event_log_ 0 /* Defines the level up to which the events are printed. 131 VVERBOSE (6) means all events are printed. 132 This parameter could also come from a command line option */ 133 134 /* Definition of levels for the logging of errors */ 135 #define ERROR_WARNING 4 /* warning, recovery not necessary. */ 136 #define ERROR_MINOR 3 /* recovery from error was possible without affecting the system. */ 137 #define ERROR_MAJOR 2 /* recovery from error was possible with some affects to the system, 138 for instance abort of an association. */ 139 #define ERROR_FATAL 1 /* recovery from error was not possible, the program exits. */ 140 141 #define Current_error_log_ 1 /* Defines the level up to which the errors are printed. 142 ERROR_WARNING (4) means all events are printed. 143 This parameter could also come from a command line option */ 144 145 typedef unsigned char boolean; 146 typedef unsigned int TimerID; 147 148 #define TIMER_TYPE_INIT 0 149 #define TIMER_TYPE_SHUTDOWN 1 150 #define TIMER_TYPE_RTXM 3 151 #define TIMER_TYPE_SACK 2 152 #define TIMER_TYPE_CWND 4 153 #define TIMER_TYPE_HEARTBEAT 5 154 #define TIMER_TYPE_USER 6 155 156 typedef struct chunk_data_struct 157 { 158 unsigned int chunk_len; 159 unsigned int chunk_tsn; /* for efficiency */ 160 unsigned char data[MAX_SCTP_PDU]; 161 unsigned int gap_reports; 162 struct timeval transmission_time; 163 /* ack_time : in msecs after transmission time, initially 0, -1 if retransmitted */ 164 int ack_time; 165 unsigned int num_of_transmissions; 166 /* time after which chunk should not be retransmitted */ 167 struct timeval expiry_time; 168 gboolean dontBundle; 169 /* lst destination used to send chunk to */ 170 unsigned int last_destination; 171 int initial_destination; 172 /* this is set to true, whenever chunk is sent/received on unreliable stream */ 173 gboolean isUnreliable; 174 gboolean hasBeenAcked; 175 gboolean hasBeenDropped; 176 gboolean hasBeenFastRetransmitted; 177 gboolean hasBeenRequeued; 178 gpointer context; 179 } chunk_data; 180 181 #ifndef max 182 #define max(x,y) ((x)>(y))?(x):(y) 183 #endif 184 #ifndef min 185 #define min(x,y) ((x)<(y))?(x):(y) 186 #endif 187 188 #define event_log(x,y) if (Current_event_log_ >= x) event_log1((x), __FILE__, (y)) 189 #define event_logi(x,y,z) if (Current_event_log_ >= x) event_log1((x), __FILE__, (y), (z)) 190 #define event_logii(x,y,z,i) if (Current_event_log_ >= x) event_log1((x), __FILE__, (y), (z), (i)) 191 #define event_logiii(x,y,z,i,j) if (Current_event_log_ >= x) event_log1((x), __FILE__, (y), (z), (i), (j)) 192 #define event_logiiii(x,y,z,i,j,k) if (Current_event_log_ >= x) event_log1((x), __FILE__, (y), (z), (i), (j),(k)) 193 #define event_logiiiii(x,y,z,i,j,k,l) if (Current_event_log_ >= x) event_log1((x), __FILE__, (y), (z), (i), (j),(k),(l)) 194 #define event_logiiiiiiii(x,y,z,i,j,k,l,m,n,o) if (Current_event_log_ >= x) event_log1((x), __FILE__, (y), (z), (i), (j),(k),(l),(m),(n),(o)) 195 196 197 #define error_log(x,y) if (Current_error_log_ >= x) error_log1((x), __FILE__, __LINE__, (y)) 198 #define error_logi(x,y,z) if (Current_error_log_ >= x) error_log1((x), __FILE__, __LINE__, (y),(z)) 199 #define error_logii(x,y,z,i) if (Current_error_log_ >= x) error_log1((x), __FILE__, __LINE__, (y),(z),(i)) 200 #define error_logiii(x,y,z,i,j) if (Current_error_log_ >= x) error_log1((x), __FILE__, __LINE__, (y),(z),(i),(j)) 201 #define error_logiiii(x,y,z,i,j,k) if (Current_error_log_ >= x) error_log1((x), __FILE__, __LINE__, (y),(z),(i),(j),(k)) 202 #define error_log_sys(x,y) error_log_sys1((x), __FILE__, __LINE__, (y)) 203 #define DLL_error_log(x,y) if (Current_error_log_ >= x) error_log1((x), __FILE__, __LINE__, (y)) 204 205 #define IF_LOG(x, y) if (x <= Current_error_log_) {y} 206 /* read_tracelevels reads from a file the tracelevels for errors and events for each module. 207 Modules that are not listed in the file will not be traced. if the file does not exist or 208 is empty, the global tracelevel defined in globals.h will be used. 209 The format of the file is 210 module1.c errorTraceLevel eventTraceLevel 211 module2.c errorTraceLevel eventTraceLevel 212 .... 213 214 The file must be terminated by a null line. 215 */ 216 void read_tracelevels(void); 217 218 219 void debug_print(FILE * fd, const char *f, ...); 220 221 /** 222 * function to output the result of the adl_gettime-call, i.e. the time now 223 */ 224 void print_time(short level); 225 226 /** 227 * print the error string after a system call and exit 228 */ 229 void perr_exit(const char *infostring); 230 231 232 /* This function logs events. 233 Parameters: 234 @param event_log_level : INTERNAL_EVENT_0 INTERNAL_EVENT_1 EXTERNAL_EVENT_X EXTERNAL_EVENT 235 @param module_name : the name of the module that received the event. 236 @param log_info : the info that is printed with the modulename. 237 @param anyno : optional pointer to unsigned int, which is printed along with log_info. 238 The conversion specification must be contained in log_info. 239 @author H�zlwimmer 240 */ 241 void event_log1(short event_log_level, const char *module_name, const char *log_info, ...); 242 243 244 245 /* This function logs errors. 246 Parameters: 247 @param error_log_level : ERROR_MINOR ERROR_MAJOR ERROR_FATAL 248 @param module_name : the name of the module that received the event. 249 @param line_no : the line number within above module. 250 @param log_info : the info that is printed with the modulename. 251 @author H�zlwimmer 252 */ 253 void error_log1(short error_log_level, const char *module_name, int line_no, const char *log_info, ...); 254 255 256 /* This function logs system call errors. 257 This function calls error_log. 258 Parameters: 259 @param error_log_level : ERROR_MINOR ERROR_MAJOR ERROR_FATAL 260 @param module_name : the name of the module that received the event. 261 @param line_no : the line number within above module. 262 @param errnumber : the errno from systemlibrary. 263 @param log_info : the info that is printed with the modulename and error text. 264 @author H�zlwimmer 265 */ 266 void error_log_sys1(short error_log_level, const char *module_name, int line_no, short errnumber); 267 268 269 /** 270 * helper functions that correctly handle the 32bit wrapround 271 */ 272 int before(unsigned int seq1, unsigned int seq2); 273 int after(unsigned int seq1, unsigned int seq2); 274 int sAfter(unsigned short seq1, unsigned short seq2); 275 int sBefore(unsigned short seq1, unsigned short seq2); 276 277 /** 278 * is s1 <= s2 <= s3 ? 279 */ 280 int between(unsigned int seq1, unsigned int seq2, unsigned int seq3); 281 282 /** 283 * compute IP checksum yourself. If packet does not have even packet boundaries, 284 * last byte will be set 0 and length increased by one. (should never happen in 285 * this SCTP implementation, since we always have 32 bit boundaries ! 286 * Make sure the checksum is computed last thing before sending, and the checksum 287 * field is initialized to 0 before starting the computation 288 */ 289 unsigned short in_check(unsigned char *buf, int sz); 290 291 292 int sort_prChunk(pr_stream_data* one, pr_stream_data* two); 293 294 /* 295 * function that correctly sorts TSN values, minding the 296 * wrapround 297 */ 298 int sort_tsn(chunk_data * one, chunk_data * two); 299 300 void free_list_element(gpointer list_element, gpointer user_data); 301 302 303 /* shortcut macro to specify address field of struct sockaddr */ 304 #define sock2ip(X) (((struct sockaddr_in *)(X))->sin_addr.s_addr) 305 #ifdef HAVE_IPV6 306 #define sock2ip6(X) (((struct sockaddr_in6 *)(X))->sin6_addr.s6_addr) 307 #define sock2ip6addr(X) (((struct sockaddr_in6 *)(X))->sin6_addr) 308 #endif /* HAVE_IPV6 */ 309 310 /* union for handling either type of addresses: ipv4 and ipv6 */ 311 #ifndef SOCKUNION_DEFINE 312 #define SOCKUNION_DEFINE 1 313 union sockunion 314 { 315 struct sockaddr sa; 316 struct sockaddr_in sin; 317 #ifdef HAVE_IPV6 318 struct sockaddr_in6 sin6; 319 #endif /* HAVE_IPV6 */ 320 }; 321 322 #endif /* SOCKUNION_DEFINE */ 323 324 #define sockunion_family(X) (X)->sa.sa_family 325 326 #define SUPPORT_ADDRESS_TYPE_IPV4 0x00000001 327 328 #define SUPPORT_ADDRESS_TYPE_IPV6 0x00000002 329 #define SUPPORT_ADDRESS_TYPE_DNS 0x00000004 330 331 typedef enum { 332 flag_HideLoopback = (1 << 0), 333 flag_HideLinkLocal = (1 << 1), 334 flag_HideSiteLocal = (1 << 2), 335 flag_HideLocal = flag_HideLoopback|flag_HideLinkLocal|flag_HideSiteLocal, 336 flag_HideAnycast = (1 << 3), 337 flag_HideMulticast = (1 << 4), 338 flag_HideBroadcast = (1 << 5), 339 flag_HideReserved = (1 << 6), 340 flag_Default = flag_HideBroadcast|flag_HideMulticast|flag_HideAnycast, 341 flag_HideAllExceptLoopback = (1 << 7), 342 flag_HideAllExceptLinkLocal = (1 << 8), 343 flag_HideAllExceptSiteLocal = (1 << 9) 344 } AddressScopingFlags; 345 346 347 #define DEFAULT_MTU_CEILING 1500 348 349 350 #ifndef CHECK 351 #define CHECK(cond) if(!(cond)) { fprintf(stderr, "INTERNAL ERROR in %s, line %u: condition %s is not satisfied!\n", __FILE__, __LINE__, #cond); abort(); } 352 #endif 353 354 #endif 355