1 #include <SecureObjectSync/SOSPeer.h>
2 #include <SecureObjectSync/SOSPeerCoder.h>
3 #include <SecureObjectSync/SOSTransportMessage.h>
4 #include <SecureObjectSync/SOSCoder.h>
5 #include <SecureObjectSync/SOSAccount.h>
6 #include <SecureObjectSync/SOSEngine.h>
8 #include <utilities/debugging.h>
9 #include <utilities/SecCFWrappers.h>
11 #include <AssertMacros.h>
12 #include "SOSInternal.h"
14 static CFStringRef kSOSPeerCoderKey
= CFSTR("coder");
16 bool SOSPeerCoderInitializeForPeer(SOSTransportMessageRef transport
, SOSFullPeerInfoRef myPeerInfo
, SOSPeerInfoRef peerInfo
, CFErrorRef
*error
){
17 CFErrorRef coderError
= NULL
;
19 CFStringRef peer_id
= SOSPeerInfoGetPeerID(peerInfo
);
20 SOSCoderRef coder
= NULL
;
21 CFDataRef coderData
= NULL
;
22 bool haveGoodCoder
= false;
23 CFMutableDictionaryRef peerState
= SOSEngineGetPeerState(SOSTransportMessageGetEngine(transport
), peer_id
);
26 coderData
= CFDictionaryGetValue(peerState
, kSOSPeerCoderKey
);
28 coder
= SOSCoderCreateFromData(coderData
, &coderError
);
30 secerror("Found data but couldn't make coder for %@: %@", peer_id
, coderError
);
32 haveGoodCoder
= coder
;
33 SOSCoderDispose(coder
);
39 secnotice("peer", "New coder for id %@.", peer_id
);
41 coder
= SOSCoderCreate(peerInfo
, myPeerInfo
, error
);
43 coderData
= SOSCoderCopyDER(coder
, error
);
45 if(!(haveGoodCoder
= SOSEngineSetCoderData(SOSTransportMessageGetEngine(transport
), peer_id
, coderData
, error
))){
46 secerror("SOSPeerCoderInitializeForPeer, Could not save coder data");
49 CFReleaseNull(coderData
);
50 SOSCoderDispose(coder
);
52 secerror("Couldn't make coder for %@", peer_id
);
55 CFReleaseNull(coderError
);
59 void SOSPeerCoderConsume(SOSEnginePeerMessageSentBlock
*sent
, bool ok
){
64 enum SOSCoderUnwrapStatus
SOSPeerHandleCoderMessage(SOSPeerRef peer
, CFStringRef peer_id
, CFDataRef codedMessage
, CFDataRef
*decodedMessage
, CFErrorRef
*error
){
66 enum SOSCoderUnwrapStatus result
= SOSCoderUnwrapError
;
67 CFMutableDataRef localDecodedMessage
= NULL
;
69 SOSCoderStatus coderStatus
= kSOSCoderDataReturned
;
70 CFDataRef coderData
= SOSEngineGetCoderData(SOSPeerGetEngine(peer
), SOSPeerGetID(peer
));
71 require_quiet(coderData
, fail
);
72 SOSCoderRef coder
= SOSCoderCreateFromData(coderData
, error
);
74 CFErrorRef localError
= NULL
;
76 coderStatus
= SOSCoderUnwrap(coder
, codedMessage
, &localDecodedMessage
, peer_id
, error
);
79 case kSOSCoderDataReturned
: {
80 logRawMessage(localDecodedMessage
, false, 0);
81 result
= SOSCoderUnwrapDecoded
;
84 case kSOSCoderNegotiating
: // Sent message already in Unwrap.
85 result
= SOSCoderUnwrapHandled
;
86 secnotice("engine", "%@ engine negotiating", peer_id
);
88 case kSOSCoderNegotiationCompleted
:
89 if(SOSEnginePeerDidConnect(SOSPeerGetEngine(peer
), peer_id
, error
))
90 result
= SOSCoderUnwrapHandled
;
91 secnotice("engine", "%@ engine negotiation complete", peer_id
);
93 case kSOSCoderFailure
: // Probably restart coder
94 secnotice("engine", "%@ engine failed handling message %@", peer_id
, error
? *error
: NULL
);
96 if(SOSCoderStart(coder
, &localError
) == kSOSCoderFailure
){
97 secerror("Attempt to recover coder failed to restart: %@", localError
);
100 case kSOSCoderStaleEvent
: // We received an event we have already processed in the past.
101 secnotice("engine", "%@ engine stale event ignored", peer_id
);
108 *decodedMessage
= CFRetainSafe(localDecodedMessage
);
109 CFReleaseNull(localDecodedMessage
);
111 coderData
= SOSCoderCopyDER(coder
, error
);
112 if(!SOSEngineSetCoderData(SOSPeerGetEngine(peer
), peer_id
, coderData
, error
)){
113 secerror("SOSTransportMessageSendMessageIfNeeded, Could not save peer state");
115 CFReleaseNull(coderData
);
116 SOSCoderDispose(coder
);
119 CFReleaseNull(localError
);
125 bool SOSPeerCoderSendMessageIfNeeded(SOSPeerRef peer
, CFDataRef
*message_to_send
, CFStringRef circle_id
, CFStringRef peer_id
, SOSEnginePeerMessageSentBlock
*sent
, CFErrorRef
*error
){
126 SOSCoderRef coder
= SOSPeerGetCoder(peer
);
129 require_quiet(coder
, fail
);
131 if (SOSCoderCanWrap(coder
)) {
132 secnotice("transport", "%@ Coder can wrap, getting message from engine", peer_id
);
133 CFMutableDataRef codedMessage
= NULL
;
134 CFDataRef message
= SOSEngineCreateMessageToSyncToPeer(SOSPeerGetEngine(peer
), peer_id
, sent
, error
);
136 secnotice("transport", "%@ SOSEngineCreateMessageToSyncToPeer failed: %@",peer_id
, *error
);
138 ok
= message
&& (SOSCoderWrap(coder
, message
, &codedMessage
, peer_id
, error
) == kSOSCoderDataReturned
);
140 secnotice("transport", "%@ SOSCoderWrap failed: %@",peer_id
, *error
);
144 CFRetainAssign(*message_to_send
, codedMessage
);
146 CFReleaseNull(codedMessage
);
147 CFReleaseNull(message
);
149 *message_to_send
= SOSCoderCopyPendingResponse(coder
);
150 secnotice("transport", "%@ Negotiating, %@", peer_id
, message_to_send
? CFSTR("Sending negotiation message.") : CFSTR("waiting for negotiation message."));
151 *sent
= Block_copy(^(bool wasSent
){
153 SOSCoderConsumeResponse(coder
);