Mercurial > hg > freeDiameter
comparison libfdproto/messages.c @ 1230:e72c9dad62ac
Fix issue with generating Failed-AVP when the error is DIAMETER_MISSING_AVP. Also fix a memory leak in that case
author | Sebastien Decugis <sdecugis@freediameter.net> |
---|---|
date | Sun, 21 Jul 2013 11:57:39 +0200 |
parents | 4e52f009861a |
children | c9a160b815ea |
comparison
equal
deleted
inserted
replaced
1229:4e52f009861a | 1230:e72c9dad62ac |
---|---|
2368 CHECK_FCT_DO( fd_msg_avp_new(model_avp, 0, &avp ), return NULL ); | 2368 CHECK_FCT_DO( fd_msg_avp_new(model_avp, 0, &avp ), return NULL ); |
2369 | 2369 |
2370 /* Type of the AVP */ | 2370 /* Type of the AVP */ |
2371 CHECK_FCT_DO( fd_dict_getval(model_avp, &avp_info), return NULL ); | 2371 CHECK_FCT_DO( fd_dict_getval(model_avp, &avp_info), return NULL ); |
2372 | 2372 |
2373 /* Set an initial size */ | |
2374 avp->avp_public.avp_len = GETAVPHDRSZ( avp->avp_public.avp_flags ) + avp_value_sizes[avp_info.avp_basetype]; | |
2375 | |
2373 /* Prepare the empty value */ | 2376 /* Prepare the empty value */ |
2374 memset(&val, 0, sizeof(val)); | 2377 memset(&val, 0, sizeof(val)); |
2375 switch (avp_info.avp_basetype) { | 2378 switch (avp_info.avp_basetype) { |
2376 case AVP_TYPE_OCTETSTRING: | 2379 case AVP_TYPE_OCTETSTRING: |
2377 val.os.data = os; | 2380 val.os.data = os; |
2378 val.os.len = sizeof(os); | 2381 val.os.len = sizeof(os); |
2382 avp->avp_public.avp_len += val.os.len; | |
2379 case AVP_TYPE_INTEGER32: | 2383 case AVP_TYPE_INTEGER32: |
2380 case AVP_TYPE_INTEGER64: | 2384 case AVP_TYPE_INTEGER64: |
2381 case AVP_TYPE_UNSIGNED32: | 2385 case AVP_TYPE_UNSIGNED32: |
2382 case AVP_TYPE_UNSIGNED64: | 2386 case AVP_TYPE_UNSIGNED64: |
2383 case AVP_TYPE_FLOAT32: | 2387 case AVP_TYPE_FLOAT32: |
2437 if (count < min) { | 2441 if (count < min) { |
2438 fd_log_error("Conflicting rule: the number of occurences (%d) is < the rule min (%d) for '%s'.", count, min, avp_name); | 2442 fd_log_error("Conflicting rule: the number of occurences (%d) is < the rule min (%d) for '%s'.", count, min, avp_name); |
2439 if (pr_data->pei) { | 2443 if (pr_data->pei) { |
2440 pr_data->pei->pei_errcode = "DIAMETER_MISSING_AVP"; | 2444 pr_data->pei->pei_errcode = "DIAMETER_MISSING_AVP"; |
2441 pr_data->pei->pei_avp = empty_avp(rule->rule_avp); | 2445 pr_data->pei->pei_avp = empty_avp(rule->rule_avp); |
2446 pr_data->pei->pei_avp_free = 1; | |
2442 } | 2447 } |
2443 return EBADMSG; | 2448 return EBADMSG; |
2444 } | 2449 } |
2445 | 2450 |
2446 /* Check the "max" value */ | 2451 /* Check the "max" value */ |
2450 if (rule->rule_max == 0) | 2455 if (rule->rule_max == 0) |
2451 pr_data->pei->pei_errcode = "DIAMETER_AVP_NOT_ALLOWED"; | 2456 pr_data->pei->pei_errcode = "DIAMETER_AVP_NOT_ALLOWED"; |
2452 else | 2457 else |
2453 pr_data->pei->pei_errcode = "DIAMETER_AVP_OCCURS_TOO_MANY_TIMES"; | 2458 pr_data->pei->pei_errcode = "DIAMETER_AVP_OCCURS_TOO_MANY_TIMES"; |
2454 pr_data->pei->pei_avp = empty_avp(rule->rule_avp); /* Well we are supposed to return the (max + 1)th instance of the AVP instead... Pfff... */ TODO("Improve..."); | 2459 pr_data->pei->pei_avp = empty_avp(rule->rule_avp); /* Well we are supposed to return the (max + 1)th instance of the AVP instead... Pfff... */ TODO("Improve..."); |
2460 pr_data->pei->pei_avp_free = 1; | |
2455 } | 2461 } |
2456 return EBADMSG; | 2462 return EBADMSG; |
2457 } | 2463 } |
2458 | 2464 |
2459 /* Check the position and order (if relevant) */ | 2465 /* Check the position and order (if relevant) */ |
2469 fd_log_error("Conflicting rule: the FIXED_HEAD AVP appears first in (%d) position, the rule requires (%d) for '%s'.", first, rule->rule_order, avp_name); | 2475 fd_log_error("Conflicting rule: the FIXED_HEAD AVP appears first in (%d) position, the rule requires (%d) for '%s'.", first, rule->rule_order, avp_name); |
2470 if (pr_data->pei) { | 2476 if (pr_data->pei) { |
2471 pr_data->pei->pei_errcode = "DIAMETER_MISSING_AVP"; | 2477 pr_data->pei->pei_errcode = "DIAMETER_MISSING_AVP"; |
2472 pr_data->pei->pei_message = "AVP was not in its fixed position"; | 2478 pr_data->pei->pei_message = "AVP was not in its fixed position"; |
2473 pr_data->pei->pei_avp = empty_avp(rule->rule_avp); | 2479 pr_data->pei->pei_avp = empty_avp(rule->rule_avp); |
2480 pr_data->pei->pei_avp_free = 1; | |
2474 } | 2481 } |
2475 return EBADMSG; | 2482 return EBADMSG; |
2476 } | 2483 } |
2477 break; | 2484 break; |
2478 | 2485 |
2482 fd_log_error("Conflicting rule: the FIXED_TAIL AVP appears last in (%d) position, the rule requires (%d) for '%s'.", last, rule->rule_order, avp_name); | 2489 fd_log_error("Conflicting rule: the FIXED_TAIL AVP appears last in (%d) position, the rule requires (%d) for '%s'.", last, rule->rule_order, avp_name); |
2483 if (pr_data->pei) { | 2490 if (pr_data->pei) { |
2484 pr_data->pei->pei_errcode = "DIAMETER_MISSING_AVP"; | 2491 pr_data->pei->pei_errcode = "DIAMETER_MISSING_AVP"; |
2485 pr_data->pei->pei_message = "AVP was not in its fixed position"; | 2492 pr_data->pei->pei_message = "AVP was not in its fixed position"; |
2486 pr_data->pei->pei_avp = empty_avp(rule->rule_avp); | 2493 pr_data->pei->pei_avp = empty_avp(rule->rule_avp); |
2494 pr_data->pei->pei_avp_free = 1; | |
2487 } | 2495 } |
2488 return EBADMSG; | 2496 return EBADMSG; |
2489 } | 2497 } |
2490 break; | 2498 break; |
2491 | 2499 |