Browse code

sctp support for more notification

- support all relevant notifications, for now just dump some DBG() info

Andrei Pelinescu-Onciul authored on 27/08/2008 08:36:53
Showing 1 changed files
... ...
@@ -253,61 +253,195 @@ error:
253 253
 
254 254
 
255 255
 
256
+/* debugging: return a string name for SCTP_ASSOC_CHANGE state */
257
+static char* sctp_assoc_change_state2s(short int state)
258
+{
259
+	char* s;
260
+	
261
+	switch(state){
262
+		case SCTP_COMM_UP:
263
+			s="SCTP_COMM_UP";
264
+			break;
265
+		case SCTP_COMM_LOST:
266
+			s="SCTP_COMM_LOST";
267
+			break;
268
+		case SCTP_RESTART:
269
+			s="SCTP_RESTART";
270
+			break;
271
+		case SCTP_SHUTDOWN_COMP:
272
+			s="SCTP_SHUTDOWN_COMP";
273
+			break;
274
+		case SCTP_CANT_STR_ASSOC:
275
+			s="SCTP_CANT_STR_ASSOC";
276
+			break;
277
+		default:
278
+			s="UNKOWN";
279
+			break;
280
+	};
281
+	return s;
282
+}
283
+
284
+
285
+
286
+/* debugging: return a string name for a SCTP_PEER_ADDR_CHANGE state */
287
+static char* sctp_paddr_change_state2s(unsigned int state)
288
+{
289
+	char* s;
290
+	
291
+	switch (state){
292
+		case SCTP_ADDR_AVAILABLE:
293
+			s="SCTP_ADDR_AVAILABLE";
294
+			break;
295
+		case SCTP_ADDR_UNREACHABLE:
296
+			s="SCTP_ADDR_UNREACHABLE";
297
+			break;
298
+		case SCTP_ADDR_REMOVED:
299
+			s="SCTP_ADDR_REMOVED";
300
+			break;
301
+		case SCTP_ADDR_ADDED:
302
+			s="SCTP_ADDR_ADDED";
303
+			break;
304
+		case SCTP_ADDR_MADE_PRIM:
305
+			s="SCTP_ADDR_MADE_PRIM";
306
+			break;
307
+		case SCTP_ADDR_CONFIRMED:
308
+			s="SCTP_ADDR_CONFIRMED";
309
+			break;
310
+		default:
311
+			s="UNKNOWN";
312
+			break;
313
+	}
314
+	return s;
315
+}
316
+
317
+
318
+
256 319
 static int sctp_handle_notification(struct socket_info* si,
257 320
 									union sockaddr_union* su,
258 321
 									char* buf, unsigned len)
