6 #include <architecture/byte_order.h>
7 #include <security_cdsa_utilities/cssmdb.h>
8 #include "SharedMemoryClient.h"
10 #include <security_utilities/crc.h>
12 static const char* kPrefix
= "/var/db/mds/messages/se_";
14 using namespace Security
;
16 SharedMemoryClient::SharedMemoryClient (const char* segmentName
, SegmentOffsetType segmentSize
)
18 StLock
<Mutex
> _(mMutex
);
20 mSegmentName
= segmentName
;
21 mSegmentSize
= segmentSize
;
22 mSegment
= mDataArea
= mDataPtr
= 0;
25 int segmentDescriptor
;
27 std::string
name (kPrefix
);
30 // make a connection to the shared memory block
31 segmentDescriptor
= open (name
.c_str (), O_RDONLY
, S_IROTH
);
32 if (segmentDescriptor
< 0) // error on opening the shared memory segment?
34 // CssmError::throwMe (CSSM_ERRCODE_INTERNAL_ERROR);
39 // map the segment into place
40 mSegment
= (u_int8_t
*) mmap (NULL
, segmentSize
, PROT_READ
, MAP_SHARED
, segmentDescriptor
, 0);
41 close (segmentDescriptor
);
43 if (mSegment
== MAP_FAILED
)
48 mDataArea
= mSegment
+ sizeof (SegmentOffsetType
);
49 mDataMax
= mSegment
+ segmentSize
;
50 mDataPtr
= mDataArea
+ GetProducerCount ();
55 SharedMemoryClient::~SharedMemoryClient ()
57 StLock
<Mutex
> _(mMutex
);
58 if (mSegment
== NULL
|| mSegment
== MAP_FAILED
) // error on opening the shared memory segment?
60 CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR
);
62 munmap (mSegment
, mSegmentSize
);
67 SegmentOffsetType
SharedMemoryClient::GetProducerCount ()
69 if (mSegment
== NULL
|| mSegment
== MAP_FAILED
) // error on opening the shared memory segment?
71 CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR
);
73 return OSSwapBigToHostInt32 (*(u_int32_t
*) mSegment
);
78 const char* SharedMemoryClient::GetSegmentName ()
80 return mSegmentName
.c_str ();
85 size_t SharedMemoryClient::GetSegmentSize ()
92 void SharedMemoryClient::ReadData (void* buffer
, SegmentOffsetType length
)
94 if (mSegment
== NULL
|| mSegment
== MAP_FAILED
) // error on opening the shared memory segment?
96 CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR
);
99 u_int8_t
* bptr
= (u_int8_t
*) buffer
;
101 SegmentOffsetType bytesToEnd
= (SegmentOffsetType
)(mDataMax
- mDataPtr
);
103 // figure out how many bytes we can read
104 SegmentOffsetType bytesToRead
= (length
<= bytesToEnd
) ? length
: bytesToEnd
;
106 // move the first part of the data
107 memcpy (bptr
, mDataPtr
, bytesToRead
);
110 // see if we have anything else to read
111 mDataPtr
+= bytesToRead
;
113 length
-= bytesToRead
;
116 mDataPtr
= mDataArea
;
117 memcpy(bptr
, mDataPtr
, length
);
124 SegmentOffsetType
SharedMemoryClient::ReadOffset()
126 SegmentOffsetType offset
;
127 ReadData(&offset
, sizeof(SegmentOffsetType
));
128 offset
= OSSwapBigToHostInt32 (offset
);
134 bool SharedMemoryClient::ReadMessage (void* message
, SegmentOffsetType
&length
, UnavailableReason
&ur
)
136 StLock
<Mutex
> _(mMutex
);
138 if (mSegment
== NULL
|| mSegment
== MAP_FAILED
) // error on opening the shared memory segment?
140 CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR
);
145 size_t offset
= mDataPtr
- mDataArea
;
146 if (offset
== GetProducerCount())
152 // get the length of the message in the buffer
153 length
= ReadOffset();
155 // we have the possibility that data is correct, figure out where the data is actually located
156 // get the length of the message stored there
157 if (length
== 0 || length
>= kPoolAvailableForData
)
165 ur
= kURBufferCorrupt
;
168 // something's gone wrong, reset.
169 mDataPtr
= mDataArea
+ GetProducerCount ();
174 SegmentOffsetType crc
= ReadOffset();
176 // read the data into the buffer
177 ReadData (message
, length
);
180 SegmentOffsetType crc2
= CalculateCRC((u_int8_t
*) message
, length
);
183 ur
= kURBufferCorrupt
;
184 mDataPtr
= mDataArea
+ GetProducerCount ();