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

Reply via email to