259 322
 {
260 323
 	union sctp_notification* snp;
324
+	char su_buf[SU2A_MAX_STR_SIZE];
325
+	
261 326
 	DBG("sctp_rcv_loop: MSG_NOTIFICATION\n");
327
+	
328
+	#define SNOT DBG
329
+	#define ERR_LEN_TOO_SMALL(length, val, bind_addr, from_su, text) \
330
+		if (unlikely((length)<(val))){\
331
+			SNOT("ERROR: sctp notification from %s on %.*s:%d: " \
332
+						text " too short (%d bytes instead of %d bytes)\n", \
333
+						su2a((from_su), sizeof(*(from_su))), \
334
+						(bind_addr)->name.len, (bind_addr)->name.s, \
335
+						(bind_addr)->port_no, (length), (val)); \
336
+			goto error; \
337
+		}
262 338
 
263 339
 	if (len < sizeof(snp->sn_header)){
264 340
 		LOG(L_ERR, "ERROR: sctp_handle_notification: invalid length %d "
265 341
 					"on %.*s:%d, from %s\n",
266 342
 					len, si->name.len, si->name.s, si->port_no,
267 343
 					su2a(su, sizeof(*su)));
268
-		goto err;
344
+		goto error;
269 345
 	}
270 346
 	snp=(union sctp_notification*) buf;
271 347
 	switch(snp->sn_header.sn_type){
272 348
 		case SCTP_REMOTE_ERROR:
273
-			if (likely(len>=(sizeof(struct sctp_remote_error)))){
274
-				INFO("sctp notification from %s on %.*s:%d:"
275
-						" SCTP_REMOTE_ERROR: %d, len %d\n",
276
-						su2a(su, sizeof(*su)), si->name.len, si->name.s,
277
-						si->port_no,
278
-						ntohs(snp->sn_remote_error.sre_error),
279
-						ntohs(snp->sn_remote_error.sre_length)
280
-						);
281
-			}else{
282
-				LOG(L_ERR, "ERROR: sctp notification from %s on %.*s:%d:"
283
-						" SCTP_REMOTE_ERROR: too short\n",
284
-						su2a(su, sizeof(*su)), si->name.len, si->name.s,
285
-						si->port_no);
286
-				goto err;
287
-			}
349
+			ERR_LEN_TOO_SMALL(len, sizeof(struct sctp_remote_error), si, su,
350
+								"SCTP_REMOTE_ERROR");
351
+			SNOT("sctp notification from %s on %.*s:%d: SCTP_REMOTE_ERROR:"
352
+					" %d, len %d\n, assoc. %d",
353
+					su2a(su, sizeof(*su)), si->name.len, si->name.s,
354
+					si->port_no,
355
+					ntohs(snp->sn_remote_error.sre_error),
356
+					ntohs(snp->sn_remote_error.sre_length),
357
+					snp->sn_remote_error.sre_assoc_id
358
+				);
288 359
 			break;
289 360
 		case SCTP_SEND_FAILED:
290
-			if (likely(len>=(sizeof(struct sctp_send_failed)))){
291
-				INFO("sctp notification from %s on %.*s:%d:"
292
-						" SCTP_SEND_FAILED: error %d\n",
293
-						su2a(su, sizeof(*su)), si->name.len, si->name.s,
294
-						si->port_no, snp->sn_send_failed.ssf_error);
295
-			}else{
296
-				LOG(L_ERR, "ERROR: sctp notification from %s on %.*s:%d:"
297
-						" SCTP_SEND_FAILED: too short\n",
298
-						su2a(su, sizeof(*su)), si->name.len, si->name.s,
299
-						si->port_no);
300
-				goto err;
301
-			}
361
+			ERR_LEN_TOO_SMALL(len, sizeof(struct sctp_send_failed), si, su,
362
+								"SCTP_SEND_FAILED");
363
+			SNOT("sctp notification from %s on %.*s:%d: SCTP_SEND_FAILED:"
364
+					" error %d, assoc. %d, flags %x\n",
365
+					su2a(su, sizeof(*su)), si->name.len, si->name.s,
366
+					si->port_no, snp->sn_send_failed.ssf_error,
367
+					snp->sn_send_failed.ssf_assoc_id,
368
+					snp->sn_send_failed.ssf_flags);
369
+			break;
370
+		case SCTP_PEER_ADDR_CHANGE:
371
+			ERR_LEN_TOO_SMALL(len, sizeof(struct sctp_paddr_change), si, su,
372
+								"SCTP_PEER_ADDR_CHANGE");
373
+			strcpy(su_buf, su2a((union sockaddr_union*)
374
+									&snp->sn_paddr_change.spc_aaddr, 
375
+									sizeof(snp->sn_paddr_change.spc_aaddr)));
376
+			SNOT("sctp notification from %s on %.*s:%d: SCTP_PEER_ADDR_CHANGE"
377
+					": %s: %s: assoc. %d \n",
378
+					su2a(su, sizeof(*su)), si->name.len, si->name.s,
379
+					si->port_no, su_buf,
380
+					sctp_paddr_change_state2s(snp->sn_paddr_change.spc_state),
381
+					snp->sn_paddr_change.spc_assoc_id
382
+					);
383
+			break;
384
+		case SCTP_SHUTDOWN_EVENT:
385
+			ERR_LEN_TOO_SMALL(len, sizeof(struct sctp_shutdown_event), si, su,
386
+								"SCTP_SHUTDOWN_EVENT");
387
+			SNOT("sctp notification from %s on %.*s:%d: SCTP_SHUTDOWN_EVENT:"
388
+					" assoc. %d\n",
389
+					su2a(su, sizeof(*su)), si->name.len, si->name.s,
390
+					si->port_no, snp->sn_shutdown_event.sse_assoc_id);
391
+			break;
392
+		case SCTP_ASSOC_CHANGE:
393
+			ERR_LEN_TOO_SMALL(len, sizeof(struct sctp_assoc_change), si, su,
394
+								"SCTP_ASSOC_CHANGE");
395
+			SNOT("sctp notification from %s on %.*s:%d: SCTP_ASSOC_CHANGE"
396
+					": %s: assoc. %d, ostreams %d, istreams %d\n",
397
+					su2a(su, sizeof(*su)), si->name.len, si->name.s,
398
+					si->port_no,
399
+					sctp_assoc_change_state2s(snp->sn_assoc_change.sac_state),
400
+					snp->sn_assoc_change.sac_assoc_id,
401
+					snp->sn_assoc_change.sac_outbound_streams,
402
+					snp->sn_assoc_change.sac_inbound_streams
403
+					);
404
+			break;
405
+#ifdef SCTP_ADAPTION_INDICATION
406
+		case SCTP_ADAPTION_INDICATION:
407
+			ERR_LEN_TOO_SMALL(len, sizeof(struct sctp_adaption_event), si, su,
408
+								"SCTP_ADAPTION_INDICATION");
409
+			SNOT("sctp notification from %s on %.*s:%d: "
410
+					"SCTP_ADAPTION_INDICATION \n",
411
+					su2a(su, sizeof(*su)), si->name.len, si->name.s,
412
+					si->port_no);
413
+			break;
414
+#endif /* SCTP_ADAPTION_INDICATION */
415
+		case SCTP_PARTIAL_DELIVERY_EVENT:
416
+			ERR_LEN_TOO_SMALL(len, sizeof(struct sctp_pdapi_event), si, su,
417
+								"SCTP_PARTIAL_DELIVERY_EVENT");
418
+			SNOT("sctp notification from %s on %.*s:%d: "
419
+					"SCTP_PARTIAL_DELIVERY_EVENT: %d%s, assoc. %d\n",
420
+					su2a(su, sizeof(*su)), si->name.len, si->name.s,
421
+					si->port_no, snp->sn_pdapi_event.pdapi_indication,
422
+					(snp->sn_pdapi_event.pdapi_indication==
423
+					 	SCTP_PARTIAL_DELIVERY_ABORTED)? " PD ABORTED":"",
424
+					snp->sn_pdapi_event.pdapi_assoc_id);
302 425
 			break;
426
+#ifdef SCTP_SENDER_DRY_EVENT /* new, not yet supported */
427
+		case SCTP_SENDER_DRY_EVENT:
428
+			ERR_LEN_TOO_SMALL(len, sizeof(struct sctp_sender_dry_event),
429
+								si, su, "SCTP_SENDER_DRY_EVENT");
430
+			SNOT("sctp notification from %s on %.*s:%d: "
431
+					"SCTP_SENDER_DRY_EVENT on %d\n",
432
+					su2a(su, sizeof(*su)), si->name.len, si->name.s,
433
+					si->port_no, snp->sn_sender_dry_event.sender_dry_assoc_id);
434
+			break;
435
+#endif /* SCTP_SENDER_DRY_EVENT */
303 436
 		default:
304
-			INFO("sctp notification from %s on %.*s:%d: UNKNOWN (%d)\n",
437
+			SNOT("sctp notification from %s on %.*s:%d: UNKNOWN (%d)\n",
305 438
 					su2a(su, sizeof(*su)), si->name.len, si->name.s,
306 439
 					si->port_no, snp->sn_header.sn_type);
307 440
 	}
308 441
 	return 0;
309
-err:
442
+error:
310 443
 	return -1;
444
+	#undef ERR_LEN_TOO_SMALL
311 445
 }
312 446
 
313 447