summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/bio/bss_dgram.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/bio/bss_dgram.c')
-rw-r--r--src/lib/libcrypto/bio/bss_dgram.c1114
1 files changed, 554 insertions, 560 deletions
diff --git a/src/lib/libcrypto/bio/bss_dgram.c b/src/lib/libcrypto/bio/bss_dgram.c
index 67a13ae845..330f6fc404 100644
--- a/src/lib/libcrypto/bio/bss_dgram.c
+++ b/src/lib/libcrypto/bio/bss_dgram.c
@@ -113,7 +113,8 @@ static long dgram_sctp_ctrl(BIO *h, int cmd, long arg1, void *arg2);
113static int dgram_sctp_new(BIO *h); 113static int dgram_sctp_new(BIO *h);
114static int dgram_sctp_free(BIO *data); 114static int dgram_sctp_free(BIO *data);
115#ifdef SCTP_AUTHENTICATION_EVENT 115#ifdef SCTP_AUTHENTICATION_EVENT
116static void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp); 116static void dgram_sctp_handle_auth_free_key_event(BIO *b,
117 union sctp_notification *snp);
117#endif 118#endif
118#endif 119#endif
119 120
@@ -121,8 +122,7 @@ static int BIO_dgram_should_retry(int s);
121 122
122static void get_current_time(struct timeval *t); 123static void get_current_time(struct timeval *t);
123 124
124static BIO_METHOD methods_dgramp= 125static BIO_METHOD methods_dgramp = {
125 {
126 BIO_TYPE_DGRAM, 126 BIO_TYPE_DGRAM,
127 "datagram socket", 127 "datagram socket",
128 dgram_write, 128 dgram_write,
@@ -133,11 +133,10 @@ static BIO_METHOD methods_dgramp=
133 dgram_new, 133 dgram_new,
134 dgram_free, 134 dgram_free,
135 NULL, 135 NULL,
136 }; 136};
137 137
138#ifndef OPENSSL_NO_SCTP 138#ifndef OPENSSL_NO_SCTP
139static BIO_METHOD methods_dgramp_sctp= 139static BIO_METHOD methods_dgramp_sctp = {
140 {
141 BIO_TYPE_DGRAM_SCTP, 140 BIO_TYPE_DGRAM_SCTP,
142 "datagram sctp socket", 141 "datagram sctp socket",
143 dgram_sctp_write, 142 dgram_sctp_write,
@@ -148,11 +147,10 @@ static BIO_METHOD methods_dgramp_sctp=
148 dgram_sctp_new, 147 dgram_sctp_new,
149 dgram_sctp_free, 148 dgram_sctp_free,
150 NULL, 149 NULL,
151 }; 150};
152#endif 151#endif
153 152
154typedef struct bio_dgram_data_st 153typedef struct bio_dgram_data_st {
155 {
156 union { 154 union {
157 struct sockaddr sa; 155 struct sockaddr sa;
158 struct sockaddr_in sa_in; 156 struct sockaddr_in sa_in;
@@ -165,18 +163,16 @@ typedef struct bio_dgram_data_st
165 unsigned int mtu; 163 unsigned int mtu;
166 struct timeval next_timeout; 164 struct timeval next_timeout;
167 struct timeval socket_timeout; 165 struct timeval socket_timeout;
168 } bio_dgram_data; 166} bio_dgram_data;
169 167
170#ifndef OPENSSL_NO_SCTP 168#ifndef OPENSSL_NO_SCTP
171typedef struct bio_dgram_sctp_save_message_st 169typedef struct bio_dgram_sctp_save_message_st {
172 { 170 BIO *bio;
173 BIO *bio; 171 char *data;
174 char *data; 172 int length;
175 int length; 173} bio_dgram_sctp_save_message;
176 } bio_dgram_sctp_save_message;
177 174
178typedef struct bio_dgram_sctp_data_st 175typedef struct bio_dgram_sctp_data_st {
179 {
180 union { 176 union {
181 struct sockaddr sa; 177 struct sockaddr sa;
182 struct sockaddr_in sa_in; 178 struct sockaddr_in sa_in;
@@ -198,79 +194,88 @@ typedef struct bio_dgram_sctp_data_st
198 int save_shutdown; 194 int save_shutdown;
199 int peer_auth_tested; 195 int peer_auth_tested;
200 bio_dgram_sctp_save_message saved_message; 196 bio_dgram_sctp_save_message saved_message;
201 } bio_dgram_sctp_data; 197} bio_dgram_sctp_data;
202#endif 198#endif
203 199
204BIO_METHOD *BIO_s_datagram(void) 200BIO_METHOD
205 { 201*BIO_s_datagram(void)
206 return(&methods_dgramp); 202{
207 } 203 return (&methods_dgramp);
204}
208 205
209BIO *BIO_new_dgram(int fd, int close_flag) 206BIO
210 { 207*BIO_new_dgram(int fd, int close_flag)
208{
211 BIO *ret; 209 BIO *ret;
212 210
213 ret=BIO_new(BIO_s_datagram()); 211 ret = BIO_new(BIO_s_datagram());
214 if (ret == NULL) return(NULL); 212 if (ret == NULL)
215 BIO_set_fd(ret,fd,close_flag); 213 return (NULL);
216 return(ret); 214 BIO_set_fd(ret, fd, close_flag);
217 } 215 return (ret);
216}
218 217
219static int dgram_new(BIO *bi) 218static int
220 { 219dgram_new(BIO *bi)
220{
221 bio_dgram_data *data = NULL; 221 bio_dgram_data *data = NULL;
222 222
223 bi->init=0; 223 bi->init = 0;
224 bi->num=0; 224 bi->num = 0;
225 data = OPENSSL_malloc(sizeof(bio_dgram_data)); 225 data = OPENSSL_malloc(sizeof(bio_dgram_data));
226 if (data == NULL) 226 if (data == NULL)
227 return 0; 227 return 0;
228 memset(data, 0x00, sizeof(bio_dgram_data)); 228 memset(data, 0x00, sizeof(bio_dgram_data));
229 bi->ptr = data; 229 bi->ptr = data;
230 230
231 bi->flags=0; 231 bi->flags = 0;
232 return(1); 232 return (1);
233 } 233}
234 234
235static int dgram_free(BIO *a) 235static int
236 { 236dgram_free(BIO *a)
237{
237 bio_dgram_data *data; 238 bio_dgram_data *data;
238 239
239 if (a == NULL) return(0); 240 if (a == NULL)
240 if ( ! dgram_clear(a)) 241 return (0);
242 if (!dgram_clear(a))
241 return 0; 243 return 0;
242 244
243 data = (bio_dgram_data *)a->ptr; 245 data = (bio_dgram_data *)a->ptr;
244 if(data != NULL) OPENSSL_free(data); 246 if (data != NULL)
247 OPENSSL_free(data);
245 248
246 return(1); 249 return (1);
247 } 250}
248 251
249static int dgram_clear(BIO *a) 252static int
250 { 253dgram_clear(BIO *a)
251 if (a == NULL) return(0); 254{
252 if (a->shutdown) 255 if (a == NULL)
253 { 256 return (0);
254 if (a->init) 257 if (a->shutdown) {
255 { 258 if (a->init) {
256 shutdown(a->num, SHUT_RDWR); 259 shutdown(a->num, SHUT_RDWR);
257 close(a->num); 260 close(a->num);
258 }
259 a->init=0;
260 a->flags=0;
261 } 261 }
262 return(1); 262 a->init = 0;
263 a->flags = 0;
263 } 264 }
265 return (1);
266}
264 267
265static void dgram_adjust_rcv_timeout(BIO *b) 268static void
266 { 269dgram_adjust_rcv_timeout(BIO *b)
270{
267#if defined(SO_RCVTIMEO) 271#if defined(SO_RCVTIMEO)
268 bio_dgram_data *data = (bio_dgram_data *)b->ptr; 272 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
269 union { size_t s; int i; } sz = {0}; 273 union { size_t s;
274 int i;
275 } sz = {0};
270 276
271 /* Is a timer active? */ 277 /* Is a timer active? */
272 if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) 278 if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
273 {
274 struct timeval timenow, timeleft; 279 struct timeval timenow, timeleft;
275 280
276 /* Read current socket timeout */ 281 /* Read current socket timeout */
@@ -279,20 +284,19 @@ static void dgram_adjust_rcv_timeout(BIO *b)
279 284
280 sz.i = sizeof(timeout); 285 sz.i = sizeof(timeout);
281 if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 286 if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
282 (void*)&timeout, &sz.i) < 0) 287 (void*)&timeout, &sz.i) < 0) {
283 { perror("getsockopt"); } 288 perror("getsockopt");
284 else 289 } else {
285 {
286 data->socket_timeout.tv_sec = timeout / 1000; 290 data->socket_timeout.tv_sec = timeout / 1000;
287 data->socket_timeout.tv_usec = (timeout % 1000) * 1000; 291 data->socket_timeout.tv_usec = (timeout % 1000) * 1000;
288 } 292 }
289#else 293#else
290 sz.i = sizeof(data->socket_timeout); 294 sz.i = sizeof(data->socket_timeout);
291 if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 295 if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
292 &(data->socket_timeout), (void *)&sz) < 0) 296 &(data->socket_timeout), (void *)&sz) < 0) {
293 { perror("getsockopt"); } 297 perror("getsockopt");
294 else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0) 298 } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0)
295 OPENSSL_assert(sz.s<=sizeof(data->socket_timeout)); 299 OPENSSL_assert(sz.s <= sizeof(data->socket_timeout));
296#endif 300#endif
297 301
298 /* Get current time */ 302 /* Get current time */
@@ -302,126 +306,128 @@ static void dgram_adjust_rcv_timeout(BIO *b)
302 memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval)); 306 memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval));
303 timeleft.tv_sec -= timenow.tv_sec; 307 timeleft.tv_sec -= timenow.tv_sec;
304 timeleft.tv_usec -= timenow.tv_usec; 308 timeleft.tv_usec -= timenow.tv_usec;
305 if (timeleft.tv_usec < 0) 309 if (timeleft.tv_usec < 0) {
306 {
307 timeleft.tv_sec--; 310 timeleft.tv_sec--;
308 timeleft.tv_usec += 1000000; 311 timeleft.tv_usec += 1000000;
309 } 312 }
310 313
311 if (timeleft.tv_sec < 0) 314 if (timeleft.tv_sec < 0) {
312 {
313 timeleft.tv_sec = 0; 315 timeleft.tv_sec = 0;
314 timeleft.tv_usec = 1; 316 timeleft.tv_usec = 1;
315 } 317 }
316 318
317 /* Adjust socket timeout if next handhake message timer 319 /* Adjust socket timeout if next handhake message timer
318 * will expire earlier. 320 * will expire earlier.
319 */ 321 */
320 if ((data->socket_timeout.tv_sec == 0 && data->socket_timeout.tv_usec == 0) || 322 if ((data->socket_timeout.tv_sec == 0 &&
321 (data->socket_timeout.tv_sec > timeleft.tv_sec) || 323 data->socket_timeout.tv_usec == 0) ||
322 (data->socket_timeout.tv_sec == timeleft.tv_sec && 324 (data->socket_timeout.tv_sec > timeleft.tv_sec) ||
323 data->socket_timeout.tv_usec >= timeleft.tv_usec)) 325 (data->socket_timeout.tv_sec == timeleft.tv_sec &&
324 { 326 data->socket_timeout.tv_usec >= timeleft.tv_usec)) {
325#ifdef OPENSSL_SYS_WINDOWS 327#ifdef OPENSSL_SYS_WINDOWS
326 timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000; 328 timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000;
327 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 329 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
328 (void*)&timeout, sizeof(timeout)) < 0) 330 (void*)&timeout, sizeof(timeout)) < 0) {
329 { perror("setsockopt"); } 331 perror("setsockopt");
332 }
330#else 333#else
331 if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft, 334 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
332 sizeof(struct timeval)) < 0) 335 &timeleft, sizeof(struct timeval)) < 0) {
333 { perror("setsockopt"); } 336 perror("setsockopt");
334#endif
335 } 337 }
336 }
337#endif 338#endif
339 }
338 } 340 }
341#endif
342}
339 343
340static void dgram_reset_rcv_timeout(BIO *b) 344static void
341 { 345dgram_reset_rcv_timeout(BIO *b)
346{
342#if defined(SO_RCVTIMEO) 347#if defined(SO_RCVTIMEO)
343 bio_dgram_data *data = (bio_dgram_data *)b->ptr; 348 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
344 349
345 /* Is a timer active? */ 350 /* Is a timer active? */
346 if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) 351 if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) {
347 {
348#ifdef OPENSSL_SYS_WINDOWS 352#ifdef OPENSSL_SYS_WINDOWS
349 int timeout = data->socket_timeout.tv_sec * 1000 + 353 int timeout = data->socket_timeout.tv_sec * 1000 +
350 data->socket_timeout.tv_usec / 1000; 354 data->socket_timeout.tv_usec / 1000;
351 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 355 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
352 (void*)&timeout, sizeof(timeout)) < 0) 356 (void*)&timeout, sizeof(timeout)) < 0) {
353 { perror("setsockopt"); } 357 perror("setsockopt");
358 }
354#else 359#else
355 if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout), 360 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
356 sizeof(struct timeval)) < 0) 361 &(data->socket_timeout), sizeof(struct timeval)) < 0) {
357 { perror("setsockopt"); } 362 perror("setsockopt");
358#endif
359 } 363 }
360#endif 364#endif
361 } 365 }
366#endif
367}
362 368
363static int dgram_read(BIO *b, char *out, int outl) 369static int
364 { 370dgram_read(BIO *b, char *out, int outl)
365 int ret=0; 371{
372 int ret = 0;
366 bio_dgram_data *data = (bio_dgram_data *)b->ptr; 373 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
367 374
368 struct { 375 struct {
369 /* 376 /*
370 * See commentary in b_sock.c. <appro> 377 * See commentary in b_sock.c. <appro>
371 */ 378 */
372 union { size_t s; int i; } len; 379 union {
373 union { 380 size_t s;
374 struct sockaddr sa; 381 int i;
375 struct sockaddr_in sa_in; 382 } len;
383 union {
384 struct sockaddr sa;
385 struct sockaddr_in sa_in;
376#if OPENSSL_USE_IPV6 386#if OPENSSL_USE_IPV6
377 struct sockaddr_in6 sa_in6; 387 struct sockaddr_in6 sa_in6;
378#endif 388#endif
379 } peer; 389 } peer;
380 } sa; 390 } sa;
381 391
382 sa.len.s=0; 392 sa.len.s = 0;
383 sa.len.i=sizeof(sa.peer); 393 sa.len.i = sizeof(sa.peer);
384 394
385 if (out != NULL) 395 if (out != NULL) {
386 {
387 errno = 0; 396 errno = 0;
388 memset(&sa.peer, 0x00, sizeof(sa.peer)); 397 memset(&sa.peer, 0x00, sizeof(sa.peer));
389 dgram_adjust_rcv_timeout(b); 398 dgram_adjust_rcv_timeout(b);
390 ret=recvfrom(b->num,out,outl,0,&sa.peer.sa,(void *)&sa.len); 399 ret = recvfrom(b->num, out, outl, 0, &sa.peer.sa,(void *)&sa.len);
391 if (sizeof(sa.len.i)!=sizeof(sa.len.s) && sa.len.i==0) 400 if (sizeof(sa.len.i) != sizeof(sa.len.s) && sa.len.i == 0) {
392 { 401 OPENSSL_assert(sa.len.s <= sizeof(sa.peer));
393 OPENSSL_assert(sa.len.s<=sizeof(sa.peer));
394 sa.len.i = (int)sa.len.s; 402 sa.len.i = (int)sa.len.s;
395 } 403 }
396 404
397 if ( ! data->connected && ret >= 0) 405 if (! data->connected && ret >= 0)
398 BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer); 406 BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer);
399 407
400 BIO_clear_retry_flags(b); 408 BIO_clear_retry_flags(b);
401 if (ret < 0) 409 if (ret < 0) {
402 { 410 if (BIO_dgram_should_retry(ret)) {
403 if (BIO_dgram_should_retry(ret))
404 {
405 BIO_set_retry_read(b); 411 BIO_set_retry_read(b);
406 data->_errno = errno; 412 data->_errno = errno;
407 }
408 } 413 }
414 }
409 415
410 dgram_reset_rcv_timeout(b); 416 dgram_reset_rcv_timeout(b);
411 }
412 return(ret);
413 } 417 }
418 return (ret);
419}
414 420
415static int dgram_write(BIO *b, const char *in, int inl) 421static int
416 { 422dgram_write(BIO *b, const char *in, int inl)
423{
417 int ret; 424 int ret;
418 bio_dgram_data *data = (bio_dgram_data *)b->ptr; 425 bio_dgram_data *data = (bio_dgram_data *)b->ptr;
419 errno = 0; 426 errno = 0;
420 427
421 if ( data->connected ) 428 if (data->connected)
422 ret=write(b->num,in,inl); 429 ret = write(b->num, in, inl);
423 else 430 else {
424 {
425 int peerlen = sizeof(data->peer); 431 int peerlen = sizeof(data->peer);
426 432
427 if (data->peer.sa.sa_family == AF_INET) 433 if (data->peer.sa.sa_family == AF_INET)
@@ -431,33 +437,33 @@ static int dgram_write(BIO *b, const char *in, int inl)
431 peerlen = sizeof(data->peer.sa_in6); 437 peerlen = sizeof(data->peer.sa_in6);
432#endif 438#endif
433#if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK) 439#if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK)
434 ret=sendto(b->num, (char *)in, inl, 0, &data->peer.sa, peerlen); 440 ret = sendto(b->num, (char *)in, inl, 0, &data->peer.sa, peerlen);
435#else 441#else
436 ret=sendto(b->num, in, inl, 0, &data->peer.sa, peerlen); 442 ret = sendto(b->num, in, inl, 0, &data->peer.sa, peerlen);
437#endif 443#endif
438 } 444 }
439 445
440 BIO_clear_retry_flags(b); 446 BIO_clear_retry_flags(b);
441 if (ret <= 0) 447 if (ret <= 0) {
442 { 448 if (BIO_dgram_should_retry(ret)) {
443 if (BIO_dgram_should_retry(ret)) 449 BIO_set_retry_write(b);
444 { 450
445 BIO_set_retry_write(b);
446 data->_errno = errno; 451 data->_errno = errno;
447 452
448#if 0 /* higher layers are responsible for querying MTU, if necessary */ 453#if 0 /* higher layers are responsible for querying MTU, if necessary */
449 if ( data->_errno == EMSGSIZE) 454 if (data->_errno == EMSGSIZE)
450 /* retrieve the new MTU */ 455 /* retrieve the new MTU */
451 BIO_ctrl(b, BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); 456 BIO_ctrl(b, BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
452#endif 457#endif
453 }
454 } 458 }
455 return(ret);
456 } 459 }
460 return (ret);
461}
457 462
458static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) 463static long
459 { 464dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
460 long ret=1; 465{
466 long ret = 1;
461 int *ip; 467 int *ip;
462 struct sockaddr *to = NULL; 468 struct sockaddr *to = NULL;
463 bio_dgram_data *data = NULL; 469 bio_dgram_data *data = NULL;
@@ -472,76 +478,73 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
472#if OPENSSL_USE_IPV6 478#if OPENSSL_USE_IPV6
473 struct sockaddr_in6 s6; 479 struct sockaddr_in6 s6;
474#endif 480#endif
475 } addr; 481 } addr;
476#endif 482#endif
477 483
478 data = (bio_dgram_data *)b->ptr; 484 data = (bio_dgram_data *)b->ptr;
479 485
480 switch (cmd) 486 switch (cmd) {
481 {
482 case BIO_CTRL_RESET: 487 case BIO_CTRL_RESET:
483 num=0; 488 num = 0;
484 case BIO_C_FILE_SEEK: 489 case BIO_C_FILE_SEEK:
485 ret=0; 490 ret = 0;
486 break; 491 break;
487 case BIO_C_FILE_TELL: 492 case BIO_C_FILE_TELL:
488 case BIO_CTRL_INFO: 493 case BIO_CTRL_INFO:
489 ret=0; 494 ret = 0;
490 break; 495 break;
491 case BIO_C_SET_FD: 496 case BIO_C_SET_FD:
492 dgram_clear(b); 497 dgram_clear(b);
493 b->num= *((int *)ptr); 498 b->num= *((int *)ptr);
494 b->shutdown=(int)num; 499 b->shutdown = (int)num;
495 b->init=1; 500 b->init = 1;
496 break; 501 break;
497 case BIO_C_GET_FD: 502 case BIO_C_GET_FD:
498 if (b->init) 503 if (b->init) {
499 { 504 ip = (int *)ptr;
500 ip=(int *)ptr; 505 if (ip != NULL)
501 if (ip != NULL) *ip=b->num; 506 *ip = b->num;
502 ret=b->num; 507 ret = b->num;
503 } 508 } else
504 else 509 ret = -1;
505 ret= -1;
506 break; 510 break;
507 case BIO_CTRL_GET_CLOSE: 511 case BIO_CTRL_GET_CLOSE:
508 ret=b->shutdown; 512 ret = b->shutdown;
509 break; 513 break;
510 case BIO_CTRL_SET_CLOSE: 514 case BIO_CTRL_SET_CLOSE:
511 b->shutdown=(int)num; 515 b->shutdown = (int)num;
512 break; 516 break;
513 case BIO_CTRL_PENDING: 517 case BIO_CTRL_PENDING:
514 case BIO_CTRL_WPENDING: 518 case BIO_CTRL_WPENDING:
515 ret=0; 519 ret = 0;
516 break; 520 break;
517 case BIO_CTRL_DUP: 521 case BIO_CTRL_DUP:
518 case BIO_CTRL_FLUSH: 522 case BIO_CTRL_FLUSH:
519 ret=1; 523 ret = 1;
520 break; 524 break;
521 case BIO_CTRL_DGRAM_CONNECT: 525 case BIO_CTRL_DGRAM_CONNECT:
522 to = (struct sockaddr *)ptr; 526 to = (struct sockaddr *)ptr;
523#if 0 527#if 0
524 if (connect(b->num, to, sizeof(struct sockaddr)) < 0) 528 if (connect(b->num, to, sizeof(struct sockaddr)) < 0) {
525 { perror("connect"); ret = 0; } 529 perror("connect");
526 else 530 ret = 0;
527 { 531 } else {
528#endif 532#endif
529 switch (to->sa_family) 533 switch (to->sa_family) {
530 { 534 case AF_INET:
531 case AF_INET: 535 memcpy(&data->peer, to, sizeof(data->peer.sa_in));
532 memcpy(&data->peer,to,sizeof(data->peer.sa_in)); 536 break;
533 break;
534#if OPENSSL_USE_IPV6 537#if OPENSSL_USE_IPV6
535 case AF_INET6: 538 case AF_INET6:
536 memcpy(&data->peer,to,sizeof(data->peer.sa_in6)); 539 memcpy(&data->peer, to, sizeof(data->peer.sa_in6));
537 break; 540 break;
538#endif 541#endif
539 default: 542 default:
540 memcpy(&data->peer,to,sizeof(data->peer.sa)); 543 memcpy(&data->peer, to, sizeof(data->peer.sa));
541 break; 544 break;
542 }
543#if 0
544 } 545 }
546#if 0
547 }
545#endif 548#endif
546 break; 549 break;
547 /* (Linux)kernel sets DF bit on outgoing IP packets */ 550 /* (Linux)kernel sets DF bit on outgoing IP packets */
@@ -549,31 +552,31 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
549#if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO) 552#if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO)
550 addr_len = (socklen_t)sizeof(addr); 553 addr_len = (socklen_t)sizeof(addr);
551 memset((void *)&addr, 0, sizeof(addr)); 554 memset((void *)&addr, 0, sizeof(addr));
552 if (getsockname(b->num, &addr.sa, &addr_len) < 0) 555 if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
553 {
554 ret = 0; 556 ret = 0;
555 break; 557 break;
556 } 558 }
557 switch (addr.sa.sa_family) 559 switch (addr.sa.sa_family) {
558 {
559 case AF_INET: 560 case AF_INET:
560 sockopt_val = IP_PMTUDISC_DO; 561 sockopt_val = IP_PMTUDISC_DO;
561 if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER, 562 if ((ret = setsockopt(b->num, IPPROTO_IP,
562 &sockopt_val, sizeof(sockopt_val))) < 0) 563 IP_MTU_DISCOVER, &sockopt_val,
564 sizeof(sockopt_val))) < 0)
563 perror("setsockopt"); 565 perror("setsockopt");
564 break; 566 break;
565#if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) 567#if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO)
566 case AF_INET6: 568 case AF_INET6:
567 sockopt_val = IPV6_PMTUDISC_DO; 569 sockopt_val = IPV6_PMTUDISC_DO;
568 if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER, 570 if ((ret = setsockopt(b->num, IPPROTO_IPV6,
569 &sockopt_val, sizeof(sockopt_val))) < 0) 571 IPV6_MTU_DISCOVER, &sockopt_val,
572 sizeof(sockopt_val))) < 0)
570 perror("setsockopt"); 573 perror("setsockopt");
571 break; 574 break;
572#endif 575#endif
573 default: 576 default:
574 ret = -1; 577 ret = -1;
575 break; 578 break;
576 } 579 }
577 ret = -1; 580 ret = -1;
578#else 581#else
579 break; 582 break;
@@ -582,74 +585,67 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
582#if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU) 585#if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU)
583 addr_len = (socklen_t)sizeof(addr); 586 addr_len = (socklen_t)sizeof(addr);
584 memset((void *)&addr, 0, sizeof(addr)); 587 memset((void *)&addr, 0, sizeof(addr));
585 if (getsockname(b->num, &addr.sa, &addr_len) < 0) 588 if (getsockname(b->num, &addr.sa, &addr_len) < 0) {
586 {
587 ret = 0; 589 ret = 0;
588 break; 590 break;
589 } 591 }
590 sockopt_len = sizeof(sockopt_val); 592 sockopt_len = sizeof(sockopt_val);
591 switch (addr.sa.sa_family) 593 switch (addr.sa.sa_family) {
592 {
593 case AF_INET: 594 case AF_INET:
594 if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val, 595 if ((ret = getsockopt(b->num, IPPROTO_IP, IP_MTU,
595 &sockopt_len)) < 0 || sockopt_val < 0) 596 (void *)&sockopt_val, &sockopt_len)) < 0 ||
596 { 597 sockopt_val < 0) {
597 ret = 0; 598 ret = 0;
598 } 599 } else {
599 else
600 {
601 /* we assume that the transport protocol is UDP and no 600 /* we assume that the transport protocol is UDP and no
602 * IP options are used. 601 * IP options are used.
603 */ 602 */
604 data->mtu = sockopt_val - 8 - 20; 603 data->mtu = sockopt_val - 8 - 20;
605 ret = data->mtu; 604 ret = data->mtu;
606 } 605 }
607 break; 606 break;
608#if OPENSSL_USE_IPV6 && defined(IPV6_MTU) 607#if OPENSSL_USE_IPV6 && defined(IPV6_MTU)
609 case AF_INET6: 608 case AF_INET6:
610 if ((ret = getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU, (void *)&sockopt_val, 609 if ((ret = getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU,
611 &sockopt_len)) < 0 || sockopt_val < 0) 610 (void *)&sockopt_val, &sockopt_len)) < 0 ||
612 { 611 sockopt_val < 0) {
613 ret = 0; 612 ret = 0;
614 } 613 } else {
615 else
616 {
617 /* we assume that the transport protocol is UDP and no 614 /* we assume that the transport protocol is UDP and no
618 * IPV6 options are used. 615 * IPV6 options are used.
619 */ 616 */
620 data->mtu = sockopt_val - 8 - 40; 617 data->mtu = sockopt_val - 8 - 40;
621 ret = data->mtu; 618 ret = data->mtu;
622 } 619 }
623 break; 620 break;
624#endif 621#endif
625 default: 622default:
626 ret = 0; 623 ret = 0;
627 break; 624 break;
628 } 625 }
629#else 626#else
630 ret = 0; 627 ret = 0;
631#endif 628#endif
632 break; 629 break;
633 case BIO_CTRL_DGRAM_GET_FALLBACK_MTU: 630 case BIO_CTRL_DGRAM_GET_FALLBACK_MTU:
634 switch (data->peer.sa.sa_family) 631 switch (data->peer.sa.sa_family) {
635 { 632 case AF_INET:
636 case AF_INET: 633 ret = 576 - 20 - 8;
637 ret = 576 - 20 - 8; 634 break;
638 break;
639#if OPENSSL_USE_IPV6 635#if OPENSSL_USE_IPV6
640 case AF_INET6: 636 case AF_INET6:
641#ifdef IN6_IS_ADDR_V4MAPPED 637#ifdef IN6_IS_ADDR_V4MAPPED
642 if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr)) 638 if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr))
643 ret = 576 - 20 - 8; 639 ret = 576 - 20 - 8;
644 else 640 else
645#endif 641#endif
646 ret = 1280 - 40 - 8; 642 ret = 1280 - 40 - 8;
647 break; 643 break;
648#endif 644#endif
649 default: 645 default:
650 ret = 576 - 20 - 8; 646 ret = 576 - 20 - 8;
651 break; 647 break;
652 } 648 }
653 break; 649 break;
654 case BIO_CTRL_DGRAM_GET_MTU: 650 case BIO_CTRL_DGRAM_GET_MTU:
655 return data->mtu; 651 return data->mtu;
@@ -661,65 +657,59 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
661 case BIO_CTRL_DGRAM_SET_CONNECTED: 657 case BIO_CTRL_DGRAM_SET_CONNECTED:
662 to = (struct sockaddr *)ptr; 658 to = (struct sockaddr *)ptr;
663 659
664 if ( to != NULL) 660 if (to != NULL) {
665 {
666 data->connected = 1; 661 data->connected = 1;
667 switch (to->sa_family) 662 switch (to->sa_family) {
668 {
669 case AF_INET:
670 memcpy(&data->peer,to,sizeof(data->peer.sa_in));
671 break;
672#if OPENSSL_USE_IPV6
673 case AF_INET6:
674 memcpy(&data->peer,to,sizeof(data->peer.sa_in6));
675 break;
676#endif
677 default:
678 memcpy(&data->peer,to,sizeof(data->peer.sa));
679 break;
680 }
681 }
682 else
683 {
684 data->connected = 0;
685 memset(&(data->peer), 0x00, sizeof(data->peer));
686 }
687 break;
688 case BIO_CTRL_DGRAM_GET_PEER:
689 switch (data->peer.sa.sa_family)
690 {
691 case AF_INET: 663 case AF_INET:
692 ret=sizeof(data->peer.sa_in); 664 memcpy(&data->peer, to, sizeof(data->peer.sa_in));
693 break; 665 break;
694#if OPENSSL_USE_IPV6 666#if OPENSSL_USE_IPV6
695 case AF_INET6: 667 case AF_INET6:
696 ret=sizeof(data->peer.sa_in6); 668 memcpy(&data->peer, to, sizeof(data->peer.sa_in6));
697 break; 669 break;
698#endif 670#endif
699 default: 671 default:
700 ret=sizeof(data->peer.sa); 672 memcpy(&data->peer, to, sizeof(data->peer.sa));
701 break; 673 break;
702 } 674 }
703 if (num==0 || num>ret) 675 } else {
704 num=ret; 676 data->connected = 0;
705 memcpy(ptr,&data->peer,(ret=num)); 677 memset(&(data->peer), 0x00, sizeof(data->peer));
678 }
679 break;
680 case BIO_CTRL_DGRAM_GET_PEER:
681 switch (data->peer.sa.sa_family) {
682 case AF_INET:
683 ret = sizeof(data->peer.sa_in);
684 break;
685#if OPENSSL_USE_IPV6
686 case AF_INET6:
687 ret = sizeof(data->peer.sa_in6);
688 break;
689#endif
690 default:
691 ret = sizeof(data->peer.sa);
692 break;
693 }
694 if (num == 0 || num > ret)
695 num = ret;
696 memcpy(ptr, &data->peer, (ret = num));
706 break; 697 break;
707 case BIO_CTRL_DGRAM_SET_PEER: 698 case BIO_CTRL_DGRAM_SET_PEER:
708 to = (struct sockaddr *) ptr; 699 to = (struct sockaddr *) ptr;
709 switch (to->sa_family) 700 switch (to->sa_family) {
710 { 701 case AF_INET:
711 case AF_INET: 702 memcpy(&data->peer, to, sizeof(data->peer.sa_in));
712 memcpy(&data->peer,to,sizeof(data->peer.sa_in)); 703 break;
713 break;
714#if OPENSSL_USE_IPV6 704#if OPENSSL_USE_IPV6
715 case AF_INET6: 705 case AF_INET6:
716 memcpy(&data->peer,to,sizeof(data->peer.sa_in6)); 706 memcpy(&data->peer, to, sizeof(data->peer.sa_in6));
717 break; 707 break;
718#endif 708#endif
719 default: 709 default:
720 memcpy(&data->peer,to,sizeof(data->peer.sa)); 710 memcpy(&data->peer, to, sizeof(data->peer.sa));
721 break; 711 break;
722 } 712 }
723 break; 713 break;
724 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: 714 case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT:
725 memcpy(&(data->next_timeout), ptr, sizeof(struct timeval)); 715 memcpy(&(data->next_timeout), ptr, sizeof(struct timeval));
@@ -728,47 +718,53 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
728 case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: 718 case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
729#ifdef OPENSSL_SYS_WINDOWS 719#ifdef OPENSSL_SYS_WINDOWS
730 { 720 {
731 struct timeval *tv = (struct timeval *)ptr; 721 struct timeval *tv = (struct timeval *)ptr;
732 int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000; 722 int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000;
733 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 723 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
734 (void*)&timeout, sizeof(timeout)) < 0) 724 (void*)&timeout, sizeof(timeout)) < 0) {
735 { perror("setsockopt"); ret = -1; } 725 perror("setsockopt");
726 ret = -1;
727 }
736 } 728 }
737#else 729#else
738 if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr, 730 if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr,
739 sizeof(struct timeval)) < 0) 731 sizeof(struct timeval)) < 0) {
740 { perror("setsockopt"); ret = -1; } 732 perror("setsockopt");
733 ret = -1;
734 }
741#endif 735#endif
742 break; 736 break;
743 case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT: 737 case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
744 { 738 {
745 union { size_t s; int i; } sz = {0}; 739 union {
740 size_t s;
741 int i;
742 } sz = {0};
746#ifdef OPENSSL_SYS_WINDOWS 743#ifdef OPENSSL_SYS_WINDOWS
747 int timeout; 744 int timeout;
748 struct timeval *tv = (struct timeval *)ptr; 745 struct timeval *tv = (struct timeval *)ptr;
749 746
750 sz.i = sizeof(timeout); 747 sz.i = sizeof(timeout);
751 if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 748 if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
752 (void*)&timeout, &sz.i) < 0) 749 (void*)&timeout, &sz.i) < 0) {
753 { perror("getsockopt"); ret = -1; } 750 perror("getsockopt");
754 else 751 ret = -1;
755 { 752 } else {
756 tv->tv_sec = timeout / 1000; 753 tv->tv_sec = timeout / 1000;
757 tv->tv_usec = (timeout % 1000) * 1000; 754 tv->tv_usec = (timeout % 1000) * 1000;
758 ret = sizeof(*tv); 755 ret = sizeof(*tv);
759 } 756 }
760#else 757#else
761 sz.i = sizeof(struct timeval); 758 sz.i = sizeof(struct timeval);
762 if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, 759 if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO,
763 ptr, (void *)&sz) < 0) 760 ptr, (void *)&sz) < 0) {
764 { perror("getsockopt"); ret = -1; } 761 perror("getsockopt");
765 else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0) 762 ret = -1;
766 { 763 } else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0) {
767 OPENSSL_assert(sz.s<=sizeof(struct timeval)); 764 OPENSSL_assert(sz.s <= sizeof(struct timeval));
768 ret = (int)sz.s; 765 ret = (int)sz.s;
769 } 766 } else
770 else 767 ret = sz.i;
771 ret = sz.i;
772#endif 768#endif
773 } 769 }
774 break; 770 break;
@@ -777,47 +773,53 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
777 case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT: 773 case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT:
778#ifdef OPENSSL_SYS_WINDOWS 774#ifdef OPENSSL_SYS_WINDOWS
779 { 775 {
780 struct timeval *tv = (struct timeval *)ptr; 776 struct timeval *tv = (struct timeval *)ptr;
781 int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000; 777 int timeout = tv->tv_sec * 1000 + tv->tv_usec/1000;
782 if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, 778 if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
783 (void*)&timeout, sizeof(timeout)) < 0) 779 (void*)&timeout, sizeof(timeout)) < 0) {
784 { perror("setsockopt"); ret = -1; } 780 perror("setsockopt");
781 ret = -1;
782 }
785 } 783 }
786#else 784#else
787 if ( setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr, 785 if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr,
788 sizeof(struct timeval)) < 0) 786 sizeof(struct timeval)) < 0) {
789 { perror("setsockopt"); ret = -1; } 787 perror("setsockopt");
788 ret = -1;
789 }
790#endif 790#endif
791 break; 791 break;
792 case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT: 792 case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT:
793 { 793 {
794 union { size_t s; int i; } sz = {0}; 794 union {
795 size_t s;
796 int i;
797 } sz = {0};
795#ifdef OPENSSL_SYS_WINDOWS 798#ifdef OPENSSL_SYS_WINDOWS
796 int timeout; 799 int timeout;
797 struct timeval *tv = (struct timeval *)ptr; 800 struct timeval *tv = (struct timeval *)ptr;
798 801
799 sz.i = sizeof(timeout); 802 sz.i = sizeof(timeout);
800 if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, 803 if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
801 (void*)&timeout, &sz.i) < 0) 804 (void*)&timeout, &sz.i) < 0) {
802 { perror("getsockopt"); ret = -1; } 805 perror("getsockopt");
803 else 806 ret = -1;
804 { 807 } else {
805 tv->tv_sec = timeout / 1000; 808 tv->tv_sec = timeout / 1000;
806 tv->tv_usec = (timeout % 1000) * 1000; 809 tv->tv_usec = (timeout % 1000) * 1000;
807 ret = sizeof(*tv); 810 ret = sizeof(*tv);
808 } 811 }
809#else 812#else
810 sz.i = sizeof(struct timeval); 813 sz.i = sizeof(struct timeval);
811 if ( getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, 814 if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO,
812 ptr, (void *)&sz) < 0) 815 ptr, (void *)&sz) < 0) {
813 { perror("getsockopt"); ret = -1; } 816 perror("getsockopt");
814 else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0) 817 ret = -1;
815 { 818 } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) {
816 OPENSSL_assert(sz.s<=sizeof(struct timeval)); 819 OPENSSL_assert(sz.s <= sizeof(struct timeval));
817 ret = (int)sz.s; 820 ret = (int)sz.s;
818 } 821 } else
819 else 822 ret = sz.i;
820 ret = sz.i;
821#endif 823#endif
822 } 824 }
823 break; 825 break;
@@ -826,52 +828,52 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
826 /* fall-through */ 828 /* fall-through */
827 case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP: 829 case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP:
828#ifdef OPENSSL_SYS_WINDOWS 830#ifdef OPENSSL_SYS_WINDOWS
829 if ( data->_errno == WSAETIMEDOUT) 831 if (data->_errno == WSAETIMEDOUT)
830#else 832#else
831 if ( data->_errno == EAGAIN) 833 if (data->_errno == EAGAIN)
832#endif 834#endif
833 { 835 {
834 ret = 1; 836 ret = 1;
835 data->_errno = 0; 837 data->_errno = 0;
836 } 838 } else
837 else
838 ret = 0; 839 ret = 0;
839 break; 840 break;
840#ifdef EMSGSIZE 841#ifdef EMSGSIZE
841 case BIO_CTRL_DGRAM_MTU_EXCEEDED: 842 case BIO_CTRL_DGRAM_MTU_EXCEEDED:
842 if ( data->_errno == EMSGSIZE) 843 if (data->_errno == EMSGSIZE) {
843 {
844 ret = 1; 844 ret = 1;
845 data->_errno = 0; 845 data->_errno = 0;
846 } 846 } else
847 else
848 ret = 0; 847 ret = 0;
849 break; 848 break;
850#endif 849#endif
851 default: 850 default:
852 ret=0; 851 ret = 0;
853 break; 852 break;
854 }
855 return(ret);
856 } 853 }
854 return (ret);
855}
857 856
858static int dgram_puts(BIO *bp, const char *str) 857static int
859 { 858dgram_puts(BIO *bp, const char *str)
860 int n,ret; 859{
860 int n, ret;
861 861
862 n=strlen(str); 862 n = strlen(str);
863 ret=dgram_write(bp,str,n); 863 ret = dgram_write(bp, str, n);
864 return(ret); 864 return (ret);
865 } 865}
866 866
867#ifndef OPENSSL_NO_SCTP 867#ifndef OPENSSL_NO_SCTP
868BIO_METHOD *BIO_s_datagram_sctp(void) 868BIO_METHOD
869 { 869*BIO_s_datagram_sctp(void)
870 return(&methods_dgramp_sctp); 870{
871 } 871 return (&methods_dgramp_sctp);
872}
872 873
873BIO *BIO_new_dgram_sctp(int fd, int close_flag) 874BIO
874 { 875*BIO_new_dgram_sctp(int fd, int close_flag)
876{
875 BIO *bio; 877 BIO *bio;
876 int ret, optval = 20000; 878 int ret, optval = 20000;
877 int auth_data = 0, auth_forward = 0; 879 int auth_data = 0, auth_forward = 0;
@@ -887,9 +889,10 @@ BIO *BIO_new_dgram_sctp(int fd, int close_flag)
887#endif 889#endif
888#endif 890#endif
889 891
890 bio=BIO_new(BIO_s_datagram_sctp()); 892 bio = BIO_new(BIO_s_datagram_sctp());
891 if (bio == NULL) return(NULL); 893 if (bio == NULL)
892 BIO_set_fd(bio,fd,close_flag); 894 return (NULL);
895 BIO_set_fd(bio, fd, close_flag);
893 896
894 /* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */ 897 /* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */
895 auth.sauth_chunk = OPENSSL_SCTP_DATA_CHUNK_TYPE; 898 auth.sauth_chunk = OPENSSL_SCTP_DATA_CHUNK_TYPE;
@@ -909,13 +912,14 @@ BIO *BIO_new_dgram_sctp(int fd, int close_flag)
909 OPENSSL_assert(ret >= 0); 912 OPENSSL_assert(ret >= 0);
910 913
911 for (p = (unsigned char*) authchunks->gauth_chunks; 914 for (p = (unsigned char*) authchunks->gauth_chunks;
912 p < (unsigned char*) authchunks + sockopt_len; 915 p < (unsigned char*) authchunks + sockopt_len;
913 p += sizeof(uint8_t)) 916 p += sizeof(uint8_t)) {
914 { 917 if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE)
915 if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) auth_data = 1; 918 auth_data = 1;
916 if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) auth_forward = 1; 919 if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE)
917 } 920 auth_forward = 1;
918 921 }
922
919 OPENSSL_free(authchunks); 923 OPENSSL_free(authchunks);
920 924
921 OPENSSL_assert(auth_data); 925 OPENSSL_assert(auth_data);
@@ -947,20 +951,22 @@ BIO *BIO_new_dgram_sctp(int fd, int close_flag)
947 ret = setsockopt(fd, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, &optval, sizeof(optval)); 951 ret = setsockopt(fd, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, &optval, sizeof(optval));
948 OPENSSL_assert(ret >= 0); 952 OPENSSL_assert(ret >= 0);
949 953
950 return(bio); 954 return (bio);
951 } 955}
952 956
953int BIO_dgram_is_sctp(BIO *bio) 957int
954 { 958BIO_dgram_is_sctp(BIO *bio)
959{
955 return (BIO_method_type(bio) == BIO_TYPE_DGRAM_SCTP); 960 return (BIO_method_type(bio) == BIO_TYPE_DGRAM_SCTP);
956 } 961}
957 962
958static int dgram_sctp_new(BIO *bi) 963static int
959 { 964dgram_sctp_new(BIO *bi)
965{
960 bio_dgram_sctp_data *data = NULL; 966 bio_dgram_sctp_data *data = NULL;
961 967
962 bi->init=0; 968 bi->init = 0;
963 bi->num=0; 969 bi->num = 0;
964 data = OPENSSL_malloc(sizeof(bio_dgram_sctp_data)); 970 data = OPENSSL_malloc(sizeof(bio_dgram_sctp_data));
965 if (data == NULL) 971 if (data == NULL)
966 return 0; 972 return 0;
@@ -968,46 +974,50 @@ static int dgram_sctp_new(BIO *bi)
968#ifdef SCTP_PR_SCTP_NONE 974#ifdef SCTP_PR_SCTP_NONE
969 data->prinfo.pr_policy = SCTP_PR_SCTP_NONE; 975 data->prinfo.pr_policy = SCTP_PR_SCTP_NONE;
970#endif 976#endif
971 bi->ptr = data; 977 bi->ptr = data;
972 978
973 bi->flags=0; 979 bi->flags = 0;
974 return(1); 980 return (1);
975 } 981}
976 982
977static int dgram_sctp_free(BIO *a) 983static int
978 { 984dgram_sctp_free(BIO *a)
985{
979 bio_dgram_sctp_data *data; 986 bio_dgram_sctp_data *data;
980 987
981 if (a == NULL) return(0); 988 if (a == NULL)
982 if ( ! dgram_clear(a)) 989 return (0);
990 if (! dgram_clear(a))
983 return 0; 991 return 0;
984 992
985 data = (bio_dgram_sctp_data *)a->ptr; 993 data = (bio_dgram_sctp_data *)a->ptr;
986 if(data != NULL) OPENSSL_free(data); 994 if (data != NULL)
995 OPENSSL_free(data);
987 996
988 return(1); 997 return (1);
989 } 998}
990 999
991#ifdef SCTP_AUTHENTICATION_EVENT 1000#ifdef SCTP_AUTHENTICATION_EVENT
992void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp) 1001void
993 { 1002dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp)
1003{
994 int ret; 1004 int ret;
995 struct sctp_authkey_event* authkeyevent = &snp->sn_auth_event; 1005 struct sctp_authkey_event* authkeyevent = &snp->sn_auth_event;
996 1006
997 if (authkeyevent->auth_indication == SCTP_AUTH_FREE_KEY) 1007 if (authkeyevent->auth_indication == SCTP_AUTH_FREE_KEY) {
998 {
999 struct sctp_authkeyid authkeyid; 1008 struct sctp_authkeyid authkeyid;
1000 1009
1001 /* delete key */ 1010 /* delete key */
1002 authkeyid.scact_keynumber = authkeyevent->auth_keynumber; 1011 authkeyid.scact_keynumber = authkeyevent->auth_keynumber;
1003 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY, 1012 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
1004 &authkeyid, sizeof(struct sctp_authkeyid)); 1013 &authkeyid, sizeof(struct sctp_authkeyid));
1005 }
1006 } 1014 }
1015}
1007#endif 1016#endif
1008 1017
1009static int dgram_sctp_read(BIO *b, char *out, int outl) 1018static int
1010 { 1019dgram_sctp_read(BIO *b, char *out, int outl)
1020{
1011 int ret = 0, n = 0, i, optval; 1021 int ret = 0, n = 0, i, optval;
1012 socklen_t optlen; 1022 socklen_t optlen;
1013 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr; 1023 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
@@ -1017,12 +1027,10 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
1017 struct cmsghdr *cmsg; 1027 struct cmsghdr *cmsg;
1018 char cmsgbuf[512]; 1028 char cmsgbuf[512];
1019 1029
1020 if (out != NULL) 1030 if (out != NULL) {
1021 {
1022 errno = 0; 1031 errno = 0;
1023 1032
1024 do 1033 do {
1025 {
1026 memset(&data->rcvinfo, 0x00, sizeof(struct bio_dgram_sctp_rcvinfo)); 1034 memset(&data->rcvinfo, 0x00, sizeof(struct bio_dgram_sctp_rcvinfo));
1027 iov.iov_base = out; 1035 iov.iov_base = out;
1028 iov.iov_len = outl; 1036 iov.iov_len = outl;
@@ -1035,15 +1043,12 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
1035 msg.msg_flags = 0; 1043 msg.msg_flags = 0;
1036 n = recvmsg(b->num, &msg, 0); 1044 n = recvmsg(b->num, &msg, 0);
1037 1045
1038 if (msg.msg_controllen > 0) 1046 if (msg.msg_controllen > 0) {
1039 { 1047 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
1040 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
1041 {
1042 if (cmsg->cmsg_level != IPPROTO_SCTP) 1048 if (cmsg->cmsg_level != IPPROTO_SCTP)
1043 continue; 1049 continue;
1044#ifdef SCTP_RCVINFO 1050#ifdef SCTP_RCVINFO
1045 if (cmsg->cmsg_type == SCTP_RCVINFO) 1051 if (cmsg->cmsg_type == SCTP_RCVINFO) {
1046 {
1047 struct sctp_rcvinfo *rcvinfo; 1052 struct sctp_rcvinfo *rcvinfo;
1048 1053
1049 rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg); 1054 rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg);
@@ -1054,11 +1059,10 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
1054 data->rcvinfo.rcv_tsn = rcvinfo->rcv_tsn; 1059 data->rcvinfo.rcv_tsn = rcvinfo->rcv_tsn;
1055 data->rcvinfo.rcv_cumtsn = rcvinfo->rcv_cumtsn; 1060 data->rcvinfo.rcv_cumtsn = rcvinfo->rcv_cumtsn;
1056 data->rcvinfo.rcv_context = rcvinfo->rcv_context; 1061 data->rcvinfo.rcv_context = rcvinfo->rcv_context;
1057 } 1062 }
1058#endif 1063#endif
1059#ifdef SCTP_SNDRCV 1064#ifdef SCTP_SNDRCV
1060 if (cmsg->cmsg_type == SCTP_SNDRCV) 1065 if (cmsg->cmsg_type == SCTP_SNDRCV) {
1061 {
1062 struct sctp_sndrcvinfo *sndrcvinfo; 1066 struct sctp_sndrcvinfo *sndrcvinfo;
1063 1067
1064 sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); 1068 sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
@@ -1069,23 +1073,20 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
1069 data->rcvinfo.rcv_tsn = sndrcvinfo->sinfo_tsn; 1073 data->rcvinfo.rcv_tsn = sndrcvinfo->sinfo_tsn;
1070 data->rcvinfo.rcv_cumtsn = sndrcvinfo->sinfo_cumtsn; 1074 data->rcvinfo.rcv_cumtsn = sndrcvinfo->sinfo_cumtsn;
1071 data->rcvinfo.rcv_context = sndrcvinfo->sinfo_context; 1075 data->rcvinfo.rcv_context = sndrcvinfo->sinfo_context;
1072 }
1073#endif
1074 } 1076 }
1077#endif
1075 } 1078 }
1079 }
1076 1080
1077 if (n <= 0) 1081 if (n <= 0) {
1078 {
1079 if (n < 0) 1082 if (n < 0)
1080 ret = n; 1083 ret = n;
1081 break; 1084 break;
1082 } 1085 }
1083 1086
1084 if (msg.msg_flags & MSG_NOTIFICATION) 1087 if (msg.msg_flags & MSG_NOTIFICATION) {
1085 {
1086 snp = (union sctp_notification*) out; 1088 snp = (union sctp_notification*) out;
1087 if (snp->sn_header.sn_type == SCTP_SENDER_DRY_EVENT) 1089 if (snp->sn_header.sn_type == SCTP_SENDER_DRY_EVENT) {
1088 {
1089#ifdef SCTP_EVENT 1090#ifdef SCTP_EVENT
1090 struct sctp_event event; 1091 struct sctp_event event;
1091#else 1092#else
@@ -1095,13 +1096,12 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
1095 /* If a message has been delayed until the socket 1096 /* If a message has been delayed until the socket
1096 * is dry, it can be sent now. 1097 * is dry, it can be sent now.
1097 */ 1098 */
1098 if (data->saved_message.length > 0) 1099 if (data->saved_message.length > 0) {
1099 {
1100 dgram_sctp_write(data->saved_message.bio, data->saved_message.data, 1100 dgram_sctp_write(data->saved_message.bio, data->saved_message.data,
1101 data->saved_message.length); 1101 data->saved_message.length);
1102 OPENSSL_free(data->saved_message.data); 1102 OPENSSL_free(data->saved_message.data);
1103 data->saved_message.length = 0; 1103 data->saved_message.length = 0;
1104 } 1104 }
1105 1105
1106 /* disable sender dry event */ 1106 /* disable sender dry event */
1107#ifdef SCTP_EVENT 1107#ifdef SCTP_EVENT
@@ -1121,7 +1121,7 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
1121 i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe)); 1121 i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
1122 OPENSSL_assert(i >= 0); 1122 OPENSSL_assert(i >= 0);
1123#endif 1123#endif
1124 } 1124 }
1125 1125
1126#ifdef SCTP_AUTHENTICATION_EVENT 1126#ifdef SCTP_AUTHENTICATION_EVENT
1127 if (snp->sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) 1127 if (snp->sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
@@ -1132,14 +1132,12 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
1132 data->handle_notifications(b, data->notification_context, (void*) out); 1132 data->handle_notifications(b, data->notification_context, (void*) out);
1133 1133
1134 memset(out, 0, outl); 1134 memset(out, 0, outl);
1135 } 1135 } else
1136 else
1137 ret += n; 1136 ret += n;
1138 } 1137 }
1139 while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR) && (ret < outl)); 1138 while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR) && (ret < outl));
1140 1139
1141 if (ret > 0 && !(msg.msg_flags & MSG_EOR)) 1140 if (ret > 0 && !(msg.msg_flags & MSG_EOR)) {
1142 {
1143 /* Partial message read, this should never happen! */ 1141 /* Partial message read, this should never happen! */
1144 1142
1145 /* The buffer was too small, this means the peer sent 1143 /* The buffer was too small, this means the peer sent
@@ -1159,8 +1157,8 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
1159 * max record size (2^14 + 2048 + 13) 1157 * max record size (2^14 + 2048 + 13)
1160 */ 1158 */
1161 optlen = (socklen_t) sizeof(int); 1159 optlen = (socklen_t) sizeof(int);
1162 ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, 1160 ret = getsockopt(b->num, IPPROTO_SCTP,
1163 &optval, &optlen); 1161 SCTP_PARTIAL_DELIVERY_POINT, &optval, &optlen);
1164 OPENSSL_assert(ret >= 0); 1162 OPENSSL_assert(ret >= 0);
1165 OPENSSL_assert(optval >= 18445); 1163 OPENSSL_assert(optval >= 18445);
1166 1164
@@ -1173,21 +1171,18 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
1173 memset(out, 0, outl); 1171 memset(out, 0, outl);
1174 BIO_set_retry_read(b); 1172 BIO_set_retry_read(b);
1175 return -1; 1173 return -1;
1176 } 1174 }
1177 1175
1178 BIO_clear_retry_flags(b); 1176 BIO_clear_retry_flags(b);
1179 if (ret < 0) 1177 if (ret < 0) {
1180 { 1178 if (BIO_dgram_should_retry(ret)) {
1181 if (BIO_dgram_should_retry(ret))
1182 {
1183 BIO_set_retry_read(b); 1179 BIO_set_retry_read(b);
1184 data->_errno = errno; 1180 data->_errno = errno;
1185 }
1186 } 1181 }
1182 }
1187 1183
1188 /* Test if peer uses SCTP-AUTH before continuing */ 1184 /* Test if peer uses SCTP-AUTH before continuing */
1189 if (!data->peer_auth_tested) 1185 if (!data->peer_auth_tested) {
1190 {
1191 int ii, auth_data = 0, auth_forward = 0; 1186 int ii, auth_data = 0, auth_forward = 0;
1192 unsigned char *p; 1187 unsigned char *p;
1193 struct sctp_authchunks *authchunks; 1188 struct sctp_authchunks *authchunks;
@@ -1199,29 +1194,30 @@ static int dgram_sctp_read(BIO *b, char *out, int outl)
1199 OPENSSL_assert(ii >= 0); 1194 OPENSSL_assert(ii >= 0);
1200 1195
1201 for (p = (unsigned char*) authchunks->gauth_chunks; 1196 for (p = (unsigned char*) authchunks->gauth_chunks;
1202 p < (unsigned char*) authchunks + optlen; 1197 p < (unsigned char*) authchunks + optlen;
1203 p += sizeof(uint8_t)) 1198 p += sizeof(uint8_t)) {
1204 { 1199 if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE)
1205 if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) auth_data = 1; 1200 auth_data = 1;
1206 if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) auth_forward = 1; 1201 if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE)
1207 } 1202 auth_forward = 1;
1203 }
1208 1204
1209 OPENSSL_free(authchunks); 1205 OPENSSL_free(authchunks);
1210 1206
1211 if (!auth_data || !auth_forward) 1207 if (!auth_data || !auth_forward) {
1212 { 1208 BIOerr(BIO_F_DGRAM_SCTP_READ, BIO_R_CONNECT_ERROR);
1213 BIOerr(BIO_F_DGRAM_SCTP_READ,BIO_R_CONNECT_ERROR);
1214 return -1; 1209 return -1;
1215 } 1210 }
1216 1211
1217 data->peer_auth_tested = 1; 1212 data->peer_auth_tested = 1;
1218 }
1219 } 1213 }
1220 return(ret);
1221 } 1214 }
1215 return (ret);
1216}
1222 1217
1223static int dgram_sctp_write(BIO *b, const char *in, int inl) 1218static int
1224 { 1219dgram_sctp_write(BIO *b, const char *in, int inl)
1220{
1225 int ret; 1221 int ret;
1226 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr; 1222 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *)b->ptr;
1227 struct bio_dgram_sctp_sndinfo *sinfo = &(data->sndinfo); 1223 struct bio_dgram_sctp_sndinfo *sinfo = &(data->sndinfo);
@@ -1256,8 +1252,7 @@ static int dgram_sctp_write(BIO *b, const char *in, int inl)
1256 * socket is not dry yet, we have to save it and send it 1252 * socket is not dry yet, we have to save it and send it
1257 * as soon as the socket gets dry. 1253 * as soon as the socket gets dry.
1258 */ 1254 */
1259 if (data->save_shutdown && !BIO_dgram_sctp_wait_for_dry(b)) 1255 if (data->save_shutdown && !BIO_dgram_sctp_wait_for_dry(b)) {
1260 {
1261 data->saved_message.bio = b; 1256 data->saved_message.bio = b;
1262 data->saved_message.length = inl; 1257 data->saved_message.length = inl;
1263 data->saved_message.data = OPENSSL_malloc(inl); 1258 data->saved_message.data = OPENSSL_malloc(inl);
@@ -1317,20 +1312,20 @@ static int dgram_sctp_write(BIO *b, const char *in, int inl)
1317 ret = sendmsg(b->num, &msg, 0); 1312 ret = sendmsg(b->num, &msg, 0);
1318 1313
1319 BIO_clear_retry_flags(b); 1314 BIO_clear_retry_flags(b);
1320 if (ret <= 0) 1315 if (ret <= 0) {
1321 { 1316 if (BIO_dgram_should_retry(ret)) {
1322 if (BIO_dgram_should_retry(ret)) 1317 BIO_set_retry_write(b);
1323 { 1318
1324 BIO_set_retry_write(b);
1325 data->_errno = errno; 1319 data->_errno = errno;
1326 }
1327 } 1320 }
1328 return(ret);
1329 } 1321 }
1322 return (ret);
1323}
1330 1324
1331static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr) 1325static long
1332 { 1326dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
1333 long ret=1; 1327{
1328 long ret = 1;
1334 bio_dgram_sctp_data *data = NULL; 1329 bio_dgram_sctp_data *data = NULL;
1335 socklen_t sockopt_len = 0; 1330 socklen_t sockopt_len = 0;
1336 struct sctp_authkeyid authkeyid; 1331 struct sctp_authkeyid authkeyid;
@@ -1338,8 +1333,7 @@ static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
1338 1333
1339 data = (bio_dgram_sctp_data *)b->ptr; 1334 data = (bio_dgram_sctp_data *)b->ptr;
1340 1335
1341 switch (cmd) 1336 switch (cmd) {
1342 {
1343 case BIO_CTRL_DGRAM_QUERY_MTU: 1337 case BIO_CTRL_DGRAM_QUERY_MTU:
1344 /* Set to maximum (2^14) 1338 /* Set to maximum (2^14)
1345 * and ignore user input to enable transport 1339 * and ignore user input to enable transport
@@ -1384,7 +1378,8 @@ static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
1384 /* Get active key */ 1378 /* Get active key */
1385 sockopt_len = sizeof(struct sctp_authkeyid); 1379 sockopt_len = sizeof(struct sctp_authkeyid);
1386 ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len); 1380 ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len);
1387 if (ret < 0) break; 1381 if (ret < 0)
1382 break;
1388 1383
1389 /* Add new key */ 1384 /* Add new key */
1390 sockopt_len = sizeof(struct sctp_authkey) + 64 * sizeof(uint8_t); 1385 sockopt_len = sizeof(struct sctp_authkey) + 64 * sizeof(uint8_t);
@@ -1400,12 +1395,14 @@ static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
1400 memcpy(&authkey->sca_key[0], ptr, 64 * sizeof(uint8_t)); 1395 memcpy(&authkey->sca_key[0], ptr, 64 * sizeof(uint8_t));
1401 1396
1402 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_KEY, authkey, sockopt_len); 1397 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_KEY, authkey, sockopt_len);
1403 if (ret < 0) break; 1398 if (ret < 0)
1399 break;
1404 1400
1405 /* Reset active key */ 1401 /* Reset active key */
1406 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, 1402 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
1407 &authkeyid, sizeof(struct sctp_authkeyid)); 1403 &authkeyid, sizeof(struct sctp_authkeyid));
1408 if (ret < 0) break; 1404 if (ret < 0)
1405 break;
1409 1406
1410 break; 1407 break;
1411 case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY: 1408 case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY:
@@ -1414,13 +1411,15 @@ static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
1414 /* Get active key */ 1411 /* Get active key */
1415 sockopt_len = sizeof(struct sctp_authkeyid); 1412 sockopt_len = sizeof(struct sctp_authkeyid);
1416 ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len); 1413 ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len);
1417 if (ret < 0) break; 1414 if (ret < 0)
1415 break;
1418 1416
1419 /* Set active key */ 1417 /* Set active key */
1420 authkeyid.scact_keynumber = authkeyid.scact_keynumber + 1; 1418 authkeyid.scact_keynumber = authkeyid.scact_keynumber + 1;
1421 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, 1419 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY,
1422 &authkeyid, sizeof(struct sctp_authkeyid)); 1420 &authkeyid, sizeof(struct sctp_authkeyid));
1423 if (ret < 0) break; 1421 if (ret < 0)
1422 break;
1424 1423
1425 /* CCS has been sent, so remember that and fall through 1424 /* CCS has been sent, so remember that and fall through
1426 * to check if we need to deactivate an old key 1425 * to check if we need to deactivate an old key
@@ -1435,12 +1434,12 @@ static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
1435 data->ccs_rcvd = 1; 1434 data->ccs_rcvd = 1;
1436 1435
1437 /* CSS has been both, received and sent, so deactivate an old key */ 1436 /* CSS has been both, received and sent, so deactivate an old key */
1438 if (data->ccs_rcvd == 1 && data->ccs_sent == 1) 1437 if (data->ccs_rcvd == 1 && data->ccs_sent == 1) {
1439 {
1440 /* Get active key */ 1438 /* Get active key */
1441 sockopt_len = sizeof(struct sctp_authkeyid); 1439 sockopt_len = sizeof(struct sctp_authkeyid);
1442 ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len); 1440 ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, &sockopt_len);
1443 if (ret < 0) break; 1441 if (ret < 0)
1442 break;
1444 1443
1445 /* Deactivate key or delete second last key if 1444 /* Deactivate key or delete second last key if
1446 * SCTP_AUTHENTICATION_EVENT is not available. 1445 * SCTP_AUTHENTICATION_EVENT is not available.
@@ -1449,22 +1448,23 @@ static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
1449#ifdef SCTP_AUTH_DEACTIVATE_KEY 1448#ifdef SCTP_AUTH_DEACTIVATE_KEY
1450 sockopt_len = sizeof(struct sctp_authkeyid); 1449 sockopt_len = sizeof(struct sctp_authkeyid);
1451 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DEACTIVATE_KEY, 1450 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DEACTIVATE_KEY,
1452 &authkeyid, sockopt_len); 1451 &authkeyid, sockopt_len);
1453 if (ret < 0) break; 1452 if (ret < 0)
1453 break;
1454#endif 1454#endif
1455#ifndef SCTP_AUTHENTICATION_EVENT 1455#ifndef SCTP_AUTHENTICATION_EVENT
1456 if (authkeyid.scact_keynumber > 0) 1456 if (authkeyid.scact_keynumber > 0) {
1457 {
1458 authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1; 1457 authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1;
1459 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY, 1458 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY,
1460 &authkeyid, sizeof(struct sctp_authkeyid)); 1459 &authkeyid, sizeof(struct sctp_authkeyid));
1461 if (ret < 0) break; 1460 if (ret < 0)
1462 } 1461 break;
1462 }
1463#endif 1463#endif
1464 1464
1465 data->ccs_rcvd = 0; 1465 data->ccs_rcvd = 0;
1466 data->ccs_sent = 0; 1466 data->ccs_sent = 0;
1467 } 1467 }
1468 break; 1468 break;
1469 case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO: 1469 case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO:
1470 /* Returns the size of the copied struct. */ 1470 /* Returns the size of the copied struct. */
@@ -1524,30 +1524,30 @@ static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr)
1524 /* Pass to default ctrl function to 1524 /* Pass to default ctrl function to
1525 * process SCTP unspecific commands 1525 * process SCTP unspecific commands
1526 */ 1526 */
1527 ret=dgram_ctrl(b, cmd, num, ptr); 1527 ret = dgram_ctrl(b, cmd, num, ptr);
1528 break; 1528 break;
1529 }
1530 return(ret);
1531 } 1529 }
1530 return (ret);
1531}
1532 1532
1533int BIO_dgram_sctp_notification_cb(BIO *b, 1533int
1534 void (*handle_notifications)(BIO *bio, void *context, void *buf), 1534BIO_dgram_sctp_notification_cb(BIO *b,
1535 void *context) 1535 void (*handle_notifications)(BIO *bio, void *context, void *buf),
1536 { 1536 void *context)
1537{
1537 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr; 1538 bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
1538 1539
1539 if (handle_notifications != NULL) 1540 if (handle_notifications != NULL) {
1540 {
1541 data->handle_notifications = handle_notifications; 1541 data->handle_notifications = handle_notifications;
1542 data->notification_context = context; 1542 data->notification_context = context;
1543 } 1543 } else
1544 else
1545 return -1; 1544 return -1;
1546 1545
1547 return 0; 1546 return 0;
1548 } 1547}
1549 1548
1550int BIO_dgram_sctp_wait_for_dry(BIO *b) 1549int
1550BIO_dgram_sctp_wait_for_dry(BIO *b)
1551{ 1551{
1552 int is_dry = 0; 1552 int is_dry = 0;
1553 int n, sockflags, ret; 1553 int n, sockflags, ret;
@@ -1574,9 +1574,9 @@ int BIO_dgram_sctp_wait_for_dry(BIO *b)
1574 ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize); 1574 ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
1575 if (ret < 0) 1575 if (ret < 0)
1576 return -1; 1576 return -1;
1577 1577
1578 event.sctp_sender_dry_event = 1; 1578 event.sctp_sender_dry_event = 1;
1579 1579
1580 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe)); 1580 ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, sizeof(struct sctp_event_subscribe));
1581#endif 1581#endif
1582 if (ret < 0) 1582 if (ret < 0)
@@ -1595,17 +1595,15 @@ int BIO_dgram_sctp_wait_for_dry(BIO *b)
1595 msg.msg_flags = 0; 1595 msg.msg_flags = 0;
1596 1596
1597 n = recvmsg(b->num, &msg, MSG_PEEK); 1597 n = recvmsg(b->num, &msg, MSG_PEEK);
1598 if (n <= 0) 1598 if (n <= 0) {
1599 {
1600 if ((n < 0) && (errno != EAGAIN) && (errno != EWOULDBLOCK)) 1599 if ((n < 0) && (errno != EAGAIN) && (errno != EWOULDBLOCK))
1601 return -1; 1600 return -1;
1602 else 1601 else
1603 return 0; 1602 return 0;
1604 } 1603 }
1605 1604
1606 /* if we find a notification, process it and try again if necessary */ 1605 /* if we find a notification, process it and try again if necessary */
1607 while (msg.msg_flags & MSG_NOTIFICATION) 1606 while (msg.msg_flags & MSG_NOTIFICATION) {
1608 {
1609 memset(&snp, 0x00, sizeof(union sctp_notification)); 1607 memset(&snp, 0x00, sizeof(union sctp_notification));
1610 iov.iov_base = (char *)&snp; 1608 iov.iov_base = (char *)&snp;
1611 iov.iov_len = sizeof(union sctp_notification); 1609 iov.iov_len = sizeof(union sctp_notification);
@@ -1618,16 +1616,14 @@ int BIO_dgram_sctp_wait_for_dry(BIO *b)
1618 msg.msg_flags = 0; 1616 msg.msg_flags = 0;
1619 1617
1620 n = recvmsg(b->num, &msg, 0); 1618 n = recvmsg(b->num, &msg, 0);
1621 if (n <= 0) 1619 if (n <= 0) {
1622 {
1623 if ((n < 0) && (errno != EAGAIN) && (errno != EWOULDBLOCK)) 1620 if ((n < 0) && (errno != EAGAIN) && (errno != EWOULDBLOCK))
1624 return -1; 1621 return -1;
1625 else 1622 else
1626 return is_dry; 1623 return is_dry;
1627 } 1624 }
1628 1625
1629 if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) 1626 if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) {
1630 {
1631 is_dry = 1; 1627 is_dry = 1;
1632 1628
1633 /* disable sender dry event */ 1629 /* disable sender dry event */
@@ -1649,7 +1645,7 @@ int BIO_dgram_sctp_wait_for_dry(BIO *b)
1649#endif 1645#endif
1650 if (ret < 0) 1646 if (ret < 0)
1651 return -1; 1647 return -1;
1652 } 1648 }
1653 1649
1654#ifdef SCTP_AUTHENTICATION_EVENT 1650#ifdef SCTP_AUTHENTICATION_EVENT
1655 if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) 1651 if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
@@ -1672,34 +1668,32 @@ int BIO_dgram_sctp_wait_for_dry(BIO *b)
1672 msg.msg_flags = 0; 1668 msg.msg_flags = 0;
1673 1669
1674 /* if we have seen the dry already, don't wait */ 1670 /* if we have seen the dry already, don't wait */
1675 if (is_dry) 1671 if (is_dry) {
1676 {
1677 sockflags = fcntl(b->num, F_GETFL, 0); 1672 sockflags = fcntl(b->num, F_GETFL, 0);
1678 fcntl(b->num, F_SETFL, O_NONBLOCK); 1673 fcntl(b->num, F_SETFL, O_NONBLOCK);
1679 } 1674 }
1680 1675
1681 n = recvmsg(b->num, &msg, MSG_PEEK); 1676 n = recvmsg(b->num, &msg, MSG_PEEK);
1682 1677
1683 if (is_dry) 1678 if (is_dry) {
1684 {
1685 fcntl(b->num, F_SETFL, sockflags); 1679 fcntl(b->num, F_SETFL, sockflags);
1686 } 1680 }
1687 1681
1688 if (n <= 0) 1682 if (n <= 0) {
1689 {
1690 if ((n < 0) && (errno != EAGAIN) && (errno != EWOULDBLOCK)) 1683 if ((n < 0) && (errno != EAGAIN) && (errno != EWOULDBLOCK))
1691 return -1; 1684 return -1;
1692 else 1685 else
1693 return is_dry; 1686 return is_dry;
1694 }
1695 } 1687 }
1688 }
1696 1689
1697 /* read anything else */ 1690 /* read anything else */
1698 return is_dry; 1691 return is_dry;
1699} 1692}
1700 1693
1701int BIO_dgram_sctp_msg_waiting(BIO *b) 1694int
1702 { 1695BIO_dgram_sctp_msg_waiting(BIO *b)
1696{
1703 int n, sockflags; 1697 int n, sockflags;
1704 union sctp_notification snp; 1698 union sctp_notification snp;
1705 struct msghdr msg; 1699 struct msghdr msg;
@@ -1708,7 +1702,7 @@ int BIO_dgram_sctp_msg_waiting(BIO *b)
1708 1702
1709 /* Check if there are any messages waiting to be read */ 1703 /* Check if there are any messages waiting to be read */
1710 do 1704 do
1711 { 1705 {
1712 memset(&snp, 0x00, sizeof(union sctp_notification)); 1706 memset(&snp, 0x00, sizeof(union sctp_notification));
1713 iov.iov_base = (char *)&snp; 1707 iov.iov_base = (char *)&snp;
1714 iov.iov_len = sizeof(union sctp_notification); 1708 iov.iov_len = sizeof(union sctp_notification);
@@ -1726,8 +1720,7 @@ int BIO_dgram_sctp_msg_waiting(BIO *b)
1726 fcntl(b->num, F_SETFL, sockflags); 1720 fcntl(b->num, F_SETFL, sockflags);
1727 1721
1728 /* if notification, process and try again */ 1722 /* if notification, process and try again */
1729 if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)) 1723 if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)) {
1730 {
1731#ifdef SCTP_AUTHENTICATION_EVENT 1724#ifdef SCTP_AUTHENTICATION_EVENT
1732 if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) 1725 if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
1733 dgram_sctp_handle_auth_free_key_event(b, &snp); 1726 dgram_sctp_handle_auth_free_key_event(b, &snp);
@@ -1747,34 +1740,35 @@ int BIO_dgram_sctp_msg_waiting(BIO *b)
1747 1740
1748 if (data->handle_notifications != NULL) 1741 if (data->handle_notifications != NULL)
1749 data->handle_notifications(b, data->notification_context, (void*) &snp); 1742 data->handle_notifications(b, data->notification_context, (void*) &snp);
1750 } 1743 }
1751 1744
1752 } while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)); 1745 } while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION));
1753 1746
1754 /* Return 1 if there is a message to be read, return 0 otherwise. */ 1747 /* Return 1 if there is a message to be read, return 0 otherwise. */
1755 if (n > 0) 1748 if (n > 0)
1756 return 1; 1749 return 1;
1757 else 1750 else
1758 return 0; 1751 return 0;
1759 } 1752}
1760 1753
1761static int dgram_sctp_puts(BIO *bp, const char *str) 1754static int
1762 { 1755dgram_sctp_puts(BIO *bp, const char *str)
1763 int n,ret; 1756{
1757 int n, ret;
1764 1758
1765 n=strlen(str); 1759 n = strlen(str);
1766 ret=dgram_sctp_write(bp,str,n); 1760 ret = dgram_sctp_write(bp, str, n);
1767 return(ret); 1761 return (ret);
1768 } 1762}
1769#endif 1763#endif
1770 1764
1771static int BIO_dgram_should_retry(int i) 1765static int
1772 { 1766BIO_dgram_should_retry(int i)
1767{
1773 int err; 1768 int err;
1774 1769
1775 if ((i == 0) || (i == -1)) 1770 if ((i == 0) || (i == -1)) {
1776 { 1771 err = errno;
1777 err=errno;
1778 1772
1779#if defined(OPENSSL_SYS_WINDOWS) 1773#if defined(OPENSSL_SYS_WINDOWS)
1780 /* If the socket return value (i) is -1 1774 /* If the socket return value (i) is -1
@@ -1785,15 +1779,15 @@ static int BIO_dgram_should_retry(int i)
1785 */ 1779 */
1786#endif 1780#endif
1787 1781
1788 return(BIO_dgram_non_fatal_error(err)); 1782 return (BIO_dgram_non_fatal_error(err));
1789 }
1790 return(0);
1791 } 1783 }
1784 return (0);
1785}
1792 1786
1793int BIO_dgram_non_fatal_error(int err) 1787int
1794 { 1788BIO_dgram_non_fatal_error(int err)
1795 switch (err) 1789{
1796 { 1790 switch (err) {
1797#if defined(OPENSSL_SYS_WINDOWS) 1791#if defined(OPENSSL_SYS_WINDOWS)
1798# if defined(WSAEWOULDBLOCK) 1792# if defined(WSAEWOULDBLOCK)
1799 case WSAEWOULDBLOCK: 1793 case WSAEWOULDBLOCK:
@@ -1838,17 +1832,17 @@ int BIO_dgram_non_fatal_error(int err)
1838 case EALREADY: 1832 case EALREADY:
1839#endif 1833#endif
1840 1834
1841 return(1); 1835 return (1);
1842 /* break; */ 1836 /* break; */
1843 default: 1837 default:
1844 break; 1838 break;
1845 }
1846 return(0);
1847 } 1839 }
1840 return (0);
1841}
1848 1842
1849static void get_current_time(struct timeval *t) 1843static void
1850 { 1844get_current_time(struct timeval *t) {
1851 gettimeofday(t, NULL); 1845 gettimeofday(t, NULL);
1852 } 1846}
1853 1847
1854#endif 1848#endif