1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24  */
25 
26 /**
27  * \file KMSAgentDataUnitCache.cpp
28  */
29 
30 #include <stdio.h>
31 #include "SYSCommon.h"
32 #include "KMSClientProfile.h"
33 #include "KMSAgentDataUnitCache.h"
34 
CDataUnitCache(int i_iMaxSize)35 CDataUnitCache::CDataUnitCache(int i_iMaxSize)
36 {
37     m_iSize = 0;
38     m_iIndex = 0;
39     m_iMaxSize = i_iMaxSize;
40     m_pCache = 0;
41 
42     K_CreateMutex(&m_Lock);
43 }
44 
~CDataUnitCache()45 CDataUnitCache::~CDataUnitCache()
46 {
47     delete[] m_pCache;
48     K_DestroyMutex(m_Lock);
49 }
50 
Insert(const unsigned char * const i_pDataUnitID,int i_iDataUnitIDMaxLen,const unsigned char * const i_pDataUnitKeyID,int i_iDataUnitKeyIDMaxLen,const utf8char * const i_wsApplianceNetworkAddress)51 bool CDataUnitCache::Insert(
52                 const unsigned char* const i_pDataUnitID,
53                 int i_iDataUnitIDMaxLen,
54                 const unsigned char* const i_pDataUnitKeyID ,
55                 int i_iDataUnitKeyIDMaxLen,
56                 const utf8char* const i_wsApplianceNetworkAddress )
57 {
58     FATAL_ASSERT( (i_pDataUnitID && i_iDataUnitIDMaxLen == KMS_DATA_UNIT_ID_SIZE) ||
59                   (i_pDataUnitKeyID && i_iDataUnitKeyIDMaxLen == KMS_KEY_ID_SIZE));
60     FATAL_ASSERT( i_wsApplianceNetworkAddress &&
61                   strlen( i_wsApplianceNetworkAddress ) < KMS_MAX_NETWORK_ADDRESS );
62 
63     Lock();
64 
65     if ( m_pCache == 0 )
66     {
67         m_pCache = new DataUnitCacheEntry[m_iMaxSize];
68 
69         if ( !m_pCache )
70         {
71             // no error logged on out of memory
72             Unlock();
73 #if defined(DEBUG) && defined(METAWARE)
74             log_printf("CDataUnitCache::Insert new DataUnitCacheEntry alloc failure\n");
75 #endif
76             return false;
77         }
78     }
79 
80     if( m_iSize >= m_iMaxSize )
81     {
82         // the cache is full, so reuse an old slot
83 
84         m_iIndex  = (m_iIndex + 1) % m_iMaxSize;
85     }
86     else
87     {
88         m_iIndex = m_iSize;
89 
90         m_iSize++;
91     }
92 
93     strncpy( m_pCache[m_iIndex].m_wsApplianceNetworkAddress,
94              i_wsApplianceNetworkAddress,
95              sizeof(m_pCache[m_iIndex].m_wsApplianceNetworkAddress) );
96     m_pCache[m_iIndex].m_wsApplianceNetworkAddress[sizeof(m_pCache[m_iIndex].m_wsApplianceNetworkAddress)-1] = '\0';
97 
98     if ( i_pDataUnitID )
99     {
100         memcpy( m_pCache[m_iIndex].m_aDataUnitID,
101                 i_pDataUnitID,
102                 i_iDataUnitIDMaxLen );
103     }
104     else
105     {
106         memset( m_pCache[m_iIndex].m_aDataUnitID,0,KMS_DATA_UNIT_ID_SIZE);
107     }
108 
109     if ( i_pDataUnitKeyID )
110     {
111         memcpy( m_pCache[m_iIndex].m_aDataUnitKeyID,
112             i_pDataUnitKeyID,
113             i_iDataUnitKeyIDMaxLen );
114     }
115     else
116     {
117         memset(m_pCache[m_iIndex].m_aDataUnitKeyID,0,KMS_KEY_ID_SIZE);
118     }
119 
120     Unlock();
121 
122     return true;
123 }
124 
GetApplianceByDataUnitID(const unsigned char * const i_pDataUnitID,int i_iDataUnitIDMaxLen,utf8char * const o_wsApplianceNetworkAddress,int i_iMaxApplianceNetworkAddressLen)125 bool CDataUnitCache::GetApplianceByDataUnitID(
126                 const unsigned char* const i_pDataUnitID,
127                 int i_iDataUnitIDMaxLen,
128                 utf8char* const o_wsApplianceNetworkAddress,
129                 int i_iMaxApplianceNetworkAddressLen )
130 {
131     FATAL_ASSERT( i_pDataUnitID );
132     FATAL_ASSERT( i_iDataUnitIDMaxLen == KMS_DATA_UNIT_ID_SIZE );
133     FATAL_ASSERT( i_iMaxApplianceNetworkAddressLen <= KMS_MAX_NETWORK_ADDRESS );
134 
135     // assumes o_wsApplianceNetworkAddress points to at least KMS_MAX_NETWORK_ADDRESS
136 
137     Lock();
138 
139     int i;
140     for( i = 0; i < m_iSize; i++ )
141     {
142         if( memcmp(m_pCache[i].m_aDataUnitID, i_pDataUnitID, KMS_DATA_UNIT_ID_SIZE) == 0 )
143         {
144             strncpy( o_wsApplianceNetworkAddress,
145                 m_pCache[i].m_wsApplianceNetworkAddress,
146                 i_iMaxApplianceNetworkAddressLen );
147             o_wsApplianceNetworkAddress[i_iMaxApplianceNetworkAddressLen-1] = '\0';
148             Unlock();
149             return true;
150         }
151     }
152 
153     Unlock();
154 
155     return false;
156 }
157 
GetApplianceByDataUnitKeyID(const unsigned char * const i_pDataUnitKeyID,int i_iDataUnitKeyIDMaxLen,utf8char * const o_wsApplianceNetworkAddress,int i_iMaxApplianceNetworkAddressLen)158 bool CDataUnitCache::GetApplianceByDataUnitKeyID(
159                 const unsigned char* const i_pDataUnitKeyID,
160                 int i_iDataUnitKeyIDMaxLen,
161                 utf8char* const o_wsApplianceNetworkAddress,
162                 int i_iMaxApplianceNetworkAddressLen )
163 {
164     FATAL_ASSERT( i_pDataUnitKeyID );
165     FATAL_ASSERT( i_iDataUnitKeyIDMaxLen == KMS_KEY_ID_SIZE );
166     FATAL_ASSERT( i_iMaxApplianceNetworkAddressLen <= KMS_MAX_NETWORK_ADDRESS );
167 
168     // assumes o_wsApplianceNetworkAddress points to at least KMS_MAX_NETWORK_ADDRESS
169 
170     Lock();
171 
172     int i;
173     for( i = 0; i < m_iSize; i++ )
174     {
175         if( memcmp(m_pCache[i].m_aDataUnitKeyID,
176                 i_pDataUnitKeyID, KMS_KEY_ID_SIZE) == 0 )
177         {
178             strncpy( o_wsApplianceNetworkAddress,
179                 m_pCache[i].m_wsApplianceNetworkAddress,
180                 i_iMaxApplianceNetworkAddressLen );
181             o_wsApplianceNetworkAddress[i_iMaxApplianceNetworkAddressLen-1] = '\0';
182 
183             Unlock();
184 
185             return true;
186         }
187     }
188 
189     Unlock();
190 
191     return false;
192 }
193 
Lock()194 void CDataUnitCache::Lock()
195 {
196     K_LockMutex(m_Lock);
197 }
198 
Unlock()199 void CDataUnitCache::Unlock()
200 {
201     K_UnlockMutex(m_Lock);
202 }
203