/** * Allocates a new AAAMessage. * @param commandCode - the command code for this message * @param applicationId - application id to be set * @param sessionId - session id to be set * @param request - if you want to create a response, put the request here. If you want a * request, call with NULL * @returns the AAAMessage* or NULL on error * \note This function is taken from DISC http://developer.berlios.de/projects/disc/ */ AAAMessage *AAANewMessage( AAACommandCode commandCode, AAAApplicationId applicationId, AAASessionId *sessionId, AAAMessage *request) { AAAMessage *msg; AAA_AVP *avp; AAA_AVP *avp_t; #if 0 unsigned int code; #endif str dest_host={"?",1}; str dest_realm={"?",1}; msg = 0; if (!sessionId||!sessionId->s) { if (request && request->sessionId){ /* copy old session id */ avp = request->sessionId; if (avp) { sessionId = &(avp->data); } }else{ //because of diameter base messages etc // LOG(L_ERR,"ERROR:AAANewMessage: param session-ID received null and it's a request!!\n"); // goto error; } } /* allocated a new AAAMessage structure and set it to 0 */ msg = (AAAMessage*)shm_malloc(sizeof(AAAMessage)); if (!msg) { LOG(L_ERR,"ERROR:AAANewMessage: no more free memory!!\n"); goto error; } memset(msg,0,sizeof(AAAMessage)); /* command code */ msg->commandCode = commandCode; /* application ID */ msg->applicationId = applicationId; /* add session ID */ if (sessionId){ avp = AAACreateAVP( 263, 0, 0, sessionId->s, sessionId->len, AVP_DUPLICATE_DATA); if ( !avp || AAAAddAVPToMessage(msg,avp,0)!=AAA_ERR_SUCCESS) { LOG(L_ERR,"ERROR:AAANewMessage: cannot create/add Session-Id avp\n"); if (avp) AAAFreeAVP( &avp ); goto error; } msg->sessionId = avp; } /* add origin host AVP */ /* changed by cristian to comply with rfc3588: * 6.3. Origin-Host AVP * * The Origin-Host AVP (AVP Code 264) is of type * DiameterIdentity... */ avp = AAACreateAVP( 264, 0, 0, config->fqdn.s, config->fqdn.len, AVP_DUPLICATE_DATA); if (!avp||AAAAddAVPToMessage(msg,avp,msg->avpList.tail)!=AAA_ERR_SUCCESS) { LOG(L_ERR,"ERROR:AAANewMessage: cannot create/add Origin-Host avp\n"); if (avp) AAAFreeAVP( &avp ); goto error; } msg->orig_host = avp; /* add origin realm AVP */ avp = AAACreateAVP( 296, 0, 0, config->realm.s, config->realm.len, AVP_DUPLICATE_DATA); if (!avp||AAAAddAVPToMessage(msg,avp,msg->avpList.tail)!=AAA_ERR_SUCCESS) { LOG(L_ERR,"ERROR:AAANewMessage: cannot create/add Origin-Realm avp\n"); if (avp) AAAFreeAVP( &avp ); goto error; } msg->orig_realm = avp; if (!request) { /* it's a new request -> set the flag */ msg->flags = 0x80; /* keep track of the session -> SendMessage will need it! */ msg->sId = sessionId; } else { /* it'a an answer -> it will have the same session Id */ msg->sId = request->sId; /* link the incoming peer to the answer */ msg->in_peer = request->in_peer; /* set the P flag as in request */ msg->flags |= request->flags&0x40; /**/ msg->endtoendId = request->endtoendId; msg->hopbyhopId = request->hopbyhopId; /* Mirror the old originhost/realm to destinationhost/realm*/ avp = AAAFindMatchingAVP(request,0,AVP_Origin_Host,0,0); if (avp) dest_host = avp->data; /* add destination host and destination realm */ avp = AAACreateAVP(AVP_Destination_Host,AAA_AVP_FLAG_MANDATORY,0, dest_host.s,dest_host.len,AVP_DUPLICATE_DATA); if (!avp) { LOG(L_ERR,"ERR:AAANewMessage: Failed creating Destination Host avp\n"); return 0; } if (AAAAddAVPToMessage(msg,avp,msg->avpList.tail)!=AAA_ERR_SUCCESS) { LOG(L_ERR,"ERR:AAANewMessage: Failed adding Destination Host avp to message\n"); AAAFreeAVP(&avp); return 0; } avp = AAAFindMatchingAVP(request,0,AVP_Origin_Realm,0,0); if (avp) dest_realm = avp->data; avp = AAACreateAVP(AVP_Destination_Realm,AAA_AVP_FLAG_MANDATORY,0, dest_realm.s,dest_realm.len,AVP_DUPLICATE_DATA); if (!avp) { LOG(L_ERR,"ERR:AAANewMessage: Failed creating Destination Realm avp\n"); return 0; } if (AAAAddAVPToMessage(msg,avp,msg->avpList.tail)!=AAA_ERR_SUCCESS) { LOG(L_ERR,"ERR:AAANewMessage: Failed adding Destination Realm avp to message\n"); AAAFreeAVP(&avp); return 0; } msg->res_code=0; /* mirror all the proxy-info avp in the same order */ avp_t = request->avpList.head; while ( (avp_t=AAAFindMatchingAVP (request,avp_t,284,0,AAA_FORWARD_SEARCH))!=0 ) { if ( (avp=AAACloneAVP(avp_t,1))==0 || AAAAddAVPToMessage( msg, avp, msg->avpList.tail)!=AAA_ERR_SUCCESS ) goto error; } } return msg; error: LOG(L_ERR,"ERROR:AAANewMessage: failed to create a new AAA message!\n"); AAAFreeMessage(&msg); return 0; }
/** * Allocates a new AAAMessage. * @param commandCode - the command code for this message * @param applicationId - application id to be set * @param sessionId - session id to be set * @param request - if you want to create a response, put the request here. If you want a * request, call with NULL * @returns the AAAMessage* or NULL on error * \note This function is taken from DISC http://developer.berlios.de/projects/disc/ */ AAAMessage *AAANewMessage( AAACommandCode commandCode, AAAApplicationId applicationId, AAASession *session, AAAMessage *request) { AAAMessage *msg; AAA_AVP *avp; AAA_AVP *avp_t; str *sessionId=0; #if 0 unsigned int code; #endif // str dest_host={"?",1}; str dest_realm={"?",1}; msg = 0; if (!session||!session->id.s) { if (request){ /* copy old session id from AVP */ if (request->sessionId) sessionId = &(request->sessionId->data); }else{ if (commandCode!=Code_DW) LM_DBG("AAANewMessage: param session received null and it's a request!!\n"); } }else{ sessionId = &(session->id); } /* allocated a new AAAMessage structure and set it to 0 */ msg = (AAAMessage*)shm_malloc(sizeof(AAAMessage)); if (!msg) { LM_ERR("AAANewMessage: no more free memory!!\n"); goto error; } memset(msg,0,sizeof(AAAMessage)); /* command code */ msg->commandCode = commandCode; /* application ID */ msg->applicationId = applicationId; /*add session ID */ if (sessionId){ avp = AAACreateAVP( 263, 0, 0, sessionId->s, sessionId->len, AVP_DUPLICATE_DATA); if ( !avp || AAAAddAVPToMessage(msg,avp,0)!=AAA_ERR_SUCCESS) { LM_ERR("AAANewMessage: cannot create/add Session-Id avp\n"); if (avp) AAAFreeAVP( &avp ); goto error; } msg->sessionId = avp; } /* add origin host AVP */ /* changed by cristian to comply with rfc3588: * 6.3. Origin-Host AVP * * The Origin-Host AVP (AVP Code 264) is of type * DiameterIdentity... */ avp = AAACreateAVP( 264, 0, 0, config->fqdn.s, config->fqdn.len, AVP_DUPLICATE_DATA); if (!avp||AAAAddAVPToMessage(msg,avp,msg->avpList.tail)!=AAA_ERR_SUCCESS) { LM_ERR("AAANewMessage: cannot create/add Origin-Host avp\n"); if (avp) AAAFreeAVP( &avp ); goto error; } msg->orig_host = avp; /* add origin realm AVP */ avp = AAACreateAVP( 296, 0, 0, config->realm.s, config->realm.len, AVP_DUPLICATE_DATA); if (!avp||AAAAddAVPToMessage(msg,avp,msg->avpList.tail)!=AAA_ERR_SUCCESS) { LM_ERR("AAANewMessage: cannot create/add Origin-Realm avp\n"); if (avp) AAAFreeAVP( &avp ); goto error; } msg->orig_realm = avp; if (!request) { /* it's a new request -> set the flag */ msg->flags = 0x80; } else { /* link the incoming peer to the answer */ msg->in_peer = request->in_peer; /* set the P flag as in request */ msg->flags |= request->flags&0x40; /**/ msg->endtoendId = request->endtoendId; msg->hopbyhopId = request->hopbyhopId; //TODO: aon:move this information in the AAASession structure, do not add these fields for if (msg->commandCode==Code_CE||msg->commandCode==Code_DP||msg->commandCode==Code_DW || msg->commandCode==Diameter_CCR || msg->commandCode==Diameter_RAR){ // Don't add Destination Host/Realm because some stacks are way to picky and will just refuse it }else{ /* Mirror the old originhost/realm to destinationhost/realm*/ //avp = AAAFindMatchingAVP(request,0,AVP_Origin_Host,0,0); //if (avp) dest_host = avp->data; /* add destination host and destination realm */ //avp = AAACreateAVP(AVP_Destination_Host,AAA_AVP_FLAG_MANDATORY,0, // dest_host.s,dest_host.len,AVP_DUPLICATE_DATA); //if (!avp) { // LM_ERR("ERR:AAANewMessage: Failed creating Destination Host avp\n"); // goto error; // } // if (AAAAddAVPToMessage(msg,avp,msg->avpList.tail)!=AAA_ERR_SUCCESS) { // LM_ERR("ERR:AAANewMessage: Failed adding Destination Host avp to message\n"); // AAAFreeAVP(&avp); // goto error; // } avp = AAAFindMatchingAVP(request,0,AVP_Origin_Realm,0,0); if (avp) dest_realm = avp->data; avp = AAACreateAVP(AVP_Destination_Realm,AAA_AVP_FLAG_MANDATORY,0, dest_realm.s,dest_realm.len,AVP_DUPLICATE_DATA); if (!avp) { LM_ERR("ERR:AAANewMessage: Failed creating Destination Realm avp\n"); goto error; } if (AAAAddAVPToMessage(msg,avp,msg->avpList.tail)!=AAA_ERR_SUCCESS) { LM_ERR("ERR:AAANewMessage: Failed adding Destination Realm avp to message\n"); AAAFreeAVP(&avp); goto error; } } msg->res_code=0; /* mirror all the proxy-info avp in the same order */ avp_t = request->avpList.head; while ( (avp_t=AAAFindMatchingAVP (request,avp_t,284,0,AAA_FORWARD_SEARCH))!=0 ) { if ( (avp=AAACloneAVP(avp_t,1))==0 || AAAAddAVPToMessage( msg, avp, msg->avpList.tail)!=AAA_ERR_SUCCESS ) goto error; } } return msg; error: LM_ERR("AAANewMessage: failed to create a new AAA message!\n"); AAAFreeMessage(&msg); return 0; }