reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
RegSyncClient.cxx
Go to the documentation of this file.
1#include "rutil/ResipAssert.h"
2#include <sstream>
3
7#include <rutil/Data.hxx>
8#include <rutil/DnsUtil.hxx>
9#include <rutil/Logger.hxx>
10#include <rutil/ParseBuffer.hxx>
11#include <rutil/Socket.hxx>
13#include <rutil/Timer.hxx>
14
17
18using namespace repro;
19using namespace resip;
20using namespace std;
21
22#define RESIPROCATE_SUBSYSTEM Subsystem::REPRO
23
25 Data address,
26 unsigned short port,
27 InMemorySyncPubDb* pubDb) :
28 mRegDb(regDb),
29 mPubDb(pubDb),
30 mAddress(address),
31 mPort(port),
32 mSocketDesc(0)
33{
34 resip_assert(mRegDb);
35}
36
37void
38RegSyncClient::delaySeconds(unsigned int seconds)
39{
40 // Delay for requested number of seconds - but check every second if we are shutdown or not
41 for(unsigned int i = 0; i < seconds && !mShutdown; i++)
42 {
43 sleepMs(1000);
44 }
45}
46
47void
49{
51 if(mSocketDesc)
52 {
53#ifdef WIN32
54 closesocket(mSocketDesc);
55 mSocketDesc = 0;
56#else
57 ::shutdown(mSocketDesc, SHUT_RDWR);
58#endif
59 }
60}
61
62void
64{
65 int rc;
66
67 addrinfo* results;
68 addrinfo hint;
69 memset(&hint, 0, sizeof(hint));
70 hint.ai_family = AF_UNSPEC;
71 hint.ai_flags = AI_PASSIVE;
72 hint.ai_socktype = SOCK_STREAM;
73
74 rc = getaddrinfo(mAddress.c_str(), 0, &hint, &results);
75 if(rc != 0)
76 {
77 ErrLog(<< "RegSyncClient: unknown host " << mAddress);
78 return;
79 }
80
81 // Use first address resolved if there are more than one.
82 Tuple servAddr(*results->ai_addr, TCP);
83 servAddr.setPort(mPort);
84 Tuple localAddr(Data::Empty /* all interfaces */, 0, servAddr.ipVersion(), TCP);
85 //InfoLog(<< "**********" << servAddr << " " << localAddr << " " << localAddr.isAnyInterface());
86
87 freeaddrinfo(results);
88
89 while(!mShutdown)
90 {
91 // Create TCP Socket
92 mSocketDesc = (int)socket(servAddr.ipVersion() == V6 ? PF_INET6 : PF_INET , SOCK_STREAM, 0);
93 if(mSocketDesc < 0)
94 {
95 int e = getErrno();
96 ErrLog(<< "RegSyncClient: cannot open socket, err=" << e);
97 mSocketDesc = 0;
98 return;
99 }
100
101 // bind to any local interface/port
102 rc = ::bind(mSocketDesc, &localAddr.getMutableSockaddr(), localAddr.length());
103 if(rc < 0)
104 {
105 int e = getErrno();
106 ErrLog(<<"RegSyncClient: error binding locally, err=" << e);
107 closeSocket(mSocketDesc);
108 mSocketDesc = 0;
109 return;
110 }
111
112 // Connect to server
113 rc = ::connect(mSocketDesc, &servAddr.getMutableSockaddr(), servAddr.length());
114 if(rc < 0)
115 {
116 int e = getErrno();
117 if(!mShutdown) ErrLog(<< "RegSyncClient: error connecting to " << mAddress << ":" << mPort << ", err=" << e);
118 closeSocket(mSocketDesc);
119 mSocketDesc = 0;
120 delaySeconds(30);
121 continue;
122 }
123
124 Data request(
125 "<InitialSync>\r\n"
126 " <Request>\r\n"
127 " <Version>" + Data(REGSYNC_VERSION) + "</Version>\r\n" // For use in detecting if client/server are a compatible version
128 " </Request>\r\n"
129 "</InitialSync>\r\n");
130 rc = ::send(mSocketDesc, request.c_str(), (int)request.size(), 0);
131 if(rc < 0)
132 {
133 int e = getErrno();
134 if(!mShutdown) ErrLog(<< "RegSyncClient: error sending, err=" << e);
135 closeSocket(mSocketDesc);
136 mSocketDesc = 0;
137 continue;
138 }
139
140 // Make socket non blocking
141 bool ok = makeSocketNonBlocking(mSocketDesc);
142 if (!ok)
143 {
144 int e = getErrno();
145 ErrLog(<< "RegSyncClient: Could not make HTTP socket non-blocking, err=" << e);
146 closeSocket(mSocketDesc);
147 mSocketDesc = 0;
148 continue;
149 }
150
151 while(rc > 0)
152 {
153 FdSet fdset;
154 fdset.setRead(mSocketDesc);
155 fdset.setExcept(mSocketDesc);
156 timeval tm;
157 tm.tv_sec = 30; // TODO - make a setting?
158 tm.tv_usec = 0;
159 rc = fdset.select(tm);
160 if(rc > 0)
161 {
162 rc = ::recv(mSocketDesc, (char*)&mRxBuffer, sizeof(mRxBuffer), 0);
163 if(rc < 0)
164 {
165 int e = getErrno();
166 if(!mShutdown) ErrLog(<< "RegSyncClient: error receiving, err=" << e);
167 closeSocket(mSocketDesc);
168 mSocketDesc = 0;
169 break;
170 }
171
172 if(rc > 0)
173 {
174 mRxDataBuffer += Data(Data::Borrow, (const char*)&mRxBuffer, rc);
175 while(tryParse());
176 }
177 }
178 else if(rc == 0) // timeout - send keepalive
179 {
180 rc = ::send(mSocketDesc, Symbols::CRLFCRLF, (int)request.size(), 0);
181 if(rc < 0)
182 {
183 int e = getErrno();
184 // If send is blocking then we must have pending send data - so just ignore error - no need to keepalive
185 if ( e != EAGAIN && e != EWOULDBLOCK ) // Treat EGAIN and EWOULDBLOCK as the same: http://stackoverflow.com/questions/7003234/which-systems-define-eagain-and-ewouldblock-as-different-values
186 {
187 if(!mShutdown) ErrLog(<< "RegSyncClient: error sending keepalive, err=" << e);
188 closeSocket(mSocketDesc);
189 mSocketDesc = 0;
190 continue;
191 }
192 }
193 //else
194 //{
195 // InfoLog( << "RegSyncClient: keepalive sent!");
196 //}
197 }
198 else
199 {
200 int e = getErrno();
201 if(!mShutdown) ErrLog(<< "RegSyncClient: error calling select, err=" << e);
202 closeSocket(mSocketDesc);
203 mSocketDesc = 0;
204 break;
205 }
206 }
207 } // end while
208
209 if(mSocketDesc) closeSocket(mSocketDesc);
210}
211
212bool
213RegSyncClient::tryParse()
214{
215 ParseBuffer pb(mRxDataBuffer);
216 Data initialTag;
217 const char* start = pb.position();
218 pb.skipWhitespace();
219 pb.skipToChar('<');
220 if(!pb.eof())
221 {
222 pb.skipChar();
223 const char* anchor = pb.position();
224 pb.skipToChar('>');
225 if(!pb.eof())
226 {
227 initialTag = pb.data(anchor);
228 // Find end of initial tag
229 pb.skipToChars("</" + initialTag + ">");
230 if (!pb.eof())
231 {
232 pb.skipN(initialTag.size() + 3); // Skip past </InitialTag>
233 handleXml(pb.data(start));
234
235 // Remove processed data from RxBuffer
236 pb.skipWhitespace();
237 if(!pb.eof())
238 {
239 anchor = pb.position();
240 pb.skipToEnd();
241 mRxDataBuffer = pb.data(anchor);
242 return true;
243 }
244 else
245 {
246 mRxDataBuffer.clear();
247 }
248 }
249 }
250 }
251 return false;
252}
253
254void
255RegSyncClient::handleXml(const Data& xmlData)
256{
257 //InfoLog(<< "RegSyncClient::handleXml received: " << xmlData);
258
259 try
260 {
261 ParseBuffer pb(xmlData);
262 XMLCursor xml(pb);
263
264 if(isEqualNoCase(xml.getTag(), "InitialSync"))
265 {
266 // Must be an InitialSync response
267 InfoLog(<< "RegSyncClient::handleXml: InitialSync complete.");
268 }
269 else if(isEqualNoCase(xml.getTag(), "reginfo"))
270 {
271 try
272 {
273 handleRegInfoEvent(xml);
274 }
275 catch(BaseException& e)
276 {
277 ErrLog(<< "RegSyncClient::handleXml: exception: " << e);
278 }
279 }
280 else if (isEqualNoCase(xml.getTag(), "pubinfo"))
281 {
282 try
283 {
284 handlePubInfoEvent(xml);
285 }
286 catch (BaseException& e)
287 {
288 ErrLog(<< "RegSyncClient::handleXml: exception: " << e);
289 }
290 }
291 else
292 {
293 WarningLog(<< "RegSyncClient::handleXml: Ignoring XML message with unknown method: " << xml.getTag());
294 }
295 }
296 catch(resip::BaseException& e)
297 {
298 WarningLog(<< "RegSyncClient::handleXml: Ignoring XML message due to ParseException: " << e);
299 }
300}
301
302void
303RegSyncClient::handleRegInfoEvent(resip::XMLCursor& xml)
304{
306 Uri aor;
307 ContactList contacts;
308 DebugLog(<< "RegSyncClient::handleRegInfoEvent");
309 if(xml.firstChild())
310 {
311 do
312 {
313 if(isEqualNoCase(xml.getTag(), "aor"))
314 {
315 if(xml.firstChild())
316 {
317 aor = Uri(xml.getValue().xmlCharDataDecode());
318 xml.parent();
319 }
320 //InfoLog(<< "RegSyncClient::handleRegInfoEvent: aor=" << aor);
321 }
322 else if(isEqualNoCase(xml.getTag(), "contactinfo"))
323 {
324 if(xml.firstChild())
325 {
327 do
328 {
329 if(isEqualNoCase(xml.getTag(), "contacturi"))
330 {
331 if(xml.firstChild())
332 {
333 //InfoLog(<< "RegSyncClient::handleRegInfoEvent: contacturi=" << xml.getValue());
335 xml.parent();
336 }
337 }
338 else if(isEqualNoCase(xml.getTag(), "expires"))
339 {
340 if(xml.firstChild())
341 {
342 //InfoLog(<< "RegSyncClient::handleRegInfoEvent: expires=" << xml.getValue());
343 uint64_t expires = xml.getValue().convertUInt64();
344 rec.mRegExpires = (expires == 0 ? 0 : now+expires);
345 xml.parent();
346 }
347 }
348 else if(isEqualNoCase(xml.getTag(), "lastupdate"))
349 {
350 if(xml.firstChild())
351 {
352 //InfoLog(<< "RegSyncClient::handleRegInfoEvent: lastupdate=" << xml.getValue());
353 rec.mLastUpdated = now-xml.getValue().convertUInt64();
354 xml.parent();
355 }
356 }
357 else if(isEqualNoCase(xml.getTag(), "receivedfrom"))
358 {
359 if(xml.firstChild())
360 {
362 //InfoLog(<< "RegSyncClient::handleRegInfoEvent: receivedfrom=" << xml.getValue() << " tuple=" << rec.mReceivedFrom);
363 xml.parent();
364 }
365 }
366 else if(isEqualNoCase(xml.getTag(), "publicaddress"))
367 {
368 if(xml.firstChild())
369 {
371 //InfoLog(<< "RegSyncClient::handleRegInfoEvent: publicaddress=" << xml.getValue() << " tuple=" << rec.mPublicAddress);
372 xml.parent();
373 }
374 }
375 else if(isEqualNoCase(xml.getTag(), "sippath"))
376 {
377 if(xml.firstChild())
378 {
379 //InfoLog(<< "RegSyncClient::handleRegInfoEvent: sippath=" << xml.getValue());
381 xml.parent();
382 }
383 }
384 else if(isEqualNoCase(xml.getTag(), "instance"))
385 {
386 if(xml.firstChild())
387 {
388 //InfoLog(<< "RegSyncClient::handleRegInfoEvent: instance=" << xml.getValue());
390 xml.parent();
391 }
392 }
393 else if(isEqualNoCase(xml.getTag(), "regid"))
394 {
395 if(xml.firstChild())
396 {
397 //InfoLog(<< "RegSyncClient::handleRegInfoEvent: regid=" << xml.getValue());
398 rec.mRegId = xml.getValue().convertUnsignedLong();
399 xml.parent();
400 }
401 }
402 else if (isEqualNoCase(xml.getTag(), "useragent"))
403 {
404 if (xml.firstChild())
405 {
406 //InfoLog(<< "RegSyncClient::handleRegInfoEvent: useragent=" << xml.getValue());
408 xml.parent();
409 }
410 }
411 } while(xml.nextSibling());
412 xml.parent();
413
414 // Add record to list
415 rec.mSyncContact = true; // This ContactInstanceRecord came from registration sync process
416 contacts.push_back(rec);
417 }
418 }
419 } while(xml.nextSibling());
420 xml.parent();
421 }
422 xml.parent();
423
424 if (mRegDb)
425 {
426 processModify(aor, contacts);
427 }
428}
429
430void
431RegSyncClient::processModify(const resip::Uri& aor, ContactList& syncContacts)
432{
433 ContactList currentContacts;
434
435 mRegDb->lockRecord(aor);
436 mRegDb->getContacts(aor, currentContacts);
437
438 InfoLog(<< "RegSyncClient::processModify: for aor=" << aor <<
439 ", numSyncContacts=" << syncContacts.size() <<
440 ", numCurrentContacts=" << currentContacts.size());
441
442 // Iteratate through new syncContact List
443 ContactList::iterator itSync = syncContacts.begin();
444 ContactList::iterator itCurrent;
445 bool found;
446 for(; itSync != syncContacts.end(); itSync++)
447 {
448 InfoLog(<< " RegSyncClient::processModify: contact=" << itSync->mContact << ", instance=" << itSync->mInstance << ", regid=" << itSync->mRegId);
449
450 // See if contact already exists in currentContacts
451 found = false;
452 for(itCurrent = currentContacts.begin(); itCurrent != currentContacts.end(); itCurrent++)
453 {
454 if(*itSync == *itCurrent)
455 {
456 found = true;
457 // We found a match - check if sycnContacts LastUpdated time is newer
458 if(itSync->mLastUpdated > itCurrent->mLastUpdated)
459 {
460 // Replace current contact with Sync contact
461 mRegDb->updateContact(aor, *itSync);
462 }
463 }
464 }
465 if(!found)
466 {
467 mRegDb->updateContact(aor, *itSync);
468 }
469 }
470 mRegDb->unlockRecord(aor);
471}
472
473void
474RegSyncClient::handlePubInfoEvent(resip::XMLCursor& xml)
475{
478 DebugLog(<< "RegSyncClient::handlePubInfoEvent");
479 if (xml.firstChild())
480 {
481 do
482 {
483 if (isEqualNoCase(xml.getTag(), "eventtype"))
484 {
485 if (xml.firstChild())
486 {
487 document.mEventType = xml.getValue();
488 xml.parent();
489 }
490 }
491 else if (isEqualNoCase(xml.getTag(), "documentkey"))
492 {
493 if (xml.firstChild())
494 {
495 document.mDocumentKey = xml.getValue().xmlCharDataDecode();
496 xml.parent();
497 }
498 }
499 else if (isEqualNoCase(xml.getTag(), "etag"))
500 {
501 if (xml.firstChild())
502 {
503 document.mETag = xml.getValue().xmlCharDataDecode();
504 xml.parent();
505 }
506 }
507 else if (isEqualNoCase(xml.getTag(), "expires"))
508 {
509 if (xml.firstChild())
510 {
511 uint64_t expires = xml.getValue().convertUInt64();
512 document.mExpirationTime = (expires == 0 ? 0 : now + expires);
513 document.mLingerTime = document.mExpirationTime;
514 xml.parent();
515 }
516 }
517 else if (isEqualNoCase(xml.getTag(), "lastUpdate"))
518 {
519 if (xml.firstChild())
520 {
521 document.mLastUpdated = now - xml.getValue().convertUInt64();
522 xml.parent();
523 }
524 }
525 else if (isEqualNoCase(xml.getTag(), "contents"))
526 {
527 if (xml.firstChild())
528 {
529 Data contentsData = xml.getValue().xmlCharDataDecode();
530 HeaderFieldValue hfv(contentsData.data(), contentsData.size());
532 document.mContents.reset((Contents*)new GenericPidfContents(pidf)); // ensure we copy other pidf - since it shares data with contentsData
533 xml.parent();
534 }
535 }
536 else if (isEqualNoCase(xml.getTag(), "isencrypted"))
537 {
538 if (xml.firstChild())
539 {
540 if (document.mSecurityAttributes.get() == 0)
541 {
542 document.mSecurityAttributes.reset(new SecurityAttributes);
543 }
544 if (isEqualNoCase(xml.getValue(), "true"))
545 {
546 document.mSecurityAttributes->setEncrypted();
547 }
548 xml.parent();
549 }
550 }
551 else if (isEqualNoCase(xml.getTag(), "sigstatus"))
552 {
553 if (xml.firstChild())
554 {
555 if (document.mSecurityAttributes.get() == 0)
556 {
557 document.mSecurityAttributes.reset(new SecurityAttributes);
558 }
559 if (isEqualNoCase(xml.getValue(), "none"))
560 {
561 document.mSecurityAttributes->setSignatureStatus(SignatureNone);
562 }
563 else if (isEqualNoCase(xml.getValue(), "bad"))
564 {
565 document.mSecurityAttributes->setSignatureStatus(SignatureIsBad);
566 }
567 else if (isEqualNoCase(xml.getValue(), "trusted"))
568 {
569 document.mSecurityAttributes->setSignatureStatus(SignatureTrusted);
570 }
571 else if (isEqualNoCase(xml.getValue(), "catrusted"))
572 {
573 document.mSecurityAttributes->setSignatureStatus(SignatureCATrusted);
574 }
575 else if (isEqualNoCase(xml.getValue(), "nottrusted"))
576 {
577 document.mSecurityAttributes->setSignatureStatus(SignatureNotTrusted);
578 }
579 else if (isEqualNoCase(xml.getValue(), "selfsigned"))
580 {
581 document.mSecurityAttributes->setSignatureStatus(SignatureSelfSigned);
582 }
583 xml.parent();
584 }
585 }
586 else if (isEqualNoCase(xml.getTag(), "signer"))
587 {
588 if (xml.firstChild())
589 {
590 if (document.mSecurityAttributes.get() == 0)
591 {
592 document.mSecurityAttributes.reset(new SecurityAttributes);
593 }
594 document.mSecurityAttributes->setSigner(xml.getValue().xmlCharDataDecode());
595 xml.parent();
596 }
597 }
598 else if (isEqualNoCase(xml.getTag(), "identity"))
599 {
600 if (xml.firstChild())
601 {
602 if (document.mSecurityAttributes.get() == 0)
603 {
604 document.mSecurityAttributes.reset(new SecurityAttributes);
605 }
606 document.mSecurityAttributes->setIdentity(xml.getValue().xmlCharDataDecode());
607 xml.parent();
608 }
609 }
610 else if (isEqualNoCase(xml.getTag(), "identitystrength"))
611 {
612 if (xml.firstChild())
613 {
614 if (document.mSecurityAttributes.get() == 0)
615 {
616 document.mSecurityAttributes.reset(new SecurityAttributes);
617 }
618 if (isEqualNoCase(xml.getValue(), "from"))
619 {
620 document.mSecurityAttributes->setIdentityStrength(SecurityAttributes::From);
621 }
622 else if (isEqualNoCase(xml.getValue(), "failedidentity"))
623 {
624 document.mSecurityAttributes->setIdentityStrength(SecurityAttributes::FailedIdentity);
625 }
626 else if (isEqualNoCase(xml.getValue(), "identity"))
627 {
628 document.mSecurityAttributes->setIdentityStrength(SecurityAttributes::Identity);
629 }
630 xml.parent();
631 }
632 }
633 } while (xml.nextSibling());
634 xml.parent();
635 }
636 xml.parent();
637
638 if (mPubDb)
639 {
640 if (document.mExpirationTime != 0)
641 {
642 document.mSyncPublication = true;
643 mPubDb->addUpdateDocument(document);
644 }
645 else
646 {
647 // Note: This never comes in an initial sync - only realtime updates
648 mPubDb->removeDocument(document.mEventType, document.mDocumentKey, document.mETag, document.mLastUpdated, true);
649 }
650 }
651}
652
653/* ====================================================================
654 * The Vovida Software License, Version 1.0
655 *
656 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
657 * Copyright (c) 2015 SIP Spectrum, Inc. All rights reserved.
658 *
659 * Redistribution and use in source and binary forms, with or without
660 * modification, are permitted provided that the following conditions
661 * are met:
662 *
663 * 1. Redistributions of source code must retain the above copyright
664 * notice, this list of conditions and the following disclaimer.
665 *
666 * 2. Redistributions in binary form must reproduce the above copyright
667 * notice, this list of conditions and the following disclaimer in
668 * the documentation and/or other materials provided with the
669 * distribution.
670 *
671 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
672 * and "Vovida Open Communication Application Library (VOCAL)" must
673 * not be used to endorse or promote products derived from this
674 * software without prior written permission. For written
675 * permission, please contact vocal@vovida.org.
676 *
677 * 4. Products derived from this software may not be called "VOCAL", nor
678 * may "VOCAL" appear in their name, without prior written
679 * permission of Vovida Networks, Inc.
680 *
681 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
682 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
683 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
684 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
685 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
686 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
687 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
688 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
689 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
690 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
691 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
692 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
693 * DAMAGE.
694 *
695 * ====================================================================
696 *
697 * This software consists of voluntary contributions made by Vovida
698 * Networks, Inc. and many individuals on behalf of Vovida Networks,
699 * Inc. For more information on Vovida Networks, Inc., please see
700 * <http://www.vovida.org/>.
701 *
702 */
703
#define DebugLog(args_)
Definition Logger.hxx:128
#define InfoLog(args_)
Definition Logger.hxx:131
#define WarningLog(args_)
Definition Logger.hxx:134
#define ErrLog(args_)
Definition Logger.hxx:137
#define REGSYNC_VERSION
#define resip_assert(x)
This file needs to work for both C and C++ code.
#define sleepMs(t)
Definition Server.hxx:16
Handles cross-platform sockets compatibility.
static int getErrno()
RegSyncClient(resip::InMemorySyncRegDb *regDb, resip::Data address, unsigned short port, resip::InMemorySyncPubDb *pubDb=0)
virtual void shutdown()
virtual void thread()
The abstract base-class for all exceptions thrown by resip code.
A single contact record, bound to an Aor during registration.
Base class for all SIP body types.
Definition Contents.hxx:51
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
Definition Data.hxx:90
Data xmlCharDataDecode() const
Performs in-place XML Character Data un-escaping of a Data.
Definition Data.cxx:1464
Data base64decode() const
Performs RFC 3548 Base 64 decoding of the contents of this data.
Definition Data.cxx:2607
static const Data Empty
Constant that represents a zero-length data.
Definition Data.hxx:882
const char * c_str() const
Returns a null-terminated string representing.
Definition Data.cxx:1097
@ Borrow
The Data instance is borrowing the memory from the passed in buffer.
Definition Data.hxx:260
unsigned long convertUnsignedLong() const
Definition Data.cxx:1724
uint64_t convertUInt64() const
Takes the contents of the Data and converts them to an unsigned 64-bit integer.
Definition Data.cxx:1758
size_type size() const noexcept
Returns the number of bytes in this Data.
Definition Data.hxx:599
Data & clear()
Clears the contents of this Data.
Definition Data.hxx:800
const char * data() const noexcept
Returns a pointer to the contents of this Data.
Definition Data.hxx:608
Object-oriented wrapper for your platform's file-descriptor set.
Definition Socket.hxx:162
void setRead(Socket fd)
Definition Socket.hxx:204
void setExcept(Socket fd)
Definition Socket.hxx:227
int select()
Definition Socket.hxx:171
SIP body type for holding PIDF contents (MIME content-type application/pidf+xml).
static const Mime & getStaticType()
Implementation of a persistence manager.
virtual void addUpdateDocument(const PubDocument &document)
virtual bool removeDocument(const Data &eventType, const Data &documentKey, const Data &eTag, uint64_t lastUpdated, bool syncPublication=false)
Implementation of a persistence manager.
virtual update_status_t updateContact(const resip::Uri &aor, const ContactInstanceRecord &rec)
virtual void unlockRecord(const Uri &aor)
virtual void getContacts(const Uri &aor, ContactList &container)
virtual void lockRecord(const Uri &aor)
Represents the "name-addr" and the "addr-spec" elements in the RFC 3261 grammar.
Definition NameAddr.hxx:19
Provides string-parsing functionality with protection from buffer overflow.
void push_back(const T &t)
Inserts a header field value at the back of this container.
static const char * CRLFCRLF
Definition Symbols.hxx:22
virtual void shutdown()
Definition ThreadIf.cxx:190
static uint64_t getTimeSecs()
Returns the current clock time in seconds.
Definition Timer.hxx:78
Represents a network address.
Definition Tuple.hxx:59
IpVersion ipVersion() const
Returns V4 or V6 as appropriate.
Definition Tuple.cxx:537
static Tuple makeTupleFromBinaryToken(const Data &binaryToken, const Data &salt=Data::Empty)
Definition Tuple.cxx:328
sockaddr & getMutableSockaddr()
Retrieve the binary representation of the socket address for this tuple.
Definition Tuple.hxx:113
void setPort(int port)
Definition Tuple.cxx:449
socklen_t length() const
Definition Tuple.cxx:655
Represents the "SIP-URI" and "SIPS-URI" elements in the RFC 3261 grammar.
Definition Uri.hxx:22
const Data & getValue() const
const Data & getTag() const
This Class is used to implement a primitive form of RPC using loose XML formatting.
dcm! – add UnusedChecking(_enum) below;
bool isEqualNoCase(const Data &left, const Data &right)
Definition Data.hxx:1116
int closeSocket(Socket fd)
Definition Socket.cxx:134
bool makeSocketNonBlocking(Socket fd)
Definition Socket.cxx:21
std::list< ContactInstanceRecord > ContactList
unsigned __int64 uint64_t
Definition stdint.h:95