aboutsummaryrefslogtreecommitdiffstats
path: root/modules/eng_aep/aep_conn.cpp
blob: 9293f45fc9bd59077e63a9572c7e9da2402992d0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/*************************************************
* AEP Connection Management Source File          *
* (C) 1999-2006 The Botan Project                *
*************************************************/

#include <botan/aep_conn.h>
#include <botan/libstate.h>
#include <botan/parsing.h>
#include <botan/hw_aep.h>

namespace Botan {

/*************************************************
* Persistent connection pool                     *
*************************************************/
std::vector<AEP_Connection::Connection_Info> AEP_Connection::pool;
Mutex* AEP_Connection::guard = 0;

/*************************************************
* Close all currently open connections           *
*************************************************/
void AEP_Connection::close_all_connections()
   {
   guard->lock();
   for(u32bit j = 0; j != pool.size(); j++)
      AEP::AEP_CloseConnection(pool[j].id);
   pool.clear();
   guard->unlock();
   delete guard;
   guard = 0;
   }

/*************************************************
* Get a new connection handle                    *
*************************************************/
AEP_Connection::AEP_Connection()
   {
   // FIXME: race condition
   if(!guard)
      guard = global_state().get_mutex();

   Mutex_Holder lock(guard);

   this_connection = 0;

   for(u32bit j = 0; j != pool.size(); j++)
      {
      if(pool[j].in_use)
         continue;

      pool[j].in_use = true;
      this_connection = pool[j].id;
      }

   if(this_connection == 0)
      {
      Connection_Info new_conn;

      u32bit retval = AEP::AEP_OpenConnection(&new_conn.id);
      if(retval != 0)
         throw Stream_IO_Error("AEP_OpenConnection failed");
      new_conn.in_use = true;

      if(pool.size() < MAX_CACHED_CONNECTIONS)
         pool.push_back(new_conn);

      this_connection = new_conn.id;
      }
   }

/*************************************************
* Free a connection handle                       *
*************************************************/
AEP_Connection::~AEP_Connection()
   {
   Mutex_Holder lock(guard);

   for(u32bit j = 0; j != pool.size(); j++)
      {
      if(pool[j].id != this_connection)
         continue;

      pool[j].in_use = false;
      return;
      }

   int retval = AEP::AEP_CloseConnection(this_connection);
   if(retval != 0)
      throw Exception("AEP_CloseConnection returned " + to_string(retval));
   }

}