Author: sayer Date: 2009-01-19 18:11:43 +0100 (Mon, 19 Jan 2009) New Revision: 1225
Modified: trunk/apps/diameter_client/DiameterClient.cpp trunk/apps/diameter_client/DiameterClient.h trunk/apps/diameter_client/ServerConnection.cpp trunk/apps/diameter_client/ServerConnection.h trunk/apps/diameter_client/lib_dbase/defs.h trunk/apps/diameter_client/lib_dbase/diameter_msg.c trunk/apps/diameter_client/lib_dbase/diameter_msg.h trunk/apps/diameter_client/lib_dbase/tcp_comm.c trunk/apps/diameter_client/lib_dbase/tcp_comm.h Log: implements Disconnect-Peer-Request (DPR) handling and more proper (?) TLS connection shutdown. Modified: trunk/apps/diameter_client/DiameterClient.cpp =================================================================== --- trunk/apps/diameter_client/DiameterClient.cpp 2009-01-09 09:55:37 UTC (rev 1224) +++ trunk/apps/diameter_client/DiameterClient.cpp 2009-01-19 17:11:43 UTC (rev 1225) @@ -1,16 +1,16 @@ /* * $Id$ * - * Copyright (C) 2007-2008 IPTEGO GmbH + * Copyright (C) 2007-2009 IPTEGO GmbH * - * This file is part of sems, a free SIP media server. + * This file is part of SEMS, a free SIP media server. * * sems is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version * - * For a license to use the ser software under conditions + * For a license to use the SEMS software under conditions * other than those described here, or to purchase support for this * software, please contact iptel.org by e-mail at the following addresses: * [email protected] @@ -20,11 +20,12 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #include "DiameterClient.h" #include "log.h" @@ -165,9 +166,77 @@ row.assertArrayFmt("iiib"); } sendRequest(args, ret); + } else if(method == "test1"){ + AmArg a; + a.push(AmArg("vtm")); +// a.push(AmArg("10.1.0.196")); +// a.push(AmArg(8080)); + a.push(AmArg("62.220.31.182")); + a.push(AmArg(9381)); +// a.push(AmArg("127.0.0.1")); +// a.push(AmArg(4433)); + a.push(AmArg("vtm01")); + a.push(AmArg("vtm.t-online.de")); + a.push(AmArg("10.42.32.13")); + a.push(AmArg(16777241)); + a.push(AmArg(29631)); + a.push(AmArg("vtm")); + a.push(AmArg(20)); // timeout +// a.push(AmArg("ca.pem")); +// a.push(AmArg("client.pem")); + newConnection(a, ret); + } else if(method == "test2"){ + AmArg a; +#define AAA_APP_USPI 16777241 +#define AVP_E164_NUMBER 1024 +#define AAA_VENDOR_IPTEGO 29631 +#define AAA_LAR 16777214 + + a.push(AmArg("vtm")); + a.push(AmArg(AAA_LAR)); + a.push(AmArg(AAA_APP_USPI)); + DBG("x pushin \n"); + AmArg avps; + + AmArg e164; + e164.push((int)AVP_E164_NUMBER); + e164.push((int)AAA_AVP_FLAG_VENDOR_SPECIFIC | AAA_AVP_FLAG_MANDATORY); + e164.push((int)AAA_VENDOR_IPTEGO); + string e164_number = "+49331600001"; + e164.push(ArgBlob(e164_number.c_str(), e164_number.length())); + avps.push(e164); + + AmArg drealm; + drealm.push((int)AVP_Destination_Realm); + drealm.push((int)AAA_AVP_FLAG_MANDATORY); + drealm.push((int)0); + string dest_realm = "iptego.de"; + drealm.push(ArgBlob(dest_realm.c_str(), dest_realm.length())); + avps.push(drealm); + + a.push(avps); + a.push(AmArg("bogus_link")); + + // check... + + DBG("x checking\n"); + a.assertArrayFmt("siias"); + DBG("x checking\n"); + // check values + AmArg& vals = a.get(3); + for (size_t i=0;i<vals.size(); i++) { + AmArg& row = vals.get(i); + // [int avp_id, int flags, int vendor, blob data] + row.assertArrayFmt("iiib"); + } + DBG("x sendrequest\n"); + sendRequest(a, ret); + } else if(method == "_list"){ ret.push(AmArg("newConnection")); ret.push(AmArg("sendRequest")); + ret.push(AmArg("test1")); + ret.push(AmArg("test2")); } else throw AmDynInvoke::NotImplemented(method); } Modified: trunk/apps/diameter_client/DiameterClient.h =================================================================== --- trunk/apps/diameter_client/DiameterClient.h 2009-01-09 09:55:37 UTC (rev 1224) +++ trunk/apps/diameter_client/DiameterClient.h 2009-01-19 17:11:43 UTC (rev 1225) @@ -1,16 +1,16 @@ /* * $Id$ * - * Copyright (C) 2007-2008 IPTEGO GmbH + * Copyright (C) 2007-2009 IPTEGO GmbH * - * This file is part of sems, a free SIP media server. + * This file is part of SEMS, a free SIP media server. * * sems is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version * - * For a license to use the ser software under conditions + * For a license to use the SEMS software under conditions * other than those described here, or to purchase support for this * software, please contact iptel.org by e-mail at the following addresses: * [email protected] @@ -20,10 +20,11 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #ifndef _DIAMETER_CLIENT_H #define _DIAMETER_CLIENT_H Modified: trunk/apps/diameter_client/ServerConnection.cpp =================================================================== --- trunk/apps/diameter_client/ServerConnection.cpp 2009-01-09 09:55:37 UTC (rev 1224) +++ trunk/apps/diameter_client/ServerConnection.cpp 2009-01-19 17:11:43 UTC (rev 1225) @@ -1,16 +1,16 @@ /* * $Id$ * - * Copyright (C) 2007-2008 IPTEGO GmbH + * Copyright (C) 2007-2009 IPTEGO GmbH * - * This file is part of sems, a free SIP media server. + * This file is part of SEMS, a free SIP media server. * * sems is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version * - * For a license to use the ser software under conditions + * For a license to use the SEMS software under conditions * other than those described here, or to purchase support for this * software, please contact iptel.org by e-mail at the following addresses: * [email protected] @@ -20,8 +20,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -62,8 +62,11 @@ } -void DiameterServerConnection::terminate() { +void DiameterServerConnection::terminate(bool tls_shutdown) { if (dia_conn) { + if (tls_shutdown) + tcp_tls_shutdown(dia_conn); + tcp_close_connection(dia_conn); tcp_destroy_connection(dia_conn); dia_conn = NULL; @@ -244,37 +247,48 @@ AAAFreeMessage(&cer); - int res = tcp_recv_msg(conn.dia_conn, &conn.rb, + unsigned int cea_receive_cnt = 3; + while (true) { + int res = tcp_recv_msg(conn.dia_conn, &conn.rb, CONNECT_CEA_REPLY_TIMEOUT, 0); - - if (res <= 0) { - if (!res) { - ERROR( " openConnection(): did not receive response (CEA).\n"); - } else { - ERROR( " openConnection(): error receiving response (CEA).\n"); + + if (res <= 0) { + if (!res) { + ERROR( " openConnection(): did not receive response (CEA).\n"); + } else { + ERROR( " openConnection(): error receiving response (CEA).\n"); + } + conn.terminate(); + setRetryConnectLater(); + return; } - conn.terminate(); - setRetryConnectLater(); - return; - } + + /* obtain the structure corresponding to the message */ + AAAMessage* cea = AAATranslateMessage(conn.rb.buf, conn.rb.buf_len, 0); + if(!cea) { + ERROR( " openConnection(): could not decipher response (CEA).\n"); + conn.terminate(); + setRetryConnectLater(); + return; + } - /* obtain the structure corresponding to the message */ - AAAMessage* cea = AAATranslateMessage(conn.rb.buf, conn.rb.buf_len, 0); - if(!cea) { - ERROR( " openConnection(): could not decipher response (CEA).\n"); - conn.terminate(); - setRetryConnectLater(); - return; - } - - // assume its CEA.... - + if (cea->commandCode == AAA_CC_CEA) { #ifdef EXTRA_DEBUG - if (cea != NULL) - AAAPrintMessage(cea); + AAAPrintMessage(cea); #endif + AAAFreeMessage(&cea); + break; + } - AAAFreeMessage(&cea); + AAAFreeMessage(&cea); + + if (!(cea_receive_cnt--)) { + ERROR( " openConnection(): no CEA received.\n"); + conn.terminate(); + setRetryConnectLater(); + return; + } + } DBG("Connection opened.\n"); open = true; @@ -425,6 +439,7 @@ AAAMessageSetReply(reply); if (addOrigin(reply) || addResultCodeAVP(reply, AAA_SUCCESS)) { + AAAFreeMessage(&reply); return AAA_ERROR_MESSAGE; } @@ -451,7 +466,62 @@ }; break; case AAA_CC_DPR: { // Disconnect-Peer-Request - DBG("Disconnect-Peer-Request not yet implemented\n"); + string disconnect_cause = "UNKNOWN"; + AAA_AVP* avp = req->avpList.head; + while (avp) { + if (avp->code == AVP_Disconnect_Cause) { + switch((unsigned int)htonl(*((unsigned int*)avp->data.s))){ + case 0:disconnect_cause = "REBOOTING"; break; + case 1:disconnect_cause = "BUSY"; break; + case 2:disconnect_cause = "DO_NOT_WANT_TO_TALK_TO_YOU"; break; + } + break; + } + avp=avp->next; + } + + DBG("Disconnect-Peer-Request received. Cause: '%s'." + " Sending Disconnect-Peer-Answer...\n", disconnect_cause.c_str()); + + AAAMessage* reply; + if ( (reply=AAAInMessage(AAA_CC_DPA, AAA_APP_DIAMETER_COMMON_MSG))==NULL) { + ERROR(M_NAME":handleRequest(): can't create new " + "DPA message!\n"); + return AAA_ERROR_MESSAGE; + } + + AAAMessageSetReply(reply); + + // always send success (causing retry of requests on + // different connection first, so race is unlikely) + if (addOrigin(reply) || addResultCodeAVP(reply, AAA_SUCCESS)) { + AAAFreeMessage(&reply); + return AAA_ERROR_MESSAGE; + } + + reply->endtoendId = req->endtoendId; + reply->hopbyhopId = req->hopbyhopId; + + if(AAABuildMsgBuffer(reply) != AAA_ERR_SUCCESS) { + ERROR( " sendRequest(): message buffer not created\n"); + AAAFreeMessage(&reply); + return AAA_ERROR_MESSAGE; + } + + int ret = tcp_send(conn.dia_conn, reply->buf.s, reply->buf.len); + if (ret) { + ERROR( " sendRequest(): could not send message\n"); + closeConnection(); + AAAFreeMessage(&reply); + return AAA_ERROR_COMM; + } + + AAAFreeMessage(&reply); + + setRetryConnectLater(); + + return 0; + }; break; default: { @@ -538,9 +608,15 @@ int res = tcp_recv_msg(conn.dia_conn, &conn.rb, 0, CONN_WAIT_USECS); + if (res < 0) { - ERROR( M_NAME "receive(): tcp_recv_reply() failed.\n"); - closeConnection(); + if (res == AAA_CONN_SHUTDOWN) { + INFO( M_NAME "receive(): shutdown - closing connection.\n"); + closeConnection(true); + } else { + closeConnection(); + ERROR( M_NAME "receive(): tcp_recv_reply() failed.\n"); + } return; } @@ -634,7 +710,7 @@ void ServerConnection::shutdownConnection() { gettimeofday(&connect_ts, NULL); connect_ts.tv_sec += RETRY_CONNECTION_SYSERROR; - closeConnection(); + closeConnection(true); req_map_mut.lock(); DBG("shutdown: posting timeout to %zd pending requests....\n", @@ -652,8 +728,8 @@ req_map_mut.unlock(); } -void ServerConnection::closeConnection() { +void ServerConnection::closeConnection(bool tls_shutdown) { if (open) - conn.terminate(); + conn.terminate(tls_shutdown); open = false; } Modified: trunk/apps/diameter_client/ServerConnection.h =================================================================== --- trunk/apps/diameter_client/ServerConnection.h 2009-01-09 09:55:37 UTC (rev 1224) +++ trunk/apps/diameter_client/ServerConnection.h 2009-01-19 17:11:43 UTC (rev 1225) @@ -1,16 +1,16 @@ /* * $Id$ * - * Copyright (C) 2007-2008 IPTEGO GmbH + * Copyright (C) 2007-2009 IPTEGO GmbH * - * This file is part of sems, a free SIP media server. + * This file is part of SEMS, a free SIP media server. * * sems is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version * - * For a license to use the ser software under conditions + * For a license to use the SEMS software under conditions * other than those described here, or to purchase support for this * software, please contact iptel.org by e-mail at the following addresses: * [email protected] @@ -20,10 +20,11 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #ifndef _DIAMETER_SERVER_CONNECTION_H #define _DIAMETER_SERVER_CONNECTION_H @@ -81,7 +82,7 @@ AAAMsgIdentifier h2h; AAAMsgIdentifier e2e; - void terminate(); + void terminate(bool tls_shutdown = false); void setIDs(AAAMessage* msg); @@ -125,7 +126,7 @@ AmMutex req_map_mut; void openConnection(); - void closeConnection(); + void closeConnection(bool tls_shutdown = false); int addOrigin(AAAMessage* msg); Modified: trunk/apps/diameter_client/lib_dbase/defs.h =================================================================== --- trunk/apps/diameter_client/lib_dbase/defs.h 2009-01-09 09:55:37 UTC (rev 1224) +++ trunk/apps/diameter_client/lib_dbase/defs.h 2009-01-19 17:11:43 UTC (rev 1225) @@ -22,9 +22,11 @@ #define AAA_NOT_AUTHORIZED 2 #define AAA_SRVERR 3 -#define AAA_ERROR -1 +#define AAA_ERROR -1 #define AAA_CONN_CLOSED -2 -#define AAA_TIMEOUT -3 +#define AAA_TIMEOUT -3 +#define AAA_CONN_SHUTDOWN -2 + #define AAA_USER_IN_GROUP 0 #define AAA_NO_CONNECTION -1 Modified: trunk/apps/diameter_client/lib_dbase/diameter_msg.c =================================================================== --- trunk/apps/diameter_client/lib_dbase/diameter_msg.c 2009-01-09 09:55:37 UTC (rev 1224) +++ trunk/apps/diameter_client/lib_dbase/diameter_msg.c 2009-01-19 17:11:43 UTC (rev 1225) @@ -4,6 +4,7 @@ * 2003-04-07 created by bogdan * * Copyright (C) 2002-2003 FhG Fokus + * Copyright (C) 2007-2009 IPTEGO GmbH * * This file is part of disc, a free diameter server/client. * Modified: trunk/apps/diameter_client/lib_dbase/diameter_msg.h =================================================================== --- trunk/apps/diameter_client/lib_dbase/diameter_msg.h 2009-01-09 09:55:37 UTC (rev 1224) +++ trunk/apps/diameter_client/lib_dbase/diameter_msg.h 2009-01-19 17:11:43 UTC (rev 1225) @@ -4,6 +4,7 @@ * 2003-04-07 created by bogdan * * Copyright (C) 2002-2003 FhG Fokus + * Copyright (C) 2007-2009 IPTEGO GmbH * * This file is part of disc, a free diameter server/client. * Modified: trunk/apps/diameter_client/lib_dbase/tcp_comm.c =================================================================== --- trunk/apps/diameter_client/lib_dbase/tcp_comm.c 2009-01-09 09:55:37 UTC (rev 1224) +++ trunk/apps/diameter_client/lib_dbase/tcp_comm.c 2009-01-19 17:11:43 UTC (rev 1225) @@ -4,7 +4,7 @@ * Digest Authentication - Diameter support * * Copyright (C) 2001-2003 FhG Fokus - * Copyright (C) 2007 iptego GmbH + * Copyright (C) 2007-2009 iptego GmbH * * This file is part of ser, a free SIP server. * @@ -195,9 +195,20 @@ meth=TLSv1_client_method(); conn_st->ctx = SSL_CTX_new(meth); + if (!conn_st->ctx) { + ERROR("SSL: creating TLSv1_client_method context\n"); + return 0; + } + + if (SSL_CTX_set_default_verify_paths(conn_st->ctx) != 1) { + ERROR("SSL: SSL_CTX_set_default_verify_paths\n"); + return 0; + } + if (!strlen(client_cert_file)) { DBG("no client certificate - not authenticating client.\n"); } else { + if (!SSL_CTX_use_certificate_chain_file(conn_st->ctx, client_cert_file)) { ERROR("using certificate from file '%s'\n", client_cert_file); @@ -249,6 +260,15 @@ return conn_st; } +void tcp_tls_shutdown(dia_tcp_conn* conn_st) { +#ifdef WITH_OPENSSL + if (conn_st->ctx && conn_st->ssl) { + SSL_shutdown(conn_st->ssl); + } +#endif +} + + void reset_read_buffer(rd_buf_t *rb) { rb->ret_code = 0; @@ -516,8 +536,8 @@ ERROR( M_NAME":tcp_reply_recv(): error when trying to read from socket\n"); return AAA_CONN_CLOSED; case CONN_CLOSED: - ERROR( M_NAME":tcp_reply_recv(): connection closed by diameter peer\n"); - return AAA_CONN_CLOSED; + INFO( M_NAME":tcp_reply_recv(): connection closed by diameter peer\n"); + return AAA_CONN_SHUTDOWN; } return 1; //received something } Modified: trunk/apps/diameter_client/lib_dbase/tcp_comm.h =================================================================== --- trunk/apps/diameter_client/lib_dbase/tcp_comm.h 2009-01-09 09:55:37 UTC (rev 1224) +++ trunk/apps/diameter_client/lib_dbase/tcp_comm.h 2009-01-19 17:11:43 UTC (rev 1225) @@ -4,7 +4,7 @@ * Digest Authentication - Diameter support * * Copyright (C) 2001-2003 FhG Fokus - * Copyright (C) 2008 iptego GmbH + * Copyright (C) 2008-2009 iptego GmbH * * This file is part of ser, a free SIP server. * @@ -54,6 +54,7 @@ #define CONN_ERROR -1 #define CONN_CLOSED -2 + #ifdef __cplusplus extern "C" { #endif @@ -92,6 +93,7 @@ void tcp_destroy_connection(dia_tcp_conn* conn_st); + void tcp_tls_shutdown(dia_tcp_conn* conn_st); #ifdef __cplusplus } #endif _______________________________________________ Semsdev mailing list [email protected] http://lists.iptel.org/mailman/listinfo/semsdev
