From 0c4bf77a670aedb38b880d1b3770793eefb00131 Mon Sep 17 00:00:00 2001 From: Dmytro Bogovych Date: Mon, 27 Dec 2021 11:02:19 +0200 Subject: [PATCH] - start upgrade to resiprocate 1.12 --- src/libs/resiprocate/CMakeLists.txt | 8 +- src/libs/resiprocate/resip/.cvsignore | 19 - src/libs/resiprocate/resip/dum/AppDialog.cxx | 2 +- .../resiprocate/resip/dum/AppDialogSet.cxx | 2 +- .../resip/dum/AppDialogSetFactory.cxx | 2 +- .../resiprocate/resip/dum/BaseCreator.cxx | 30 +- .../resip/dum/BaseSubscription.cxx | 5 +- src/libs/resiprocate/resip/dum/BaseUsage.cxx | 5 + src/libs/resiprocate/resip/dum/BaseUsage.hxx | 8 +- .../resiprocate/resip/dum/ChallengeInfo.cxx | 4 +- .../resip/dum/ClientAuthExtension.cxx | 10 +- .../resip/dum/ClientAuthExtension.hxx | 4 +- .../resip/dum/ClientAuthManager.cxx | 93 +- .../resip/dum/ClientAuthManager.hxx | 14 +- .../resip/dum/ClientInviteSession.cxx | 303 +- .../resip/dum/ClientInviteSession.hxx | 13 +- .../resip/dum/ClientOutOfDialogReq.cxx | 2 +- .../resip/dum/ClientPagerMessage.cxx | 131 +- .../resip/dum/ClientPagerMessage.hxx | 20 +- .../resip/dum/ClientPublication.cxx | 100 +- .../resip/dum/ClientPublication.hxx | 2 + .../resip/dum/ClientRegistration.cxx | 203 +- .../resip/dum/ClientRegistration.hxx | 19 +- .../resip/dum/ClientSubscription.cxx | 227 +- .../resip/dum/ClientSubscription.hxx | 9 +- .../resip/dum/ContactInstanceRecord.cxx | 229 +- .../resip/dum/ContactInstanceRecord.hxx | 18 + .../resip/dum/DefaultServerReferHandler.hxx | 2 +- .../resiprocate/resip/dum/DestroyUsage.cxx | 2 +- src/libs/resiprocate/resip/dum/Dialog.cxx | 207 +- src/libs/resiprocate/resip/dum/Dialog.hxx | 6 +- .../resiprocate/resip/dum/DialogEventInfo.cxx | 10 +- .../resiprocate/resip/dum/DialogEventInfo.hxx | 10 +- .../resip/dum/DialogEventStateManager.cxx | 73 +- .../resip/dum/DialogEventStateManager.hxx | 1 + src/libs/resiprocate/resip/dum/DialogSet.cxx | 129 +- src/libs/resiprocate/resip/dum/DialogSet.hxx | 2 +- .../resiprocate/resip/dum/DialogSetId.cxx | 4 +- .../resiprocate/resip/dum/DialogUsage.cxx | 36 +- .../resiprocate/resip/dum/DialogUsage.hxx | 13 +- .../resip/dum/DialogUsageManager.cxx | 332 +- .../resip/dum/DialogUsageManager.hxx | 58 +- src/libs/resiprocate/resip/dum/DumCommand.hxx | 2 +- .../resiprocate/resip/dum/DumException.hxx | 2 +- src/libs/resiprocate/resip/dum/DumFeature.cxx | 4 +- src/libs/resiprocate/resip/dum/DumFeature.hxx | 2 +- .../resip/dum/DumFeatureMessage.cxx | 2 +- src/libs/resiprocate/resip/dum/DumHelper.cxx | 15 +- .../resip/dum/DumProcessHandler.cxx | 4 +- src/libs/resiprocate/resip/dum/DumThread.cxx | 4 +- src/libs/resiprocate/resip/dum/DumTimeout.cxx | 10 +- src/libs/resiprocate/resip/dum/DumTimeout.hxx | 2 + src/libs/resiprocate/resip/dum/Handle.hxx | 6 +- .../resiprocate/resip/dum/HandleManager.cxx | 56 +- .../resiprocate/resip/dum/HttpProvider.cxx | 6 +- .../resiprocate/resip/dum/HttpProvider.hxx | 4 +- .../resiprocate/resip/dum/IdentityHandler.cxx | 6 +- .../dum/InMemoryRegistrationDatabase.cxx | 4 +- .../dum/InMemoryRegistrationDatabase.hxx | 4 +- .../resip/dum/InMemorySyncPubDb.cxx | 437 + .../resip/dum/InMemorySyncPubDb.hxx | 119 + .../resip/dum/InMemorySyncRegDb.cxx | 103 +- .../resip/dum/InMemorySyncRegDb.hxx | 30 +- .../resiprocate/resip/dum/InviteSession.cxx | 502 +- .../resiprocate/resip/dum/InviteSession.hxx | 49 +- .../resip/dum/InviteSessionCreator.cxx | 11 +- .../resip/dum/InviteSessionHandler.cxx | 13 +- .../resip/dum/InviteSessionHandler.hxx | 7 +- .../resip/dum/KeepAliveManager.cxx | 11 +- src/libs/resiprocate/resip/dum/Makefile.am | 266 + src/libs/resiprocate/resip/dum/Makefile.in | 1430 +++ .../resiprocate/resip/dum/MasterProfile.cxx | 69 +- .../resiprocate/resip/dum/MasterProfile.hxx | 65 +- .../resiprocate/resip/dum/OutgoingEvent.hxx | 4 +- .../resip/dum/PagerMessageHandler.hxx | 2 +- src/libs/resiprocate/resip/dum/Profile.cxx | 52 +- src/libs/resiprocate/resip/dum/Profile.hxx | 12 +- .../resip/dum/PublicationHandler.hxx | 1 + .../dum/PublicationPersistenceManager.hxx | 408 + .../resip/dum/RADIUSServerAuthManager.cxx | 289 +- .../resip/dum/RADIUSServerAuthManager.hxx | 98 +- .../resiprocate/resip/dum/RedirectManager.cxx | 4 +- .../resip/dum/RegistrationHandler.cxx | 307 +- .../resip/dum/RegistrationHandler.hxx | 11 +- .../resip/dum/ServerAuthManager.cxx | 163 +- .../resip/dum/ServerAuthManager.hxx | 12 +- .../resip/dum/ServerInviteSession.cxx | 1322 ++- .../resip/dum/ServerInviteSession.hxx | 37 +- .../resip/dum/ServerOutOfDialogReq.cxx | 76 +- .../resip/dum/ServerPagerMessage.cxx | 44 +- .../resip/dum/ServerPublication.cxx | 58 +- .../resip/dum/ServerPublication.hxx | 2 +- .../resip/dum/ServerRegistration.cxx | 72 +- .../resip/dum/ServerRegistration.hxx | 20 +- .../resip/dum/ServerSubscription.cxx | 138 +- .../resip/dum/ServerSubscription.hxx | 11 +- .../resip/dum/SubscriptionHandler.cxx | 4 + .../resip/dum/SubscriptionHandler.hxx | 6 +- .../resiprocate/resip/dum/TargetCommand.cxx | 8 +- .../resiprocate/resip/dum/TargetCommand.hxx | 6 +- .../resip/dum/TlsPeerAuthManager.cxx | 188 +- .../resip/dum/TlsPeerAuthManager.hxx | 22 +- .../resip/dum/TlsPeerIdentityInfoMessage.cxx | 97 + .../resip/dum/TlsPeerIdentityInfoMessage.hxx | 83 + .../resiprocate/resip/dum/UserAuthInfo.cxx | 4 +- .../resiprocate/resip/dum/UserProfile.cxx | 11 +- .../resiprocate/resip/dum/UserProfile.hxx | 12 + .../resip/dum/WsCookieAuthManager.cxx | 200 + .../resip/dum/WsCookieAuthManager.hxx | 88 + src/libs/resiprocate/resip/dum/dum.pro | 206 - .../resip/dum/dum_10_0.vcxproj.filters | 546 - .../resiprocate/resip/dum/dum_12_0.vcxproj | 615 ++ .../{dum_10_0.vcxproj => dum_14_0.vcxproj} | 213 +- .../resiprocate/resip/dum/dum_15_0.vcxproj | 616 ++ src/libs/resiprocate/resip/dum/dum_7_1.vcproj | 744 -- src/libs/resiprocate/resip/dum/dum_8_0.vcproj | 1027 -- src/libs/resiprocate/resip/dum/dum_9_0.vcproj | 1035 -- .../resiprocate/resip/dum/dum_9_0.vcxproj | 346 - .../resip/dum/dum_9_0.vcxproj.filters | 546 - .../resip/dum/dum_9_0.vcxproj.user | 4 - .../resip/dum/ssl/EncryptionManager.cxx | 82 +- .../resip/dum/ssl/EncryptionManager.hxx | 4 +- src/libs/resiprocate/resip/stack/.cvsignore | 74 - ...SelectInterruptor.hxx => AddTransport.hxx} | 219 +- .../resip/stack/ApplicationMessage.hxx | 2 +- src/libs/resiprocate/resip/stack/Auth.cxx | 20 +- .../resip/stack/BasicDomainMatcher.cxx | 76 + .../resip/stack/BasicDomainMatcher.hxx | 70 + .../resip/stack/BranchParameter.cxx | 29 +- .../stack/CancelClientInviteTransaction.hxx | 7 +- .../resip/stack/CancelableTimerQueue.hxx | 18 +- src/libs/resiprocate/resip/stack/ChangeLog | 9506 ----------------- .../resiprocate/resip/stack/Connection.cxx | 238 +- .../resiprocate/resip/stack/Connection.hxx | 12 +- .../resip/stack/ConnectionBase.cxx | 492 +- .../resip/stack/ConnectionBase.hxx | 33 +- .../resip/stack/ConnectionManager.cxx | 120 +- .../resip/stack/ConnectionManager.hxx | 14 +- .../resip/stack/ConnectionTerminated.hxx | 4 +- src/libs/resiprocate/resip/stack/Contents.cxx | 23 +- src/libs/resiprocate/resip/stack/Contents.hxx | 3 + .../resip/stack/ContentsFactoryBase.cxx | 2 +- src/libs/resiprocate/resip/stack/Cookie.cxx | 113 + src/libs/resiprocate/resip/stack/Cookie.hxx | 77 + .../resiprocate/resip/stack/DataParameter.cxx | 4 +- .../resiprocate/resip/stack/DateCategory.cxx | 288 +- .../resip/stack/DayOfWeekHash.gperf | 19 + .../resip/stack/DeprecatedDialog.cxx | 54 +- .../resip/stack/DialogInfoContents.cxx | 879 ++ .../resip/stack/DialogInfoContents.hxx | 309 + .../resiprocate/resip/stack/Dispatcher.cxx | 187 + .../resiprocate/resip/stack/Dispatcher.hxx | 183 + .../resiprocate/resip/stack/DnsInterface.cxx | 159 +- .../resiprocate/resip/stack/DnsInterface.hxx | 45 +- .../resiprocate/resip/stack/DnsResult.cxx | 296 +- .../resiprocate/resip/stack/DnsResult.hxx | 94 +- .../resiprocate/resip/stack/DomainMatcher.hxx | 101 + .../resip/stack/DtmfPayloadContents.cxx | 241 + .../resip/stack/DtmfPayloadContents.hxx | 137 + src/libs/resiprocate/resip/stack/Embedded.cxx | 2 +- .../resip/stack/EnableFlowTimer.hxx | 188 +- .../resip/stack/EventStackThread.cxx | 6 +- .../resip/stack/EventStackThread.hxx | 2 +- .../resip/stack/ExistsOrDataParameter.cxx | 4 +- .../resip/stack/ExtendedDomainMatcher.cxx | 100 + .../resip/stack/ExtendedDomainMatcher.hxx | 70 + .../resip/stack/ExtensionHeader.cxx | 16 +- .../resip/stack/ExtensionParameter.cxx | 18 +- .../resip/stack/ExtensionParameter.hxx | 10 +- .../resip/stack/GenericPidfContents.cxx | 890 ++ .../resip/stack/GenericPidfContents.hxx | 181 + .../stack/HEPSipMessageLoggingHandler.cxx | 93 + .../stack/HEPSipMessageLoggingHandler.hxx | 69 + .../resip/stack/HeaderFieldValue.cxx | 12 + .../resip/stack/HeaderFieldValue.hxx | 1 + .../resip/stack/HeaderFieldValueList.cxx | 4 +- .../resiprocate/resip/stack/HeaderHash.gperf | 12 + .../resiprocate/resip/stack/HeaderHash.hxx | 9 +- .../resiprocate/resip/stack/HeaderTypes.hxx | 14 + src/libs/resiprocate/resip/stack/Headers.cxx | 26 +- src/libs/resiprocate/resip/stack/Headers.hxx | 17 + src/libs/resiprocate/resip/stack/Helper.cxx | 221 +- src/libs/resiprocate/resip/stack/Helper.hxx | 13 +- .../resip/stack/InternalTransport.cxx | 66 +- .../resip/stack/InternalTransport.hxx | 27 +- .../resiprocate/resip/stack/InteropHelper.cxx | 3 + .../resiprocate/resip/stack/InteropHelper.hxx | 26 + .../stack/InvokeAfterSocketCreationFunc.hxx | 79 + .../resiprocate/resip/stack/KeepAlivePong.hxx | 184 +- .../resiprocate/resip/stack/LazyParser.cxx | 4 +- src/libs/resiprocate/resip/stack/Makefile | 157 - src/libs/resiprocate/resip/stack/Makefile.am | 457 + src/libs/resiprocate/resip/stack/Makefile.in | 1856 ++++ src/libs/resiprocate/resip/stack/Message.cxx | 6 +- .../resip/stack/MessageFilterRule.cxx | 9 +- .../resip/stack/MessageWaitingContents.cxx | 10 +- .../resiprocate/resip/stack/MethodHash.hxx | 9 +- .../resiprocate/resip/stack/MethodTypes.cxx | 2 +- src/libs/resiprocate/resip/stack/Mime.hxx | 2 +- .../resiprocate/resip/stack/MonthHash.gperf | 24 + .../resip/stack/MultipartMixedContents.cxx | 7 +- src/libs/resiprocate/resip/stack/NameAddr.cxx | 12 +- src/libs/resiprocate/resip/stack/NameAddr.hxx | 4 + .../resip/stack/ParameterHash.gperf | 16 + .../resiprocate/resip/stack/ParameterHash.hxx | 9 +- .../resip/stack/ParameterTypeEnums.hxx | 25 +- .../resip/stack/ParameterTypes.cxx | 23 +- .../resip/stack/ParameterTypes.hxx | 24 +- .../resip/stack/ParserCategories.hxx | 1 + .../resip/stack/ParserCategory.cxx | 4 +- .../resip/stack/ParserContainerBase.cxx | 21 +- .../resip/stack/ParserContainerBase.hxx | 18 +- src/libs/resiprocate/resip/stack/Pidf.cxx | 66 +- src/libs/resiprocate/resip/stack/Pidf.hxx | 18 +- .../resip/stack/QuotedDataParameter.cxx | 2 +- .../resip/stack/RemoveTransport.hxx | 93 + src/libs/resiprocate/resip/stack/Rlmi.cxx | 1 - .../resiprocate/resip/stack/SdpContents.cxx | 101 +- .../resiprocate/resip/stack/SdpContents.hxx | 32 +- .../resiprocate/resip/stack/SecurityTypes.hxx | 11 + .../resip/stack/SipConfigParse.cxx | 217 + .../resip/stack/SipConfigParse.hxx | 78 + .../resiprocate/resip/stack/SipMessage.cxx | 138 +- .../resiprocate/resip/stack/SipMessage.hxx | 103 +- src/libs/resiprocate/resip/stack/SipStack.cxx | 463 +- src/libs/resiprocate/resip/stack/SipStack.hxx | 191 +- .../resip/stack/StatelessHandler.cxx | 8 +- src/libs/resiprocate/resip/stack/Symbols.cxx | 13 +- src/libs/resiprocate/resip/stack/Symbols.hxx | 12 + .../resip/stack/TcpBaseTransport.cxx | 156 +- .../resip/stack/TcpBaseTransport.hxx | 7 +- .../resip/stack/TcpConnectState.cxx | 83 + .../resip/stack/TcpConnectState.hxx | 91 + .../resiprocate/resip/stack/TcpConnection.cxx | 29 +- .../resiprocate/resip/stack/TcpConnection.hxx | 2 +- .../resiprocate/resip/stack/TcpTransport.cxx | 21 +- .../resiprocate/resip/stack/TcpTransport.hxx | 5 +- .../resiprocate/resip/stack/TerminateFlow.hxx | 188 +- .../resiprocate/resip/stack/TimerMessage.cxx | 9 +- .../resiprocate/resip/stack/TimerQueue.cxx | 35 +- .../resiprocate/resip/stack/TimerQueue.hxx | 25 +- src/libs/resiprocate/resip/stack/Token.cxx | 11 +- src/libs/resiprocate/resip/stack/Token.hxx | 11 +- .../stack/TokenOrQuotedStringCategory.cxx | 272 + .../stack/TokenOrQuotedStringCategory.hxx | 135 + .../resip/stack/TransactionController.cxx | 38 +- .../resip/stack/TransactionController.hxx | 10 +- .../resip/stack/TransactionMap.cxx | 2 +- .../resip/stack/TransactionMap.hxx | 13 +- .../resip/stack/TransactionMessage.hxx | 4 +- .../resip/stack/TransactionState.cxx | 488 +- .../resip/stack/TransactionState.hxx | 25 +- .../resip/stack/TransactionUser.cxx | 33 +- .../resip/stack/TransactionUser.hxx | 36 +- .../resip/stack/TransactionUserMessage.cxx | 6 +- .../resiprocate/resip/stack/Transport.cxx | 80 +- .../resiprocate/resip/stack/Transport.hxx | 74 +- .../resip/stack/TransportSelector.cxx | 643 +- .../resip/stack/TransportSelector.hxx | 182 +- .../resip/stack/TransportSelectorThread.hxx | 5 +- .../resip/stack/TransportThread.cxx | 3 +- .../resip/stack/TransportThread.hxx | 2 +- src/libs/resiprocate/resip/stack/TuIM.cxx | 132 +- .../resiprocate/resip/stack/TuSelector.cxx | 22 +- .../resiprocate/resip/stack/TuSelector.hxx | 4 +- src/libs/resiprocate/resip/stack/Tuple.cxx | 274 +- src/libs/resiprocate/resip/stack/Tuple.hxx | 54 +- .../resip/stack/TupleMarkManager.cxx | 2 - .../resip/stack/TupleMarkManager.hxx | 2 - .../resiprocate/resip/stack/UdpTransport.cxx | 216 +- .../resiprocate/resip/stack/UdpTransport.hxx | 5 +- src/libs/resiprocate/resip/stack/Uri.cxx | 131 +- src/libs/resiprocate/resip/stack/Uri.hxx | 19 +- .../resiprocate/resip/stack/ValueFifo.hxx | 4 +- src/libs/resiprocate/resip/stack/Via.cxx | 6 +- src/libs/resiprocate/resip/stack/Worker.hxx | 74 + .../stack/WorkerThread.cxx} | 129 +- .../{FloatParameter.cxx => WorkerThread.hxx} | 66 +- .../resip/stack/WsBaseTransport.cxx | 65 + .../resip/stack/WsBaseTransport.hxx | 66 + .../resiprocate/resip/stack/WsConnection.cxx | 57 + .../resiprocate/resip/stack/WsConnection.hxx | 68 + .../resip/stack/WsConnectionBase.cxx | 59 + .../resip/stack/WsConnectionBase.hxx | 74 + .../resip/stack/WsConnectionValidator.hxx | 54 + .../resip/stack/WsCookieContext.cxx | 159 + .../resip/stack/WsCookieContext.hxx | 78 + .../resip/stack/WsCookieContextFactory.hxx | 87 + .../resiprocate/resip/stack/WsDecorator.cxx | 100 + .../resiprocate/resip/stack/WsDecorator.hxx | 63 + .../resip/stack/WsFrameExtractor.cxx | 289 + .../resip/stack/WsFrameExtractor.hxx | 90 + .../resiprocate/resip/stack/WsTransport.cxx | 88 + .../resiprocate/resip/stack/WsTransport.hxx | 78 + .../resiprocate/resip/stack/XMLCursor.cxx | 680 -- .../resiprocate/resip/stack/XMLCursor.hxx | 250 - .../resiprocate/resip/stack/config.hxx.in | 116 - .../resiprocate/resip/stack/dayofweek.gperf | 9 - .../resip/stack/gen/DayOfWeekHash.cxx | 143 + .../resip/stack/{ => gen}/HeaderHash.cxx | 576 +- .../resip/stack/{ => gen}/MethodHash.cxx | 42 +- .../resiprocate/resip/stack/gen/MonthHash.cxx | 154 + .../resip/stack/{ => gen}/ParameterHash.cxx | 505 +- .../resiprocate/resip/stack/gperf_w32.bat | 31 +- src/libs/resiprocate/resip/stack/makeCert.cxx | 177 - src/libs/resiprocate/resip/stack/month.gperf | 14 - .../resiprocate/resip/stack/resiprocate.pro | 310 - .../stack/resiprocate_10_0.vcxproj.filters | 856 -- ...xproj => resiprocate_12_0.vcxproj.filters} | 282 +- ..._10_0.vcxproj => resiprocate_14_0.vcxproj} | 292 +- .../stack/resiprocate_14_0.vcxproj.filters | 351 + .../resip/stack/resiprocate_15_0.vcxproj | 874 ++ .../stack/resiprocate_15_0.vcxproj.filters | 351 + .../resip/stack/resiprocate_7_1.vcproj | 1125 -- .../resip/stack/resiprocate_8_0.vcproj | 1490 --- .../resip/stack/resiprocate_9_0.vcproj | 1509 --- .../stack/resiprocate_9_0.vcxproj.filters | 853 -- .../resip/stack/resiprocate_9_0.vcxproj.user | 4 - .../resip/stack/ssl/DtlsTransport.cxx | 82 +- .../resip/stack/ssl/DtlsTransport.hxx | 10 +- .../resiprocate/resip/stack/ssl/Security.cxx | 1105 +- .../resiprocate/resip/stack/ssl/Security.hxx | 50 +- .../resip/stack/ssl/TlsBaseTransport.cxx | 211 + .../resip/stack/ssl/TlsBaseTransport.hxx | 148 + .../resip/stack/ssl/TlsConnection.cxx | 267 +- .../resip/stack/ssl/TlsTransport.cxx | 61 +- .../resip/stack/ssl/TlsTransport.hxx | 29 +- .../resip/stack/ssl/WinSecurity.cxx | 208 +- .../resip/stack/ssl/WinSecurity.hxx | 6 +- .../resip/stack/ssl/WssConnection.cxx | 56 + .../resip/stack/ssl/WssConnection.hxx | 66 + .../resip/stack/ssl/WssTransport.cxx | 118 + .../resip/stack/ssl/WssTransport.hxx | 109 + src/libs/resiprocate/rutil/.cvsignore | 30 - src/libs/resiprocate/rutil/AbstractFifo.cxx | 2 +- src/libs/resiprocate/rutil/AbstractFifo.hxx | 6 +- src/libs/resiprocate/rutil/AndroidLogger.cxx | 93 + src/libs/resiprocate/rutil/AndroidLogger.hxx | 73 + src/libs/resiprocate/rutil/AsyncBool.hxx | 55 + src/libs/resiprocate/rutil/AtomicCounter.cxx | 32 - src/libs/resiprocate/rutil/AtomicCounter.hxx | 26 - src/libs/resiprocate/rutil/Coders.cxx | 2 +- src/libs/resiprocate/rutil/Condition.cxx | 104 +- src/libs/resiprocate/rutil/ConfigParse.cxx | 195 +- src/libs/resiprocate/rutil/ConfigParse.hxx | 36 +- src/libs/resiprocate/rutil/CountStream.hxx | 2 +- src/libs/resiprocate/rutil/Data.cxx | 456 +- src/libs/resiprocate/rutil/Data.hxx | 61 +- src/libs/resiprocate/rutil/DataStream.cxx | 8 +- src/libs/resiprocate/rutil/DigestStream.hxx | 2 +- src/libs/resiprocate/rutil/DinkyPool.hxx | 11 +- src/libs/resiprocate/rutil/DnsUtil.cxx | 123 +- src/libs/resiprocate/rutil/DnsUtil.hxx | 2 +- src/libs/resiprocate/rutil/FdPoll.cxx | 2262 ++-- src/libs/resiprocate/rutil/FdPoll.hxx | 12 +- src/libs/resiprocate/rutil/Fifo.hxx | 6 +- src/libs/resiprocate/rutil/FileSystem.cxx | 34 +- src/libs/resiprocate/rutil/FileSystem.hxx | 23 +- .../rutil/GeneralCongestionManager.cxx | 24 +- .../rutil/GeneralCongestionManager.hxx | 7 + .../resiprocate/rutil/GenericIPAddress.cxx | 69 + .../resiprocate/rutil/GenericIPAddress.hxx | 18 +- .../resiprocate/rutil/GenericTimerQueue.hxx | 2 +- src/libs/resiprocate/rutil/HashMap.hxx | 106 +- .../resiprocate/rutil/HeapInstanceCounter.cxx | 2 +- src/libs/resiprocate/rutil/Inserter.hxx | 6 +- .../rutil/IntrusiveListElement.hxx | 88 +- src/libs/resiprocate/rutil/Log.cxx | 296 +- src/libs/resiprocate/rutil/Log.hxx | 45 +- src/libs/resiprocate/rutil/MD5Stream.cxx | 14 + src/libs/resiprocate/rutil/MD5Stream.hxx | 3 + src/libs/resiprocate/rutil/Makefile | 157 - src/libs/resiprocate/rutil/Makefile.am | 257 + src/libs/resiprocate/rutil/Makefile.in | 1379 +++ src/libs/resiprocate/rutil/Mutex.cxx | 20 +- src/libs/resiprocate/rutil/NetNs.cxx | 282 + src/libs/resiprocate/rutil/NetNs.hxx | 175 + src/libs/resiprocate/rutil/ParseBuffer.cxx | 58 +- src/libs/resiprocate/rutil/ParseBuffer.hxx | 8 +- src/libs/resiprocate/rutil/Poll.cxx | 160 +- src/libs/resiprocate/rutil/Poll.hxx | 49 +- .../resiprocate/rutil/ProducerFifoBuffer.hxx | 5 +- .../rutil/RADIUSDigestAuthenticator.cxx | 35 +- .../rutil/RADIUSDigestAuthenticator.hxx | 12 + src/libs/resiprocate/rutil/RWMutex.cxx | 6 +- src/libs/resiprocate/rutil/Random.cxx | 17 +- src/libs/resiprocate/rutil/Random.hxx | 2 +- src/libs/resiprocate/rutil/RecursiveMutex.cxx | 34 +- src/libs/resiprocate/rutil/ResipAssert.h | 150 + .../resiprocate/rutil/SelectInterruptor.cxx | 64 +- .../resiprocate/rutil/SelectInterruptor.hxx | 12 +- src/libs/resiprocate/rutil/ServerProcess.cxx | 256 +- src/libs/resiprocate/rutil/ServerProcess.hxx | 22 + src/libs/resiprocate/rutil/Sha1.cxx | 339 + src/libs/resiprocate/rutil/Sha1.hxx | 116 + src/libs/resiprocate/rutil/SharedCount.hxx | 6 +- src/libs/resiprocate/rutil/SharedPtr.hxx | 16 +- src/libs/resiprocate/rutil/Socket.cxx | 37 +- src/libs/resiprocate/rutil/Socket.hxx | 30 +- src/libs/resiprocate/rutil/SysLogBuf.cxx | 78 +- src/libs/resiprocate/rutil/SysLogBuf.hxx | 16 + src/libs/resiprocate/rutil/SysLogStream.cxx | 6 + src/libs/resiprocate/rutil/SysLogStream.hxx | 1 + src/libs/resiprocate/rutil/ThreadIf.cxx | 14 +- src/libs/resiprocate/rutil/Time.cxx | 32 +- src/libs/resiprocate/rutil/Time.hxx | 11 +- src/libs/resiprocate/rutil/TimeLimitFifo.hxx | 8 +- src/libs/resiprocate/rutil/Timer.cxx | 11 +- src/libs/resiprocate/rutil/Timer.hxx | 18 +- src/libs/resiprocate/rutil/TransportType.cxx | 46 +- src/libs/resiprocate/rutil/TransportType.hxx | 8 + src/libs/resiprocate/rutil/WinCompat.cxx | 122 +- src/libs/resiprocate/rutil/WinCompat.hxx | 2 + src/libs/resiprocate/rutil/XMLCursor.cxx | 52 +- src/libs/resiprocate/rutil/XMLCursor.hxx | 16 +- src/libs/resiprocate/rutil/cajun/Readme.txt | 14 - .../resiprocate/rutil/cajun/ReleaseNotes.txt | 42 - .../resiprocate/rutil/cajun/json/elements.h | 299 - .../resiprocate/rutil/cajun/json/elements.inl | 442 - .../resiprocate/rutil/cajun/json/reader.h | 148 - .../resiprocate/rutil/cajun/json/reader.inl | 533 - .../resiprocate/rutil/cajun/json/visitor.h | 65 - .../resiprocate/rutil/cajun/json/writer.h | 78 - .../resiprocate/rutil/cajun/json/writer.inl | 178 - src/libs/resiprocate/rutil/compat.hxx | 180 +- src/libs/resiprocate/rutil/dns/AresDns.cxx | 199 +- src/libs/resiprocate/rutil/dns/AresDns.hxx | 8 +- .../resiprocate/rutil/dns/DnsAAAARecord.cxx | 6 +- .../resiprocate/rutil/dns/DnsHostRecord.cxx | 2 +- .../resiprocate/rutil/dns/DnsNaptrRecord.cxx | 2 +- src/libs/resiprocate/rutil/dns/DnsStub.cxx | 94 +- src/libs/resiprocate/rutil/dns/DnsStub.hxx | 69 +- src/libs/resiprocate/rutil/dns/DnsThread.cxx | 3 +- src/libs/resiprocate/rutil/dns/DnsThread.hxx | 2 +- .../resiprocate/rutil/dns/ExternalDns.hxx | 3 + src/libs/resiprocate/rutil/dns/LocalDns.cxx | 6 +- src/libs/resiprocate/rutil/dns/LocalDns.hxx | 10 +- src/libs/resiprocate/rutil/dns/RRCache.cxx | 40 +- src/libs/resiprocate/rutil/dns/RRCache.hxx | 2 +- src/libs/resiprocate/rutil/dns/RRList.cxx | 10 +- src/libs/resiprocate/rutil/dns/RRVip.cxx | 2 +- src/libs/resiprocate/rutil/fixupGperf | 0 src/libs/resiprocate/rutil/hep/HepAgent.cxx | 138 + src/libs/resiprocate/rutil/hep/HepAgent.hxx | 284 + src/libs/resiprocate/rutil/hep/ResipHep.cxx | 93 + src/libs/resiprocate/rutil/hep/ResipHep.hxx | 171 + src/libs/resiprocate/rutil/msvc/inttypes.h | 306 + src/libs/resiprocate/rutil/msvc/stdint.h | 259 + .../resiprocate/rutil/resipfaststreams.hxx | 130 +- src/libs/resiprocate/rutil/rutil.pro | 157 - .../rutil/rutil_10_0.vcxproj.filters | 456 - src/libs/resiprocate/rutil/rutil_12_0.vcxproj | 604 ++ ...{rutil_10_0.vcxproj => rutil_14_0.vcxproj} | 219 +- src/libs/resiprocate/rutil/rutil_15_0.vcxproj | 605 ++ src/libs/resiprocate/rutil/rutil_7_1.vcproj | 642 -- src/libs/resiprocate/rutil/rutil_8_0.vcproj | 909 -- src/libs/resiprocate/rutil/rutil_9_0.vcproj | 918 -- src/libs/resiprocate/rutil/rutil_9_0.vcxproj | 315 - .../rutil/rutil_9_0.vcxproj.filters | 462 - .../resiprocate/rutil/rutil_9_0.vcxproj.user | 4 - .../resiprocate/rutil/ssl/OpenSSLInit.cxx | 53 +- .../resiprocate/rutil/ssl/OpenSSLInit.hxx | 2 +- src/libs/resiprocate/rutil/ssl/SHA1Stream.cxx | 10 +- src/libs/resiprocate/rutil/ssl/SHA1Stream.hxx | 2 +- src/libs/resiprocate/rutil/stun/Stun.cxx | 110 +- src/libs/resiprocate/rutil/stun/Udp.cxx | 16 +- src/libs/resiprocate/rutil/stun/Udp.hxx | 5 +- src/libs/resiprocate/rutil/vmd5.cxx | 4 +- 468 files changed, 37035 insertions(+), 35842 deletions(-) delete mode 100644 src/libs/resiprocate/resip/.cvsignore create mode 100644 src/libs/resiprocate/resip/dum/InMemorySyncPubDb.cxx create mode 100644 src/libs/resiprocate/resip/dum/InMemorySyncPubDb.hxx create mode 100644 src/libs/resiprocate/resip/dum/Makefile.am create mode 100644 src/libs/resiprocate/resip/dum/Makefile.in create mode 100644 src/libs/resiprocate/resip/dum/PublicationPersistenceManager.hxx create mode 100644 src/libs/resiprocate/resip/dum/TlsPeerIdentityInfoMessage.cxx create mode 100644 src/libs/resiprocate/resip/dum/TlsPeerIdentityInfoMessage.hxx create mode 100644 src/libs/resiprocate/resip/dum/WsCookieAuthManager.cxx create mode 100644 src/libs/resiprocate/resip/dum/WsCookieAuthManager.hxx delete mode 100644 src/libs/resiprocate/resip/dum/dum.pro delete mode 100644 src/libs/resiprocate/resip/dum/dum_10_0.vcxproj.filters create mode 100644 src/libs/resiprocate/resip/dum/dum_12_0.vcxproj rename src/libs/resiprocate/resip/dum/{dum_10_0.vcxproj => dum_14_0.vcxproj} (69%) create mode 100644 src/libs/resiprocate/resip/dum/dum_15_0.vcxproj delete mode 100644 src/libs/resiprocate/resip/dum/dum_7_1.vcproj delete mode 100644 src/libs/resiprocate/resip/dum/dum_8_0.vcproj delete mode 100644 src/libs/resiprocate/resip/dum/dum_9_0.vcproj delete mode 100644 src/libs/resiprocate/resip/dum/dum_9_0.vcxproj delete mode 100644 src/libs/resiprocate/resip/dum/dum_9_0.vcxproj.filters delete mode 100644 src/libs/resiprocate/resip/dum/dum_9_0.vcxproj.user delete mode 100644 src/libs/resiprocate/resip/stack/.cvsignore rename src/libs/resiprocate/resip/stack/{SelectInterruptor.hxx => AddTransport.hxx} (58%) create mode 100644 src/libs/resiprocate/resip/stack/BasicDomainMatcher.cxx create mode 100644 src/libs/resiprocate/resip/stack/BasicDomainMatcher.hxx delete mode 100644 src/libs/resiprocate/resip/stack/ChangeLog create mode 100644 src/libs/resiprocate/resip/stack/Cookie.cxx create mode 100644 src/libs/resiprocate/resip/stack/Cookie.hxx create mode 100644 src/libs/resiprocate/resip/stack/DayOfWeekHash.gperf create mode 100644 src/libs/resiprocate/resip/stack/DialogInfoContents.cxx create mode 100644 src/libs/resiprocate/resip/stack/DialogInfoContents.hxx create mode 100644 src/libs/resiprocate/resip/stack/Dispatcher.cxx create mode 100644 src/libs/resiprocate/resip/stack/Dispatcher.hxx create mode 100644 src/libs/resiprocate/resip/stack/DomainMatcher.hxx create mode 100644 src/libs/resiprocate/resip/stack/DtmfPayloadContents.cxx create mode 100644 src/libs/resiprocate/resip/stack/DtmfPayloadContents.hxx create mode 100644 src/libs/resiprocate/resip/stack/ExtendedDomainMatcher.cxx create mode 100644 src/libs/resiprocate/resip/stack/ExtendedDomainMatcher.hxx create mode 100644 src/libs/resiprocate/resip/stack/GenericPidfContents.cxx create mode 100644 src/libs/resiprocate/resip/stack/GenericPidfContents.hxx create mode 100644 src/libs/resiprocate/resip/stack/HEPSipMessageLoggingHandler.cxx create mode 100644 src/libs/resiprocate/resip/stack/HEPSipMessageLoggingHandler.hxx create mode 100644 src/libs/resiprocate/resip/stack/InvokeAfterSocketCreationFunc.hxx delete mode 100644 src/libs/resiprocate/resip/stack/Makefile create mode 100644 src/libs/resiprocate/resip/stack/Makefile.am create mode 100644 src/libs/resiprocate/resip/stack/Makefile.in create mode 100644 src/libs/resiprocate/resip/stack/MonthHash.gperf create mode 100644 src/libs/resiprocate/resip/stack/RemoveTransport.hxx create mode 100644 src/libs/resiprocate/resip/stack/SipConfigParse.cxx create mode 100644 src/libs/resiprocate/resip/stack/SipConfigParse.hxx create mode 100644 src/libs/resiprocate/resip/stack/TcpConnectState.cxx create mode 100644 src/libs/resiprocate/resip/stack/TcpConnectState.hxx create mode 100644 src/libs/resiprocate/resip/stack/TokenOrQuotedStringCategory.cxx create mode 100644 src/libs/resiprocate/resip/stack/TokenOrQuotedStringCategory.hxx create mode 100644 src/libs/resiprocate/resip/stack/Worker.hxx rename src/libs/resiprocate/{rutil/DigestStream.cxx => resip/stack/WorkerThread.cxx} (59%) rename src/libs/resiprocate/resip/stack/{FloatParameter.cxx => WorkerThread.hxx} (67%) create mode 100644 src/libs/resiprocate/resip/stack/WsBaseTransport.cxx create mode 100644 src/libs/resiprocate/resip/stack/WsBaseTransport.hxx create mode 100644 src/libs/resiprocate/resip/stack/WsConnection.cxx create mode 100644 src/libs/resiprocate/resip/stack/WsConnection.hxx create mode 100644 src/libs/resiprocate/resip/stack/WsConnectionBase.cxx create mode 100644 src/libs/resiprocate/resip/stack/WsConnectionBase.hxx create mode 100644 src/libs/resiprocate/resip/stack/WsConnectionValidator.hxx create mode 100644 src/libs/resiprocate/resip/stack/WsCookieContext.cxx create mode 100644 src/libs/resiprocate/resip/stack/WsCookieContext.hxx create mode 100644 src/libs/resiprocate/resip/stack/WsCookieContextFactory.hxx create mode 100644 src/libs/resiprocate/resip/stack/WsDecorator.cxx create mode 100644 src/libs/resiprocate/resip/stack/WsDecorator.hxx create mode 100644 src/libs/resiprocate/resip/stack/WsFrameExtractor.cxx create mode 100644 src/libs/resiprocate/resip/stack/WsFrameExtractor.hxx create mode 100644 src/libs/resiprocate/resip/stack/WsTransport.cxx create mode 100644 src/libs/resiprocate/resip/stack/WsTransport.hxx delete mode 100644 src/libs/resiprocate/resip/stack/XMLCursor.cxx delete mode 100644 src/libs/resiprocate/resip/stack/XMLCursor.hxx delete mode 100644 src/libs/resiprocate/resip/stack/config.hxx.in delete mode 100644 src/libs/resiprocate/resip/stack/dayofweek.gperf create mode 100644 src/libs/resiprocate/resip/stack/gen/DayOfWeekHash.cxx rename src/libs/resiprocate/resip/stack/{ => gen}/HeaderHash.cxx (63%) rename src/libs/resiprocate/resip/stack/{ => gen}/MethodHash.cxx (81%) create mode 100644 src/libs/resiprocate/resip/stack/gen/MonthHash.cxx rename src/libs/resiprocate/resip/stack/{ => gen}/ParameterHash.cxx (60%) delete mode 100644 src/libs/resiprocate/resip/stack/makeCert.cxx delete mode 100644 src/libs/resiprocate/resip/stack/month.gperf delete mode 100644 src/libs/resiprocate/resip/stack/resiprocate.pro delete mode 100644 src/libs/resiprocate/resip/stack/resiprocate_10_0.vcxproj.filters rename src/libs/resiprocate/resip/stack/{resiprocate_9_0.vcxproj => resiprocate_12_0.vcxproj.filters} (52%) rename src/libs/resiprocate/resip/stack/{resiprocate_10_0.vcxproj => resiprocate_14_0.vcxproj} (67%) create mode 100644 src/libs/resiprocate/resip/stack/resiprocate_14_0.vcxproj.filters create mode 100644 src/libs/resiprocate/resip/stack/resiprocate_15_0.vcxproj create mode 100644 src/libs/resiprocate/resip/stack/resiprocate_15_0.vcxproj.filters delete mode 100644 src/libs/resiprocate/resip/stack/resiprocate_7_1.vcproj delete mode 100644 src/libs/resiprocate/resip/stack/resiprocate_8_0.vcproj delete mode 100644 src/libs/resiprocate/resip/stack/resiprocate_9_0.vcproj delete mode 100644 src/libs/resiprocate/resip/stack/resiprocate_9_0.vcxproj.filters delete mode 100644 src/libs/resiprocate/resip/stack/resiprocate_9_0.vcxproj.user create mode 100644 src/libs/resiprocate/resip/stack/ssl/TlsBaseTransport.cxx create mode 100644 src/libs/resiprocate/resip/stack/ssl/TlsBaseTransport.hxx create mode 100644 src/libs/resiprocate/resip/stack/ssl/WssConnection.cxx create mode 100644 src/libs/resiprocate/resip/stack/ssl/WssConnection.hxx create mode 100644 src/libs/resiprocate/resip/stack/ssl/WssTransport.cxx create mode 100644 src/libs/resiprocate/resip/stack/ssl/WssTransport.hxx delete mode 100644 src/libs/resiprocate/rutil/.cvsignore create mode 100644 src/libs/resiprocate/rutil/AndroidLogger.cxx create mode 100644 src/libs/resiprocate/rutil/AndroidLogger.hxx create mode 100644 src/libs/resiprocate/rutil/AsyncBool.hxx delete mode 100644 src/libs/resiprocate/rutil/AtomicCounter.cxx delete mode 100644 src/libs/resiprocate/rutil/AtomicCounter.hxx create mode 100644 src/libs/resiprocate/rutil/GenericIPAddress.cxx delete mode 100644 src/libs/resiprocate/rutil/Makefile create mode 100644 src/libs/resiprocate/rutil/Makefile.am create mode 100644 src/libs/resiprocate/rutil/Makefile.in create mode 100644 src/libs/resiprocate/rutil/NetNs.cxx create mode 100644 src/libs/resiprocate/rutil/NetNs.hxx create mode 100644 src/libs/resiprocate/rutil/ResipAssert.h create mode 100644 src/libs/resiprocate/rutil/Sha1.cxx create mode 100644 src/libs/resiprocate/rutil/Sha1.hxx delete mode 100644 src/libs/resiprocate/rutil/cajun/Readme.txt delete mode 100644 src/libs/resiprocate/rutil/cajun/ReleaseNotes.txt delete mode 100644 src/libs/resiprocate/rutil/cajun/json/elements.h delete mode 100644 src/libs/resiprocate/rutil/cajun/json/elements.inl delete mode 100644 src/libs/resiprocate/rutil/cajun/json/reader.h delete mode 100644 src/libs/resiprocate/rutil/cajun/json/reader.inl delete mode 100644 src/libs/resiprocate/rutil/cajun/json/visitor.h delete mode 100644 src/libs/resiprocate/rutil/cajun/json/writer.h delete mode 100644 src/libs/resiprocate/rutil/cajun/json/writer.inl mode change 100644 => 100755 src/libs/resiprocate/rutil/fixupGperf create mode 100644 src/libs/resiprocate/rutil/hep/HepAgent.cxx create mode 100644 src/libs/resiprocate/rutil/hep/HepAgent.hxx create mode 100644 src/libs/resiprocate/rutil/hep/ResipHep.cxx create mode 100644 src/libs/resiprocate/rutil/hep/ResipHep.hxx create mode 100644 src/libs/resiprocate/rutil/msvc/inttypes.h create mode 100644 src/libs/resiprocate/rutil/msvc/stdint.h delete mode 100644 src/libs/resiprocate/rutil/rutil.pro delete mode 100644 src/libs/resiprocate/rutil/rutil_10_0.vcxproj.filters create mode 100644 src/libs/resiprocate/rutil/rutil_12_0.vcxproj rename src/libs/resiprocate/rutil/{rutil_10_0.vcxproj => rutil_14_0.vcxproj} (63%) create mode 100644 src/libs/resiprocate/rutil/rutil_15_0.vcxproj delete mode 100644 src/libs/resiprocate/rutil/rutil_7_1.vcproj delete mode 100644 src/libs/resiprocate/rutil/rutil_8_0.vcproj delete mode 100644 src/libs/resiprocate/rutil/rutil_9_0.vcproj delete mode 100644 src/libs/resiprocate/rutil/rutil_9_0.vcxproj delete mode 100644 src/libs/resiprocate/rutil/rutil_9_0.vcxproj.filters delete mode 100644 src/libs/resiprocate/rutil/rutil_9_0.vcxproj.user diff --git a/src/libs/resiprocate/CMakeLists.txt b/src/libs/resiprocate/CMakeLists.txt index 05bac91c..60f78c32 100644 --- a/src/libs/resiprocate/CMakeLists.txt +++ b/src/libs/resiprocate/CMakeLists.txt @@ -58,7 +58,6 @@ set (STACK_SOURCES resip/stack/DeprecatedDialog.cxx resip/stack/GenericUri.cxx resip/stack/GenericContents.cxx - resip/stack/FloatParameter.cxx resip/stack/ExternalBodyContents.cxx resip/stack/ExtensionParameter.cxx resip/stack/ExtensionHeader.cxx @@ -68,13 +67,13 @@ set (STACK_SOURCES resip/stack/EventStackThread.cxx resip/stack/Embedded.cxx resip/stack/DtlsMessage.cxx - resip/stack/HeaderHash.cxx +# resip/stack/HeaderHash.cxx resip/stack/HeaderFieldValueList.cxx resip/stack/HeaderFieldValue.cxx resip/stack/MsgHeaderScanner.cxx resip/stack/Mime.cxx resip/stack/MethodTypes.cxx - resip/stack/MethodHash.cxx +# resip/stack/MethodHash.cxx resip/stack/MessageWaitingContents.cxx resip/stack/MessageFilterRule.cxx resip/stack/Message.cxx @@ -89,7 +88,7 @@ set (STACK_SOURCES resip/stack/Helper.cxx resip/stack/HeaderTypes.cxx resip/stack/Headers.cxx - resip/stack/ParameterHash.cxx +# resip/stack/ParameterHash.cxx resip/stack/Parameter.cxx resip/stack/OctetContents.cxx resip/stack/NonceHelper.cxx @@ -305,7 +304,6 @@ SET (RUTIL_SOURCES rutil/KeyValueStore.cxx rutil/HeapInstanceCounter.cxx rutil/GeneralCongestionManager.cxx - rutil/AtomicCounter.cxx rutil/WinCompat.cxx ) diff --git a/src/libs/resiprocate/resip/.cvsignore b/src/libs/resiprocate/resip/.cvsignore deleted file mode 100644 index 22f96b59..00000000 --- a/src/libs/resiprocate/resip/.cvsignore +++ /dev/null @@ -1,19 +0,0 @@ -*.ncb -*.suo -.DS_Store -.make_prefs -Makefile.in -autom4te*.cache -autoscan.log -config.log -config.status -configure.scan -lib.debug.Linux.i686 -lib.opt.Linux.i686 -lib.prof.Linux.i686 -libtool -resiprocate-old-junk -depcomp -install-sh -compile -proj diff --git a/src/libs/resiprocate/resip/dum/AppDialog.cxx b/src/libs/resiprocate/resip/dum/AppDialog.cxx index 63ddb450..27994929 100644 --- a/src/libs/resiprocate/resip/dum/AppDialog.cxx +++ b/src/libs/resiprocate/resip/dum/AppDialog.cxx @@ -1,5 +1,5 @@ -#include "resip/dum/Dialog.hxx" #include "resip/dum/AppDialog.hxx" +#include "resip/dum/Dialog.hxx" using namespace resip; using namespace std; diff --git a/src/libs/resiprocate/resip/dum/AppDialogSet.cxx b/src/libs/resiprocate/resip/dum/AppDialogSet.cxx index 2079e4bb..56977774 100644 --- a/src/libs/resiprocate/resip/dum/AppDialogSet.cxx +++ b/src/libs/resiprocate/resip/dum/AppDialogSet.cxx @@ -86,7 +86,7 @@ AppDialogSet::getDialogSetId() AppDialogSet* AppDialogSet::reuse() { - assert(mDialogSet); + resip_assert(mDialogSet); mDialogSet->appDissociate(); mDialogSet = 0; diff --git a/src/libs/resiprocate/resip/dum/AppDialogSetFactory.cxx b/src/libs/resiprocate/resip/dum/AppDialogSetFactory.cxx index 0331ba85..dcaee561 100644 --- a/src/libs/resiprocate/resip/dum/AppDialogSetFactory.cxx +++ b/src/libs/resiprocate/resip/dum/AppDialogSetFactory.cxx @@ -1,5 +1,5 @@ -#include "resip/dum/DialogUsageManager.hxx" #include "resip/dum/AppDialogSetFactory.hxx" +#include "resip/dum/DialogUsageManager.hxx" #include "resip/stack/SipMessage.hxx" #include "resip/dum/AppDialogSet.hxx" #include "rutil/WinLeakCheck.hxx" diff --git a/src/libs/resiprocate/resip/dum/BaseCreator.cxx b/src/libs/resiprocate/resip/dum/BaseCreator.cxx index e133744d..a09be4e3 100644 --- a/src/libs/resiprocate/resip/dum/BaseCreator.cxx +++ b/src/libs/resiprocate/resip/dum/BaseCreator.cxx @@ -1,5 +1,5 @@ -#include "rutil/Logger.hxx" #include "resip/stack/Helper.hxx" +#include "rutil/Logger.hxx" #include "resip/dum/DialogUsageManager.hxx" #include "resip/dum/MasterProfile.hxx" #include "resip/dum/BaseCreator.hxx" @@ -43,7 +43,7 @@ BaseCreator::getUserProfile() void BaseCreator::makeInitialRequest(const NameAddr& target, MethodTypes method) { - assert(mUserProfile.get()); + resip_assert(mUserProfile.get()); makeInitialRequest(target, mUserProfile->getDefaultFrom(), method); } @@ -63,7 +63,7 @@ BaseCreator::makeInitialRequest(const NameAddr& target, const NameAddr& from, Me mLastRequest->header(h_From).param(p_tag) = Helper::computeTag(Helper::tagSize); mLastRequest->header(h_CallId).value() = Helper::computeCallId(); - assert(mUserProfile.get()); + resip_assert(mUserProfile.get()); if (!mUserProfile->getImsAuthUserName().empty()) { Auth auth; @@ -137,33 +137,15 @@ BaseCreator::makeInitialRequest(const NameAddr& target, const NameAddr& from, Me Via via; mLastRequest->header(h_Vias).push_front(via); - if(mUserProfile->isAdvertisedCapability(Headers::Allow)) - { - mLastRequest->header(h_Allows) = mDum.getMasterProfile()->getAllowedMethods(); - } - if(mUserProfile->isAdvertisedCapability(Headers::AcceptEncoding)) - { - mLastRequest->header(h_AcceptEncodings) = mDum.getMasterProfile()->getSupportedEncodings(); - } - if(mUserProfile->isAdvertisedCapability(Headers::AcceptLanguage)) - { - mLastRequest->header(h_AcceptLanguages) = mDum.getMasterProfile()->getSupportedLanguages(); - } - if(mUserProfile->isAdvertisedCapability(Headers::AllowEvents)) - { - mLastRequest->header(h_AllowEvents) = mDum.getMasterProfile()->getAllowedEvents(); - } - if(mUserProfile->isAdvertisedCapability(Headers::Supported)) - { - mLastRequest->header(h_Supporteds) = mDum.getMasterProfile()->getSupportedOptionTags(); - } + // Add Advertised Capabilities to initial request + mDum.setAdvertisedCapabilities(*mLastRequest.get(), mUserProfile); // Merge Embedded parameters mLastRequest->mergeUri(target.uri()); //DumHelper::setOutgoingEncryptionLevel(mLastRequest, mEncryptionLevel); - DebugLog ( << "BaseCreator::makeInitialRequest: " << std::endl << std::endl << mLastRequest); + DebugLog ( << "BaseCreator::makeInitialRequest: " << std::endl << std::endl << *mLastRequest); } diff --git a/src/libs/resiprocate/resip/dum/BaseSubscription.cxx b/src/libs/resiprocate/resip/dum/BaseSubscription.cxx index 79c3aa97..cdbedfc8 100644 --- a/src/libs/resiprocate/resip/dum/BaseSubscription.cxx +++ b/src/libs/resiprocate/resip/dum/BaseSubscription.cxx @@ -15,7 +15,6 @@ BaseSubscription::BaseSubscription(DialogUsageManager& dum, Dialog& dialog, cons mSubscriptionId(Data::Empty), mTimerSeq(0), mSubscriptionState(Invalid) - { if (request.exists(h_Event)) { @@ -37,7 +36,7 @@ BaseSubscription::BaseSubscription(DialogUsageManager& dum, Dialog& dialog, cons bool BaseSubscription::matches(const SipMessage& msg) { - if (msg.isResponse() && msg.header(h_CSeq) == mLastRequest->header(h_CSeq)) + if (msg.isResponse() && mLastRequest.get() != 0 && msg.header(h_CSeq) == mLastRequest->header(h_CSeq)) { return true; } @@ -48,7 +47,6 @@ BaseSubscription::matches(const SipMessage& msg) return msg.header(h_Event).value() == mEventType && ( !msg.header(h_Event).exists(p_id) || msg.header(h_Event).param(p_id) == mSubscriptionId); - } else { @@ -58,7 +56,6 @@ BaseSubscription::matches(const SipMessage& msg) } } - BaseSubscription::~BaseSubscription() { } diff --git a/src/libs/resiprocate/resip/dum/BaseUsage.cxx b/src/libs/resiprocate/resip/dum/BaseUsage.cxx index 8311c7f1..1ac830f8 100644 --- a/src/libs/resiprocate/resip/dum/BaseUsage.cxx +++ b/src/libs/resiprocate/resip/dum/BaseUsage.cxx @@ -38,6 +38,11 @@ BaseUsage::getBaseHandle() return mHandle; } +void BaseUsage::postDum(Message* messageForDum) +{ + mDum.post(messageForDum); +} + #if 0 EncodeStream& BaseUsage::dump(EncodeStream& strm) const diff --git a/src/libs/resiprocate/resip/dum/BaseUsage.hxx b/src/libs/resiprocate/resip/dum/BaseUsage.hxx index 38a7ea52..999a3c93 100644 --- a/src/libs/resiprocate/resip/dum/BaseUsage.hxx +++ b/src/libs/resiprocate/resip/dum/BaseUsage.hxx @@ -8,11 +8,12 @@ namespace resip { -class DialogUsageManager; class Dialog; +class DialogUsageManager; class DumTimeout; -class SipMessage; +class Message; class NameAddr; +class SipMessage; class BaseUsage : public Handled { @@ -24,6 +25,9 @@ class BaseUsage : public Handled virtual const char* name() const; }; + /// @brief posts a message on dum + virtual void postDum(Message* messageForDum); + virtual void end()=0; virtual EncodeStream& dump(EncodeStream& strm) const=0; diff --git a/src/libs/resiprocate/resip/dum/ChallengeInfo.cxx b/src/libs/resiprocate/resip/dum/ChallengeInfo.cxx index 39c737d8..b38d0a97 100644 --- a/src/libs/resiprocate/resip/dum/ChallengeInfo.cxx +++ b/src/libs/resiprocate/resip/dum/ChallengeInfo.cxx @@ -1,5 +1,5 @@ -#include +#include "rutil/ResipAssert.h" #include "resip/dum/ChallengeInfo.hxx" #include "rutil/Data.hxx" @@ -49,7 +49,7 @@ ChallengeInfo::brief() const resip::Message* ChallengeInfo::clone() const { - assert(false); return NULL; + resip_assert(false); return NULL; } std::ostream& diff --git a/src/libs/resiprocate/resip/dum/ClientAuthExtension.cxx b/src/libs/resiprocate/resip/dum/ClientAuthExtension.cxx index 55eda67f..bed418e3 100644 --- a/src/libs/resiprocate/resip/dum/ClientAuthExtension.cxx +++ b/src/libs/resiprocate/resip/dum/ClientAuthExtension.cxx @@ -2,12 +2,12 @@ using namespace resip; -std::unique_ptr ClientAuthExtension::mInstance = std::unique_ptr(new ClientAuthExtension()); +std::auto_ptr ClientAuthExtension::mInstance = std::auto_ptr(new ClientAuthExtension()); void -ClientAuthExtension::setInstance(std::unique_ptr ext) +ClientAuthExtension::setInstance(std::auto_ptr ext) { - mInstance = std::move(ext); + mInstance = ext; } @@ -21,7 +21,7 @@ ClientAuthExtension::makeChallengeResponseAuth(const SipMessage& request, const Data& nonceCountString, Auth& auth) { - assert(0); + resip_assert(0); } void @@ -34,7 +34,7 @@ ClientAuthExtension::makeChallengeResponseAuthWithA1(const SipMessage& request, const Data& nonceCountString, Auth& auth) { - assert(0); + resip_assert(0); } diff --git a/src/libs/resiprocate/resip/dum/ClientAuthExtension.hxx b/src/libs/resiprocate/resip/dum/ClientAuthExtension.hxx index 4c7a2c8b..3c77762d 100644 --- a/src/libs/resiprocate/resip/dum/ClientAuthExtension.hxx +++ b/src/libs/resiprocate/resip/dum/ClientAuthExtension.hxx @@ -45,7 +45,7 @@ class ClientAuthExtension virtual bool algorithmAndQopSupported(const Auth& challenge); - static void setInstance(std::unique_ptr ext); + static void setInstance(std::auto_ptr ext); static ClientAuthExtension& instance() { return *mInstance; @@ -54,7 +54,7 @@ class ClientAuthExtension ClientAuthExtension() {} - static std::unique_ptr mInstance; + static std::auto_ptr mInstance; }; diff --git a/src/libs/resiprocate/resip/dum/ClientAuthManager.cxx b/src/libs/resiprocate/resip/dum/ClientAuthManager.cxx index 4770e071..25f1809f 100644 --- a/src/libs/resiprocate/resip/dum/ClientAuthManager.cxx +++ b/src/libs/resiprocate/resip/dum/ClientAuthManager.cxx @@ -1,4 +1,4 @@ -#include +#include "rutil/ResipAssert.h" #include "resip/stack/Helper.hxx" #include "resip/stack/SipMessage.hxx" @@ -100,18 +100,18 @@ private: Data mNonceCountString; }; + ClientAuthManager::ClientAuthManager() { } - bool ClientAuthManager::handle(UserProfile& userProfile, SipMessage& origRequest, const SipMessage& response) { try { - assert( response.isResponse() ); - assert( origRequest.isRequest() ); + resip_assert( response.isResponse() ); + resip_assert( origRequest.isRequest() ); DialogSetId id(origRequest); @@ -133,6 +133,7 @@ ClientAuthManager::handle(UserProfile& userProfile, SipMessage& origRequest, con return false; } + // 401 or 407... if (!(response.exists(h_WWWAuthenticates) || response.exists(h_ProxyAuthenticates))) { DebugLog (<< "Invalid challenge for " << id << ", nothing to respond to; fail"); @@ -145,7 +146,7 @@ ClientAuthManager::handle(UserProfile& userProfile, SipMessage& origRequest, con // AuthState associated with this DialogSet if the algorithm is supported if (authState.handleChallenge(userProfile, response)) { - assert(origRequest.header(h_Vias).size() == 1); + resip_assert(origRequest.header(h_Vias).size() == 1); origRequest.header(h_CSeq).sequence()++; DebugLog (<< "Produced response to digest challenge for " << userProfile ); return true; @@ -157,7 +158,7 @@ ClientAuthManager::handle(UserProfile& userProfile, SipMessage& origRequest, con } catch(BaseException& e) { - assert(0); + resip_assert(0); ErrLog(<< "Unexpected exception in ClientAuthManager::handle " << e); return false; } @@ -176,15 +177,26 @@ ClientAuthManager::addAuthentication(SipMessage& request) void ClientAuthManager::clearAuthenticationState(const DialogSetId& dsId) { - dialogSetDestroyed(dsId); + AttemptedAuthMap::iterator it = mAttemptedAuths.find(dsId); + if (it != mAttemptedAuths.end()) + { + mAttemptedAuths.erase(it); + } +} + +void +ClientAuthManager::dialogSetDestroyed(const DialogSetId& id) +{ + clearAuthenticationState(id); } ClientAuthManager::AuthState::AuthState() : - mFailed(false) + mFailed(false), + mCacheUseLimit(0), + mCacheUseCount(0) { } - bool ClientAuthManager::AuthState::handleChallenge(UserProfile& userProfile, const SipMessage& challenge) { @@ -192,11 +204,11 @@ ClientAuthManager::AuthState::handleChallenge(UserProfile& userProfile, const Si { return false; } - bool handled = true; + bool handled = true; if (challenge.exists(h_WWWAuthenticates)) { for (Auths::const_iterator i = challenge.header(h_WWWAuthenticates).begin(); - i != challenge.header(h_WWWAuthenticates).end(); ++i) + i != challenge.header(h_WWWAuthenticates).end(); ++i) { if (i->exists(p_realm)) { @@ -214,8 +226,8 @@ ClientAuthManager::AuthState::handleChallenge(UserProfile& userProfile, const Si } if (challenge.exists(h_ProxyAuthenticates)) { - for (Auths::const_iterator i = challenge.header(h_ProxyAuthenticates).begin(); - i != challenge.header(h_ProxyAuthenticates).end(); ++i) + for(Auths::const_iterator i = challenge.header(h_ProxyAuthenticates).begin(); + i != challenge.header(h_ProxyAuthenticates).end(); ++i) { if (i->exists(p_realm)) { @@ -225,16 +237,20 @@ ClientAuthManager::AuthState::handleChallenge(UserProfile& userProfile, const Si break; } } - else - { - return false; - } - } - if(!handled) - { - InfoLog( << "ClientAuthManager::AuthState::handleChallenge failed for: " << challenge); + else + { + return false; + } } } + if(!handled) + { + InfoLog( << "ClientAuthManager::AuthState::handleChallenge failed for: " << challenge); + } + else + { + mCacheUseLimit = userProfile.getDigestCacheUseLimit(); + } return handled; } @@ -245,6 +261,13 @@ ClientAuthManager::AuthState::authSucceeded() { i->second.authSucceeded(); } + mCacheUseCount++; + if(mCacheUseLimit != 0 && mCacheUseCount >= mCacheUseLimit) + { + // Cache use limit reached - clear auth state + mRealms.clear(); + mCacheUseCount = 0; + } } void @@ -265,8 +288,7 @@ ClientAuthManager::AuthState::addAuthentication(SipMessage& request) ClientAuthManager::RealmState::RealmState() : mIsProxyCredential(false), mState(Invalid), - mNonceCount(0), - mAuthPtr(NULL) + mNonceCount(0) { } @@ -298,7 +320,7 @@ ClientAuthManager::RealmState::authSucceeded() switch(mState) { case Invalid: - assert(0); + resip_assert(0); break; case Current: case Cached: @@ -306,7 +328,7 @@ ClientAuthManager::RealmState::authSucceeded() transition(Cached); break; case Failed: - assert(0); + resip_assert(0); break; }; } @@ -388,11 +410,11 @@ ClientAuthManager::RealmState::findCredential(UserProfile& userProfile, const Au const Data& realm = auth.param(p_realm); //!dcm! -- icky, expose static empty soon...ptr instead of reference? mCredential = userProfile.getDigestCredential(realm); - if ( mCredential.realm.empty() ) + if (mCredential.realm.empty()) { DebugLog( << "Got a 401 or 407 but could not find credentials for realm: " << realm); -// DebugLog (<< auth); -// DebugLog (<< response); + // DebugLog (<< auth); + // DebugLog (<< response); return false; } return true; @@ -401,7 +423,7 @@ ClientAuthManager::RealmState::findCredential(UserProfile& userProfile, const Au void ClientAuthManager::RealmState::addAuthentication(SipMessage& request) { - assert(mState != Failed); + resip_assert(mState != Failed); if (mState == Failed) return; Data nonceCountString; @@ -413,16 +435,8 @@ ClientAuthManager::RealmState::addAuthentication(SipMessage& request) // Add client auth decorator so that we ensure any body hashes are calcuated after user defined outbound decorators that // may be modifying the message body - std::unique_ptr clientAuthDecorator(new ClientAuthDecorator(mIsProxyCredential, mAuth, mCredential, authQop, nonceCountString)); - request.addOutboundDecorator(std::move(clientAuthDecorator)); -} - -void ClientAuthManager::dialogSetDestroyed(const DialogSetId& id) -{ - if ( mAttemptedAuths.find(id) != mAttemptedAuths.end()) - { - mAttemptedAuths.erase(id); - } + std::auto_ptr clientAuthDecorator(new ClientAuthDecorator(mIsProxyCredential, mAuth, mCredential, authQop, nonceCountString)); + request.addOutboundDecorator(clientAuthDecorator); } // bool @@ -443,7 +457,6 @@ void ClientAuthManager::dialogSetDestroyed(const DialogSetId& id) // } - /* ==================================================================== * The Vovida Software License, Version 1.0 * diff --git a/src/libs/resiprocate/resip/dum/ClientAuthManager.hxx b/src/libs/resiprocate/resip/dum/ClientAuthManager.hxx index 684e588b..fb87e0cc 100644 --- a/src/libs/resiprocate/resip/dum/ClientAuthManager.hxx +++ b/src/libs/resiprocate/resip/dum/ClientAuthManager.hxx @@ -42,7 +42,6 @@ class ClientAuthManager // bool operator()(const Auth& lhs, const Auth& rhs) const; // }; - class RealmState { public: @@ -74,13 +73,10 @@ class ClientAuthManager unsigned int mNonceCount; Auth mAuth; - // FH add the realm state so it can change - Auth *mAuthPtr; - -// .dcm. only one credential per realm per challenge supported -// typedef std::map CredentialMap; -// CredentialMap proxyCredentials; -// CredentialMap wwwCredentials; + // .dcm. only one credential per realm per challenge supported + // typedef std::map CredentialMap; + // CredentialMap proxyCredentials; + // CredentialMap wwwCredentials; }; class AuthState @@ -95,6 +91,8 @@ class ClientAuthManager typedef std::map RealmStates; RealmStates mRealms; bool mFailed; + unsigned long mCacheUseLimit; + unsigned long mCacheUseCount; }; typedef std::map AttemptedAuthMap; diff --git a/src/libs/resiprocate/resip/dum/ClientInviteSession.cxx b/src/libs/resiprocate/resip/dum/ClientInviteSession.cxx index 948f07b1..819bfa2f 100644 --- a/src/libs/resiprocate/resip/dum/ClientInviteSession.cxx +++ b/src/libs/resiprocate/resip/dum/ClientInviteSession.cxx @@ -1,5 +1,6 @@ #include "resip/stack/Contents.hxx" +#include "resip/dum/BaseCreator.hxx" #include "resip/dum/ClientInviteSession.hxx" #include "resip/dum/Dialog.hxx" #include "resip/dum/DialogEventStateManager.hxx" @@ -31,12 +32,13 @@ ClientInviteSession::ClientInviteSession(DialogUsageManager& dum, InviteSession(dum, dialog), mStaleCallTimerSeq(1), mCancelledTimerSeq(1), - mServerSub(serverSub) + mServerSub(serverSub), + mAllowOfferInPrack(false) { - assert(request->isRequest()); + resip_assert(request->isRequest()); if(initialOffer) { - mProposedLocalOfferAnswer = unique_ptr(initialOffer->clone()); + mProposedLocalOfferAnswer = auto_ptr(initialOffer->clone()); mProposedEncryptionLevel = level; } *mLastLocalSessionModification = *request; // Copy message, so that modifications to mLastLocalSessionModification don't effect creator->getLastRequest @@ -64,22 +66,32 @@ ClientInviteSession::provideOffer(const Contents& offer, DialogUsageManager::Enc switch(mState) { case UAC_EarlyWithAnswer: - { - transition(UAC_SentUpdateEarly); + if(mAllowOfferInPrack) + { + // This flag is enabled when we are about to send our first PRACK. We are + // allowed to send an offer in our first PRACK request, so don't use UPDATE in + // this case. + // Remember proposed local offferAnswer. + mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(offer, alternative); + mProposedEncryptionLevel = level; + } + else + { + transition(UAC_SentUpdateEarly); - // Creates an UPDATE request with application supplied offer. - mDialog.makeRequest(*mLastLocalSessionModification, UPDATE); - InviteSession::setOfferAnswer(*mLastLocalSessionModification, offer); + // Creates an UPDATE request with application supplied offer. + mDialog.makeRequest(*mLastLocalSessionModification, UPDATE); + InviteSession::setOfferAnswer(*mLastLocalSessionModification, offer); - // Remember proposed local offferAnswer. - mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(offer, alternative); - mProposedEncryptionLevel = level; + // Remember proposed local offferAnswer. + mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(offer, alternative); + mProposedEncryptionLevel = level; - // Send the req and do state transition. - DumHelper::setOutgoingEncryptionLevel(*mLastLocalSessionModification, mProposedEncryptionLevel); - send(mLastLocalSessionModification); + // Send the req and do state transition. + DumHelper::setOutgoingEncryptionLevel(*mLastLocalSessionModification, mProposedEncryptionLevel); + send(mLastLocalSessionModification); + } break; - } case UAC_SentAnswer: // just queue it for later @@ -97,7 +109,8 @@ ClientInviteSession::provideOffer(const Contents& offer, DialogUsageManager::Enc case UAC_Cancelled: case UAC_QueuedUpdate: case Terminated: - assert(0); + WarningLog (<< "Incorrect state to provideOffer: " << toData(mState)); + throw DialogUsage::Exception("Can't provide an offer", __FILE__,__LINE__); break; default: @@ -124,11 +137,11 @@ ClientInviteSession::provideAnswer (const Contents& answer) transition(UAC_SentAnswer); // Remember proposed local offerAnswer. - mCurrentRemoteOfferAnswer = std::move(mProposedRemoteOfferAnswer); + mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer; mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer); - // Creates an PRACK request with application supplied offer. - sendPrack(answer); + // Creates a PRACK request with application supplied answer + sendPrack(answer, mCurrentEncryptionLevel); break; } @@ -137,9 +150,8 @@ ClientInviteSession::provideAnswer (const Contents& answer) transition(Connected); sendAck(&answer); - mCurrentRemoteOfferAnswer = std::move(mProposedRemoteOfferAnswer); + mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer; mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer); - // mLastSessionModification = ack; // ?slg? is this needed? break; } case UAC_ReceivedUpdateEarly: @@ -154,7 +166,7 @@ ClientInviteSession::provideAnswer (const Contents& answer) mDialog.makeResponse(*response, *mLastRemoteSessionModification, 200); InviteSession::setOfferAnswer(*response, answer, 0); mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer); - mCurrentRemoteOfferAnswer = std::move(mProposedRemoteOfferAnswer); + mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer; InfoLog (<< "Sending " << response->brief()); DumHelper::setOutgoingEncryptionLevel(*response, mCurrentEncryptionLevel); send(response); @@ -169,7 +181,8 @@ ClientInviteSession::provideAnswer (const Contents& answer) case UAC_Cancelled: case UAC_QueuedUpdate: case Terminated: - assert(0); + WarningLog (<< "Incorrect state to provideAnswer: " << toData(mState)); + throw DialogUsage::Exception("Can't provide an answer", __FILE__,__LINE__); break; default: @@ -220,7 +233,7 @@ ClientInviteSession::end(EndReason reason) case UAC_Start: WarningLog (<< "Try to end when in state=" << toData(mState)); - assert(0); + resip_assert(0); break; case Terminated: @@ -255,7 +268,8 @@ ClientInviteSession::reject (int statusCode, WarningCategory *warning) break; } - case UAC_Answered:{ + case UAC_Answered: + { // We received an offer in a 2xx response, and we want to reject it // ACK with no body, then send bye sendAck(); @@ -273,7 +287,7 @@ ClientInviteSession::reject (int statusCode, WarningCategory *warning) case UAC_SentAnswer: case UAC_Cancelled: WarningLog (<< "Try to reject when in state=" << toData(mState)); - assert(0); + resip_assert(0); break; default: @@ -304,7 +318,7 @@ ClientInviteSession::cancel() break; default: - assert(0); + resip_assert(0); break; } } @@ -344,7 +358,6 @@ ClientInviteSession::startStaleCallTimer() { InfoLog (<< toData(mState) << ": startStaleCallTimer"); unsigned long when = mDialog.mDialogSet.getUserProfile()->getDefaultStaleCallTime(); - when += Random::getRandom() % 120; mDum.addTimer(DumTimeout::StaleCall, when, @@ -405,7 +418,7 @@ ClientInviteSession::dispatch(const SipMessage& msg) } } - if (checkRseq(msg)) + if (isBadRseq(msg)) { return; } @@ -529,15 +542,16 @@ ClientInviteSession::handleRedirect (const SipMessage& msg) void ClientInviteSession::handleProvisional(const SipMessage& msg) { - assert(msg.isResponse()); - assert(msg.header(h_StatusLine).statusCode() < 200); - assert(msg.header(h_StatusLine).statusCode() > 100); + resip_assert(msg.isResponse()); + resip_assert(msg.header(h_StatusLine).statusCode() < 200); + resip_assert(msg.header(h_StatusLine).statusCode() > 100); //.dcm. Kept the following checks here rather than discardMessage as the // state machine can be affected(termination). // !dcm! should we really end the InviteSession or should be discard the 1xx instead? - if (msg.header(h_CSeq).sequence() != mLastLocalSessionModification->header(h_CSeq).sequence()) + // Check CSeq in 1xx against original INVITE request + if (msg.header(h_CSeq).sequence() != mDialog.mDialogSet.getCreator()->getLastRequest()->header(h_CSeq).sequence()) { InfoLog (<< "Failure: CSeq doesn't match invite: " << msg.brief()); onFailureAspect(getHandle(), msg); @@ -562,9 +576,9 @@ ClientInviteSession::handleProvisional(const SipMessage& msg) void ClientInviteSession::handleFinalResponse(const SipMessage& msg) { - assert(msg.isResponse()); - assert(msg.header(h_StatusLine).statusCode() >= 200); - assert(msg.header(h_StatusLine).statusCode() < 300); + resip_assert(msg.isResponse()); + resip_assert(msg.header(h_StatusLine).statusCode() >= 200); + resip_assert(msg.header(h_StatusLine).statusCode() < 300); handleSessionTimerResponse(msg); storePeerCapabilities(msg); @@ -572,7 +586,7 @@ ClientInviteSession::handleFinalResponse(const SipMessage& msg) } void -ClientInviteSession::handleOffer (const SipMessage& msg, const Contents& offer) +ClientInviteSession::handle1xxOffer(const SipMessage& msg, const Contents& offer) { InviteSessionHandler* handler = mDum.mInviteSessionHandler; @@ -583,27 +597,44 @@ ClientInviteSession::handleOffer (const SipMessage& msg, const Contents& offer) } void -ClientInviteSession::handleAnswer(const SipMessage& msg, const Contents& answer) +ClientInviteSession::handle1xxAnswer(const SipMessage& msg, const Contents& answer) { - //mCurrentLocalOfferAnswer = mProposedLocalOfferAnswer; setCurrentLocalOfferAnswer(msg); mCurrentEncryptionLevel = getEncryptionLevel(msg); mCurrentRemoteOfferAnswer = InviteSession::makeOfferAnswer(answer); InviteSessionHandler* handler = mDum.mInviteSessionHandler; handleProvisional(msg); + + // flag to let handle1xxAnswer know that it is OK to send an offer in the + // first PRACK (for a provisional with SDP answer) and to let providerOffer know + // that the offer will be going in an PRACK and not in an update. Flag is not + // needed after handle1xxAnswer is called so it is reset. + mAllowOfferInPrack = true; + handler->onAnswer(getSessionHandle(), msg, answer); - sendPrackIfNeeded(msg); + // Reset flag - no longer needed + mAllowOfferInPrack = false; + + // If offer is provided in onAnswer callback then send offer in PRACK + if(mProposedLocalOfferAnswer.get()) + { + sendPrack(*mProposedLocalOfferAnswer.get(), mProposedEncryptionLevel); + } + else + { + sendPrackIfNeeded(msg); + } } // will not include SDP (this is a subsequent 1xx) void ClientInviteSession::sendPrackIfNeeded(const SipMessage& msg) { - assert(msg.isResponse()); - assert(msg.header(h_StatusLine).statusCode() < 200); - assert(msg.header(h_StatusLine).statusCode() > 100); + resip_assert(msg.isResponse()); + resip_assert(msg.header(h_StatusLine).statusCode() < 200); + resip_assert(msg.header(h_StatusLine).statusCode() > 100); if (isReliable(msg)) { @@ -614,11 +645,12 @@ ClientInviteSession::sendPrackIfNeeded(const SipMessage& msg) } } -// This version is used to send an answer to the UAS in PRACK -// from EarlyWithOffer state. Assumes that it is the first PRACK. Subsequent -// PRACK will not have SDP +// This version is used to send an answer to the UAS in PRACK from EarlyWithOffer +// state. Assumes that it is the first PRACK. Subsequent PRACK will not have SDP +// Also used to send an offer in the first PRACK if the 18x included an +// answer. void -ClientInviteSession::sendPrack(const Contents& offerAnswer) +ClientInviteSession::sendPrack(const Contents& offerAnswer, DialogUsageManager::EncryptionLevel encryptionLevel) { SharedPtr prack(new SipMessage); mDialog.makeRequest(*prack, PRACK); @@ -626,44 +658,19 @@ ClientInviteSession::sendPrack(const Contents& offerAnswer) InviteSession::setOfferAnswer(*prack, offerAnswer); - // Remember last session modification. - // mLastSessionModification = prack; // ?slg? is this needed? - - DumHelper::setOutgoingEncryptionLevel(*prack, mCurrentEncryptionLevel); + DumHelper::setOutgoingEncryptionLevel(*prack, encryptionLevel); send(prack); } - -/* -bool -ClientInviteSession::isNextProvisional(const SipMessage& msg) -{ -} - -bool -ClientInviteSession::isRetransmission(const SipMessage& msg) -{ - if ( mLastReceivedRSeq == 0 || - msg.header(h_RSeq).value() <= mLastReceivedRSeq) - { - return false; - } - else - { - return true; - } -} -*/ - void ClientInviteSession::dispatchStart (const SipMessage& msg) { - assert(msg.isResponse()); - assert(msg.header(h_StatusLine).statusCode() > 100); - assert(msg.header(h_CSeq).method() == INVITE); + resip_assert(msg.isResponse()); + resip_assert(msg.header(h_StatusLine).statusCode() > 100); + resip_assert(msg.header(h_CSeq).method() == INVITE); InviteSessionHandler* handler = mDum.mInviteSessionHandler; - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); InviteSession::Event event = toEvent(msg, offerAnswer.get()); @@ -675,12 +682,12 @@ ClientInviteSession::dispatchStart (const SipMessage& msg) if(!isTerminated()) { handleProvisional(msg); - sendPrackIfNeeded(msg); //may wish to move emprty PRACK handling - //outside the state machine + sendPrackIfNeeded(msg); // may wish to move emprty PRACK handling + // outside the state machine } break; - case On1xxEarly: + case On1xxEarly: // only unreliable //!dcm! according to draft-ietf-sipping-offeranswer there can be a non // reliable 1xx followed by a reliable 1xx. Also, the intial 1xx // doesn't have to have an offer. However, DUM will only generate @@ -704,7 +711,7 @@ ClientInviteSession::dispatchStart (const SipMessage& msg) handler->onNewSession(getHandle(), InviteSession::Offer, msg); if(!isTerminated()) { - handleOffer(msg, *offerAnswer); + handle1xxOffer(msg, *offerAnswer); } break; @@ -713,7 +720,7 @@ ClientInviteSession::dispatchStart (const SipMessage& msg) handler->onNewSession(getHandle(), InviteSession::Answer, msg); if(!isTerminated()) { - handleAnswer(msg, *offerAnswer); + handle1xxAnswer(msg, *offerAnswer); } break; @@ -722,7 +729,7 @@ ClientInviteSession::dispatchStart (const SipMessage& msg) handleFinalResponse(msg); mProposedRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer); handler->onNewSession(getHandle(), InviteSession::Offer, msg); - assert(mProposedLocalOfferAnswer.get() == 0); + resip_assert(mProposedLocalOfferAnswer.get() == 0); mCurrentEncryptionLevel = getEncryptionLevel(msg); if(!isTerminated()) { @@ -738,7 +745,6 @@ ClientInviteSession::dispatchStart (const SipMessage& msg) transition(Connected); sendAck(); handleFinalResponse(msg); - //mCurrentLocalOfferAnswer = mProposedLocalOfferAnswer; setCurrentLocalOfferAnswer(msg); mCurrentEncryptionLevel = getEncryptionLevel(msg); mCurrentRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer); @@ -793,13 +799,14 @@ void ClientInviteSession::dispatchEarly (const SipMessage& msg) { InviteSessionHandler* handler = mDum.mInviteSessionHandler; - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); switch (toEvent(msg, offerAnswer.get())) { case On1xx: transition(UAC_Early); handleProvisional(msg); + sendPrackIfNeeded(msg); break; case On1xxEarly: // only unreliable @@ -814,19 +821,19 @@ ClientInviteSession::dispatchEarly (const SipMessage& msg) case On1xxOffer: transition(UAC_EarlyWithOffer); - handleOffer(msg, *offerAnswer); + handle1xxOffer(msg, *offerAnswer); break; case On1xxAnswer: transition(UAC_EarlyWithAnswer); - handleAnswer(msg, *offerAnswer); + handle1xxAnswer(msg, *offerAnswer); break; case On2xxOffer: transition(UAC_Answered); handleFinalResponse(msg); - assert(mProposedLocalOfferAnswer.get() == 0); + resip_assert(mProposedLocalOfferAnswer.get() == 0); mCurrentEncryptionLevel = getEncryptionLevel(msg); mProposedRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer); @@ -841,7 +848,6 @@ ClientInviteSession::dispatchEarly (const SipMessage& msg) transition(Connected); sendAck(); handleFinalResponse(msg); - //mCurrentLocalOfferAnswer = mProposedLocalOfferAnswer; setCurrentLocalOfferAnswer(msg); mCurrentEncryptionLevel = getEncryptionLevel(msg); mCurrentRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer); @@ -902,11 +908,13 @@ ClientInviteSession::dispatchEarly (const SipMessage& msg) { // ?slg? no offerAnswer in update - just respond immediately - do we need a callback? SharedPtr response(new SipMessage); - *mLastRemoteSessionModification = msg; mDialog.makeResponse(*response, msg, 200); send(response); break; } + + case On200Prack: + break; default: // !kh! @@ -920,7 +928,7 @@ void ClientInviteSession::dispatchAnswered (const SipMessage& msg) { //InviteSessionHandler* handler = mDum.mInviteSessionHandler; - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); switch (toEvent(msg, offerAnswer.get())) { @@ -972,7 +980,7 @@ void ClientInviteSession::dispatchEarlyWithOffer (const SipMessage& msg) { InviteSessionHandler* handler = mDum.mInviteSessionHandler; - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); switch (toEvent(msg, offerAnswer.get())) { @@ -1022,7 +1030,6 @@ ClientInviteSession::dispatchEarlyWithOffer (const SipMessage& msg) { // ?slg? no offerAnswer in update - just respond immediately - do we need a callback? SharedPtr response(new SipMessage); - *mLastRemoteSessionModification = msg; mDialog.makeResponse(*response, msg, 200); send(response); break; @@ -1040,7 +1047,7 @@ void ClientInviteSession::dispatchSentAnswer (const SipMessage& msg) { InviteSessionHandler* handler = mDum.mInviteSessionHandler; - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); switch (toEvent(msg, offerAnswer.get())) { @@ -1055,18 +1062,29 @@ ClientInviteSession::dispatchSentAnswer (const SipMessage& msg) onConnectedAspect(getHandle(), msg); break; - case On2xxAnswer: case On2xxOffer: + // RFC6337 section 3.1.2 recommends we ignore any illegal SDP here to be more interoperable + WarningLog(<< "Ignoring illegal SDP offer in 2xx: " << msg.brief()); + transition(Connected); + sendAck(); + handleFinalResponse(msg); + onConnectedAspect(getHandle(), msg); + break; + + case On2xxAnswer: case On1xxAnswer: - case On1xxOffer: sendAck(); sendBye(); - InfoLog (<< "Failure: illegal offer/answer: " << msg.brief()); + WarningLog(<< "Failure: illegal offer/answer: " << msg.brief()); transition(Terminated); onFailureAspect(getHandle(), msg); handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); break; + case On1xxOffer: + // RFC6337 section 3.1.2 recommends we ignore any illegal SDP here to be more interoperable + WarningLog(<< "Ignoring illegal SDP offer in 1xx: " << msg.brief()); + // No break is itentional case On1xx: handleProvisional(msg); sendPrackIfNeeded(msg); @@ -1101,7 +1119,7 @@ void ClientInviteSession::dispatchQueuedUpdate (const SipMessage& msg) { InviteSessionHandler* handler = mDum.mInviteSessionHandler; - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); switch (toEvent(msg, offerAnswer.get())) { @@ -1131,18 +1149,29 @@ ClientInviteSession::dispatchQueuedUpdate (const SipMessage& msg) onConnectedAspect(getHandle(), msg); break; - case On2xxAnswer: case On2xxOffer: + // RFC6337 section 3.1.2 recommends we ignore any illegal SDP here to be more interoperable + WarningLog(<< "Ignoring illegal SDP offer in 2xx: " << msg.brief()); + transition(Connected); + sendAck(); + handleFinalResponse(msg); + onConnectedAspect(getHandle(), msg); + break; + + case On2xxAnswer: case On1xxAnswer: - case On1xxOffer: sendAck(); sendBye(); - InfoLog (<< "Failure: illegal offer/answer: " << msg.brief()); + WarningLog(<< "Failure: illegal offer/answer: " << msg.brief()); transition(Terminated); onFailureAspect(getHandle(), msg); handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); break; + case On1xxOffer: + // RFC6337 section 3.1.2 recommends we ignore any illegal SDP here to be more interoperable + WarningLog(<< "Ignoring illegal SDP offer in 1xx: " << msg.brief()); + // No break is itentional case On1xx: handleProvisional(msg); sendPrackIfNeeded(msg); @@ -1179,21 +1208,19 @@ void ClientInviteSession::dispatchEarlyWithAnswer (const SipMessage& msg) { InviteSessionHandler* handler = mDum.mInviteSessionHandler; - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); switch (toEvent(msg, offerAnswer.get())) { + case On1xxOffer: + // RFC6337 section 3.1.1 recommends we ignore any illegal SDP here to be more interoperable + WarningLog(<< "Ignoring illegal SDP offer in 1xx: " << msg.brief()); + // No break is itentional case On1xx: handleProvisional(msg); sendPrackIfNeeded(msg); break; - case On1xxOffer: - if(!isTerminated()) - { - transition(UAC_EarlyWithOffer); - handleOffer(msg, *offerAnswer); - } - break; + case On2xx: transition(Connected); sendAck(); @@ -1201,11 +1228,19 @@ ClientInviteSession::dispatchEarlyWithAnswer (const SipMessage& msg) onConnectedAspect(getHandle(), msg); break; - case On2xxAnswer: case On2xxOffer: + // RFC6337 section 3.1.1 recommends we ignore any illegal SDP here to be more interoperable + WarningLog(<< "Ignoring illegal SDP offer in 2xx: " << msg.brief()); + transition(Connected); + sendAck(); + handleFinalResponse(msg); + onConnectedAspect(getHandle(), msg); + break; + + case On2xxAnswer: sendAck(); sendBye(); - InfoLog (<< "Failure: illegal offer/answer: " << msg.brief()); + WarningLog(<< "Failure: illegal offer/answer: " << msg.brief()); transition(Terminated); onFailureAspect(getHandle(), msg); handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); @@ -1223,7 +1258,6 @@ ClientInviteSession::dispatchEarlyWithAnswer (const SipMessage& msg) { // ?slg? no offerAnswer in update - just respond immediately - do we need a callback? SharedPtr response(new SipMessage); - *mLastRemoteSessionModification = msg; mDialog.makeResponse(*response, msg, 200); send(response); break; @@ -1246,6 +1280,18 @@ ClientInviteSession::dispatchEarlyWithAnswer (const SipMessage& msg) dispatchBye(msg); break; + case On200Prack: + // We may have sent a PRACK with an offer (if provideOffer was called from onAnswer + // from the first reliable provisional) - if so this will have SDP we need to call onAnswer + if(offerAnswer.get() && mProposedLocalOfferAnswer.get()) + { + setCurrentLocalOfferAnswer(msg); + mCurrentEncryptionLevel = getEncryptionLevel(msg); + mCurrentRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer); + handler->onAnswer(getSessionHandle(), msg, *offerAnswer); + } + break; + default: // !kh! // should not assert here for peer sent us garbage. @@ -1258,7 +1304,7 @@ void ClientInviteSession::dispatchSentUpdateEarly (const SipMessage& msg) { InviteSessionHandler* handler = mDum.mInviteSessionHandler; - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); switch (toEvent(msg, offerAnswer.get())) { @@ -1282,7 +1328,6 @@ ClientInviteSession::dispatchSentUpdateEarly (const SipMessage& msg) { // ?slg? no offerAnswer in update - just respond immediately - do we need a callback? SharedPtr response(new SipMessage); - *mLastRemoteSessionModification = msg; mDialog.makeResponse(*response, msg, 200); send(response); break; @@ -1312,6 +1357,9 @@ ClientInviteSession::dispatchSentUpdateEarly (const SipMessage& msg) mDum.destroy(this); break; + case On200Prack: + break; + default: WarningLog (<< "Don't know what this is : " << msg); break; @@ -1322,7 +1370,7 @@ void ClientInviteSession::dispatchSentUpdateEarlyGlare (const SipMessage& msg) { InviteSessionHandler* handler = mDum.mInviteSessionHandler; - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); switch (toEvent(msg, offerAnswer.get())) { @@ -1360,21 +1408,28 @@ ClientInviteSession::dispatchSentUpdateEarlyGlare (const SipMessage& msg) } void -ClientInviteSession::dispatchReceivedUpdateEarly (const SipMessage& msg) +ClientInviteSession::dispatchReceivedUpdateEarly(const SipMessage& msg) { - /* - InviteSessionHandler* handler = mDum.mInviteSessionHandler; - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); switch (toEvent(msg, offerAnswer.get())) { + case OnUpdate: + case OnUpdateOffer: + // If we receive an UPDATE before we have generated a final response to a previous UPDATE on the + // same dialog, then we MUST return a 500 response with a Retry-After header (random duration 0-10 seconds) + { + SharedPtr u500(new SipMessage); + mDialog.makeResponse(*u500, msg, 500); + u500->header(h_RetryAfter).value() = Random::getRandom() % 10; + send(u500); + } + break; + default: - // !kh! - // should not assert here for peer sent us garbage. WarningLog (<< "Don't know what this is : " << msg); break; } - */ WarningLog (<< "Ignoring message received in ReceivedUpdateEarly: " << msg); } @@ -1382,7 +1437,7 @@ void ClientInviteSession::dispatchCancelled (const SipMessage& msg) { InviteSessionHandler* handler = mDum.mInviteSessionHandler; - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); switch (toEvent(msg, offerAnswer.get())) { @@ -1422,7 +1477,7 @@ ClientInviteSession::dispatchCancelled (const SipMessage& msg) //true if 180rel should be ignored. Saves rseq as a side effect. bool -ClientInviteSession::checkRseq(const SipMessage& msg) +ClientInviteSession::isBadRseq(const SipMessage& msg) { int code = msg.isResponse() ? msg.header(h_StatusLine).statusCode() : 0; if (msg.method() == INVITE && code > 100 && code < 200) diff --git a/src/libs/resiprocate/resip/dum/ClientInviteSession.hxx b/src/libs/resiprocate/resip/dum/ClientInviteSession.hxx index 7e4d2164..e473b0ca 100644 --- a/src/libs/resiprocate/resip/dum/ClientInviteSession.hxx +++ b/src/libs/resiprocate/resip/dum/ClientInviteSession.hxx @@ -64,10 +64,10 @@ class ClientInviteSession : public InviteSession void handleRedirect (const SipMessage& msg); void handleProvisional (const SipMessage& msg); void handleFinalResponse (const SipMessage& msg); - void handleOffer (const SipMessage& msg, const Contents& offer); - void handleAnswer (const SipMessage& msg, const Contents& answer); + void handle1xxOffer (const SipMessage& msg, const Contents& offer); + void handle1xxAnswer (const SipMessage& msg, const Contents& answer); void sendPrackIfNeeded(const SipMessage& msg); - void sendPrack(const Contents& offerAnswer); + void sendPrack(const Contents& offerAnswer, DialogUsageManager::EncryptionLevel encryptionLevel); // Called by the DialogSet (friend) when the app has CANCELed the request void cancel(); @@ -75,7 +75,7 @@ class ClientInviteSession : public InviteSession // Called by the DialogSet when it receives a 2xx response void onForkAccepted(); - bool checkRseq(const SipMessage& msg); + bool isBadRseq(const SipMessage& msg); private: void startCancelTimer(); void startStaleCallTimer(); @@ -85,12 +85,13 @@ class ClientInviteSession : public InviteSession void onProvisionalAspect(ClientInviteSessionHandle c, const SipMessage& msg); void onFailureAspect(ClientInviteSessionHandle c, const SipMessage& msg); - std::unique_ptr mEarlyMedia; + std::auto_ptr mEarlyMedia; RAckCategory mRelRespInfo; unsigned int mStaleCallTimerSeq; - unsigned int mCancelledTimerSeq; + unsigned int mCancelledTimerSeq; ServerSubscriptionHandle mServerSub; + bool mAllowOfferInPrack; // disabled ClientInviteSession(const ClientInviteSession&); diff --git a/src/libs/resiprocate/resip/dum/ClientOutOfDialogReq.cxx b/src/libs/resiprocate/resip/dum/ClientOutOfDialogReq.cxx index 1824a51e..4f83ccdc 100644 --- a/src/libs/resiprocate/resip/dum/ClientOutOfDialogReq.cxx +++ b/src/libs/resiprocate/resip/dum/ClientOutOfDialogReq.cxx @@ -38,7 +38,7 @@ ClientOutOfDialogReq::end() void ClientOutOfDialogReq::dispatch(const SipMessage& msg) { - assert(msg.isResponse()); + resip_assert(msg.isResponse()); if (msg.header(h_StatusLine).statusCode() >= 200) { diff --git a/src/libs/resiprocate/resip/dum/ClientPagerMessage.cxx b/src/libs/resiprocate/resip/dum/ClientPagerMessage.cxx index d1e73ae3..79c12e27 100644 --- a/src/libs/resiprocate/resip/dum/ClientPagerMessage.cxx +++ b/src/libs/resiprocate/resip/dum/ClientPagerMessage.cxx @@ -113,10 +113,9 @@ ClientPagerMessage::getMessageRequest() } void -ClientPagerMessage::page(std::unique_ptr contents, - DialogUsageManager::EncryptionLevel level) +ClientPagerMessage::page(std::auto_ptr contents, DialogUsageManager::EncryptionLevel level) { - assert(contents.get() != 0); + resip_assert(contents.get() != 0); bool do_page = mMsgQueue.empty(); Item item; item.contents = contents.release(); @@ -124,89 +123,129 @@ ClientPagerMessage::page(std::unique_ptr contents, mMsgQueue.push_back(item); if(do_page) { - this->pageFirstMsgQueued(); + pageFirstMsgQueued(); } } class ClientPagerMessagePageCommand : public DumCommandAdapter { public: - ClientPagerMessagePageCommand(ClientPagerMessage& clientPagerMessage, - std::unique_ptr contents, + ClientPagerMessagePageCommand(const ClientPagerMessageHandle& clientPagerMessageHandle, + std::auto_ptr contents, DialogUsageManager::EncryptionLevel level) - : mClientPagerMessage(clientPagerMessage), - mContents(std::move(contents)), - mLevel(level) - { - + : mClientPagerMessageHandle(clientPagerMessageHandle), + mContents(contents), + mLevel(level) + { } virtual void executeCommand() { - mClientPagerMessage.page(std::move(mContents), mLevel); + if(mClientPagerMessageHandle.isValid()) + { + mClientPagerMessageHandle->page(mContents, mLevel); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const { return strm << "ClientPagerMessagePageCommand"; } + private: - ClientPagerMessage& mClientPagerMessage; - std::unique_ptr mContents; + ClientPagerMessageHandle mClientPagerMessageHandle; + std::auto_ptr mContents; DialogUsageManager::EncryptionLevel mLevel; }; void -ClientPagerMessage::pageCommand(std::unique_ptr contents, +ClientPagerMessage::pageCommand(std::auto_ptr contents, DialogUsageManager::EncryptionLevel level) { - mDum.post(new ClientPagerMessagePageCommand(*this, std::move(contents), level)); + mDum.post(new ClientPagerMessagePageCommand(getHandle(), contents, level)); +} + +// Use this API if the application has ongoing pending messages and it is using +// getMessageRequest to modify the target routing information for messsages (ie: +// requestUri or Route headers). This will cause the current pending message to +// be re-sent immediately using the new information that the application just set. +// Any onSuccess or onFailure callbacks that might result from the active pending +// message at the time this is called will be supressed. Any messages queued +// behind that message will be dispatched sequentially to the new target. +void +ClientPagerMessage::newTargetInfoSet() +{ + if (mMsgQueue.empty() == false) + { + // Note: calling this will cause mRequest->header(h_CSeq) to get a new value + // and the responses to the currently pending MESSAGE will be ignored + pageFirstMsgQueued(); + } } void ClientPagerMessage::dispatch(const SipMessage& msg) { - assert(msg.isResponse()); + resip_assert(msg.isResponse()); ClientPagerMessageHandler* handler = mDum.mClientPagerMessageHandler; - assert(handler); + resip_assert(handler); int code = msg.header(h_StatusLine).statusCode(); - DebugLog ( << "ClientPagerMessageReq::dispatch(msg)" << msg.brief() ); + DebugLog ( << "ClientPagerMessageReq::dispatch(msg)" << msg.brief()); { - assert(mMsgQueue.empty() == false); if (code < 200) { DebugLog ( << "ClientPagerMessageReq::dispatch - encountered provisional response" << msg.brief() ); } else if (code < 300) { - if(mMsgQueue.empty() == false) - { - delete mMsgQueue.front().contents; - mMsgQueue.pop_front(); - if(mMsgQueue.empty() == false) - { - this->pageFirstMsgQueued(); - } - - handler->onSuccess(getHandle(), msg); - } + // if cseq doesn't match last message paged then someone must have called newTargetInfoSet + // we want to supress the onSuccess callback and logic, since we re-sent this first queued + // item to a new target + if (msg.header(h_CSeq).sequence() == mRequest->header(h_CSeq).sequence()) + { + if (mMsgQueue.empty() == false) + { + delete mMsgQueue.front().contents; + mMsgQueue.pop_front(); + if (mMsgQueue.empty() == false) + { + this->pageFirstMsgQueued(); + } + } + handler->onSuccess(getHandle(), msg); + } } else { - SipMessage errResponse; - MsgQueue::iterator contents; - for(contents = mMsgQueue.begin(); contents != mMsgQueue.end(); ++contents) - { - Contents* p = contents->contents; - WarningLog ( << "Paging failed " << *p ); - Helper::makeResponse(errResponse, *mRequest, code); - handler->onFailure(getHandle(), errResponse, std::unique_ptr(p)); - contents->contents = 0; - } - mMsgQueue.clear(); + // if cseq doesn't match last message paged then someone must have called newTargetInfoSet + // we want to supress the onFailure callback and logic, since we re-sent this first queued + // item to a new target + if (msg.header(h_CSeq).sequence() == mRequest->header(h_CSeq).sequence()) + { + if (!mMsgQueue.empty()) + { + // if cseq doesn't match first queued element - someone must have called newTargetInfoSet + // we want to supress the onFailure callback and logic, since we re-sent this first queued item to a new target + SipMessage errResponse; + MsgQueue::iterator contents; + for (contents = mMsgQueue.begin(); contents != mMsgQueue.end(); ++contents) + { + Contents* p = contents->contents; + WarningLog(<< "Paging failed " << *p); + Helper::makeResponse(errResponse, *mRequest, code); + handler->onFailure(getHandle(), errResponse, std::auto_ptr(p)); + contents->contents = 0; + } + mMsgQueue.clear(); + } + else + { + handler->onFailure(getHandle(), msg, std::auto_ptr(mRequest->releaseContents())); + } + } } } } @@ -254,15 +293,15 @@ ClientPagerMessage::endCommand() } size_t -ClientPagerMessage::msgQueued () const +ClientPagerMessage::msgQueued() const { return mMsgQueue.size(); } void -ClientPagerMessage::pageFirstMsgQueued () +ClientPagerMessage::pageFirstMsgQueued() { - assert(mMsgQueue.empty() == false); + resip_assert(mMsgQueue.empty() == false); mRequest->header(h_CSeq).sequence()++; mRequest->setContents(mMsgQueue.front().contents); DumHelper::setOutgoingEncryptionLevel(*mRequest, mMsgQueue.front().encryptionLevel); @@ -271,7 +310,7 @@ ClientPagerMessage::pageFirstMsgQueued () } void -ClientPagerMessage::clearMsgQueued () +ClientPagerMessage::clearMsgQueued() { MsgQueue::iterator contents; for(contents = mMsgQueue.begin(); contents != mMsgQueue.end(); ++contents) diff --git a/src/libs/resiprocate/resip/dum/ClientPagerMessage.hxx b/src/libs/resiprocate/resip/dum/ClientPagerMessage.hxx index 92e60f23..6587551e 100644 --- a/src/libs/resiprocate/resip/dum/ClientPagerMessage.hxx +++ b/src/libs/resiprocate/resip/dum/ClientPagerMessage.hxx @@ -23,24 +23,34 @@ class ClientPagerMessage : public NonDialogUsage //I don't know how this would interact with the queuing mechanism. //Will come back to re-visit this in the future. SipMessage& getMessageRequest(); + SharedPtr getMessageRequestSharedPtr() { return mRequest; } //!kh! //queues the message if there is one sent but not yet received a response //for it. //asserts if contents->get() is NULL. - virtual void page(std::unique_ptr contents, DialogUsageManager::EncryptionLevel level=DialogUsageManager::None); + virtual void page(std::auto_ptr contents, DialogUsageManager::EncryptionLevel level=DialogUsageManager::None); virtual void end(); + // Use this API if the application has ongoing pending messages and it is using + // getMessageRequest to modify the target routing information for messages (ie: + // requestUri or Route headers). This will cause the current pending message to + // be re-sent immediately using the new information that the application just set. + // Any onSuccess or onFailure callbacks that might result from the active pending + // message at the time this is called will be suppressed. Any messages queued + // behind that message will be dispatched sequentially to the new target. + void newTargetInfoSet(); + /** * Provide asynchronous method access by using command */ virtual void endCommand(); - virtual void pageCommand(std::unique_ptr contents, DialogUsageManager::EncryptionLevel level=DialogUsageManager::None); + virtual void pageCommand(std::auto_ptr contents, DialogUsageManager::EncryptionLevel level=DialogUsageManager::None); virtual void dispatch(const SipMessage& msg); virtual void dispatch(const DumTimeout& timer); - size_t msgQueued () const; + size_t msgQueued() const; virtual EncodeStream& dump(EncodeStream& strm) const; @@ -68,8 +78,8 @@ class ClientPagerMessage : public NonDialogUsage ClientPagerMessage(const ClientPagerMessage&); ClientPagerMessage& operator=(const ClientPagerMessage&); - void pageFirstMsgQueued (); - void clearMsgQueued (); + void pageFirstMsgQueued(); + void clearMsgQueued(); }; } diff --git a/src/libs/resiprocate/resip/dum/ClientPublication.cxx b/src/libs/resiprocate/resip/dum/ClientPublication.cxx index 42f9aaad..c9b81080 100644 --- a/src/libs/resiprocate/resip/dum/ClientPublication.cxx +++ b/src/libs/resiprocate/resip/dum/ClientPublication.cxx @@ -1,4 +1,4 @@ -#include +#include "rutil/ResipAssert.h" #include "resip/stack/Helper.hxx" #include "resip/stack/SipMessage.hxx" @@ -24,8 +24,10 @@ ClientPublication::ClientPublication(DialogUsageManager& dum, DialogSet& dialogSet, SharedPtr req) : NonDialogUsage(dum, dialogSet), + mPublished(false), mWaitingForResponse(false), mPendingPublish(false), + mPendingEnd(false), mPublish(req), mEventType(req->header(h_Event).value()), mTimerSeq(0), @@ -50,14 +52,28 @@ ClientPublication::end() void ClientPublication::end(bool immediate) { - InfoLog (<< "End client publication to " << mPublish->header(h_RequestLine).uri()); - if(!immediate) + if (immediate) { + InfoLog(<< "End client publication immediately to " << mPublish->header(h_RequestLine).uri()); + delete this; + return; + } + if (mWaitingForResponse) + { + InfoLog(<< "Waiting for response, pending End of client publication to " << mPublish->header(h_RequestLine).uri()); + mPendingEnd = true; + return; + } + if (mPublished) + { + InfoLog(<< "End client publication to " << mPublish->header(h_RequestLine).uri()); mPublish->header(h_Expires).value() = 0; + mPublish->releaseContents(); send(mPublish); } else { + InfoLog(<< "End client publication immediately (not published) to " << mPublish->header(h_RequestLine).uri()); delete this; } } @@ -65,15 +81,17 @@ ClientPublication::end(bool immediate) class ClientPublicationEndCommand : public DumCommandAdapter { public: - ClientPublicationEndCommand(ClientPublication& clientPublication, bool immediate) - : mClientPublication(clientPublication), mImmediate(immediate) + ClientPublicationEndCommand(const ClientPublicationHandle& clientPublicationHandle, bool immediate) + : mClientPublicationHandle(clientPublicationHandle), mImmediate(immediate) { - } virtual void executeCommand() { - mClientPublication.end(mImmediate); + if(mClientPublicationHandle.isValid()) + { + mClientPublicationHandle->end(mImmediate); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -81,21 +99,21 @@ public: return strm << "ClientPublicationEndCommand"; } private: - ClientPublication& mClientPublication; + ClientPublicationHandle mClientPublicationHandle; bool mImmediate; }; void ClientPublication::endCommand(bool immediate) { - mDum.post(new ClientPublicationEndCommand(*this, immediate)); + mDum.post(new ClientPublicationEndCommand(getHandle(), immediate)); } void ClientPublication::dispatch(const SipMessage& msg) { ClientPublicationHandler* handler = mDum.getClientPublicationHandler(mEventType); - assert(handler); + resip_assert(handler); if (msg.isRequest()) { @@ -109,11 +127,12 @@ ClientPublication::dispatch(const SipMessage& msg) return; } - assert(code >= 200); + resip_assert(code >= 200); mWaitingForResponse = false; if (code < 300) { + mPublished = true; if (mPublish->exists(h_Expires) && mPublish->header(h_Expires).value() == 0) { handler->onRemove(getHandle(), msg); @@ -125,7 +144,7 @@ ClientPublication::dispatch(const SipMessage& msg) mPublish->header(h_SIPIfMatch) = msg.header(h_SIPETag); if(!mPendingPublish) { - mPublish->releaseContents(); + mPublish->releaseContents(); } mDum.addTimer(DumTimeout::Publication, Helper::aBitSmallerThan(msg.header(h_Expires).value()), @@ -167,7 +186,7 @@ ClientPublication::dispatch(const SipMessage& msg) } } else if (code == 408 || - (code == 503 && msg.getReceivedTransport() == 0) || + (code == 503 && !msg.isFromWire()) || ((code == 404 || code == 413 || code == 480 || @@ -208,7 +227,6 @@ ClientPublication::dispatch(const SipMessage& msg) getBaseHandle(), ++mTimerSeq); return; - } } else @@ -217,10 +235,26 @@ ClientPublication::dispatch(const SipMessage& msg) delete this; return; } - } - if (mPendingPublish) + if (mPendingEnd) + { + mPendingEnd = false; + if (mPublished) + { + mPublish->header(h_Expires).value() = 0; + mPublish->releaseContents(); + InfoLog(<< "Sending pending end PUBLISH: " << mPublish->brief()); + send(mPublish); + } + else + { + InfoLog(<< "Pending end PUBLISH, but not published, so ending immediately: " << mPublish->brief()); + delete this; + return; + } + } + else if (mPendingPublish) { InfoLog (<< "Sending pending PUBLISH: " << mPublish->brief()); send(mPublish); @@ -240,9 +274,9 @@ ClientPublication::dispatch(const DumTimeout& timer) void ClientPublication::refresh(unsigned int expiration) { - if (expiration == 0 && mPublish->exists(h_Expires)) + if (expiration != 0) { - expiration = mPublish->header(h_Expires).value(); + mPublish->header(h_Expires).value() = expiration; } send(mPublish); } @@ -250,16 +284,18 @@ ClientPublication::refresh(unsigned int expiration) class ClientPublicationRefreshCommand : public DumCommandAdapter { public: - ClientPublicationRefreshCommand(ClientPublication& clientPublication, unsigned int expiration) - : mClientPublication(clientPublication), + ClientPublicationRefreshCommand(const ClientPublicationHandle& clientPublicationHandle, unsigned int expiration) + : mClientPublicationHandle(clientPublicationHandle), mExpiration(expiration) { - } virtual void executeCommand() { - mClientPublication.refresh(mExpiration); + if(mClientPublicationHandle.isValid()) + { + mClientPublicationHandle->refresh(mExpiration); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -268,14 +304,14 @@ public: } private: - ClientPublication& mClientPublication; + ClientPublicationHandle mClientPublicationHandle; unsigned int mExpiration; }; void ClientPublication::refreshCommand(unsigned int expiration) { - mDum.post(new ClientPublicationRefreshCommand(*this, expiration)); + mDum.post(new ClientPublicationRefreshCommand(getHandle(), expiration)); } void @@ -303,16 +339,18 @@ ClientPublication::update(const Contents* body) class ClientPublicationUpdateCommand : public DumCommandAdapter { public: - ClientPublicationUpdateCommand(ClientPublication& clientPublication, const Contents* body) - : mClientPublication(clientPublication), + ClientPublicationUpdateCommand(const ClientPublicationHandle& clientPublicationHandle, const Contents* body) + : mClientPublicationHandle(clientPublicationHandle), mBody(body?body->clone():0) { - } virtual void executeCommand() { - mClientPublication.update(mBody.get()); + if(mClientPublicationHandle.isValid()) + { + mClientPublicationHandle->update(mBody.get()); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -321,14 +359,14 @@ public: } private: - ClientPublication& mClientPublication; - std::unique_ptr mBody; + ClientPublicationHandle mClientPublicationHandle; + std::auto_ptr mBody; }; void ClientPublication::updateCommand(const Contents* body) { - mDum.post(new ClientPublicationUpdateCommand(*this, body)); + mDum.post(new ClientPublicationUpdateCommand(getHandle(), body)); } void diff --git a/src/libs/resiprocate/resip/dum/ClientPublication.hxx b/src/libs/resiprocate/resip/dum/ClientPublication.hxx index c602f0df..c0688523 100644 --- a/src/libs/resiprocate/resip/dum/ClientPublication.hxx +++ b/src/libs/resiprocate/resip/dum/ClientPublication.hxx @@ -41,8 +41,10 @@ class ClientPublication : public NonDialogUsage private: friend class DialogSet; + bool mPublished; bool mWaitingForResponse; bool mPendingPublish; + bool mPendingEnd; SharedPtr mPublish; Data mEventType; diff --git a/src/libs/resiprocate/resip/dum/ClientRegistration.cxx b/src/libs/resiprocate/resip/dum/ClientRegistration.cxx index eabbd448..eb2822ea 100644 --- a/src/libs/resiprocate/resip/dum/ClientRegistration.cxx +++ b/src/libs/resiprocate/resip/dum/ClientRegistration.cxx @@ -2,7 +2,6 @@ #include #include "resip/stack/Helper.hxx" -#include "resip/stack/ExtensionHeader.hxx" #include "resip/dum/BaseCreator.hxx" #include "resip/dum/ClientAuthManager.hxx" #include "resip/dum/ClientRegistration.hxx" @@ -15,20 +14,21 @@ #include "rutil/Inserter.hxx" #include "rutil/Random.hxx" #include "rutil/ParseBuffer.hxx" +#include "rutil/TransportType.hxx" #include "rutil/WinLeakCheck.hxx" -#include "rutil/AtomicCounter.hxx" + #define RESIPROCATE_SUBSYSTEM Subsystem::DUM using namespace resip; +static const UInt32 UnreasonablyLowExpirationThreshold = 7; // The threshold before which we consider a contacts expiry to be unreasonably low + ClientRegistrationHandle ClientRegistration::getHandle() { return ClientRegistrationHandle(mDum, getBaseHandle().getId()); } -AtomicCounter ClientRegistration::InstanceCounter; - ClientRegistration::ClientRegistration(DialogUsageManager& dum, DialogSet& dialogSet, SharedPtr request) @@ -36,19 +36,25 @@ ClientRegistration::ClientRegistration(DialogUsageManager& dum, mLastRequest(request), mTimerSeq(0), mState(mLastRequest->exists(h_Contacts) ? Adding : Querying), + mEnding(false), mEndWhenDone(false), mUserRefresh(false), mRegistrationTime(mDialogSet.mUserProfile->getDefaultRegistrationTime()), mExpires(0), + mRefreshTime(0), mQueuedState(None), - mQueuedRequest(new SipMessage), - mCustomHeader(false) + mQueuedRequest(new SipMessage) { - InstanceCounter.increment(); // If no Contacts header, this is a query if (mLastRequest->exists(h_Contacts)) { - mMyContacts = mLastRequest->header(h_Contacts); + NameAddr all; + all.setAllContacts(); + if(!(mLastRequest->header(h_Contacts).front() == all)) + { + // store if not special all contacts header + mMyContacts = mLastRequest->header(h_Contacts); + } } if(mLastRequest->exists(h_Expires) && @@ -67,7 +73,6 @@ ClientRegistration::~ClientRegistration() // !dcm! Will not interact well with multiple registrations from the same AOR mDialogSet.mUserProfile->setServiceRoute(NameAddrs()); - InstanceCounter.decrement(); } void @@ -100,7 +105,7 @@ ClientRegistration::tryModification(ClientRegistration::State state) } } - assert(mQueuedState == None); + resip_assert(mQueuedState == None); mState = state; return mLastRequest; @@ -117,8 +122,6 @@ ClientRegistration::addBinding(const NameAddr& contact, UInt32 registrationTime) mRegistrationTime = registrationTime; next->header(h_Expires).value() = mRegistrationTime; next->header(h_CSeq).sequence()++; - updateWithCustomHeader(next); - // caller prefs if (mQueuedState == None) @@ -145,7 +148,6 @@ ClientRegistration::removeBinding(const NameAddr& contact) next->header(h_Contacts).push_back(*i); next->header(h_Expires).value() = 0; next->header(h_CSeq).sequence()++; - updateWithCustomHeader(next); if (mQueuedState == None) { @@ -182,7 +184,7 @@ ClientRegistration::removeAll(bool stopRegisteringWhenDone) next->header(h_Expires).value() = 0; next->header(h_CSeq).sequence()++; mEndWhenDone = stopRegisteringWhenDone; - updateWithCustomHeader(next); + if (mQueuedState == None) { send(next); @@ -226,6 +228,13 @@ ClientRegistration::removeMyBindings(bool stopRegisteringWhenDone) if (mQueuedState == None) { + if(mEnding && whenExpires() == 0) + { + resip_assert(mEndWhenDone); // will always be true when mEnding is true + // We are not actually registered, and we are ending - no need to send un-register - just terminate now + stopRegistering(); + return; + } send(next); } } @@ -233,15 +242,18 @@ ClientRegistration::removeMyBindings(bool stopRegisteringWhenDone) class ClientRegistrationRemoveMyBindings : public DumCommandAdapter { public: - ClientRegistrationRemoveMyBindings(ClientRegistration& clientRegistration, bool stopRegisteringWhenDone) - : mClientRegistration(clientRegistration), + ClientRegistrationRemoveMyBindings(const ClientRegistrationHandle& clientRegistrationHandle, bool stopRegisteringWhenDone) + : mClientRegistrationHandle(clientRegistrationHandle), mStopRegisteringWhenDone(stopRegisteringWhenDone) { } virtual void executeCommand() { - mClientRegistration.removeMyBindings(mStopRegisteringWhenDone); + if(mClientRegistrationHandle.isValid()) + { + mClientRegistrationHandle->removeMyBindings(mStopRegisteringWhenDone); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -249,14 +261,14 @@ public: return strm << "ClientRegistrationRemoveMyBindings"; } private: - ClientRegistration& mClientRegistration; + ClientRegistrationHandle mClientRegistrationHandle; bool mStopRegisteringWhenDone; }; void ClientRegistration::removeMyBindingsCommand(bool stopRegisteringWhenDone) { - mDum.post(new ClientRegistrationRemoveMyBindings(*this, stopRegisteringWhenDone)); + mDum.post(new ClientRegistrationRemoveMyBindings(getHandle(), stopRegisteringWhenDone)); } void @@ -277,7 +289,7 @@ ClientRegistration::requestRefresh(UInt32 expires) void ClientRegistration::internalRequestRefresh(UInt32 expires) { - if(mState == RetryAdding && mState == RetryRefreshing) + if(mState == RetryAdding || mState == RetryRefreshing) { // disable retry time and try refresh immediately ++mTimerSeq; @@ -288,14 +300,19 @@ ClientRegistration::internalRequestRefresh(UInt32 expires) return; } + // check if refresh really required + if(!mDum.mClientRegistrationHandler->onRefreshRequired(getHandle(), *mLastRequest)) + { + InfoLog (<< "application doesn't want to refresh " << *this); + end(); + return; + } + InfoLog (<< "requesting refresh of " << *this); mState = Refreshing; mLastRequest->header(h_CSeq).sequence()++; mLastRequest->header(h_Contacts)=mMyContacts; - - updateWithCustomHeader(mLastRequest); - if(expires > 0) { mRegistrationTime = expires; @@ -320,30 +337,41 @@ ClientRegistration::allContacts() UInt32 ClientRegistration::whenExpires() const { -// !cj! - TODO - I'm suspisious these time are getting confused on what units they are in UInt64 now = Timer::getTimeSecs(); - UInt64 ret = mExpires - now; - return (UInt32)ret; + if(mExpires > now) + { + return (UInt32)(mExpires - now); + } + else + { + return 0; + } } void ClientRegistration::end() { - removeMyBindings(true); + if(!mEnding) + { + mEnding = true; + removeMyBindings(true); + } } class ClientRegistrationEndCommand : public DumCommandAdapter { public: - ClientRegistrationEndCommand(ClientRegistration& clientRegistration) - : mClientRegistration(clientRegistration) + ClientRegistrationEndCommand(const ClientRegistrationHandle& clientRegistrationHandle) + : mClientRegistrationHandle(clientRegistrationHandle) { - } virtual void executeCommand() { - mClientRegistration.end(); + if(mClientRegistrationHandle.isValid()) + { + mClientRegistrationHandle->end(); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -351,13 +379,13 @@ public: return strm << "ClientRegistrationEndCommand"; } private: - ClientRegistration& mClientRegistration; + ClientRegistrationHandle mClientRegistrationHandle; }; void ClientRegistration::endCommand() { - mDum.post(new ClientRegistrationEndCommand(*this)); + mDum.post(new ClientRegistrationEndCommand(getHandle())); } EncodeStream& @@ -373,7 +401,7 @@ ClientRegistration::dispatch(const SipMessage& msg) try { // !jf! there may be repairable errors that we can handle here - assert(msg.isResponse()); + resip_assert(msg.isResponse()); const int& code = msg.header(h_StatusLine).statusCode(); bool nextHopSupportsOutbound = false; int keepAliveTime = 0; @@ -405,14 +433,13 @@ ClientRegistration::dispatch(const SipMessage& msg) } } - if(msg.isExternal()) + if(msg.isFromWire()) { - const Data& receivedTransport = msg.header(h_Vias).front().transport(); + resip::TransportType receivedTransport = toTransportType( + msg.header(h_Vias).front().transport()); if(keepAliveTime == 0) { - if(receivedTransport == Symbols::TCP || - receivedTransport == Symbols::TLS || - receivedTransport == Symbols::SCTP) + if(isReliable(receivedTransport)) { keepAliveTime = mDialogSet.mUserProfile->getKeepAliveTimeForStream(); } @@ -485,7 +512,9 @@ ClientRegistration::dispatch(const SipMessage& msg) // !ah! take list of ctcs and push into mMy or mOther as required. // make timers to re-register + UInt64 nowSecs = Timer::getTimeSecs(); UInt32 expiry = calculateExpiry(msg); + mExpires = nowSecs + expiry; if(msg.exists(h_Contacts)) { mAllContacts = msg.header(h_Contacts); @@ -497,10 +526,10 @@ ClientRegistration::dispatch(const SipMessage& msg) if (expiry != 0 && expiry != UINT_MAX) { - if(expiry>=7) + if(expiry >= UnreasonablyLowExpirationThreshold) { int exp = Helper::aBitSmallerThan(expiry); - mExpires = exp + Timer::getTimeSecs(); + mRefreshTime = exp + nowSecs; mDum.addTimer(DumTimeout::Registration, exp, getBaseHandle(), @@ -571,6 +600,13 @@ ClientRegistration::dispatch(const SipMessage& msg) if (mQueuedState != None) { + if(mQueuedState == Removing && mEnding && whenExpires() == 0) + { + resip_assert(mEndWhenDone); // will always be true when mEnding is true + // We are not actually registered, and we are ending - no need to send un-register - just terminate now + stopRegistering(); + return; + } InfoLog (<< "Sending queued request: " << *mQueuedRequest); mState = mQueuedState; mQueuedState = None; @@ -595,7 +631,7 @@ ClientRegistration::dispatch(const SipMessage& msg) return; } } - else if (code == 408 || (code == 503 && msg.getReceivedTransport() == 0)) + else if (code == 408 || (code == 503 && !msg.isFromWire())) { int retry = mDum.mClientRegistrationHandler->onRequestRetry(getHandle(), 0, msg); @@ -615,7 +651,7 @@ ClientRegistration::dispatch(const SipMessage& msg) else { DebugLog(<< "Application requested delayed retry on 408 or internal 503: " << retry); - mExpires = 0; + mRefreshTime = 0; switch(mState) { case Adding: @@ -625,7 +661,7 @@ ClientRegistration::dispatch(const SipMessage& msg) mState = RetryRefreshing; break; default: - assert(false); + resip_assert(false); break; } if(mDum.mClientAuthManager.get()) mDum.mClientAuthManager.get()->clearAuthenticationState(DialogSetId(*mLastRequest)); @@ -777,20 +813,55 @@ ClientRegistration::calculateExpiry(const SipMessage& reg200) const const NameAddrs& contacts(reg200.header(h_Contacts)); + // We are going to track two things here: + // 1. expiry - the lowest expiration value of all of our contacts + // 2. reasonableExpiry - the lowest expiration value of all of our contacts + // that is above the UnreasonablyLowExpirationThreshold (7 seconds) + // Before we return, if expiry is less than UnreasonablyLowExpirationThreshold + // but we had another contact that had a reasonable expiry value, then return + // that value instead. This logic covers a very interesting scenario: + // + // Consider the case where we are registered over TCP due to DNS SRV record + // configuration. Let's say an administrator reconfigures the DNS records to + // now make UDP the preferred transport. When we re-register we will now + // send the re-registration message over UDP. This will cause our contact + // address to be changed (ie: ;tranport=tcp will no longer exist). So for a + // short period of time the registrar will return two contacts to us, both + // belonging to us, one for TCP and one for UDP. The TCP one will expire in + // a short amount of time, and if we return this expiry to the dispatch() + // method then it will cause the ClientRegistration to end (see logic in + // dispatch() that prints out the error "Server is using an unreasonably low + // expiry: "... + unsigned long reasonableExpiry = 0xFFFFFFFF; + for(NameAddrs::const_iterator c=contacts.begin();c!=contacts.end();++c) { // Our expiry is never going to increase if we find one of our contacts, // so if the expiry is not lower, we just ignore it. For registrars that // leave our requested expiry alone, this code ends up being pretty quick, - // especially if there aren't contacts from other endpoints laying around. - if(c->isWellFormed() && - c->exists(p_expires) && - c->param(p_expires) < expiry && - contactIsMine(*c)) + // especially if there aren't contacts from other endpoints laying around. + if(c->isWellFormed() && c->exists(p_expires)) { - expiry=c->param(p_expires); + unsigned long contactExpires = c->param(p_expires); + if((contactExpires < expiry || + contactExpires < reasonableExpiry) && + contactIsMine(*c)) + { + expiry = contactExpires; + if(contactExpires >= UnreasonablyLowExpirationThreshold) + { + reasonableExpiry = contactExpires; + } + } } } + // If expiry is less than UnreasonablyLowExpirationThreshold and we have another + // contact that has a reasonable expiry value, then return that value instead. + // See large comment above for more details. + if(expiry < UnreasonablyLowExpirationThreshold && reasonableExpiry != 0xFFFFFFFF) + { + expiry = reasonableExpiry; + } return expiry; } @@ -863,7 +934,7 @@ ClientRegistration::checkProfileRetry(const SipMessage& msg) // Use retry interval from error response retryInterval = msg.header(h_RetryAfter).value(); } - mExpires = 0; + mRefreshTime = 0; switch(mState) { case Adding: @@ -873,7 +944,7 @@ ClientRegistration::checkProfileRetry(const SipMessage& msg) mState = RetryRefreshing; break; default: - assert(false); + resip_assert(false); break; } @@ -916,7 +987,7 @@ ClientRegistration::dispatch(const DumTimeout& timer) mState = Refreshing; break; default: - assert(false); + resip_assert(false); break; } @@ -943,31 +1014,6 @@ ClientRegistration::flowTerminated() mDum.mClientRegistrationHandler->onFlowTerminated(getHandle()); } -void -ClientRegistration::setCustomHeader(const resip::Data& name, const resip::Data& value) -{ - mCustomHeader = true; - mCustomHeaderName = name; - mCustomHeaderValue = value; -} - -void -ClientRegistration::unsetCustomHeader() -{ - mCustomHeader = false; -} - -void -ClientRegistration::updateWithCustomHeader(SharedPtr msg) -{ - if (mCustomHeader) - { - ExtensionHeader hdr(mCustomHeaderName); - msg->header(hdr).clear(); - StringCategory sc(mCustomHeaderValue); - msg->header(hdr).push_back(sc); - } -} /* ==================================================================== * The Vovida Software License, Version 1.0 @@ -1019,4 +1065,3 @@ ClientRegistration::updateWithCustomHeader(SharedPtr msg) * . * */ - diff --git a/src/libs/resiprocate/resip/dum/ClientRegistration.hxx b/src/libs/resiprocate/resip/dum/ClientRegistration.hxx index 3c6476b1..728a72da 100644 --- a/src/libs/resiprocate/resip/dum/ClientRegistration.hxx +++ b/src/libs/resiprocate/resip/dum/ClientRegistration.hxx @@ -11,14 +11,11 @@ namespace resip class SipMessage; class BaseCreator; -class AtomicCounter; //!dcm! -- shutdown/deletion API -- end? class ClientRegistration: public NonDialogUsage { public: - static AtomicCounter InstanceCounter; - //ClientRegistration(DialogUsageManager& dum, DialogSet& dialog, //SipMessage& req); ClientRegistration(DialogUsageManager& dum, DialogSet& dialog, SharedPtr req); @@ -42,7 +39,6 @@ class ClientRegistration: public NonDialogUsage when complete */ void removeMyBindings(bool stopRegisteringWhenDone=false); - /** Request a manual refresh of the registration. If 0 then default to using original expires value (to remove use removeXXX() instead) */ void requestRefresh(UInt32 expires = 0); @@ -56,12 +52,15 @@ class ClientRegistration: public NonDialogUsage /** returns a list of all contacts for this AOR - may include those added by other UA's */ const NameAddrs& allContacts(); - /** returns the number of seconds until the registration expires - relative */ + /** returns the number of seconds until the registration expires - relative, returns 0 if already expired */ UInt32 whenExpires() const; /** Calls removeMyBindings and ends usage when complete */ virtual void end(); + /** Returns true if a REGISTER request is currently pending and we are waiting for the SIP Response */ + bool isRequestPending() { return mState != Registered && mState != RetryAdding && mState != RetryRefreshing; } + /** * Provide asynchronous method access by using command */ @@ -73,8 +72,6 @@ class ClientRegistration: public NonDialogUsage virtual void dispatch(const DumTimeout& timer); virtual EncodeStream& dump(EncodeStream& strm) const; - void setCustomHeader(const resip::Data& name, const resip::Data& value); - void unsetCustomHeader(); static void tagContact(NameAddr& contact, DialogUsageManager& dum, SharedPtr& userProfile); @@ -102,7 +99,6 @@ class ClientRegistration: public NonDialogUsage bool contactIsMine(const NameAddr& contact) const; bool rinstanceIsMine(const Data& rinstance) const; bool searchByUri(const Uri& cUri) const; - void updateWithCustomHeader(SharedPtr msg); friend class DialogSet; void flowTerminated(); @@ -114,16 +110,17 @@ class ClientRegistration: public NonDialogUsage unsigned int mTimerSeq; // expected timer seq (all < are stale) State mState; + bool mEnding; bool mEndWhenDone; bool mUserRefresh; UInt32 mRegistrationTime; UInt64 mExpires; + UInt64 mRefreshTime; State mQueuedState; SharedPtr mQueuedRequest; - resip::Data mCustomHeaderName, mCustomHeaderValue; - bool mCustomHeader; - NetworkAssociation mNetworkAssociation; + NetworkAssociation mNetworkAssociation; + // disabled ClientRegistration(const ClientRegistration&); ClientRegistration& operator=(const ClientRegistration&); diff --git a/src/libs/resiprocate/resip/dum/ClientSubscription.cxx b/src/libs/resiprocate/resip/dum/ClientSubscription.cxx index f98c96f5..6a3f5c0c 100644 --- a/src/libs/resiprocate/resip/dum/ClientSubscription.cxx +++ b/src/libs/resiprocate/resip/dum/ClientSubscription.cxx @@ -18,27 +18,22 @@ using namespace resip; #define RESIPROCATE_SUBSYSTEM Subsystem::DUM -ClientSubscription::ClientSubscription(DialogUsageManager& dum, Dialog& dialog, - const SipMessage& request, UInt32 defaultSubExpiration) +ClientSubscription::ClientSubscription(DialogUsageManager& dum, Dialog& dialog, const SipMessage& request) : BaseSubscription(dum, dialog, request), mOnNewSubscriptionCalled(mEventType == "refer"), // don't call onNewSubscription for Refer subscriptions mEnded(false), mNextRefreshSecs(0), mLastSubSecs(Timer::getTimeSecs()), // Not exactly, but more forgiving - mDefaultExpires(defaultSubExpiration), + mSubscribed(false), mRefreshing(false), mHaveQueuedRefresh(false), mQueuedRefreshInterval(-1), mLargestNotifyCSeq(0) { - DebugLog (<< "ClientSubscription::ClientSubscription from " << request.brief()); + DebugLog (<< "ClientSubscription::ClientSubscription from " << request.brief() << ": " << this); if(request.method() == SUBSCRIBE) { *mLastRequest = request; - if (defaultSubExpiration > 0) - { - mLastRequest->header(h_Expires).value() = defaultSubExpiration; - } } else { @@ -59,6 +54,7 @@ ClientSubscription::~ClientSubscription() } clearDustbin(); + DebugLog(<< "ClientSubscription::~ClientSubscription: " << this); } ClientSubscriptionHandle @@ -73,37 +69,46 @@ ClientSubscription::dispatch(const SipMessage& msg) DebugLog (<< "ClientSubscription::dispatch " << msg.brief()); ClientSubscriptionHandler* handler = mDum.getClientSubscriptionHandler(mEventType); - assert(handler); + resip_assert(handler); clearDustbin(); // asserts are checks the correctness of Dialog::dispatch if (msg.isRequest() ) { - assert( msg.header(h_RequestLine).getMethod() == NOTIFY ); + resip_assert( msg.header(h_RequestLine).getMethod() == NOTIFY ); mRefreshing = false; + mSubscribed = true; // If we got a NOTIFY then we are subscribed // !dlb! 481 NOTIFY iff state is dead? //!dcm! -- heavy, should just store enough information to make response //mLastNotify = msg; + //!fj! There is a bug that prevents onNewSubscription from being called + // when, for example, the UAS sends a 408 back and + // ClientSubscriptionHandler::onRequestRetry returns 0. A fix was + // attempted in revision 10128 but it created a more important + // regression. See + // http://list.resiprocate.org/archive/resiprocate-devel/thrd83.html#08362 + // for more details. if (!mOnNewSubscriptionCalled && !getAppDialogSet()->isReUsed()) { - InfoLog (<< "[ClientSubscription] " << mLastRequest->header(h_To)); - if (msg.exists(h_Contacts)) - { - mDialog.mRemoteTarget = msg.header(h_Contacts).front(); - } - - handler->onNewSubscription(getHandle(), msg); mOnNewSubscriptionCalled = true; - } + InfoLog(<< "[ClientSubscription] " << mLastRequest->header(h_To)); + handler->onNewSubscription(getHandle(), msg); + if (mEnded) return; + } bool outOfOrder = mLargestNotifyCSeq > msg.header(h_CSeq).sequence(); if (!outOfOrder) { mLargestNotifyCSeq = msg.header(h_CSeq).sequence(); + // If not out of order, then allow NOTIFY to do a target refresh - RFC6665 + if (msg.exists(h_Contacts)) + { + mDialog.mRemoteTarget = msg.header(h_Contacts).front(); + } } else { @@ -133,13 +138,14 @@ void ClientSubscription::processResponse(const SipMessage& msg) { ClientSubscriptionHandler* handler = mDum.getClientSubscriptionHandler(mEventType); - assert(handler); + resip_assert(handler); mRefreshing = false; int statusCode = msg.header(h_StatusLine).statusCode(); if (statusCode >= 200 && statusCode <300) { + mSubscribed = true; // If we got a 200 response then we are subscribed if (msg.exists(h_Expires)) { // grab the expires from the 2xx in case there is not one on the NOTIFY .mjf. @@ -153,22 +159,30 @@ ClientSubscription::processResponse(const SipMessage& msg) if(!mOnNewSubscriptionCalled) { - // Timer for initial NOTIFY; since we don't know when the initial - // SUBSRIBE is sent, we have to set the timer when the 200 comes in, if - // it beat the NOTIFY. - mDum.addTimer(DumTimeout::WaitForNotify, - 64*Timer::T1, - getBaseHandle(), - ++mTimerSeq); + mOnNewSubscriptionCalled = true; + handler->onNewSubscription(getHandle(), msg); + if (!mEnded) + { + // Timer for initial NOTIFY; since we don't know when the initial + // SUBSCRIBE is sent, we have to set the timer when the 200 comes in, if + // it beats the NOTIFY. + mDum.addTimerMs(DumTimeout::WaitForNotify, + 64 * Timer::T1, + getBaseHandle(), + ++mTimerSeq); + } + } + else if (!mEnded) + { + sendQueuedRefreshRequest(); } - - sendQueuedRefreshRequest(); } else if (!mEnded && statusCode == 481 && + msg.header(h_To).exists(p_tag) && // Only do this if we were re-subscribing msg.exists(h_Expires) && msg.header(h_Expires).value() > 0) { - InfoLog (<< "Received 481 to SUBSCRIBE, reSUBSCRIBEing (presence server probably restarted) " + InfoLog (<< "Received 481 to SUBSCRIBE, reSUBSCRIBEing (subscription server probably restarted) " << mLastRequest->header(h_To)); reSubscribe(); // will delete "this" @@ -176,7 +190,7 @@ ClientSubscription::processResponse(const SipMessage& msg) } else if (!mEnded && (statusCode == 408 || - (statusCode == 503 && msg.getReceivedTransport() == 0) || + (statusCode == 503 && !msg.isFromWire()) || ((statusCode == 413 || statusCode == 480 || statusCode == 486 || @@ -263,7 +277,7 @@ ClientSubscription::processNextNotify() QueuedNotify* qn = mQueuedNotifies.front(); ClientSubscriptionHandler* handler = mDum.getClientSubscriptionHandler(mEventType); - assert(handler); + resip_assert(handler); unsigned long refreshInterval = 0; bool setRefreshTimer=false; @@ -279,18 +293,13 @@ ClientSubscription::processNextNotify() { expires = mLastRequest->header(h_Expires).value(); } - else if (mDefaultExpires) + else { /* if we haven't gotten an expires value from: 1. the subscription state from this notify - 2. the last request - then use the default expires (meaning it came from the 2xx in response - to the initial SUBSCRIBE). .mjf. + 2. the last request (may have came from the 2xx in response) + then use some reasonable value. */ - expires = mDefaultExpires; - } - else - { expires = 3600; } @@ -386,7 +395,7 @@ ClientSubscription::processNextNotify() } else if (isEqualNoCase(qn->notify().header(h_SubscriptionState).value(), Symbols::Terminated)) { - if(mLastRequest->header(h_Expires).value()!=0 && + if (mLastRequest->header(h_Expires).value() != 0 && isEqualNoCase(qn->notify().header(h_SubscriptionState).param(p_reason), "timeout")) { // Unexpected timeout of some sort. Look closer. @@ -396,8 +405,7 @@ ClientSubscription::processNextNotify() // NOT loop here? if(Helper::aBitSmallerThan((signed long)(Timer::getTimeSecs() - mLastSubSecs)) < 2) { - acceptUpdate(200, "I just sent a refresh, what more do you want " - "from me?"); + acceptUpdate(200, "I just sent a refresh, what more do you want from me?"); } else { @@ -406,8 +414,7 @@ ClientSubscription::processNextNotify() } else { - acceptUpdate(200, "You terminated my subscription early! What " - "gives?"); + acceptUpdate(200, "You terminated my subscription early! What gives?"); } } else @@ -422,6 +429,11 @@ ClientSubscription::processNextNotify() } else if (!mEnded) { + if (setRefreshTimer) + { + scheduleRefresh(refreshInterval); + } + handler->onUpdateExtension(getHandle(), qn->notify(), qn->outOfOrder()); } else if (mEnded) @@ -451,8 +463,9 @@ ClientSubscription::dispatch(const DumTimeout& timer) if(timer.type() == DumTimeout::WaitForNotify) { ClientSubscriptionHandler* handler = mDum.getClientSubscriptionHandler(mEventType); - if(mOnNewSubscriptionCalled && mEnded) + if(mEnded) { + InfoLog(<< "ClientSubscription: received NOTIFY timeout when trying to end, terminating..."); // NOTIFY terminated didn't come in handler->onTerminated(getHandle(),0); delete this; @@ -464,17 +477,21 @@ ClientSubscription::dispatch(const DumTimeout& timer) } else if (timer.type() == DumTimeout::SubscriptionRetry) { - // this indicates that the ClientSubscription was created by a 408 - if (mOnNewSubscriptionCalled) + // Ensure someone hasn't called end() while we were waiting + if (!mEnded) { - InfoLog(<< "ClientSubscription: application retry refresh"); - requestRefresh(); - } - else - { - InfoLog(<< "ClientSubscription: application retry new request"); - reSubscribe(); // will delete "this" - return; + // this indicates that the ClientSubscription was created by a 408 + if (mOnNewSubscriptionCalled) + { + InfoLog(<< "ClientSubscription: application retry refresh"); + requestRefresh(); + } + else + { + InfoLog(<< "ClientSubscription: application retry new request"); + reSubscribe(); // will delete "this" + return; + } } } else if(timer.type() == DumTimeout::Subscription) @@ -515,7 +532,7 @@ ClientSubscription::requestRefresh(UInt32 expires) mLastSubSecs = Timer::getTimeSecs(); send(mLastRequest); // Timer for reSUB NOTIFY. - mDum.addTimer(DumTimeout::WaitForNotify, + mDum.addTimerMs(DumTimeout::WaitForNotify, 64*Timer::T1, getBaseHandle(), ++mTimerSeq); @@ -525,15 +542,18 @@ ClientSubscription::requestRefresh(UInt32 expires) class ClientSubscriptionRefreshCommand : public DumCommandAdapter { public: - ClientSubscriptionRefreshCommand(ClientSubscription& clientSubscription, UInt32 expires) - : mClientSubscription(clientSubscription), + ClientSubscriptionRefreshCommand(const ClientSubscriptionHandle& clientSubscriptionHandle, UInt32 expires) + : mClientSubscriptionHandle(clientSubscriptionHandle), mExpires(expires) { } virtual void executeCommand() { - mClientSubscription.requestRefresh(mExpires); + if(mClientSubscriptionHandle.isValid()) + { + mClientSubscriptionHandle->requestRefresh(mExpires); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -541,14 +561,14 @@ public: return strm << "ClientSubscriptionRefreshCommand"; } private: - ClientSubscription& mClientSubscription; + ClientSubscriptionHandle mClientSubscriptionHandle; UInt32 mExpires; }; void ClientSubscription::requestRefreshCommand(UInt32 expires) { - mDum.post(new ClientSubscriptionRefreshCommand(*this, expires)); + mDum.post(new ClientSubscriptionRefreshCommand(getHandle(), expires)); } void @@ -560,41 +580,49 @@ ClientSubscription::end() void ClientSubscription::end(bool immediate) { - InfoLog (<< "End subscription: " << mLastRequest->header(h_RequestLine).uri()); - if (!mEnded) { - if(!immediate) + if(!immediate && mSubscribed) { + InfoLog(<< "End subscription: " << mLastRequest->header(h_RequestLine).uri()); mDialog.makeRequest(*mLastRequest, SUBSCRIBE); mLastRequest->header(h_Expires).value() = 0; mEnded = true; send(mLastRequest); // Timer for NOTIFY terminated - mDum.addTimer(DumTimeout::WaitForNotify, + mDum.addTimerMs(DumTimeout::WaitForNotify, 64*Timer::T1, getBaseHandle(), ++mTimerSeq); } else { + InfoLog(<< "End subscription immediately: " << mLastRequest->header(h_RequestLine).uri()); delete this; + return; } } + else + { + InfoLog(<< "End subscription called but already ended: " << mLastRequest->header(h_RequestLine).uri()); + } } class ClientSubscriptionEndCommand : public DumCommandAdapter { public: - ClientSubscriptionEndCommand(ClientSubscription& clientSubscription, bool immediate) - :mClientSubscription(clientSubscription), mImmediate(immediate) + ClientSubscriptionEndCommand(const ClientSubscriptionHandle& clientSubscriptionHandle, bool immediate) + :mClientSubscriptionHandle(clientSubscriptionHandle), mImmediate(immediate) { } virtual void executeCommand() { - mClientSubscription.end(mImmediate); + if(mClientSubscriptionHandle.isValid()) + { + mClientSubscriptionHandle->end(mImmediate); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -602,20 +630,20 @@ public: return strm << "ClientSubscriptionEndCommand"; } private: - ClientSubscription& mClientSubscription; + ClientSubscriptionHandle mClientSubscriptionHandle; bool mImmediate; }; void ClientSubscription::endCommand(bool immediate) { - mDum.post(new ClientSubscriptionEndCommand(*this, immediate)); + mDum.post(new ClientSubscriptionEndCommand(getHandle(), immediate)); } void ClientSubscription::acceptUpdate(int statusCode, const char* reason) { - assert(!mQueuedNotifies.empty()); + resip_assert(!mQueuedNotifies.empty()); if (mQueuedNotifies.empty()) { InfoLog(<< "No queued notify to accept"); @@ -636,8 +664,8 @@ ClientSubscription::acceptUpdate(int statusCode, const char* reason) class ClientSubscriptionAcceptUpdateCommand : public DumCommandAdapter { public: - ClientSubscriptionAcceptUpdateCommand(ClientSubscription& clientSubscription, int statusCode, const char* reason) - : mClientSubscription(clientSubscription), + ClientSubscriptionAcceptUpdateCommand(const ClientSubscriptionHandle& clientSubscriptionHandle, int statusCode, const char* reason) + : mClientSubscriptionHandle(clientSubscriptionHandle), mStatusCode(statusCode), mReason(reason ? Data(reason) : Data::Empty) { @@ -646,7 +674,10 @@ public: virtual void executeCommand() { - mClientSubscription.acceptUpdate(mStatusCode, mReason.c_str()); + if(mClientSubscriptionHandle.isValid()) + { + mClientSubscriptionHandle->acceptUpdate(mStatusCode, mReason.c_str()); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -654,7 +685,7 @@ public: return strm << "ClientSubscriptionAcceptUpdateCommand"; } private: - ClientSubscription& mClientSubscription; + ClientSubscriptionHandle mClientSubscriptionHandle; int mStatusCode; Data mReason; }; @@ -662,7 +693,7 @@ private: void ClientSubscription::acceptUpdateCommand(int statusCode, const char* reason) { - mDum.post(new ClientSubscriptionAcceptUpdateCommand(*this, statusCode, reason)); + mDum.post(new ClientSubscriptionAcceptUpdateCommand(getHandle(), statusCode, reason)); } void @@ -698,8 +729,8 @@ void ClientSubscription::rejectUpdate(int statusCode, const Data& reasonPhrase) { ClientSubscriptionHandler* handler = mDum.getClientSubscriptionHandler(mEventType); - assert(handler); - assert(!mQueuedNotifies.empty()); + resip_assert(handler); + resip_assert(!mQueuedNotifies.empty()); if (mQueuedNotifies.empty()) { InfoLog(<< "No queued notify to reject"); @@ -729,9 +760,15 @@ ClientSubscription::rejectUpdate(int statusCode, const Data& reasonPhrase) break; case Helper::DialogTermination: //?dcm? -- throw or destroy this? case Helper::UsageTermination: - mEnded = true; - handler->onTerminated(getHandle(), mLastResponse.get()); - delete this; + // If we are already "ended" then we are likely here because we are rejecting an inbound + // NOTIFY with a 481 that crossed with our un-subscribe request (due to end()). In this case we don't + // want to call onTerminated or delete this - we wait for end() request to run it's course. + if (!mEnded) + { + mEnded = true; + handler->onTerminated(getHandle(), mLastResponse.get()); + delete this; + } break; } } @@ -739,8 +776,8 @@ ClientSubscription::rejectUpdate(int statusCode, const Data& reasonPhrase) class ClientSubscriptionRejectUpdateCommand : public DumCommandAdapter { public: - ClientSubscriptionRejectUpdateCommand(ClientSubscription& clientSubscription, int statusCode, const Data& reasonPhrase) - : mClientSubscription(clientSubscription), + ClientSubscriptionRejectUpdateCommand(const ClientSubscriptionHandle& clientSubscriptionHandle, int statusCode, const Data& reasonPhrase) + : mClientSubscriptionHandle(clientSubscriptionHandle), mStatusCode(statusCode), mReasonPhrase(reasonPhrase) { @@ -748,7 +785,10 @@ public: virtual void executeCommand() { - mClientSubscription.rejectUpdate(mStatusCode, mReasonPhrase); + if(mClientSubscriptionHandle.isValid()) + { + mClientSubscriptionHandle->rejectUpdate(mStatusCode, mReasonPhrase); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -756,7 +796,7 @@ public: return strm << "ClientSubscriptionRejectUpdateCommand"; } private: - ClientSubscription& mClientSubscription; + ClientSubscriptionHandle mClientSubscriptionHandle; int mStatusCode; Data mReasonPhrase; }; @@ -764,16 +804,7 @@ private: void ClientSubscription::rejectUpdateCommand(int statusCode, const Data& reasonPhrase) { - mDum.post(new ClientSubscriptionRejectUpdateCommand(*this, statusCode, reasonPhrase)); -} - -void ClientSubscription::dialogDestroyed(const SipMessage& msg) -{ - ClientSubscriptionHandler* handler = mDum.getClientSubscriptionHandler(mEventType); - assert(handler); - mEnded = true; - handler->onTerminated(getHandle(), &msg); - delete this; + mDum.post(new ClientSubscriptionRejectUpdateCommand(getHandle(), statusCode, reasonPhrase)); } EncodeStream& @@ -787,7 +818,7 @@ void ClientSubscription::onReadyToSend(SipMessage& msg) { ClientSubscriptionHandler* handler = mDum.getClientSubscriptionHandler(mEventType); - assert(handler); + resip_assert(handler); handler->onReadyToSend(getHandle(), msg); } @@ -796,14 +827,14 @@ ClientSubscription::flowTerminated() { // notify handler ClientSubscriptionHandler* handler = mDum.getClientSubscriptionHandler(mEventType); - assert(handler); + resip_assert(handler); handler->onFlowTerminated(getHandle()); } void ClientSubscription::sendQueuedRefreshRequest() { - assert(!mRefreshing); + resip_assert(!mRefreshing); if (mHaveQueuedRefresh) { diff --git a/src/libs/resiprocate/resip/dum/ClientSubscription.hxx b/src/libs/resiprocate/resip/dum/ClientSubscription.hxx index 09546d33..2d400abf 100644 --- a/src/libs/resiprocate/resip/dum/ClientSubscription.hxx +++ b/src/libs/resiprocate/resip/dum/ClientSubscription.hxx @@ -14,8 +14,7 @@ class DialogUsageManager; class ClientSubscription: public BaseSubscription { public: - ClientSubscription(DialogUsageManager& dum, Dialog& dialog, - const SipMessage& request, UInt32 defaultSubExpiration); + ClientSubscription(DialogUsageManager& dum, Dialog& dialog, const SipMessage& request); typedef Handle ClientSubscriptionHandle; ClientSubscriptionHandle getHandle(); @@ -39,7 +38,6 @@ class ClientSubscription: public BaseSubscription protected: virtual ~ClientSubscription(); - virtual void dialogDestroyed(const SipMessage& msg); virtual void onReadyToSend(SipMessage& msg); virtual void send(SharedPtr msg); virtual void flowTerminated(); @@ -69,15 +67,12 @@ class ClientSubscription: public BaseSubscription Dustbin mDustbin; bool mOnNewSubscriptionCalled; - //SipMessage mLastNotify; bool mEnded; // .bwc. This is when our next reSUB is scheduled to happen. UInt64 mNextRefreshSecs; UInt64 mLastSubSecs; - // this is the expires value from the 2xx coming from the SUB message - UInt32 mDefaultExpires; - + bool mSubscribed; bool mRefreshing; bool mHaveQueuedRefresh; int mQueuedRefreshInterval; diff --git a/src/libs/resiprocate/resip/dum/ContactInstanceRecord.cxx b/src/libs/resiprocate/resip/dum/ContactInstanceRecord.cxx index fb4ab122..405608e9 100644 --- a/src/libs/resiprocate/resip/dum/ContactInstanceRecord.cxx +++ b/src/libs/resiprocate/resip/dum/ContactInstanceRecord.cxx @@ -1,7 +1,10 @@ +#include + #include "resip/dum/ContactInstanceRecord.hxx" #include "resip/stack/Helper.hxx" -#include "rutil/Timer.hxx" #include "resip/stack/SipMessage.hxx" +#include "rutil/XMLCursor.hxx" +#include "rutil/Timer.hxx" using namespace resip; @@ -11,10 +14,58 @@ ContactInstanceRecord::ContactInstanceRecord() : mRegId(0), mSyncContact(false), mUseFlowRouting(false), - mUserInfo(0) + mUserInfo(0), + mUserData(0) { } +ContactInstanceRecord::ContactInstanceRecord(const ContactInstanceRecord& rhs) : + mUserData(0) +{ + *this = rhs; +} + +ContactInstanceRecord& ContactInstanceRecord::operator=(const ContactInstanceRecord& rhs) +{ + mContact = rhs.mContact; + mRegExpires = rhs.mRegExpires; + mLastUpdated = rhs.mLastUpdated; + mReceivedFrom = rhs.mReceivedFrom; + mPublicAddress = rhs.mPublicAddress; + mSipPath = rhs.mSipPath; + mInstance = rhs.mInstance; + mUserAgent = rhs.mUserAgent; + mRegId = rhs.mRegId; + mSyncContact = rhs.mSyncContact; + mUseFlowRouting = rhs.mUseFlowRouting; + mUserInfo = rhs.mUserInfo; + if(mUserData && rhs.mUserData == 0) + { + delete mUserData; + mUserData = 0; + } + else if(mUserData == 0 && rhs.mUserData) + { + mUserData = new Data(*rhs.mUserData); + } + else if(rhs.mUserData) + { + *mUserData = *rhs.mUserData; + } + // else both are already NULL + + return(*this); +} + +ContactInstanceRecord::~ContactInstanceRecord() +{ + if(mUserData) + { + delete mUserData; + mUserData = 0; + } +} + bool ContactInstanceRecord::operator==(const ContactInstanceRecord& rhs) const { @@ -26,6 +77,13 @@ ContactInstanceRecord::operator==(const ContactInstanceRecord& rhs) const return mInstance == rhs.mInstance && mRegId == rhs.mRegId; } + else if (mRegId == 0 && rhs.mRegId == 0 && + !mInstance.empty() && !rhs.mInstance.empty()) + { + // If RegId is not specified on either but instance Id is, then look for instanceId + // match only - RFC5627 matching (even though we don't fully support GRUU yet) + return mInstance == rhs.mInstance; + } else { // otherwise both instance (if specified) and contact must match @@ -34,6 +92,173 @@ ContactInstanceRecord::operator==(const ContactInstanceRecord& rhs) const } } +void ContactInstanceRecord::stream(std::iostream& ss) const +{ + UInt64 now = Timer::getTimeSecs(); + + ss << " " << Symbols::CRLF; + ss << " " << Data::from(mContact).xmlCharDataEncode() << "" << Symbols::CRLF; + // If contact is expired or removed, then pass expires time as 0, otherwise send number of seconds until expirey + ss << " " << (((mRegExpires == 0) || (mRegExpires <= now)) ? 0 : (mRegExpires-now)) << "" << Symbols::CRLF; + ss << " " << now-mLastUpdated << "" << Symbols::CRLF; + if(mReceivedFrom.getPort() != 0) + { + resip::Data binaryFlowToken; + Tuple::writeBinaryToken(mReceivedFrom,binaryFlowToken); + ss << " " << binaryFlowToken.base64encode() << "" << Symbols::CRLF; + } + if(mPublicAddress.getType() != UNKNOWN_TRANSPORT) + { + resip::Data binaryFlowToken; + Tuple::writeBinaryToken(mPublicAddress,binaryFlowToken); + ss << " " << binaryFlowToken.base64encode() << "" << Symbols::CRLF; + } + NameAddrs::const_iterator naIt = mSipPath.begin(); + for(; naIt != mSipPath.end(); naIt++) + { + ss << " " << Data::from(naIt->uri()).xmlCharDataEncode() << "" << Symbols::CRLF; + } + if(!mInstance.empty()) + { + ss << " " << mInstance.xmlCharDataEncode() << "" << Symbols::CRLF; + } + if(mRegId != 0) + { + ss << " " << mRegId << "" << Symbols::CRLF; + } + if (!mUserAgent.empty()) + { + ss << " " << mUserAgent.xmlCharDataEncode() << "" << Symbols::CRLF; + } + + if(mUserData != 0 && mUserData->size()) + { + ss << " " << *mUserData << "" << Symbols::CRLF; + } + ss << " " << Symbols::CRLF; +} + +bool ContactInstanceRecord::deserialize(resip::XMLCursor& xml, UInt64 now) +{ + bool success = false; + // Reset this members + *this = ContactInstanceRecord(); + if(now <= 0) + { + now = Timer::getTimeSecs(); + } + + if(isEqualNoCase(xml.getTag(), "contactinfo")) + { + if(xml.firstChild()) + { + do + { + if(isEqualNoCase(xml.getTag(), "contacturi")) + { + if(xml.firstChild()) + { + //InfoLog(<< "RegSyncClient::handleRegInfoEvent: contacturi=" << xml.getValue()); + mContact = NameAddr(xml.getValue().xmlCharDataDecode()); + xml.parent(); + success = true; + } + } + else if(isEqualNoCase(xml.getTag(), "expires")) + { + if(xml.firstChild()) + { + //InfoLog(<< "RegSyncClient::handleRegInfoEvent: expires=" << xml.getValue()); + UInt64 expires = xml.getValue().convertUInt64(); + mRegExpires = (expires == 0 ? 0 : now+expires); + xml.parent(); + } + } + else if(isEqualNoCase(xml.getTag(), "lastupdate")) + { + if(xml.firstChild()) + { + //InfoLog(<< "RegSyncClient::handleRegInfoEvent: lastupdate=" << xml.getValue()); + mLastUpdated = now-xml.getValue().convertUInt64(); + xml.parent(); + } + } + else if(isEqualNoCase(xml.getTag(), "receivedfrom")) + { + if(xml.firstChild()) + { + mReceivedFrom = Tuple::makeTupleFromBinaryToken(xml.getValue().base64decode()); + //InfoLog(<< "RegSyncClient::handleRegInfoEvent: receivedfrom=" << xml.getValue() << " tuple=" << mReceivedFrom); + xml.parent(); + } + } + else if(isEqualNoCase(xml.getTag(), "publicaddress")) + { + if(xml.firstChild()) + { + mPublicAddress = Tuple::makeTupleFromBinaryToken(xml.getValue().base64decode()); + //InfoLog(<< "RegSyncClient::handleRegInfoEvent: publicaddress=" << xml.getValue() << " tuple=" << mPublicAddress); + xml.parent(); + } + } + else if(isEqualNoCase(xml.getTag(), "sippath")) + { + if(xml.firstChild()) + { + //InfoLog(<< "RegSyncClient::handleRegInfoEvent: sippath=" << xml.getValue()); + mSipPath.push_back(NameAddr(xml.getValue().xmlCharDataDecode())); + xml.parent(); + } + } + else if(isEqualNoCase(xml.getTag(), "instance")) + { + if(xml.firstChild()) + { + //InfoLog(<< "RegSyncClient::handleRegInfoEvent: instance=" << xml.getValue()); + mInstance = xml.getValue().xmlCharDataDecode(); + xml.parent(); + } + } + else if(isEqualNoCase(xml.getTag(), "regid")) + { + if(xml.firstChild()) + { + //InfoLog(<< "RegSyncClient::handleRegInfoEvent: regid=" << xml.getValue()); + mRegId = xml.getValue().convertUnsignedLong(); + xml.parent(); + } + } + else if (isEqualNoCase(xml.getTag(), "useragent")) + { + if (xml.firstChild()) + { + //InfoLog(<< "RegSyncClient::handleRegInfoEvent: useragent=" << xml.getValue()); + mUserAgent = xml.getValue().xmlCharDataDecode(); + xml.parent(); + } + } + else if(isEqualNoCase(xml.getTag(), "userdata")) + { + if(xml.firstChild()) + { + //InfoLog(<< "RegSyncClient::handleRegInfoEvent: userdata=" << xml.getValue()); + if(mUserData == 0) + { + mUserData = new Data(""); + } + *mUserData = xml.getValue().xmlCharDataDecode(); + xml.parent(); + } + } + } while(xml.nextSibling()); + xml.parent(); + } + } + + return(success); +} + + ContactInstanceRecord ContactInstanceRecord::makeRemoveDelta(const NameAddr& contact) { diff --git a/src/libs/resiprocate/resip/dum/ContactInstanceRecord.hxx b/src/libs/resiprocate/resip/dum/ContactInstanceRecord.hxx index ff7f7b0a..3c203341 100644 --- a/src/libs/resiprocate/resip/dum/ContactInstanceRecord.hxx +++ b/src/libs/resiprocate/resip/dum/ContactInstanceRecord.hxx @@ -12,6 +12,9 @@ namespace resip { + +class XMLCursor; + static const UInt64 NeverExpire = 0xFFFFFFFFFFFFFFFFULL; /** A single contact record, bound to an Aor during registration. @@ -20,10 +23,22 @@ class ContactInstanceRecord { public: ContactInstanceRecord(); + ContactInstanceRecord(const ContactInstanceRecord& rhs); + ContactInstanceRecord& operator=(const ContactInstanceRecord& rhs); + virtual ~ContactInstanceRecord(); + static ContactInstanceRecord makeRemoveDelta(const NameAddr& contact); static ContactInstanceRecord makeUpdateDelta(const NameAddr& contact, UInt64 expires, // absolute time in secs const SipMessage& msg); + + // Stream ContactInstanceRecord in XML format + void stream(std::iostream& ss) const; + + // Deserialize off xml tree + bool deserialize(resip::XMLCursor& xml, UInt64 now = 0); + /* @returns true if successfully deserialized + */ NameAddr mContact; // can contain callee caps and q-values UInt64 mRegExpires; // in seconds @@ -33,6 +48,7 @@ class ContactInstanceRecord NameAddrs mSipPath; // Value of SIP Path header from the request Data mInstance; // From the instance parameter; usually a UUID URI UInt32 mRegId; // From regid parameter of Contact header + Data mUserAgent; // From User-Agent header bool mSyncContact; // This contact came from registration sync process, instead of direct SIP registration bool mUseFlowRouting; // Set to true when routing to this contact should use flow routing // Note: There is no need to regsync this field, since such records will also have @@ -40,8 +56,10 @@ class ContactInstanceRecord // Data mServerSessionId;// if there is no SIP Path header, the connection/session identifier // Uri gruu; (GRUU is currently derived) void *mUserInfo; //!< can be used to map user record information (database record id for faster updates?) + Data* mUserData; // Optional user/application specific string bool operator==(const ContactInstanceRecord& rhs) const; + }; typedef std::list ContactList; diff --git a/src/libs/resiprocate/resip/dum/DefaultServerReferHandler.hxx b/src/libs/resiprocate/resip/dum/DefaultServerReferHandler.hxx index e63e002b..787269c8 100644 --- a/src/libs/resiprocate/resip/dum/DefaultServerReferHandler.hxx +++ b/src/libs/resiprocate/resip/dum/DefaultServerReferHandler.hxx @@ -1,5 +1,5 @@ #if !defined(RESIP_DEFAULTSERVERREFERHANDLER_HXX) -#define RESIP__DEFAULTSERVERREFERHANDLER_HXX +#define RESIP_DEFAULTSERVERREFERHANDLER_HXX #include "resip/dum/SubscriptionHandler.hxx" diff --git a/src/libs/resiprocate/resip/dum/DestroyUsage.cxx b/src/libs/resiprocate/resip/dum/DestroyUsage.cxx index 9c7deb52..bfe1243a 100644 --- a/src/libs/resiprocate/resip/dum/DestroyUsage.cxx +++ b/src/libs/resiprocate/resip/dum/DestroyUsage.cxx @@ -4,7 +4,7 @@ #include "resip/dum/DialogSet.hxx" #include "resip/dum/Dialog.hxx" #include "rutil/WinLeakCheck.hxx" -#include +#include "rutil/ResipAssert.h" #define RESIPROCATE_SUBSYSTEM Subsystem::DUM diff --git a/src/libs/resiprocate/resip/dum/Dialog.cxx b/src/libs/resiprocate/resip/dum/Dialog.cxx index 11253177..442a2147 100644 --- a/src/libs/resiprocate/resip/dum/Dialog.cxx +++ b/src/libs/resiprocate/resip/dum/Dialog.cxx @@ -15,8 +15,10 @@ #include "resip/dum/ServerSubscription.hxx" #include "resip/dum/SubscriptionHandler.hxx" #include "resip/dum/UsageUseException.hxx" +#include "rutil/ResipAssert.h" #include "rutil/Logger.hxx" #include "rutil/Inserter.hxx" +#include "rutil/TransportType.hxx" #include "rutil/WinLeakCheck.hxx" #define RESIPROCATE_SUBSYSTEM Subsystem::DUM @@ -40,16 +42,15 @@ Dialog::Dialog(DialogUsageManager& dum, const SipMessage& msg, DialogSet& ds) mLocalNameAddr(), mRemoteNameAddr(), mCallId(msg.header(h_CallID)), - mDefaultSubExpiration(0), mAppDialog(0), mDestroying(false), mReUseDialogSet(false) { - assert(msg.isExternal()); + resip_assert(msg.isExternal()); - assert(msg.header(h_CSeq).method() != MESSAGE); - assert(msg.header(h_CSeq).method() != REGISTER); - assert(msg.header(h_CSeq).method() != PUBLISH); + resip_assert(msg.header(h_CSeq).method() != MESSAGE); + resip_assert(msg.header(h_CSeq).method() != REGISTER); + resip_assert(msg.header(h_CSeq).method() != PUBLISH); mNetworkAssociation.setDum(&dum); @@ -239,7 +240,7 @@ Dialog::Dialog(DialogUsageManager& dum, const SipMessage& msg, DialogSet& ds) InfoLog(<< response); throw Exception("lastRequest does not contain a valid contact.", __FILE__, __LINE__); } - mLocalContact = creator->getLastRequest()->header(h_Contacts).front(); + mLocalContact = lastRequest->header(h_Contacts).front(); mRemoteTarget = contact; } else @@ -337,9 +338,9 @@ Dialog::getRouteSet() const void Dialog::cancel() { - assert(mType == Invitation); + resip_assert(mType == Invitation); ClientInviteSession* uac = dynamic_cast(mInviteSession); - assert (uac); + resip_assert (uac); uac->cancel(); } @@ -378,6 +379,8 @@ Dialog::handleTargetRefresh(const SipMessage& msg) { case INVITE: case UPDATE: + case SUBSCRIBE: // RFC6665 - Note: target refreshes via NOTIFY requests are handled via + // ClientSubscription usage after NOTIFY ordering is confirmed if (msg.isRequest() || (msg.isResponse() && msg.header(h_StatusLine).statusCode()/100 == 2)) { //?dcm? modify local target; 12.2.2 of 3261 implies that the remote @@ -403,13 +406,12 @@ Dialog::dispatch(const SipMessage& msg) DebugLog ( << "Dialog::dispatch: " << msg.brief()); - if(msg.isExternal()) + if(msg.isFromWire()) { - const Data& receivedTransport = msg.header(h_Vias).front().transport(); + TransportType receivedTransport = toTransportType( + msg.header(h_Vias).front().transport()); int keepAliveTime = 0; - if(receivedTransport == Symbols::TCP || - receivedTransport == Symbols::TLS || - receivedTransport == Symbols::SCTP) + if(isReliable(receivedTransport)) { keepAliveTime = mDialogSet.mUserProfile->getKeepAliveTimeForStream(); } @@ -483,6 +485,17 @@ Dialog::dispatch(const SipMessage& msg) mInviteSession->dispatch(request); } break; + case PRACK: + if (mInviteSession == 0) + { + InfoLog ( << "Spurious PRACK" ); + return; + } + else + { + mInviteSession->dispatch(request); + } + break; case ACK: case CANCEL: if (mInviteSession == 0) @@ -552,7 +565,7 @@ Dialog::dispatch(const SipMessage& msg) (request.exists(h_Requires) && request.header(h_Requires).find(Token("norefersub")))) { - assert(mInviteSession); + resip_assert(mInviteSession); mInviteSession->referNoSub(msg); } else @@ -622,7 +635,7 @@ Dialog::dispatch(const SipMessage& msg) } break; default: - assert(0); + resip_assert(0); return; } } @@ -642,7 +655,7 @@ Dialog::dispatch(const SipMessage& msg) { InfoLog( << "about to re-send request with digest credentials" << r->second->brief()); - assert (r->second->isRequest()); + resip_assert (r->second->isRequest()); mLocalCSeq++; send(r->second); @@ -665,8 +678,21 @@ Dialog::dispatch(const SipMessage& msg) } else { - // Ensure that if the route-set in the 200 is empty, then we overwrite any existing route-sets - mRouteSet.clear(); + // Note: This is code to facilitate Dialog recovery, and works in conjunction with the + // makeInviteSession API that takes a DialogSetId parameter. + // If our original outbound request contained a to tag, then we are attempting to restore a previously + // existing (outside this process) dialog. Some clients will send the routeset to use as Record-Routes + // in the response, in which case the code above will store them. However clients are not mandated to + // do so, so if our outbound INVITE had routes on it, then store these as the routeset for the dialog. + if (creator->getLastRequest()->header(h_To).exists(p_tag) && creator->getLastRequest()->exists(h_Routes)) + { + mRouteSet = creator->getLastRequest()->header(h_Routes); + } + else + { + // Ensure that if the route-set in the 200 is empty, then we overwrite any existing route-sets + mRouteSet.clear(); + } } } @@ -700,6 +726,7 @@ Dialog::dispatch(const SipMessage& msg) case INFO: case MESSAGE: case UPDATE: + case PRACK: if (mInviteSession) { mInviteSession->dispatch(response); @@ -707,7 +734,7 @@ Dialog::dispatch(const SipMessage& msg) // else drop on the floor break; - case REFER: + case REFER: if(mInviteSession) { if (code >= 300) @@ -733,39 +760,11 @@ Dialog::dispatch(const SipMessage& msg) case SUBSCRIBE: { - int code = response.header(h_StatusLine).statusCode(); ClientSubscription* client = findMatchingClientSub(response); if (client) { client->dispatch(response); } - else if (code < 300) - { - /* - we're capturing the value from the expires header off - the 2xx because the ClientSubscription is only created - after receiving the NOTIFY that comes (usually) after - this 2xx. We really should be creating the - ClientSubscription at either the 2xx or the NOTIFY - whichever arrives first. .mjf. - Note: we're capturing a duration here (not the - absolute time because all the inputs to - ClientSubscription desling with the expiration are expecting - duration type values from the headers. .mjf. - */ - if(response.exists(h_Expires)) - { - mDefaultSubExpiration = response.header(h_Expires).value(); - } - else - { - //?dcm? defaults to 3600 in ClientSubscription if no expires value - //is provided anywhere...should we assume the value from the - //sub in the basecreator if it exists? - mDefaultSubExpiration = 0; - } - return; - } else { //!dcm! -- can't subscribe in an existing Dialog, this is all @@ -792,9 +791,8 @@ Dialog::dispatch(const SipMessage& msg) break; case NOTIFY: { - //2xx responses are treated as retransmission quenchers(handled by - //the stack). Failures are dispatched to all ServerSubsscriptions, - //which may not be correct. + //Failures are dispatched to all ServerSubsscriptions, + //which may not be correct as per RFC 5057. int code = msg.header(h_StatusLine).statusCode(); if (code >= 300) @@ -811,49 +809,20 @@ Dialog::dispatch(const SipMessage& msg) mDestroying = false; possiblyDie(); } -// ServerSubscription* server = findMatchingServerSub(response); -// if (server) -// { -// server->dispatch(response); -// } + else if (code >= 200) + { + ServerSubscription* server = findMatchingServerSub(response); + if (server) + { + server->dispatch(response); + } + } } break; default: - assert(0); + resip_assert(0); return; } - -#if 0 // merged from head back to teltel-branch - if (msg.header(h_StatusLine).statusCode() >= 400 - && Helper::determineFailureMessageEffect(msg) == Helper::DialogTermination) - { - //kill all usages - mDestroying = true; - - for (list::iterator it = mServerSubscriptions.begin(); - it != mServerSubscriptions.end(); ) - { - ServerSubscription* s = *it; - it++; - s->dialogDestroyed(msg); - } - - for (list::iterator it = mClientSubscriptions.begin(); - it != mClientSubscriptions.end(); ) - { - ClientSubscription* s = *it; - it++; - s->dialogDestroyed(msg); - } - if (mInviteSession) - { - mInviteSession->dialogDestroyed(msg); - } - mDestroying = false; - possiblyDie(); //should aways result in destruction of this - return; - } -#endif } } @@ -978,7 +947,7 @@ Dialog::redirected(const SipMessage& msg) } void -Dialog::makeRequest(SipMessage& request, MethodTypes method) +Dialog::makeRequest(SipMessage& request, MethodTypes method, bool incrementCSeq) { RequestLine rLine(method); @@ -1012,13 +981,16 @@ Dialog::makeRequest(SipMessage& request, MethodTypes method) } else { - assert(request.exists(h_Vias)); + resip_assert(request.exists(h_Vias)); } //don't increment CSeq for ACK or CANCEL if (method != ACK && method != CANCEL) { - request.header(h_CSeq).sequence() = ++mLocalCSeq; + if(incrementCSeq) + { + setRequestNextCSeq(request); + } } else { @@ -1036,31 +1008,28 @@ Dialog::makeRequest(SipMessage& request, MethodTypes method) // If method is INVITE then advertise required headers if(method == INVITE || method == UPDATE) { - if(mDialogSet.mUserProfile->isAdvertisedCapability(Headers::Allow)) request.header(h_Allows) = mDum.getMasterProfile()->getAllowedMethods(); - if(mDialogSet.mUserProfile->isAdvertisedCapability(Headers::AcceptEncoding)) request.header(h_AcceptEncodings) = mDum.getMasterProfile()->getSupportedEncodings(); - if(mDialogSet.mUserProfile->isAdvertisedCapability(Headers::AcceptLanguage)) request.header(h_AcceptLanguages) = mDum.getMasterProfile()->getSupportedLanguages(); - if(mDialogSet.mUserProfile->isAdvertisedCapability(Headers::AllowEvents)) request.header(h_AllowEvents) = mDum.getMasterProfile()->getAllowedEvents(); - if(mDialogSet.mUserProfile->isAdvertisedCapability(Headers::Supported)) request.header(h_Supporteds) = mDum.getMasterProfile()->getSupportedOptionTags(); + // Add Advertised Capabilities + mDum.setAdvertisedCapabilities(request, mDialogSet.mUserProfile); } if (mDialogSet.mUserProfile->isAnonymous()) { + request.remove(h_Privacys); request.header(h_Privacys).push_back(PrivacyCategory(Symbols::id)); } DebugLog ( << "Dialog::makeRequest: " << std::endl << std::endl << request ); } - void Dialog::makeResponse(SipMessage& response, const SipMessage& request, int code) { - assert( code >= 100 ); + resip_assert( code >= 100 ); response.remove(h_Contacts); if (code < 300 && code > 100) { - assert(request.isRequest()); - assert(request.header(h_RequestLine).getMethod() == INVITE || + resip_assert(request.isRequest()); + resip_assert(request.header(h_RequestLine).getMethod() == INVITE || request.header(h_RequestLine).getMethod() == SUBSCRIBE || request.header(h_RequestLine).getMethod() == BYE || request.header(h_RequestLine).getMethod() == CANCEL || @@ -1069,6 +1038,7 @@ Dialog::makeResponse(SipMessage& response, const SipMessage& request, int code) request.header(h_RequestLine).getMethod() == NOTIFY || request.header(h_RequestLine).getMethod() == INFO || request.header(h_RequestLine).getMethod() == OPTIONS || + request.header(h_RequestLine).getMethod() == PRACK || request.header(h_RequestLine).getMethod() == UPDATE ); @@ -1079,30 +1049,12 @@ Dialog::makeResponse(SipMessage& response, const SipMessage& request, int code) response.header(h_To).param(p_tag) = mId.getLocalTag(); if((request.header(h_RequestLine).getMethod() == INVITE || + request.header(h_RequestLine).getMethod() == PRACK || request.header(h_RequestLine).getMethod() == UPDATE) && code >= 200 && code < 300) { - // Check if we should add our capabilites to the invite success response - if(mDialogSet.mUserProfile->isAdvertisedCapability(Headers::Allow)) - { - response.header(h_Allows) = mDum.getMasterProfile()->getAllowedMethods(); - } - if(mDialogSet.mUserProfile->isAdvertisedCapability(Headers::AcceptEncoding)) - { - response.header(h_AcceptEncodings) = mDum.getMasterProfile()->getSupportedEncodings(); - } - if(mDialogSet.mUserProfile->isAdvertisedCapability(Headers::AcceptLanguage)) - { - response.header(h_AcceptLanguages) = mDum.getMasterProfile()->getSupportedLanguages(); - } - if(mDialogSet.mUserProfile->isAdvertisedCapability(Headers::AllowEvents)) - { - response.header(h_AllowEvents) = mDum.getMasterProfile()->getAllowedEvents(); - } - if(mDialogSet.mUserProfile->isAdvertisedCapability(Headers::Supported)) - { - response.header(h_Supporteds) = mDum.getMasterProfile()->getSupportedOptionTags(); - } + // Add Advertised Capabilities + mDum.setAdvertisedCapabilities(response, mDialogSet.mUserProfile); } } else @@ -1114,6 +1066,12 @@ Dialog::makeResponse(SipMessage& response, const SipMessage& request, int code) DebugLog ( << "Dialog::makeResponse: " << std::endl << std::endl << response); } +void +Dialog::setRequestNextCSeq(SipMessage& request) +{ + resip_assert(request.isRequest() && request.method() != ACK && request.method() != CANCEL); + request.header(h_CSeq).sequence() = ++mLocalCSeq; +} ClientInviteSession* Dialog::makeClientInviteSession(const SipMessage& response) @@ -1121,7 +1079,7 @@ Dialog::makeClientInviteSession(const SipMessage& response) InviteSessionCreator* creator = dynamic_cast(mDialogSet.getCreator()); if (!creator) { - assert(0); // !jf! this maybe can assert by evil UAS + resip_assert(0); // !jf! this maybe can assert by evil UAS return 0; } //return mDum.createAppClientInviteSession(*this, *creator); @@ -1129,15 +1087,12 @@ Dialog::makeClientInviteSession(const SipMessage& response) creator->getInitialOffer(), creator->getEncryptionLevel(), creator->getServerSubscription()); } - - ClientSubscription* Dialog::makeClientSubscription(const SipMessage& request) { - return new ClientSubscription(mDum, *this, request, mDefaultSubExpiration); + return new ClientSubscription(mDum, *this, request); } - ServerInviteSession* Dialog::makeServerInviteSession(const SipMessage& request) { diff --git a/src/libs/resiprocate/resip/dum/Dialog.hxx b/src/libs/resiprocate/resip/dum/Dialog.hxx index 385537cc..338592e5 100644 --- a/src/libs/resiprocate/resip/dum/Dialog.hxx +++ b/src/libs/resiprocate/resip/dum/Dialog.hxx @@ -51,8 +51,9 @@ class Dialog void send(SharedPtr msg); //void send(SipMessage& msg); - void makeRequest(SipMessage& request, MethodTypes method); + void makeRequest(SipMessage& request, MethodTypes method, bool incrementCSeq = true); void makeResponse(SipMessage& response, const SipMessage& request, int responseCode); + void setRequestNextCSeq(SipMessage& request); //void setLocalContact(const NameAddr& localContact); //void setRemoteTarget(const NameAddr& remoteTarget); @@ -145,9 +146,6 @@ class Dialog NameAddr mLocalNameAddr; NameAddr mRemoteNameAddr; CallID mCallId; - - // used to capture the 2xx expiration value for the initial subscription response - UInt32 mDefaultSubExpiration; // store until we get a response (non-401/407) // !jf! this shouldn't be necessary diff --git a/src/libs/resiprocate/resip/dum/DialogEventInfo.cxx b/src/libs/resiprocate/resip/dum/DialogEventInfo.cxx index ce834cc4..c52d16ac 100644 --- a/src/libs/resiprocate/resip/dum/DialogEventInfo.cxx +++ b/src/libs/resiprocate/resip/dum/DialogEventInfo.cxx @@ -31,17 +31,17 @@ DialogEventInfo::DialogEventInfo(const DialogEventInfo& rhs) { if (rhs.mReplacesId.get()) { - mReplacesId = std::unique_ptr(new DialogId(rhs.mReplacesId->getCallId(), + mReplacesId = std::auto_ptr(new DialogId(rhs.mReplacesId->getCallId(), rhs.mReplacesId->getLocalTag(), rhs.mReplacesId->getRemoteTag())); } if (rhs.mLocalOfferAnswer.get()) { - mLocalOfferAnswer = std::unique_ptr(rhs.mLocalOfferAnswer->clone()); + mLocalOfferAnswer = std::auto_ptr(rhs.mLocalOfferAnswer->clone()); } if (rhs.mRemoteOfferAnswer.get()) { - mRemoteOfferAnswer = std::unique_ptr(rhs.mRemoteOfferAnswer->clone()); + mRemoteOfferAnswer = std::auto_ptr(rhs.mRemoteOfferAnswer->clone()); } } @@ -217,7 +217,7 @@ DialogEventInfo::getLocalOfferAnswer() const return mInviteSession->getLocalOfferAnswer(); } } - assert(mLocalOfferAnswer.get() != NULL); + resip_assert(mLocalOfferAnswer.get() != NULL); return *mLocalOfferAnswer; } @@ -231,7 +231,7 @@ DialogEventInfo::getRemoteOfferAnswer() const return mInviteSession->getRemoteOfferAnswer(); } } - assert(mRemoteOfferAnswer.get() != NULL); + resip_assert(mRemoteOfferAnswer.get() != NULL); return *mRemoteOfferAnswer; } diff --git a/src/libs/resiprocate/resip/dum/DialogEventInfo.hxx b/src/libs/resiprocate/resip/dum/DialogEventInfo.hxx index 63707adb..d93c2aea 100644 --- a/src/libs/resiprocate/resip/dum/DialogEventInfo.hxx +++ b/src/libs/resiprocate/resip/dum/DialogEventInfo.hxx @@ -83,22 +83,22 @@ class DialogEventInfo DialogId mDialogId; Direction mDirection; //ID of the dialog this dialog replaced. - std::unique_ptr mReplacesId; + std::auto_ptr mReplacesId; InviteSessionHandle mInviteSession; - std::unique_ptr mReferredBy; + std::auto_ptr mReferredBy; //could back-point to dialog for this information to save space NameAddrs mRouteSet; NameAddr mLocalIdentity; NameAddr mRemoteIdentity; Uri mLocalTarget; - std::unique_ptr mRemoteTarget; + std::auto_ptr mRemoteTarget; UInt64 mCreationTimeSeconds; - std::unique_ptr mLocalOfferAnswer; - std::unique_ptr mRemoteOfferAnswer; + std::auto_ptr mLocalOfferAnswer; + std::auto_ptr mRemoteOfferAnswer; private: bool mReplaced; diff --git a/src/libs/resiprocate/resip/dum/DialogEventStateManager.cxx b/src/libs/resiprocate/resip/dum/DialogEventStateManager.cxx index add0a1cd..bcb8ca8c 100644 --- a/src/libs/resiprocate/resip/dum/DialogEventStateManager.cxx +++ b/src/libs/resiprocate/resip/dum/DialogEventStateManager.cxx @@ -26,11 +26,11 @@ DialogEventStateManager::onTryingUas(Dialog& dialog, const SipMessage& invite) eventInfo->mDirection = DialogEventInfo::Recipient; eventInfo->mCreationTimeSeconds = Timer::getTimeSecs(); eventInfo->mInviteSession = InviteSessionHandle::NotValid(); - eventInfo->mRemoteOfferAnswer = (invite.getContents() != NULL ? std::unique_ptr(invite.getContents()->clone()) : std::unique_ptr()); + eventInfo->mRemoteOfferAnswer = (invite.getContents() != NULL ? std::auto_ptr(invite.getContents()->clone()) : std::auto_ptr()); eventInfo->mLocalIdentity = dialog.getLocalNameAddr(); eventInfo->mLocalTarget = dialog.getLocalContact().uri(); // !slg! TODO - fix me - the Dialog stored local contact has an empty hostname so that the stack will fill it in eventInfo->mRemoteIdentity = dialog.getRemoteNameAddr(); - eventInfo->mRemoteTarget = std::unique_ptr(new Uri(dialog.getRemoteTarget().uri())); + eventInfo->mRemoteTarget = std::auto_ptr(new Uri(dialog.getRemoteTarget().uri())); eventInfo->mRouteSet = dialog.getRouteSet(); eventInfo->mState = DialogEventInfo::Trying; @@ -40,20 +40,25 @@ DialogEventStateManager::onTryingUas(Dialog& dialog, const SipMessage& invite) Data replacesToTag = invite.header(h_Replaces).exists(p_toTag) ? invite.header(h_Replaces).param(p_toTag) : Data::Empty; Data replacesFromTag = invite.header(h_Replaces).exists(p_fromTag) ? invite.header(h_Replaces).param(p_fromTag) : Data::Empty; - eventInfo->mReplacesId = std::unique_ptr(new DialogId(invite.header(h_Replaces).value(), + eventInfo->mReplacesId = std::auto_ptr(new DialogId(invite.header(h_Replaces).value(), replacesToTag, replacesFromTag)); std::map::iterator it = mDialogIdToEventInfo.find(*(eventInfo->mReplacesId)); if (it != mDialogIdToEventInfo.end()) { - it->second->mReplaced = true; + // If the call to be replaced is early and it is a recipient, then it cannot get replaced (according to RFC3891) + // so we don't want to set the flag in this case. Using inverted logic statement. + if (it->second->getState() != DialogEventInfo::Early || it->second->getDirection() != DialogEventInfo::Recipient) + { + it->second->mReplaced = true; + } } } if (invite.exists(h_ReferredBy) && invite.header(h_ReferredBy).isWellFormed()) { - eventInfo->mReferredBy = std::unique_ptr(new NameAddr(invite.header(h_ReferredBy))); + eventInfo->mReferredBy = std::auto_ptr(new NameAddr(invite.header(h_ReferredBy))); } mDialogIdToEventInfo[dialog.getId()] = eventInfo; @@ -94,17 +99,17 @@ DialogEventStateManager::onTryingUac(DialogSet& dialogSet, const SipMessage& inv // ?bwc? Has something already checked for well-formedness here? // Maybe DialogSet? We need to be absolutely certain that this exists and is // well-formed. Assert for now. - assert(!invite.empty(h_Contacts)); - assert(invite.header(h_Contacts).front().isWellFormed()); + resip_assert(!invite.empty(h_Contacts)); + resip_assert(invite.header(h_Contacts).front().isWellFormed()); eventInfo->mLocalTarget = invite.header(h_Contacts).front().uri(); eventInfo->mRemoteIdentity = invite.header(h_To); - eventInfo->mLocalOfferAnswer = (invite.getContents() != NULL ? std::unique_ptr(invite.getContents()->clone()) : std::unique_ptr()); + eventInfo->mLocalOfferAnswer = (invite.getContents() != NULL ? std::auto_ptr(invite.getContents()->clone()) : std::auto_ptr()); eventInfo->mState = DialogEventInfo::Trying; if (invite.exists(h_ReferredBy) && invite.header(h_ReferredBy).isWellFormed()) { - eventInfo->mReferredBy = std::unique_ptr(new NameAddr(invite.header(h_ReferredBy))); + eventInfo->mReferredBy = std::auto_ptr(new NameAddr(invite.header(h_ReferredBy))); } mDialogIdToEventInfo[eventInfo->mDialogId] = eventInfo; @@ -131,8 +136,8 @@ DialogEventStateManager::onProceedingUac(const DialogSet& dialogSet, const SipMe { // ?bwc? Has something already checked for well-formedness here? // Maybe DialogSet? Assert for now. - assert(response.header(h_Contacts).front().isWellFormed()); - eventInfo->mRemoteTarget = std::unique_ptr(new Uri(response.header(h_Contacts).front().uri())); + resip_assert(response.header(h_Contacts).front().isWellFormed()); + eventInfo->mRemoteTarget = std::auto_ptr(new Uri(response.header(h_Contacts).front().uri())); } ProceedingDialogEvent evt(*eventInfo); mDialogEventHandler->onProceeding(evt); @@ -162,7 +167,7 @@ DialogEventStateManager::onEarly(const Dialog& dialog, InviteSessionHandle is) // local or remote target might change due to an UPDATE or re-INVITE eventInfo->mLocalTarget = dialog.getLocalContact().uri(); // !slg! TODO - fix me - the Dialog stored local contact has an empty hostname so that the stack will fill it in - eventInfo->mRemoteTarget = std::unique_ptr(new Uri(dialog.getRemoteTarget().uri())); + eventInfo->mRemoteTarget = std::auto_ptr(new Uri(dialog.getRemoteTarget().uri())); EarlyDialogEvent evt(*eventInfo); mDialogEventHandler->onEarly(evt); @@ -183,7 +188,11 @@ DialogEventStateManager::onConfirmed(const Dialog& dialog, InviteSessionHandle i // local or remote target might change due to an UPDATE or re-INVITE eventInfo->mLocalTarget = dialog.getLocalContact().uri(); // !slg! TODO - fix me - the Dialog stored local contact has an empty hostname so that the stack will fill it in - eventInfo->mRemoteTarget = std::unique_ptr(new Uri(dialog.getRemoteTarget().uri())); + eventInfo->mRemoteTarget = std::auto_ptr(new Uri(dialog.getRemoteTarget().uri())); + + // Set the latest sdp + eventInfo->mLocalOfferAnswer = (is->hasLocalOfferAnswer() ? std::auto_ptr(is->getLocalOfferAnswer().clone()) : std::auto_ptr()); + eventInfo->mRemoteOfferAnswer = (is->hasRemoteOfferAnswer() ? std::auto_ptr(is->getRemoteOfferAnswer().clone()) : std::auto_ptr()); // for the dialog that got the 200 OK SharedPtr confirmedEvt(new ConfirmedDialogEvent(*eventInfo)); @@ -239,7 +248,7 @@ DialogEventStateManager::onTerminated(const Dialog& dialog, const SipMessage& ms { // .jjg. we're killing a *specific* dialog *after* the successful completion of the initial INVITE transaction; // so just elminate this dialog, not the entire dialogset - std::unique_ptr evt(onDialogTerminatedImpl(it->second, reason, getResponseCode(msg), getFrontContact(msg))); + std::auto_ptr evt(onDialogTerminatedImpl(it->second, reason, getResponseCode(msg), getFrontContact(msg))); mDialogEventHandler->onTerminated(*evt); delete it->second; mDialogIdToEventInfo.erase(it++); @@ -283,7 +292,7 @@ DialogEventStateManager::onDialogSetTerminatedImpl(const DialogSetId& dialogSetI it->first.getDialogSetId() == dialogSetId) { eventInfo = it->second; - std::unique_ptr evt(onDialogTerminatedImpl(eventInfo, reason, getResponseCode(msg), getFrontContact(msg))); + std::auto_ptr evt(onDialogTerminatedImpl(eventInfo, reason, getResponseCode(msg), getFrontContact(msg))); mDialogEventHandler->onTerminated(*evt); delete it->second; mDialogIdToEventInfo.erase(it++); @@ -311,7 +320,7 @@ DialogEventStateManager::onDialogTerminatedImpl(DialogEventInfo* eventInfo, if (remoteTarget) { - eventInfo->mRemoteTarget = std::unique_ptr(remoteTarget); + eventInfo->mRemoteTarget = std::auto_ptr(remoteTarget); } TerminatedDialogEvent* evt = new TerminatedDialogEvent(*eventInfo, actualReason, responseCode); @@ -340,7 +349,7 @@ DialogEventStateManager::getFrontContact(const SipMessage& msg) { // ?bwc? Has something already checked for well-formedness here? // Maybe DialogSet? Assert for now. - assert(msg.header(h_Contacts).front().isWellFormed()); + resip_assert(msg.header(h_Contacts).front().isWellFormed()); pContact = new Uri(msg.header(h_Contacts).front().uri()); } } @@ -359,6 +368,34 @@ DialogEventStateManager::getDialogEventInfo() const return infos; } +DialogEventStateManager::DialogEventInfos +DialogEventStateManager::getDialogEventInfo(const Uri& entityUri, bool bMatchRemoteIdentityOnly) const +{ + DialogEventStateManager::DialogEventInfos infos; + std::map::const_iterator it = mDialogIdToEventInfo.begin(); + for (; it != mDialogIdToEventInfo.end(); it++) + { + if (!bMatchRemoteIdentityOnly) + { + // Return all calls to or from the requested entity + if (it->second->getLocalIdentity().uri().getAOR(false) == entityUri.getAOR(false) || + it->second->getRemoteIdentity().uri().getAOR(false) == entityUri.getAOR(false)) + { + infos.push_back(*(it->second)); + } + } + else + { + // Return only those dialogs whose remote identity matches the requested entity + if (it->second->getRemoteIdentity().uri().getAOR(false) == entityUri.getAOR(false)) + { + infos.push_back(*(it->second)); + } + } + } + return infos; +} + DialogEventInfo* DialogEventStateManager::findOrCreateDialogInfo(const Dialog& dialog) { @@ -403,7 +440,7 @@ DialogEventStateManager::findOrCreateDialogInfo(const Dialog& dialog) newForkInfo->mCreationTimeSeconds = Timer::getTimeSecs(); newForkInfo->mDialogId = dialog.getId(); newForkInfo->mRemoteIdentity = dialog.getRemoteNameAddr(); - newForkInfo->mRemoteTarget = std::unique_ptr(new Uri(dialog.getRemoteTarget().uri())); + newForkInfo->mRemoteTarget = std::auto_ptr(new Uri(dialog.getRemoteTarget().uri())); newForkInfo->mRouteSet = dialog.getRouteSet(); eventInfo = newForkInfo; } diff --git a/src/libs/resiprocate/resip/dum/DialogEventStateManager.hxx b/src/libs/resiprocate/resip/dum/DialogEventStateManager.hxx index d9547b81..2f9a9108 100644 --- a/src/libs/resiprocate/resip/dum/DialogEventStateManager.hxx +++ b/src/libs/resiprocate/resip/dum/DialogEventStateManager.hxx @@ -19,6 +19,7 @@ class DialogEventStateManager public: typedef std::vector DialogEventInfos; DialogEventInfos getDialogEventInfo() const; + DialogEventInfos getDialogEventInfo(const Uri& entityUri, bool bMatchRemoteIdentityOnly = false) const; virtual ~DialogEventStateManager(); diff --git a/src/libs/resiprocate/resip/dum/DialogSet.cxx b/src/libs/resiprocate/resip/dum/DialogSet.cxx index 25053bf5..b9a0c99a 100644 --- a/src/libs/resiprocate/resip/dum/DialogSet.cxx +++ b/src/libs/resiprocate/resip/dum/DialogSet.cxx @@ -48,7 +48,7 @@ DialogSet::DialogSet(BaseCreator* creator, DialogUsageManager& dum) : mServerPagerMessage(0) { setUserProfile(creator->getUserProfile()); - assert(!creator->getLastRequest()->isExternal()); + resip_assert(!creator->getLastRequest()->isExternal()); DebugLog ( << " ************* Created DialogSet(UAC) -- " << mId << "*************" ); } @@ -69,8 +69,8 @@ DialogSet::DialogSet(const SipMessage& request, DialogUsageManager& dum) : mClientPagerMessage(0), mServerPagerMessage(0) { - assert(request.isRequest()); - assert(request.isExternal()); + resip_assert(request.isRequest()); + resip_assert(request.isExternal()); mDum.mMergedRequests.insert(mMergeKey); if (request.header(h_RequestLine).method() == INVITE) { @@ -338,18 +338,18 @@ DialogSet::dispatch(const SipMessage& msg) } else { - ErrLog(<<"Response came in, but no AppDialogSet! Dropping this is very" + ErrLog(<<"Response came in, but no AppDialogSet! Dropping this is very " "likely to cause leaks, but continuing to process it is " "likely to cause a core. Taking the lesser of two evils..."); } return; } - assert(msg.isRequest() || msg.isResponse()); + resip_assert(msg.isRequest() || msg.isResponse()); if (mState == WaitingToEnd) { - assert(mDialogs.empty()); + resip_assert(mDialogs.empty()); if (msg.isResponse()) { int code = msg.header(h_StatusLine).statusCode(); @@ -451,7 +451,7 @@ DialogSet::dispatch(const SipMessage& msg) } else if(mState == Cancelling) { - assert(mDialogs.empty()); + resip_assert(mDialogs.empty()); if (msg.isResponse()) { int code = msg.header(h_StatusLine).statusCode(); @@ -520,7 +520,7 @@ DialogSet::dispatch(const SipMessage& msg) } else { - StackLog (<< "Matching dialog is destroying, dropping response message " << endl << msg); + StackLog (<< "Matching dialog is destroying, dropping response message " << endl << msg); } return; } @@ -547,6 +547,7 @@ DialogSet::dispatch(const SipMessage& msg) case BYE: case INFO: case ACK: + case PRACK: case UPDATE: if(!dialog) { @@ -570,7 +571,7 @@ DialogSet::dispatch(const SipMessage& msg) request.header(h_Requires).find(Token("norefersub"))))// out of dialog & noReferSub=true { DebugLog(<< "out of dialog refer request with norefersub"); - assert(mServerOutOfDialogRequest == 0); + resip_assert(mServerOutOfDialogRequest == 0); mServerOutOfDialogRequest = makeServerOutOfDialog(request); mServerOutOfDialogRequest->dispatch(request); return; @@ -592,7 +593,7 @@ DialogSet::dispatch(const SipMessage& msg) { // unsolicited - not allowed but commonly implemented // by large companies with a bridge as their logo - assert(mServerOutOfDialogRequest == 0); + resip_assert(mServerOutOfDialogRequest == 0); mServerOutOfDialogRequest = makeServerOutOfDialog(request); mServerOutOfDialogRequest->dispatch(request); return; @@ -600,7 +601,7 @@ DialogSet::dispatch(const SipMessage& msg) break; case PUBLISH: - assert(false); // handled in DialogUsageManager + resip_assert(false); // handled in DialogUsageManager return; case REGISTER: @@ -626,7 +627,7 @@ DialogSet::dispatch(const SipMessage& msg) // !jf! move this to DialogUsageManager DebugLog ( << "In DialogSet::dispatch, default(ServerOutOfDialogRequest), msg: " << msg ); // only can be one ServerOutOfDialogReq at a time - assert(mServerOutOfDialogRequest == 0); + resip_assert(mServerOutOfDialogRequest == 0); mServerOutOfDialogRequest = makeServerOutOfDialog(request); mServerOutOfDialogRequest->dispatch(request); return; @@ -742,7 +743,7 @@ DialogSet::dispatch(const SipMessage& msg) return; case MESSAGE: - if (dialog) + if (dialog) { break; } @@ -754,6 +755,7 @@ DialogSet::dispatch(const SipMessage& msg) case INFO: case UPDATE: + case PRACK: if (dialog) { break; @@ -791,7 +793,19 @@ DialogSet::dispatch(const SipMessage& msg) { if (msg.isRequest() && msg.header(h_RequestLine).method() == CANCEL) { - dispatchToAllDialogs(msg); + if(!mDialogs.empty()) + { + dispatchToAllDialogs(msg); + } + else + { + DebugLog ( << "In DialogSet::dispatch, CANCEL received but no dialogs to dispatch to - respond with 481, msg: " << msg ); + // Race condition - Dialogset is still around, but dialog is gone (potentially BYE'd). + // Need to respond to CANCEL in order for transaction in stack to go away + SharedPtr response(new SipMessage); + mDum.makeResponse(*response, msg, 481); + mDum.send(response); + } return; } @@ -883,7 +897,7 @@ DialogSet::dispatch(const SipMessage& msg) return; } - assert(mState != WaitingToEnd); + resip_assert(mState != WaitingToEnd); DebugLog ( << "### Calling CreateAppDialog ###: " << std::endl << std::endl <createAppDialog(msg); dialog->mAppDialog = appDialog; @@ -946,38 +960,63 @@ DialogSet::end() break; case ReceivedProvisional: { - assert (mCreator->getLastRequest()->header(h_CSeq).method() == INVITE); - mState = Terminating; - // !jf! this should be made exception safe - SharedPtr cancel(Helper::makeCancel(*getCreator()->getLastRequest())); - mDum.send(cancel); + if (mCreator->getLastRequest()->header(h_CSeq).method() == INVITE) + { + mState = Terminating; + // !jf! this should be made exception safe + SharedPtr cancel(Helper::makeCancel(*getCreator()->getLastRequest())); + mDum.send(cancel); - if (mDum.mDialogEventStateManager) - { - mDum.mDialogEventStateManager->onTerminated(*this, *cancel, InviteSessionHandler::LocalCancel); - } - - if (mDialogs.empty()) - { - mState = Cancelling; - } - else - { - //need to lag and do last element ouside of look as this DialogSet will be - //deleted if all dialogs are destroyed - for (DialogMap::iterator it = mDialogs.begin(); it != mDialogs.end(); it++) + if (mDum.mDialogEventStateManager) { - try + mDum.mDialogEventStateManager->onTerminated(*this, *cancel, InviteSessionHandler::LocalCancel); + } + + if (mDialogs.empty()) + { + mState = Cancelling; + } + else + { + //need to lag and do last element ouside of look as this DialogSet will be + //deleted if all dialogs are destroyed + for (DialogMap::iterator it = mDialogs.begin(); it != mDialogs.end(); it++) { - it->second->cancel(); - } - catch(UsageUseException& e) - { - InfoLog (<< "Caught: " << e); + try + { + it->second->cancel(); + } + catch (UsageUseException& e) + { + InfoLog(<< "Caught: " << e); + } } } } - } + else + { + // Non-Invite Dialogset + if (mDialogs.empty()) + { + mState = WaitingToEnd; + } + else + { + for (DialogMap::iterator it = mDialogs.begin(); it != mDialogs.end(); ++it) + { + try + { + it->second->end(); + } + catch (UsageUseException& e) + { + InfoLog(<< "Caught: " << e); + } + } + mState = Terminating; + } + } + } break; case Established: { @@ -1047,7 +1086,7 @@ ClientRegistration* DialogSet::makeClientRegistration(const SipMessage& response) { BaseCreator* creator = getCreator(); - assert(creator); + resip_assert(creator); return new ClientRegistration(mDum, *this, creator->getLastRequest()); } @@ -1055,7 +1094,7 @@ ClientPublication* DialogSet::makeClientPublication(const SipMessage& response) { BaseCreator* creator = getCreator(); - assert(creator); + resip_assert(creator); return new ClientPublication(mDum, *this, creator->getLastRequest()); } @@ -1063,7 +1102,7 @@ ClientOutOfDialogReq* DialogSet::makeClientOutOfDialogReq(const SipMessage& response) { BaseCreator* creator = getCreator(); - assert(creator); + resip_assert(creator); return new ClientOutOfDialogReq(mDum, *this, *creator->getLastRequest()); } @@ -1126,7 +1165,7 @@ DialogSet::getUserProfile() const void DialogSet::setUserProfile(SharedPtr userProfile) { - assert(userProfile.get()); + resip_assert(userProfile.get()); mUserProfile = userProfile; } diff --git a/src/libs/resiprocate/resip/dum/DialogSet.hxx b/src/libs/resiprocate/resip/dum/DialogSet.hxx index b9aaae06..b71d9f9f 100644 --- a/src/libs/resiprocate/resip/dum/DialogSet.hxx +++ b/src/libs/resiprocate/resip/dum/DialogSet.hxx @@ -81,7 +81,7 @@ class DialogSet /// Abandon this dialog set, but keep the AppDialogSet around void appDissociate() { - assert(mAppDialogSet); + resip_assert(mAppDialogSet); mAppDialogSet = 0; } friend class AppDialogSet; diff --git a/src/libs/resiprocate/resip/dum/DialogSetId.cxx b/src/libs/resiprocate/resip/dum/DialogSetId.cxx index 64f5b893..266a2bf9 100644 --- a/src/libs/resiprocate/resip/dum/DialogSetId.cxx +++ b/src/libs/resiprocate/resip/dum/DialogSetId.cxx @@ -40,12 +40,12 @@ DialogSetId::DialogSetId(const SipMessage& msg) : { if(msg.isRequest()) { - assert(msg.header(h_From).exists(p_tag)); + resip_assert(msg.header(h_From).exists(p_tag)); mTag = msg.header(h_From).param(p_tag); } else { - assert(msg.header(h_To).exists(p_tag)); + resip_assert(msg.header(h_To).exists(p_tag)); mTag = msg.header(h_To).param(p_tag); } } diff --git a/src/libs/resiprocate/resip/dum/DialogUsage.cxx b/src/libs/resiprocate/resip/dum/DialogUsage.cxx index 84377fe1..99a0ce06 100644 --- a/src/libs/resiprocate/resip/dum/DialogUsage.cxx +++ b/src/libs/resiprocate/resip/dum/DialogUsage.cxx @@ -4,26 +4,13 @@ #include "resip/dum/Dialog.hxx" #include "resip/dum/DialogSet.hxx" #include "resip/dum/DialogUsageManager.hxx" -#include "resip/stack/ExtensionHeader.hxx" -#include "resip/stack/ExtensionParameter.hxx" +#include "rutil/ResipAssert.h" #include "rutil/Logger.hxx" - #define RESIPROCATE_SUBSYSTEM Subsystem::DUM using namespace resip; -static void putUserHeaders(const std::map& hdr, SipMessage& msg) -{ - for (std::map::const_iterator iter = hdr.begin(); iter != hdr.end(); iter++) - { - const std::string& name = iter->first; - const std::string& value = iter->second; - - msg.header(ExtensionHeader(name.c_str())).push_back(StringCategory(value.c_str())); - } -} - DialogUsage::Exception::Exception(const Data& msg,const Data& file,int line) : BaseException(msg, file, line) { @@ -49,6 +36,11 @@ DialogUsage::~DialogUsage() AppDialogSetHandle DialogUsage::getAppDialogSet() { + if (mDialog.mDialogSet.mAppDialogSet == 0) + { + ErrLog(<< "mDialog.mDialogSet.mAppDialogSet is NULL!!!"); + return AppDialogSetHandle(); + } return mDialog.mDialogSet.mAppDialogSet->getHandle(); } @@ -76,6 +68,12 @@ DialogUsage::remoteTarget() const return mDialog.mRemoteTarget; } +const NameAddrs& +DialogUsage::getRouteSet() const +{ + return mDialog.mRouteSet; +} + const DialogId& DialogUsage::getDialogId() const { @@ -99,9 +97,6 @@ DialogUsage::send(SharedPtr msg) { // give app an chance to adorn the message. onReadyToSend(*msg); - - putUserHeaders(mUserHeaders, *msg); - mDialog.send(msg); } @@ -111,17 +106,12 @@ DialogUsage::sendCommand(SharedPtr message) mDum.post(new DialogUsageSendCommand(*this, message)); } -void -DialogUsage::setUserHeaders(const std::map &headers) -{ - mUserHeaders = headers; -} /* void DialogUsage::send(SipMessage& msg) { - assert(msg.isResponse() || msg.header(h_RequestLine).method() == ACK); + resip_assert(msg.isResponse() || msg.header(h_RequestLine).method() == ACK); mDialog.send(msg); } */ diff --git a/src/libs/resiprocate/resip/dum/DialogUsage.hxx b/src/libs/resiprocate/resip/dum/DialogUsage.hxx index cc8b6151..71590663 100644 --- a/src/libs/resiprocate/resip/dum/DialogUsage.hxx +++ b/src/libs/resiprocate/resip/dum/DialogUsage.hxx @@ -7,8 +7,6 @@ #include "resip/dum/UserProfile.hxx" #include "resip/dum/BaseUsage.hxx" #include "resip/dum/Handles.hxx" -#include -#include namespace resip { @@ -37,11 +35,11 @@ class DialogUsage : public BaseUsage const NameAddr& myAddr() const; const NameAddr& peerAddr() const; const NameAddr& remoteTarget() const; + const NameAddrs& getRouteSet() const; const DialogId& getDialogId() const; const Data& getCallId() const; SharedPtr getUserProfile(); - void setUserHeaders(const std::map& headers); - + protected: friend class DialogSet; friend class DialogUsageManager; @@ -82,14 +80,7 @@ class DialogUsage : public BaseUsage DialogUsage(DialogUsageManager& dum, Dialog& dialog); virtual ~DialogUsage(); - //virtual void sendToDialog(SharedPtr msg); - - virtual void dialogDestroyed(const SipMessage& msg) = 0; - Dialog& mDialog; - - // Custom headers - std::map mUserHeaders; }; } diff --git a/src/libs/resiprocate/resip/dum/DialogUsageManager.cxx b/src/libs/resiprocate/resip/dum/DialogUsageManager.cxx index f3487bb4..b7e8fa02 100644 --- a/src/libs/resiprocate/resip/dum/DialogUsageManager.cxx +++ b/src/libs/resiprocate/resip/dum/DialogUsageManager.cxx @@ -60,12 +60,14 @@ #include "resip/dum/OutgoingEvent.hxx" #include "resip/dum/DumHelper.hxx" #include "resip/dum/MergedRequestRemovalCommand.hxx" +#include "resip/dum/InMemorySyncPubDb.hxx" +#include "rutil/ResipAssert.h" #include "rutil/Inserter.hxx" #include "rutil/Logger.hxx" #include "rutil/Random.hxx" #include "rutil/Lockable.hxx" -#include "rutil/WinLeakCheck.hxx" #include "rutil/Timer.hxx" +#include "rutil/WinLeakCheck.hxx" #ifdef USE_SSL #include "resip/stack/ssl/Security.hxx" @@ -83,7 +85,7 @@ using namespace std; { \ if(mThreadDebugKey) \ { \ - assert(ThreadIf::tlsGetValue(mThreadDebugKey)); \ + resip_assert(ThreadIf::tlsGetValue(mThreadDebugKey)); \ } \ } while (false) #else @@ -103,6 +105,7 @@ DialogUsageManager::DialogUsageManager(SipStack& stack, bool createDefaultFeatur mDialogSetHandler(0), mRequestValidationHandler(0), mRegistrationPersistenceManager(0), + mPublicationPersistenceManager(0), mIsDefaultServerReferHandler(true), mClientPagerMessageHandler(0), mServerPagerMessageHandler(0), @@ -142,9 +145,7 @@ DialogUsageManager::DialogUsageManager(SipStack& stack, bool createDefaultFeatur #if defined (USE_SSL) addOutgoingFeature(encryptionOutgoing); #endif - } - } DialogUsageManager::~DialogUsageManager() @@ -152,14 +153,6 @@ DialogUsageManager::~DialogUsageManager() mShutdownState = Destroying; //InfoLog ( << "~DialogUsageManager" ); -#if(0) - // !kh! - DialogSetMap::iterator dialogSet = mDialogSetMap.begin(); - for (; dialogSet != mDialogSetMap.end(); ++dialogSet) - { - delete dialogSet->second; - } -#endif if(!mDialogSetMap.empty()) { DebugLog(<< "DialogUsageManager::mDialogSetMap has " << mDialogSetMap.size() << " DialogSets"); @@ -179,7 +172,7 @@ DialogUsageManager::~DialogUsageManager() while(!mDialogSetMap.empty()) { DialogSet* ds = mDialogSetMap.begin()->second; - delete ds; + delete ds; // Deleting a dialog set removes itself from the map } if(mIsDefaultServerReferHandler) @@ -190,6 +183,18 @@ DialogUsageManager::~DialogUsageManager() delete mIncomingTarget; delete mOutgoingTarget; + // Delete Server Publications + while (!mServerPublications.empty()) + { + delete mServerPublications.begin()->second; // Deleting a ServerPublication removes itself from the map + } + + // Remove any lingering incoming feature chain memory + for(FeatureChainMap::iterator it = mIncomingFeatureChainMap.begin(); it != mIncomingFeatureChainMap.end(); it++) + { + delete it->second; + } + //InfoLog ( << "~DialogUsageManager done" ); } @@ -292,41 +297,41 @@ DialogUsageManager::forceShutdown(DumShutdownHandler* h) DialogUsageManager::onAllHandlesDestroyed(); } -void DialogUsageManager::setAppDialogSetFactory(std::unique_ptr factory) +void DialogUsageManager::setAppDialogSetFactory(std::auto_ptr factory) { - mAppDialogSetFactory = std::move(factory); + mAppDialogSetFactory = factory; } SharedPtr& DialogUsageManager::getMasterProfile() { - assert(mMasterProfile.get()); + resip_assert(mMasterProfile.get()); return mMasterProfile; } SharedPtr& DialogUsageManager::getMasterUserProfile() { - assert(mMasterUserProfile.get()); + resip_assert(mMasterUserProfile.get()); return mMasterUserProfile; } void DialogUsageManager::setMasterProfile(const SharedPtr& masterProfile) { - assert(!mMasterProfile.get()); + resip_assert(!mMasterProfile.get()); mMasterProfile = masterProfile; mMasterUserProfile = masterProfile; // required so that we can return a reference to SharedPtr in getMasterUserProfile } -void DialogUsageManager::setKeepAliveManager(std::unique_ptr manager) +void DialogUsageManager::setKeepAliveManager(std::auto_ptr manager) { - mKeepAliveManager = std::move(manager); + mKeepAliveManager = manager; mKeepAliveManager->setDialogUsageManager(this); } -void DialogUsageManager::setRedirectManager(std::unique_ptr manager) +void DialogUsageManager::setRedirectManager(std::auto_ptr manager) { - mRedirectManager = std::move(manager); + mRedirectManager = manager; } void DialogUsageManager::setRedirectHandler(RedirectHandler* handler) @@ -340,9 +345,9 @@ RedirectHandler* DialogUsageManager::getRedirectHandler() } void -DialogUsageManager::setClientAuthManager(std::unique_ptr manager) +DialogUsageManager::setClientAuthManager(std::auto_ptr manager) { - mClientAuthManager = std::move(manager); + mClientAuthManager = manager; } void @@ -354,14 +359,14 @@ DialogUsageManager::setServerAuthManager(SharedPtr manager) void DialogUsageManager::setClientRegistrationHandler(ClientRegistrationHandler* handler) { - assert(!mClientRegistrationHandler); + resip_assert(!mClientRegistrationHandler); mClientRegistrationHandler = handler; } void DialogUsageManager::setServerRegistrationHandler(ServerRegistrationHandler* handler) { - assert(!mServerRegistrationHandler); + resip_assert(!mServerRegistrationHandler); mServerRegistrationHandler = handler; } @@ -374,27 +379,29 @@ DialogUsageManager::setDialogSetHandler(DialogSetHandler* handler) void DialogUsageManager::setInviteSessionHandler(InviteSessionHandler* handler) { - assert(!mInviteSessionHandler); + resip_assert(!mInviteSessionHandler); mInviteSessionHandler = handler; } void DialogUsageManager::setRequestValidationHandler(RequestValidationHandler* handler) { - assert(!mRequestValidationHandler); + resip_assert(!mRequestValidationHandler); mRequestValidationHandler = handler; } void DialogUsageManager::setRegistrationPersistenceManager(RegistrationPersistenceManager* manager) { - assert(!mRegistrationPersistenceManager); + resip_assert(!mRegistrationPersistenceManager); mRegistrationPersistenceManager = manager; } void -DialogUsageManager::setRemoteCertStore(unique_ptr store) +DialogUsageManager::setPublicationPersistenceManager(PublicationPersistenceManager* manager) { + resip_assert(!mPublicationPersistenceManager); + mPublicationPersistenceManager = manager; } void @@ -417,15 +424,15 @@ DialogUsageManager::addTimerMs(DumTimeout::Type type, unsigned long duration, void DialogUsageManager::addClientSubscriptionHandler(const Data& eventType, ClientSubscriptionHandler* handler) { - assert(handler); - assert(mClientSubscriptionHandlers.count(eventType) == 0); + resip_assert(handler); + resip_assert(mClientSubscriptionHandlers.count(eventType) == 0); mClientSubscriptionHandlers[eventType] = handler; } void DialogUsageManager::addServerSubscriptionHandler(const Data& eventType, ServerSubscriptionHandler* handler) { - assert(handler); + resip_assert(handler); //default do-nothing server side refer handler can be replaced if (eventType == "refer" && mServerSubscriptionHandlers.count(eventType)) { @@ -440,24 +447,24 @@ DialogUsageManager::addServerSubscriptionHandler(const Data& eventType, ServerSu void DialogUsageManager::addClientPublicationHandler(const Data& eventType, ClientPublicationHandler* handler) { - assert(handler); - assert(mClientPublicationHandlers.count(eventType) == 0); + resip_assert(handler); + resip_assert(mClientPublicationHandlers.count(eventType) == 0); mClientPublicationHandlers[eventType] = handler; } void DialogUsageManager::addServerPublicationHandler(const Data& eventType, ServerPublicationHandler* handler) { - assert(handler); - assert(mServerPublicationHandlers.count(eventType) == 0); + resip_assert(handler); + resip_assert(mServerPublicationHandlers.count(eventType) == 0); mServerPublicationHandlers[eventType] = handler; } void DialogUsageManager::addOutOfDialogHandler(MethodTypes type, OutOfDialogHandler* handler) { - assert(handler); - assert(mOutOfDialogHandlers.count(type) == 0); + resip_assert(handler); + resip_assert(mOutOfDialogHandlers.count(type) == 0); mOutOfDialogHandlers[type] = handler; } @@ -539,14 +546,14 @@ DialogUsageManager::makeResponse(SipMessage& response, int responseCode, const Data& reason) const { - assert(request.isRequest()); + resip_assert(request.isRequest()); Helper::makeResponse(response, request, responseCode, reason); } void DialogUsageManager::sendResponse(const SipMessage& response) { - assert(response.isResponse()); + resip_assert(response.isResponse()); mStack.send(response, this); } @@ -585,6 +592,24 @@ DialogUsageManager::makeInviteSession(const NameAddr& target, return makeInviteSession(target, getMasterUserProfile(), initialOffer, level, alternative, appDs); } +SharedPtr +DialogUsageManager::makeInviteSession(const NameAddr& target, + const DialogSetId& dialogSetId, + const SharedPtr& userProfile, + const Contents* initialOffer, + EncryptionLevel level, + const Contents* alternative, + AppDialogSet* appDs) +{ + assert(mDialogSetMap.find(dialogSetId) == mDialogSetMap.end()); + BaseCreator* baseCreator(new InviteSessionCreator(*this, target, userProfile, initialOffer, level, alternative)); + baseCreator->getLastRequest()->header(h_CallID).value() = dialogSetId.getCallId(); + baseCreator->getLastRequest()->header(h_From).param(p_tag) = dialogSetId.getLocalTag(); + SharedPtr inv = makeNewSession(baseCreator, appDs); + DumHelper::setOutgoingEncryptionLevel(*inv, level); + return inv; +} + SharedPtr DialogUsageManager::makeInviteSession(const NameAddr& target, InviteSessionHandle sessionToReplace, @@ -594,11 +619,11 @@ DialogUsageManager::makeInviteSession(const NameAddr& target, { SharedPtr inv = makeInviteSession(target, userProfile, initialOffer, ads); // add replaces header - assert(sessionToReplace.isValid()); + resip_assert(sessionToReplace.isValid()); if(sessionToReplace.isValid()) { CallId replaces; - DialogId id = sessionToReplace->getDialogId(); + const DialogId& id = sessionToReplace->getDialogId(); replaces.value() = id.getCallId(); replaces.param(p_toTag) = id.getRemoteTag(); replaces.param(p_fromTag) = id.getLocalTag(); @@ -618,11 +643,11 @@ DialogUsageManager::makeInviteSession(const NameAddr& target, { SharedPtr inv = makeInviteSession(target, userProfile, initialOffer, level, alternative, ads); // add replaces header - assert(sessionToReplace.isValid()); + resip_assert(sessionToReplace.isValid()); if(sessionToReplace.isValid()) { CallId replaces; - DialogId id = sessionToReplace->getDialogId(); + const DialogId& id = sessionToReplace->getDialogId(); replaces.value() = id.getCallId(); replaces.param(p_toTag) = id.getRemoteTag(); replaces.param(p_fromTag) = id.getLocalTag(); @@ -641,11 +666,11 @@ DialogUsageManager::makeInviteSession(const NameAddr& target, { SharedPtr inv = makeInviteSession(target, initialOffer, level, alternative, ads); // add replaces header - assert(sessionToReplace.isValid()); + resip_assert(sessionToReplace.isValid()); if(sessionToReplace.isValid()) { CallId replaces; - DialogId id = sessionToReplace->getDialogId(); + const DialogId& id = sessionToReplace->getDialogId(); replaces.value() = id.getCallId(); replaces.param(p_toTag) = id.getRemoteTag(); replaces.param(p_fromTag) = id.getLocalTag(); @@ -751,7 +776,7 @@ DialogUsageManager::makeRefer(const NameAddr& target, const H_ReferTo::Type& ref SharedPtr DialogUsageManager::makeSubscription(const NameAddr& target, const SharedPtr& userProfile, const Data& eventType, AppDialogSet* appDs) { - assert(userProfile.get()); + resip_assert(userProfile.get()); return makeNewSession(new SubscriptionCreator(*this, target, userProfile, eventType, userProfile->getDefaultSubscriptionTime()), appDs); } @@ -792,7 +817,7 @@ DialogUsageManager::makeSubscription(const NameAddr& target, const Data& eventTy SharedPtr DialogUsageManager::makeRegistration(const NameAddr& target, const SharedPtr& userProfile, AppDialogSet* appDs) { - assert(userProfile.get()); + resip_assert(userProfile.get()); return makeNewSession(new RegistrationCreator(*this, target, userProfile, userProfile->getDefaultRegistrationTime()), appDs); } @@ -881,7 +906,7 @@ DialogUsageManager::send(SharedPtr msg) userProfile = ds->getUserProfile().get(); } - assert(userProfile); + resip_assert(userProfile); if (!userProfile->isAnonymous() && userProfile->hasUserAgent()) { msg->header(h_UserAgent).value() = userProfile->getUserAgent(); @@ -899,7 +924,7 @@ DialogUsageManager::send(SharedPtr msg) msg->remove(h_Warnings); } - assert(userProfile); + resip_assert(userProfile); if (msg->isRequest() && userProfile->hasProxyRequires() && msg->header(h_RequestLine).method() != ACK @@ -924,11 +949,7 @@ DialogUsageManager::send(SharedPtr msg) SharedPtr outboundDecorator = userProfile->getOutboundDecorator(); if (outboundDecorator.get()) { - msg->addOutboundDecorator(std::unique_ptr(outboundDecorator->clone())); - } - else - { - DebugLog(<< "No outbound decorator for message"); + msg->addOutboundDecorator(std::auto_ptr(outboundDecorator->clone())); } if (msg->isRequest()) @@ -943,7 +964,11 @@ DialogUsageManager::send(SharedPtr msg) if (msg->exists(h_Vias)) { - if(!userProfile->getRportEnabled()) + if(userProfile->getRportEnabled()) + { + msg->header(h_Vias).front().param(p_rport); + } + else { msg->header(h_Vias).front().remove(p_rport); } @@ -971,12 +996,9 @@ DialogUsageManager::send(SharedPtr msg) if (mDialogEventStateManager) { Dialog* d = ds->findDialog(*msg); - if (d != 0) - { - mDialogEventStateManager->onConfirmed(*d, d->getInviteSession()); - } - else + if (d == 0) { + // If we don't have a dialog yet and we are sending an INVITE, this is a new outbound (UAC) INVITE mDialogEventStateManager->onTryingUac(*ds, *msg); } } @@ -987,7 +1009,7 @@ DialogUsageManager::send(SharedPtr msg) DebugLog (<< "SEND: " << std::endl << std::endl << *msg); OutgoingEvent* event = new OutgoingEvent(msg); - outgoingProcess(unique_ptr(event)); + outgoingProcess(auto_ptr(event)); } void @@ -998,7 +1020,7 @@ DialogUsageManager::sendCommand(SharedPtr request) } -void DialogUsageManager::outgoingProcess(unique_ptr message) +void DialogUsageManager::outgoingProcess(auto_ptr message) { Data tid = Data::Empty; { @@ -1071,12 +1093,12 @@ void DialogUsageManager::outgoingProcess(unique_ptr message) userProfile = ds->getUserProfile().get(); } - assert(userProfile); + resip_assert(userProfile); - //!dcm! -- unique SharedPtr to unique_ptr conversion prob. a worthwhile + //!dcm! -- unique SharedPtr to auto_ptr conversion prob. a worthwhile //optimzation here. SharedPtr would have to be changed; would //throw/assert if not unique. - std::unique_ptr toSend(static_cast(event->message()->clone())); + std::auto_ptr toSend(static_cast(event->message()->clone())); // .bwc. Protect ourselves from garbage with an isWellFormed() check. // (Code in Dialog doesn't check for well-formedness in the @@ -1087,11 +1109,11 @@ void DialogUsageManager::outgoingProcess(unique_ptr message) !event->message()->header(h_Routes).front().uri().exists(p_lr)) { Helper::processStrictRoute(*toSend); - sendUsingOutboundIfAppropriate(*userProfile, std::move(toSend)); + sendUsingOutboundIfAppropriate(*userProfile, toSend); } else { - sendUsingOutboundIfAppropriate(*userProfile, std::move(toSend)); + sendUsingOutboundIfAppropriate(*userProfile, toSend); } } else @@ -1102,7 +1124,7 @@ void DialogUsageManager::outgoingProcess(unique_ptr message) } void -DialogUsageManager::sendUsingOutboundIfAppropriate(UserProfile& userProfile, unique_ptr msg) +DialogUsageManager::sendUsingOutboundIfAppropriate(UserProfile& userProfile, auto_ptr msg) { //a little inefficient, branch parameter might be better DialogId id(*msg); @@ -1121,12 +1143,12 @@ DialogUsageManager::sendUsingOutboundIfAppropriate(UserProfile& userProfile, uni { DebugLog ( << "Sending with client outbound flow tuple to express outbound" ); DebugLog ( << "Flow Tuple: " << userProfile.mClientOutboundFlowTuple << " and key: " << userProfile.mClientOutboundFlowTuple.mFlowKey); - mStack.sendTo(std::move(msg), userProfile.mClientOutboundFlowTuple, this); + mStack.sendTo(msg, userProfile.mClientOutboundFlowTuple, this); } else { DebugLog ( << "Sending to express outbound w/o flow tuple"); - mStack.send(std::move(msg), this); + mStack.send(msg, this); } } else @@ -1134,12 +1156,12 @@ DialogUsageManager::sendUsingOutboundIfAppropriate(UserProfile& userProfile, uni if(userProfile.clientOutboundEnabled() && userProfile.mClientOutboundFlowTuple.mFlowKey != 0) { DebugLog ( << "Sending to outbound (no express) with flow tuple"); - mStack.sendTo(std::move(msg), userProfile.mClientOutboundFlowTuple, this); + mStack.sendTo(msg, userProfile.mClientOutboundFlowTuple, this); } else { DebugLog ( << "Sending to outbound uri"); - mStack.sendTo(std::move(msg), userProfile.getOutboundProxy().uri(), this); + mStack.sendTo(msg, userProfile.getOutboundProxy().uri(), this); } } } @@ -1148,11 +1170,11 @@ DialogUsageManager::sendUsingOutboundIfAppropriate(UserProfile& userProfile, uni DebugLog (<< "Send: " << msg->brief()); if(userProfile.clientOutboundEnabled() && userProfile.mClientOutboundFlowTuple.mFlowKey != 0) { - mStack.sendTo(std::move(msg), userProfile.mClientOutboundFlowTuple, this); + mStack.sendTo(msg, userProfile.mClientOutboundFlowTuple, this); } else { - mStack.send(std::move(msg), this); + mStack.send(msg, this); } } } @@ -1162,7 +1184,7 @@ void DialogUsageManager::end(DialogSetId setid) { DialogSet* ds = findDialogSet(setid); - if (ds == nullptr) + if (ds == 0) { throw Exception("Request no longer exists", __FILE__, __LINE__); } @@ -1308,14 +1330,14 @@ AppDialogSetHandle DialogUsageManager::findAppDialogSet(const DialogSetId& id) } void -DialogUsageManager::internalProcess(std::unique_ptr msg) +DialogUsageManager::internalProcess(std::auto_ptr msg) { #ifdef RESIP_DUM_THREAD_DEBUG if(!mThreadDebugKey) { // .bwc. Probably means multiple threads are trying to give DUM cycles // simultaneously. - assert(!mHiddenThreadDebugKey); + resip_assert(!mHiddenThreadDebugKey); // No d'tor needed, since we're just going to use a pointer to this. if(!ThreadIf::tlsKeyCreate(mThreadDebugKey, 0)) { @@ -1344,8 +1366,8 @@ DialogUsageManager::internalProcess(std::unique_ptr msg) if (tuMsg) { InfoLog (<< "TU unregistered "); - assert(mShutdownState == RemovingTransactionUser); - assert(tuMsg->type() == TransactionUserMessage::TransactionUserRemoved); + resip_assert(mShutdownState == RemovingTransactionUser); + resip_assert(tuMsg->type() == TransactionUserMessage::TransactionUserRemoved); mShutdownState = Shutdown; if (mDumShutdownHandler) { @@ -1480,7 +1502,7 @@ DialogUsageManager::internalProcess(std::unique_ptr msg) } } - incomingProcess(std::move(msg)); + incomingProcess(msg); } void @@ -1499,7 +1521,7 @@ DialogUsageManager::processExternalMessage(ExternalMessageBase* externalMessage) } void -DialogUsageManager::incomingProcess(std::unique_ptr msg) +DialogUsageManager::incomingProcess(std::auto_ptr msg) { //call or create feature chain if appropriate Data tid = Data::Empty; @@ -1568,8 +1590,16 @@ DialogUsageManager::incomingProcess(std::unique_ptr msg) } else { - assert(dynamic_cast(msg.get())); - it = mIncomingFeatureChainMap.insert(lb, FeatureChainMap::value_type(tid, new DumFeatureChain(*this, mIncomingFeatureList, *mIncomingTarget))); + if(dynamic_cast(msg.get())) + { + it = mIncomingFeatureChainMap.insert(lb, FeatureChainMap::value_type(tid, new DumFeatureChain(*this, mIncomingFeatureList, *mIncomingTarget))); + } + else + { + // Certain messages from the wire (ie: CANCEL) can end a feature, however there may still be some + // pending Async requests (non-SipMessages) that are coming in - just drop them if so + return; + } } } @@ -1592,7 +1622,7 @@ DialogUsageManager::incomingProcess(std::unique_ptr msg) try { - InfoLog (<< "Got: " << msg->brief()); + DebugLog (<< "Got: " << msg->brief()); DumDecrypted* decryptedMsg = dynamic_cast(msg.get()); SipMessage* sipMsg = 0; if (decryptedMsg) @@ -1625,7 +1655,7 @@ DialogUsageManager::incomingProcess(std::unique_ptr msg) DebugLog (<< "Failed required options validation " << *sipMsg); return; } - if( !validate100RelSuport(*sipMsg) ) + if( !validate100RelSupport(*sipMsg) ) { DebugLog (<< "Remote party does not support 100rel " << *sipMsg); return; @@ -1660,7 +1690,7 @@ DialogUsageManager::incomingProcess(std::unique_ptr msg) catch(BaseException& e) { //unparseable, bad 403 w/ 2543 trans it from FWD, etc - ErrLog(<<"Illegal message rejected: " << e.getMessage()); + ErrLog(<<"Illegal message rejected: " << e.getMessage()); } } @@ -1680,7 +1710,7 @@ DialogUsageManager::process(resip::Lockable* mutex) #ifdef RESIP_DUM_THREAD_DEBUG mThreadDebugKey=mHiddenThreadDebugKey; #endif - internalProcess(std::unique_ptr(mFifo.getNext())); + internalProcess(std::auto_ptr(mFifo.getNext())); #ifdef RESIP_DUM_THREAD_DEBUG // .bwc. Thread checking is disabled if mThreadDebugKey is 0; if the app // is using this mutex-locked process() call, we only enable thread- @@ -1698,7 +1728,7 @@ DialogUsageManager::process(resip::Lockable* mutex) bool DialogUsageManager::process(int timeoutMs, resip::Lockable* mutex) { - std::unique_ptr message; + std::auto_ptr message; if(timeoutMs == -1) { @@ -1714,7 +1744,7 @@ DialogUsageManager::process(int timeoutMs, resip::Lockable* mutex) #ifdef RESIP_DUM_THREAD_DEBUG mThreadDebugKey=mHiddenThreadDebugKey; #endif - internalProcess(std::move(message)); + internalProcess(message); #ifdef RESIP_DUM_THREAD_DEBUG // .bwc. Thread checking is disabled if mThreadDebugKey is 0; if the app // is using this mutex-locked process() call, we only enable thread- @@ -1771,8 +1801,8 @@ DialogUsageManager::validateRequiredOptions(const SipMessage& request) { // RFC 2162 - 8.2.2 if(request.exists(h_Requires) && // Don't check requires if method is ACK or CANCEL - (request.header(h_RequestLine).getMethod() != ACK || - request.header(h_RequestLine).getMethod() != CANCEL)) + request.header(h_RequestLine).getMethod() != ACK && + request.header(h_RequestLine).getMethod() != CANCEL) { Tokens unsupported = getMasterProfile()->getUnsupportedOptionsTags(request.header(h_Requires)); if (!unsupported.empty()) @@ -1796,7 +1826,7 @@ DialogUsageManager::validateRequiredOptions(const SipMessage& request) bool -DialogUsageManager::validate100RelSuport(const SipMessage& request) +DialogUsageManager::validate100RelSupport(const SipMessage& request) { if(request.header(h_RequestLine).getMethod() == INVITE) { @@ -1811,7 +1841,9 @@ DialogUsageManager::validate100RelSuport(const SipMessage& request) sendResponse(failure); if(mRequestValidationHandler) + { mRequestValidationHandler->on100RelNotSupportedByRemote(request); + } return false; } @@ -1927,8 +1959,8 @@ DialogUsageManager::validateAccept(const SipMessage& request) bool DialogUsageManager::mergeRequest(const SipMessage& request) { - assert(request.isRequest()); - assert(request.isExternal()); + resip_assert(request.isRequest()); + resip_assert(request.isExternal()); if (!request.header(h_To).exists(p_tag)) { @@ -1972,7 +2004,7 @@ DialogUsageManager::processRequest(const SipMessage& request) toTag = false; } - assert(mAppDialogSetFactory.get()); + resip_assert(mAppDialogSetFactory.get()); // !jf! note, the logic was reversed during ye great merge of March of Ought 5 if (toTag || findDialogSet(DialogSetId(request))) @@ -2043,7 +2075,7 @@ DialogUsageManager::processRequest(const SipMessage& request) } else { - InfoLog (<< "Received a CANCEL on a non-existent transaction "); + InfoLog (<< "Received a CANCEL on a non-existent transaction: tid=" << request.getTransactionId()); SipMessage failure; makeResponse(failure, request, 481); sendResponse(failure); @@ -2051,8 +2083,8 @@ DialogUsageManager::processRequest(const SipMessage& request) break; } case PUBLISH: - assert(false); - return; + resip_assert(false); + return; case SUBSCRIBE: if (!checkEventPackage(request)) { @@ -2060,7 +2092,7 @@ DialogUsageManager::processRequest(const SipMessage& request) << request.brief()); return; } - /*FALLTHRU*/ + /*FALLTHRU*/ case NOTIFY : // handle unsolicited (illegal) NOTIFYs case INVITE: // new INVITE case REFER: // out-of-dialog REFER @@ -2121,11 +2153,11 @@ DialogUsageManager::processRequest(const SipMessage& request) } case RESPONSE: case SERVICE: - assert(false); + resip_assert(false); break; case UNKNOWN: case MAX_METHODS: - assert(false); + resip_assert(false); break; } } @@ -2145,7 +2177,7 @@ DialogUsageManager::processResponse(const SipMessage& response) } else { - InfoLog (<< "Throwing away stray response: " << std::endl << std::endl << response.brief()); + InfoLog (<< "Throwing away stray response: " << std::endl << std::endl << response.brief()); } } } @@ -2168,9 +2200,22 @@ DialogUsageManager::processPublish(const SipMessage& request) } else { - SharedPtr response(new SipMessage); - makeResponse(*response, request, 412); - send(response); + // Check if publication exists in PublicationDb - may have been sync'd over, + // or exists from a restart. In this case, fabricate a new ServerSubcription + // to handle this request. + if (mPublicationPersistenceManager && + mPublicationPersistenceManager->documentExists(request.header(h_Event).value(), request.header(h_RequestLine).uri().getAor(), request.header(h_SIPIfMatch).value())) + { + ServerPublication* sp = new ServerPublication(*this, request.header(h_SIPIfMatch).value(), request); + mServerPublications[request.header(h_SIPIfMatch).value()] = sp; + sp->dispatch(request); + } + else + { + SharedPtr response(new SipMessage); + makeResponse(*response, request, 412); + send(response); + } } } else @@ -2239,7 +2284,7 @@ DialogUsageManager::checkEventPackage(const SipMessage& request) } break; default: - assert(0); + resip_assert(0); } } @@ -2247,6 +2292,10 @@ DialogUsageManager::checkEventPackage(const SipMessage& request) { SharedPtr response(new SipMessage); makeResponse(*response, request, failureCode); + if(failureCode == 489) + { + response->header(h_AllowEvents) = getMasterProfile()->getAllowedEvents(); + } send(response); return false; } @@ -2263,16 +2312,19 @@ DialogUsageManager::findDialogSet(const DialogSetId& id) if (it == mDialogSetMap.end()) { + StackLog ( << "Not found" ); return 0; } else { if(it->second->isDestroying()) { + StackLog ( << "isDestroying() == true" ); return 0; } else { + StackLog ( << "found" ); return it->second; } } @@ -2397,7 +2449,7 @@ DialogUsageManager::setOutgoingMessageInterceptor(SharedPtr feat) void DialogUsageManager::applyToAllServerSubscriptions(ServerSubscriptionFunctor* functor) { - assert(functor); + resip_assert(functor); for (DialogSetMap::iterator it = mDialogSetMap.begin(); it != mDialogSetMap.end(); ++it) { for (DialogSet::DialogMap::iterator i = it->second->mDialogs.begin(); i != it->second->mDialogs.end(); ++i) @@ -2414,7 +2466,7 @@ DialogUsageManager::applyToAllServerSubscriptions(ServerSubscriptionFunctor* fun void DialogUsageManager::applyToAllClientSubscriptions(ClientSubscriptionFunctor* functor) { - assert(functor); + resip_assert(functor); for (DialogSetMap::iterator it = mDialogSetMap.begin(); it != mDialogSetMap.end(); ++it) { for (DialogSet::DialogMap::iterator i = it->second->mDialogs.begin(); i != it->second->mDialogs.end(); ++i) @@ -2428,6 +2480,32 @@ DialogUsageManager::applyToAllClientSubscriptions(ClientSubscriptionFunctor* fun } } +void +DialogUsageManager::endAllServerSubscriptions(TerminateReason reason) +{ + // Make a copy of the map - since calling end can cause an immediate delete this on the subscription and thus cause + // the object to remove itself from the mServerSubscriptions map, messing up our iterator + ServerSubscriptions tempSubscriptions = mServerSubscriptions; + ServerSubscriptions::iterator it = tempSubscriptions.begin(); + for (; it != tempSubscriptions.end(); it++) + { + it->second->end(reason); + } +} + +void +DialogUsageManager::endAllServerPublications() +{ + // Make a copy of the map - since calling end can cause an immediate delete this on the publication and thus cause + // the object to remove itself from the mServerPublications map, messing up our iterator + ServerPublications tempPublications = mServerPublications; + ServerPublications::iterator it = tempPublications.begin(); + for (; it != tempPublications.end(); it++) + { + it->second->end(); + } +} + void DialogUsageManager::registerForConnectionTermination(Postable* listener) { @@ -2443,9 +2521,13 @@ DialogUsageManager::unRegisterForConnectionTermination(Postable* listener) void DialogUsageManager::requestMergedRequestRemoval(const MergedRequestKey& key) { - DebugLog(<< "Got merged request removal request"); - MergedRequestRemovalCommand command(*this, key); - mStack.postMS(command, Timer::TF, this); + // Only post delayed merge request removal if running, if we are shutting down, then there is no need + if (mShutdownState == Running) + { + DebugLog(<< "Got merged request removal request"); + MergedRequestRemovalCommand command(*this, key); + mStack.postMS(command, Timer::TF, this); + } } void @@ -2483,6 +2565,30 @@ DialogUsageManager::createDialogEventStateManager(DialogEventHandler* handler) return mDialogEventStateManager; } +void +DialogUsageManager::setAdvertisedCapabilities(SipMessage& msg, SharedPtr userProfile) +{ + if(userProfile->isAdvertisedCapability(Headers::Allow)) + { + msg.header(h_Allows) = getMasterProfile()->getAllowedMethods(); + } + if(userProfile->isAdvertisedCapability(Headers::AcceptEncoding)) + { + msg.header(h_AcceptEncodings) = getMasterProfile()->getSupportedEncodings(); + } + if(userProfile->isAdvertisedCapability(Headers::AcceptLanguage)) + { + msg.header(h_AcceptLanguages) = getMasterProfile()->getSupportedLanguages(); + } + if(userProfile->isAdvertisedCapability(Headers::AllowEvents)) + { + msg.header(h_AllowEvents) = getMasterProfile()->getAllowedEvents(); + } + if(userProfile->isAdvertisedCapability(Headers::Supported)) + { + msg.header(h_Supporteds) = getMasterProfile()->getSupportedOptionTags(); + } +} /* ==================================================================== * The Vovida Software License, Version 1.0 diff --git a/src/libs/resiprocate/resip/dum/DialogUsageManager.hxx b/src/libs/resiprocate/resip/dum/DialogUsageManager.hxx index ecef8d83..43d1f208 100644 --- a/src/libs/resiprocate/resip/dum/DialogUsageManager.hxx +++ b/src/libs/resiprocate/resip/dum/DialogUsageManager.hxx @@ -14,6 +14,7 @@ #include "resip/dum/Handles.hxx" #include "resip/dum/MergedRequestKey.hxx" #include "resip/dum/RegistrationPersistenceManager.hxx" +#include "resip/dum/PublicationPersistenceManager.hxx" #include "resip/dum/ServerSubscription.hxx" #include "rutil/BaseException.hxx" #include "rutil/SharedPtr.hxx" @@ -111,7 +112,8 @@ class DialogUsageManager : public HandleManager, public TransactionUser void forceShutdown(DumShutdownHandler*); - void addTransport( TransportType protocol, + // Use SipStack::addTransport instead + RESIP_DEPRECATED(void addTransport( TransportType protocol, int port=0, IpVersion version=V4, const Data& ipInterface = Data::Empty, @@ -119,8 +121,8 @@ class DialogUsageManager : public HandleManager, public TransactionUser // for TLS // based stuff const Data& privateKeyPassPhrase = Data::Empty, - SecurityTypes::SSLType sslType = SecurityTypes::TLSv1, - unsigned transportFlags = 0); + SecurityTypes::SSLType sslType = SecurityTypes::SSLv23, + unsigned transportFlags = 0)); SipStack& getSipStack(); const SipStack& getSipStack() const; @@ -128,7 +130,7 @@ class DialogUsageManager : public HandleManager, public TransactionUser Data getHostAddress(); - void setAppDialogSetFactory(std::unique_ptr); + void setAppDialogSetFactory(std::auto_ptr); void setMasterProfile(const SharedPtr& masterProfile); SharedPtr& getMasterProfile(); @@ -137,18 +139,18 @@ class DialogUsageManager : public HandleManager, public TransactionUser //optional handler to track the progress of DialogSets void setDialogSetHandler(DialogSetHandler* handler); - void setKeepAliveManager(std::unique_ptr keepAlive); + void setKeepAliveManager(std::auto_ptr keepAlive); //There is a default RedirectManager. Setting one may cause the old one //to be deleted. - void setRedirectManager(std::unique_ptr redirect); + void setRedirectManager(std::auto_ptr redirect); //informational, so a RedirectHandler is not required void setRedirectHandler(RedirectHandler* handler); RedirectHandler* getRedirectHandler(); /// If there is no ClientAuthManager, when the client receives a 401/407, /// pass it up through the normal BaseUsageHandler - void setClientAuthManager(std::unique_ptr client); + void setClientAuthManager(std::auto_ptr client); /// If there is no ServerAuthManager, the server does not authenticate requests void setServerAuthManager(resip::SharedPtr server); @@ -185,10 +187,11 @@ class DialogUsageManager : public HandleManager, public TransactionUser void removeExternalMessageHandler(ExternalMessageHandler* handler); void clearExternalMessageHandler(); - /// Sets a manager to handle storage of registration state + /// Sets a manager to handle storage of registration or publication state void setRegistrationPersistenceManager(RegistrationPersistenceManager*); - - void setRemoteCertStore(std::unique_ptr store); + RegistrationPersistenceManager* getRegistrationPersistenceManager() { return mRegistrationPersistenceManager; } + void setPublicationPersistenceManager(PublicationPersistenceManager*); + PublicationPersistenceManager* getPublicationPersistenceManager() { return mPublicationPersistenceManager; } // The message is owned by the underlying datastructure and may go away in // the future. If the caller wants to keep it, it should make a copy. The @@ -198,6 +201,7 @@ class DialogUsageManager : public HandleManager, public TransactionUser SharedPtr makeInviteSession(const NameAddr& target, const Contents* initialOffer, AppDialogSet* ads = 0); SharedPtr makeInviteSession(const NameAddr& target, const SharedPtr& userProfile, const Contents* initialOffer, EncryptionLevel level, const Contents* alternative = 0, AppDialogSet* ads = 0); SharedPtr makeInviteSession(const NameAddr& target, const Contents* initialOffer, EncryptionLevel level, const Contents* alternative = 0, AppDialogSet* ads = 0); + SharedPtr makeInviteSession(const NameAddr& target, const DialogSetId& dialogSetId, const SharedPtr& userProfile, const Contents* initialOffer, EncryptionLevel level, const Contents* alternative = 0, AppDialogSet* ads = 0); // Versions that add a replaces header SharedPtr makeInviteSession(const NameAddr& target, InviteSessionHandle sessionToReplace, const SharedPtr& userProfile, const Contents* initialOffer, AppDialogSet* ads = 0); SharedPtr makeInviteSession(const NameAddr& target, InviteSessionHandle sessionToReplace, const SharedPtr& userProfile, const Contents* initialOffer, EncryptionLevel level = None, const Contents* alternative = 0, AppDialogSet* ads = 0); @@ -338,12 +342,15 @@ class DialogUsageManager : public HandleManager, public TransactionUser //exposed so DumThread variants can be written Message* getNext(int ms) { return mFifo.getNext(ms); } - void internalProcess(std::unique_ptr msg); + void internalProcess(std::auto_ptr msg); bool messageAvailable(void) { return mFifo.messageAvailable(); } void applyToAllClientSubscriptions(ClientSubscriptionFunctor*); void applyToAllServerSubscriptions(ServerSubscriptionFunctor*); + void endAllServerSubscriptions(TerminateReason reason = Deactivated); + void endAllServerPublications(); + /// Note: Implementations of Postable must delete the message passed via post void registerForConnectionTermination(Postable*); void unRegisterForConnectionTermination(Postable*); @@ -354,6 +361,8 @@ class DialogUsageManager : public HandleManager, public TransactionUser // at the same time it deletes other handlers when DUM is destroyed. DialogEventStateManager* createDialogEventStateManager(DialogEventHandler* handler); + void setAdvertisedCapabilities(SipMessage& msg, SharedPtr userProfile); + protected: virtual void onAllHandlesDestroyed(); //TransactionUser virtuals @@ -400,9 +409,9 @@ class DialogUsageManager : public HandleManager, public TransactionUser { } - virtual void post(std::unique_ptr msg) + virtual void post(std::auto_ptr msg) { - mDum.incomingProcess(std::move(msg)); + mDum.incomingProcess(msg); } }; @@ -413,9 +422,9 @@ class DialogUsageManager : public HandleManager, public TransactionUser { } - virtual void post(std::unique_ptr msg) + virtual void post(std::auto_ptr msg) { - mDum.outgoingProcess(std::move(msg)); + mDum.outgoingProcess(msg); } }; @@ -430,7 +439,7 @@ class DialogUsageManager : public HandleManager, public TransactionUser // May call a callback to let the app adorn void sendResponse(const SipMessage& response); - void sendUsingOutboundIfAppropriate(UserProfile& userProfile, std::unique_ptr msg); + void sendUsingOutboundIfAppropriate(UserProfile& userProfile, std::auto_ptr msg); void addTimer(DumTimeout::Type type, unsigned long durationSeconds, @@ -459,7 +468,7 @@ class DialogUsageManager : public HandleManager, public TransactionUser bool validateContent(const SipMessage& request); bool validateAccept(const SipMessage& request); bool validateTo(const SipMessage& request); - bool validate100RelSuport(const SipMessage& request); + bool validate100RelSupport(const SipMessage& request); bool mergeRequest(const SipMessage& request); @@ -472,8 +481,8 @@ class DialogUsageManager : public HandleManager, public TransactionUser bool queueForIdentityCheck(SipMessage* msg); void processIdentityCheckResponse(const HttpGetMessage& msg); - void incomingProcess(std::unique_ptr msg); - void outgoingProcess(std::unique_ptr msg); + void incomingProcess(std::auto_ptr msg); + void outgoingProcess(std::auto_ptr msg); void processExternalMessage(ExternalMessageBase* externalMessage); // For delayed delete of a Usage @@ -495,9 +504,9 @@ class DialogUsageManager : public HandleManager, public TransactionUser SharedPtr mMasterProfile; SharedPtr mMasterUserProfile; - std::unique_ptr mRedirectManager; - std::unique_ptr mClientAuthManager; - //std::unique_ptr mServerAuthManager; + std::auto_ptr mRedirectManager; + std::auto_ptr mClientAuthManager; + //std::auto_ptr mServerAuthManager; InviteSessionHandler* mInviteSessionHandler; ClientRegistrationHandler* mClientRegistrationHandler; @@ -507,6 +516,7 @@ class DialogUsageManager : public HandleManager, public TransactionUser RequestValidationHandler* mRequestValidationHandler; RegistrationPersistenceManager *mRegistrationPersistenceManager; + PublicationPersistenceManager *mPublicationPersistenceManager; OutOfDialogHandler* getOutOfDialogHandler(const MethodTypes type); @@ -515,7 +525,7 @@ class DialogUsageManager : public HandleManager, public TransactionUser std::map mClientPublicationHandlers; std::map mServerPublicationHandlers; std::map mOutOfDialogHandlers; - std::unique_ptr mKeepAliveManager; + std::auto_ptr mKeepAliveManager; bool mIsDefaultServerReferHandler; ClientPagerMessageHandler* mClientPagerMessageHandler; @@ -526,7 +536,7 @@ class DialogUsageManager : public HandleManager, public TransactionUser // server subscription handler for the 'dialog' event... DialogEventStateManager* mDialogEventStateManager; - std::unique_ptr mAppDialogSetFactory; + std::auto_ptr mAppDialogSetFactory; SipStack& mStack; DumShutdownHandler* mDumShutdownHandler; diff --git a/src/libs/resiprocate/resip/dum/DumCommand.hxx b/src/libs/resiprocate/resip/dum/DumCommand.hxx index 21c137e8..cd27f43f 100644 --- a/src/libs/resiprocate/resip/dum/DumCommand.hxx +++ b/src/libs/resiprocate/resip/dum/DumCommand.hxx @@ -20,7 +20,7 @@ public: virtual Message* clone() const { - assert(false); + resip_assert(false); return NULL; } diff --git a/src/libs/resiprocate/resip/dum/DumException.hxx b/src/libs/resiprocate/resip/dum/DumException.hxx index fa42bd6b..8ea7ad8a 100644 --- a/src/libs/resiprocate/resip/dum/DumException.hxx +++ b/src/libs/resiprocate/resip/dum/DumException.hxx @@ -1,5 +1,5 @@ #if !defined(RESIP_DUMEXCEPTION_HXX) -#define RESIP__DUMEXCEPTION_HXX +#define RESIP_DUMEXCEPTION_HXX #include "rutil/BaseException.hxx" diff --git a/src/libs/resiprocate/resip/dum/DumFeature.cxx b/src/libs/resiprocate/resip/dum/DumFeature.cxx index a3e752e6..162be72a 100644 --- a/src/libs/resiprocate/resip/dum/DumFeature.cxx +++ b/src/libs/resiprocate/resip/dum/DumFeature.cxx @@ -16,7 +16,7 @@ DumFeature::~DumFeature() { } -void DumFeature::postCommand(std::unique_ptr message) +void DumFeature::postCommand(std::auto_ptr message) { - mDum.post(new TargetCommand(mTarget, std::move(message))); + mDum.post(new TargetCommand(mTarget, message)); } diff --git a/src/libs/resiprocate/resip/dum/DumFeature.hxx b/src/libs/resiprocate/resip/dum/DumFeature.hxx index eecf41b4..00f5d5a6 100644 --- a/src/libs/resiprocate/resip/dum/DumFeature.hxx +++ b/src/libs/resiprocate/resip/dum/DumFeature.hxx @@ -40,7 +40,7 @@ class DumFeature // taken ownership of msg until we get a return. If we throw, the // ownership of msg is unknown. This is unacceptable. virtual ProcessingResult process(Message* msg) = 0; - virtual void postCommand(std::unique_ptr message); + virtual void postCommand(std::auto_ptr message); protected: DialogUsageManager& mDum; diff --git a/src/libs/resiprocate/resip/dum/DumFeatureMessage.cxx b/src/libs/resiprocate/resip/dum/DumFeatureMessage.cxx index 3a0d7c11..a3d68249 100644 --- a/src/libs/resiprocate/resip/dum/DumFeatureMessage.cxx +++ b/src/libs/resiprocate/resip/dum/DumFeatureMessage.cxx @@ -1,4 +1,4 @@ -#include +#include "rutil/ResipAssert.h" #include "DumFeatureMessage.hxx" #include "rutil/WinLeakCheck.hxx" #include "resip/dum/BaseUsage.hxx" diff --git a/src/libs/resiprocate/resip/dum/DumHelper.cxx b/src/libs/resiprocate/resip/dum/DumHelper.cxx index e5dee2b3..55b403b0 100644 --- a/src/libs/resiprocate/resip/dum/DumHelper.cxx +++ b/src/libs/resiprocate/resip/dum/DumHelper.cxx @@ -7,23 +7,26 @@ using namespace std; #define RESIPROCATE_SUBSYSTEM Subsystem::DUM -void DumHelper::setOutgoingEncryptionLevel(SipMessage& message, - DialogUsageManager::EncryptionLevel level) +void +DumHelper::setOutgoingEncryptionLevel(SipMessage& message, + DialogUsageManager::EncryptionLevel level) { SecurityAttributes* attr = new SecurityAttributes(); attr->setOutgoingEncryptionLevel(convert(level)); - message.setSecurityAttributes(unique_ptr(attr)); + message.setSecurityAttributes(auto_ptr(attr)); } -void DumHelper::setEncryptionPerformed(SipMessage& message) +void +DumHelper::setEncryptionPerformed(SipMessage& message) { SecurityAttributes* attr = new SecurityAttributes(); attr->setOutgoingEncryptionLevel(message.getSecurityAttributes()->getOutgoingEncryptionLevel()); attr->setEncryptionPerformed(true); - message.setSecurityAttributes(unique_ptr(attr)); + message.setSecurityAttributes(auto_ptr(attr)); } -SecurityAttributes::OutgoingEncryptionLevel DumHelper::convert(DialogUsageManager::EncryptionLevel level) +SecurityAttributes::OutgoingEncryptionLevel +DumHelper::convert(DialogUsageManager::EncryptionLevel level) { SecurityAttributes::OutgoingEncryptionLevel ret = SecurityAttributes::None; diff --git a/src/libs/resiprocate/resip/dum/DumProcessHandler.cxx b/src/libs/resiprocate/resip/dum/DumProcessHandler.cxx index 11ec9f11..34099e49 100644 --- a/src/libs/resiprocate/resip/dum/DumProcessHandler.cxx +++ b/src/libs/resiprocate/resip/dum/DumProcessHandler.cxx @@ -55,7 +55,7 @@ DumProcessHandler::handleProcessNotification() { mExternalTimer->deleteTimer(mTimerID); } - assert(timeTillProcess < 60*4*60*1000); //4hr sanity check + resip_assert(timeTillProcess < 60*4*60*1000); //4hr sanity check mTimerID = mExternalTimer->generateAsyncID(); DebugLog ( << "Setting dum process timer: " << timeTillProcess); mExternalTimer->createTimer(mTimerID, timeTillProcess); @@ -69,7 +69,7 @@ DumProcessHandler::handleProcessNotification() void DumProcessHandler::handleTimeout(AsyncID timerID) { - assert(timerID == mTimerID); + resip_assert(timerID == mTimerID); mHaveActiveTimer = false; handleProcessNotification(); } diff --git a/src/libs/resiprocate/resip/dum/DumThread.cxx b/src/libs/resiprocate/resip/dum/DumThread.cxx index b5987596..343202db 100644 --- a/src/libs/resiprocate/resip/dum/DumThread.cxx +++ b/src/libs/resiprocate/resip/dum/DumThread.cxx @@ -18,10 +18,10 @@ DumThread::thread() { try { - std::unique_ptr msg(mDum.mFifo.getNext(1000)); // Only need to wake up to see if we are shutdown + std::auto_ptr msg(mDum.mFifo.getNext(1000)); // Only need to wake up to see if we are shutdown if (msg.get()) { - mDum.internalProcess(std::move(msg)); + mDum.internalProcess(msg); } } catch (BaseException& e) diff --git a/src/libs/resiprocate/resip/dum/DumTimeout.cxx b/src/libs/resiprocate/resip/dum/DumTimeout.cxx index dc3a11a4..932958be 100644 --- a/src/libs/resiprocate/resip/dum/DumTimeout.cxx +++ b/src/libs/resiprocate/resip/dum/DumTimeout.cxx @@ -1,4 +1,4 @@ -#include +#include "rutil/ResipAssert.h" #include "DumTimeout.hxx" #include "rutil/WinLeakCheck.hxx" #include "resip/dum/BaseUsage.hxx" @@ -63,7 +63,7 @@ const Data & DumTimeout::transactionId() const bool DumTimeout::isClientTransaction() const { - assert(0); + resip_assert(0); return false; } @@ -100,6 +100,12 @@ DumTimeout::encode(EncodeStream& strm) const case Retransmit1xx: strm <<"Retransmit1xx"; break; + case Retransmit1xxRel: + strm <<"Retransmit1xxRel"; + break; + case Resubmit1xxRel: + strm <<"Resubmit1xxRel"; + break; case WaitForAck: strm <<"WaitForAck"; break; diff --git a/src/libs/resiprocate/resip/dum/DumTimeout.hxx b/src/libs/resiprocate/resip/dum/DumTimeout.hxx index 4f68cb48..fefeac08 100644 --- a/src/libs/resiprocate/resip/dum/DumTimeout.hxx +++ b/src/libs/resiprocate/resip/dum/DumTimeout.hxx @@ -20,6 +20,8 @@ class DumTimeout : public ApplicationMessage Publication, Retransmit200, Retransmit1xx, + Retransmit1xxRel, + Resubmit1xxRel, WaitForAck, // UAS gets no ACK CanDiscardAck, StaleCall, // UAC gets no final response diff --git a/src/libs/resiprocate/resip/dum/Handle.hxx b/src/libs/resiprocate/resip/dum/Handle.hxx index 5ae74899..dd9c562c 100644 --- a/src/libs/resiprocate/resip/dum/Handle.hxx +++ b/src/libs/resiprocate/resip/dum/Handle.hxx @@ -2,7 +2,7 @@ #define RESIP_HANDLE_HXX #include -#include +#include "rutil/ResipAssert.h" #include "resip/dum/Handled.hxx" #include "resip/dum/HandleManager.hxx" #include "resip/dum/HandleException.hxx" @@ -95,8 +95,8 @@ class Handle // !nash! to be able to use Handle in Set or Map container bool operator<(const Handle& other) const { - assert(mHam); - assert(other.mHam); + resip_assert(mHam); + resip_assert(other.mHam); return mId < other.mId; } diff --git a/src/libs/resiprocate/resip/dum/HandleManager.cxx b/src/libs/resiprocate/resip/dum/HandleManager.cxx index c20ebf51..db289f17 100644 --- a/src/libs/resiprocate/resip/dum/HandleManager.cxx +++ b/src/libs/resiprocate/resip/dum/HandleManager.cxx @@ -1,4 +1,4 @@ -#include +#include "rutil/ResipAssert.h" #include "rutil/Logger.hxx" #include "rutil/Inserter.hxx" #include "resip/dum/HandleManager.hxx" @@ -72,7 +72,7 @@ void HandleManager::remove(Handled::Id id) { HandleMap::iterator i = mHandleMap.find(id); - assert (i != mHandleMap.end()); + resip_assert (i != mHandleMap.end()); mHandleMap.erase(i); if (mShuttingDown) { @@ -110,112 +110,64 @@ HandleManager::getHandled(Handled::Id id) const if (i == mHandleMap.end()) { InfoLog (<< "Reference to stale handle: " << id); - assert(0); + resip_assert(0); throw HandleException("Stale handle", __FILE__, __LINE__); } else { - assert(i->second); + resip_assert(i->second); return i->second; } } /* ==================================================================== - * The Vovida Software License, Version 1.0 - * - * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The names "VOCAL", "Vovida Open Communication Application Library", - * and "Vovida Open Communication Application Library (VOCAL)" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact vocal@vovida.org. - * - * 4. Products derived from this software may not be called "VOCAL", nor - * may "VOCAL" appear in their name, without prior written - * permission of Vovida Networks, Inc. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND - * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA - * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES - * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ==================================================================== - * - * This software consists of voluntary contributions made by Vovida - * Networks, Inc. and many individuals on behalf of Vovida Networks, - * Inc. For more information on Vovida Networks, Inc., please see - * . - * - */ diff --git a/src/libs/resiprocate/resip/dum/HttpProvider.cxx b/src/libs/resiprocate/resip/dum/HttpProvider.cxx index 0748fe79..7b7aa751 100644 --- a/src/libs/resiprocate/resip/dum/HttpProvider.cxx +++ b/src/libs/resiprocate/resip/dum/HttpProvider.cxx @@ -4,13 +4,13 @@ using namespace resip; HttpProvider* HttpProvider::mInstance = 0; -std::unique_ptr HttpProvider::mFactory; +std::auto_ptr HttpProvider::mFactory; Mutex HttpProvider::mMutex; void -HttpProvider::setFactory(std::unique_ptr fact) +HttpProvider::setFactory(std::auto_ptr fact) { - mFactory = std::move(fact); + mFactory = fact; } HttpProvider* diff --git a/src/libs/resiprocate/resip/dum/HttpProvider.hxx b/src/libs/resiprocate/resip/dum/HttpProvider.hxx index 2b3045ac..b2ef4fe9 100644 --- a/src/libs/resiprocate/resip/dum/HttpProvider.hxx +++ b/src/libs/resiprocate/resip/dum/HttpProvider.hxx @@ -21,7 +21,7 @@ class HttpProvider { public: //HttpProvider assumes memory - static void setFactory(std::unique_ptr fact); + static void setFactory(std::auto_ptr fact); //ptr so users can check for existence static HttpProvider* instance(); @@ -30,7 +30,7 @@ class HttpProvider virtual ~HttpProvider(){} //impl. singleton destructor pattern later private: static HttpProvider* mInstance; - static std::unique_ptr mFactory; + static std::auto_ptr mFactory; static Mutex mMutex; }; diff --git a/src/libs/resiprocate/resip/dum/IdentityHandler.cxx b/src/libs/resiprocate/resip/dum/IdentityHandler.cxx index 8080b1be..19d06b17 100644 --- a/src/libs/resiprocate/resip/dum/IdentityHandler.cxx +++ b/src/libs/resiprocate/resip/dum/IdentityHandler.cxx @@ -98,10 +98,10 @@ IdentityHandler::queueForIdentityCheck(SipMessage* sipMsg) } #endif - std::unique_ptr sec(new SecurityAttributes); + std::auto_ptr sec(new SecurityAttributes); sec->setIdentity(sipMsg->header(h_From).uri().getAor()); sec->setIdentityStrength(SecurityAttributes::From); - sipMsg->setSecurityAttributes(std::move(sec)); + sipMsg->setSecurityAttributes(sec); return false; } @@ -114,7 +114,7 @@ IdentityHandler::processIdentityCheckResponse(const HttpGetMessage& msg) if (it != mRequiresCerts.end()) { mDum.getSecurity()->checkAndSetIdentity( *it->second, msg.getBodyData() ); - postCommand(unique_ptr(it->second)); + postCommand(auto_ptr(it->second)); mRequiresCerts.erase(it); } #endif diff --git a/src/libs/resiprocate/resip/dum/InMemoryRegistrationDatabase.cxx b/src/libs/resiprocate/resip/dum/InMemoryRegistrationDatabase.cxx index 8df05967..6f2394a9 100644 --- a/src/libs/resiprocate/resip/dum/InMemoryRegistrationDatabase.cxx +++ b/src/libs/resiprocate/resip/dum/InMemoryRegistrationDatabase.cxx @@ -106,7 +106,7 @@ InMemoryRegistrationDatabase::unlockRecord(const Uri& aor) database_map_t::iterator i = mDatabase.find(aor); // The record must have been inserted when we locked it in the first place - assert (i != mDatabase.end()); + resip_assert (i != mDatabase.end()); if (i->second == 0) { @@ -141,7 +141,7 @@ InMemoryRegistrationDatabase::updateContact(const resip::Uri& aor, } - assert(contactList); + resip_assert(contactList); ContactList::iterator j; diff --git a/src/libs/resiprocate/resip/dum/InMemoryRegistrationDatabase.hxx b/src/libs/resiprocate/resip/dum/InMemoryRegistrationDatabase.hxx index e06e4d05..2d906857 100644 --- a/src/libs/resiprocate/resip/dum/InMemoryRegistrationDatabase.hxx +++ b/src/libs/resiprocate/resip/dum/InMemoryRegistrationDatabase.hxx @@ -47,7 +47,7 @@ class InMemoryRegistrationDatabase : public RegistrationPersistenceManager /// return all the AOR in the DB virtual void getAors(UriList& container); - private: + protected: typedef std::map database_map_t; database_map_t mDatabase; Mutex mDatabaseMutex; @@ -58,14 +58,12 @@ class InMemoryRegistrationDatabase : public RegistrationPersistenceManager bool mCheckExpiry; - protected: /** * Find aor in mDatabase * Before returning the iterator pointing to aor, * delete all expired contacts */ database_map_t::iterator findNotExpired(const Uri& aor); - }; } diff --git a/src/libs/resiprocate/resip/dum/InMemorySyncPubDb.cxx b/src/libs/resiprocate/resip/dum/InMemorySyncPubDb.cxx new file mode 100644 index 00000000..c2aaeba3 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/InMemorySyncPubDb.cxx @@ -0,0 +1,437 @@ +#include "resip/dum/InMemorySyncPubDb.hxx" +#include "rutil/compat.hxx" +#include "rutil/Timer.hxx" +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +InMemorySyncPubDb::InMemorySyncPubDb(bool syncEnabled) : mSyncEnabled(syncEnabled) +{ +} + +InMemorySyncPubDb::~InMemorySyncPubDb() +{ +} + +void +InMemorySyncPubDb::addHandler(InMemorySyncPubDbHandler* handler) +{ + Lock lock(mHandlerMutex); + mHandlers.push_back(handler); +} + +void +InMemorySyncPubDb::removeHandler(InMemorySyncPubDbHandler* handler) +{ + Lock lock(mHandlerMutex); + for(HandlerList::iterator it = mHandlers.begin(); it != mHandlers.end(); it++) + { + if(*it == handler) + { + mHandlers.erase(it); + break; + } + } +} + +bool +InMemorySyncPubDb::shouldEraseDocument(PubDocument& document, UInt64 now) +{ + if (mSyncEnabled) + { + // Check if already lingering + if (document.mExpirationTime == 0) + { + // Check if linger time is done + if (document.mLingerTime <= now) + { + return true; + } + } + else if (document.mExpirationTime <= now) + { + // Tag document to linger + document.mLastUpdated = document.mExpirationTime; + document.mExpirationTime = 0; + } + } + else + { + if (document.mExpirationTime <= now) + { + return true; + } + } + return false; +} + +void +InMemorySyncPubDb::initialSync(unsigned int connectionId) +{ + Lock g(mDatabaseMutex); + UInt64 now = Timer::getTimeSecs(); + + // Iterate through keys + KeyToETagMap::iterator keyIt = mPublicationDb.begin(); + for (; keyIt != mPublicationDb.end(); ) + { + // Iterator through documents in sub-map + ETagToDocumentMap::iterator eTagIt = keyIt->second.begin(); + for (; eTagIt != keyIt->second.end();) + { + if (shouldEraseDocument(eTagIt->second, now)) + { + keyIt->second.erase(eTagIt++); + } + else + { + invokeOnInitialSyncDocument(connectionId, eTagIt->second.mEventType, eTagIt->second.mDocumentKey, eTagIt->second.mETag, eTagIt->second.mExpirationTime, eTagIt->second.mLastUpdated, eTagIt->second.mContents.get(), eTagIt->second.mSecurityAttributes.get()); + eTagIt++; + } + } + + // If there are no more eTags then remove entity + if (keyIt->second.size() == 0) + { + mPublicationDb.erase(keyIt++); + } + else + { + keyIt++; + } + } +} + +void +InMemorySyncPubDb::addUpdateDocument(const PubDocument& document) +{ + Lock g(mDatabaseMutex); + Data mapKey = document.mEventType + document.mDocumentKey; + bool found = false; + KeyToETagMap::iterator keyIt = mPublicationDb.find(mapKey); + if (keyIt != mPublicationDb.end()) + { + // Next find eTag in sub-map + ETagToDocumentMap::iterator eTagIt = keyIt->second.find(document.mETag); + if (eTagIt != keyIt->second.end()) + { + // Doc was found! Do some checks + found = true; + // If doc is from sync then ensure it is newer + if (!document.mSyncPublication || (document.mLastUpdated > eTagIt->second.mLastUpdated)) + { + UInt64 now = Timer::getTimeSecs(); + SharedPtr contentsForOnDocumentModified = document.mContents; + SharedPtr securityAttributesForOnDocumentModified = document.mSecurityAttributes; + // We should only need to linger a document past the latest expiration time we have ever seen, since both sides will + // treat the publication as gone after this time anyway. However this is timing sensitive with the sync process. + // So we will linger a document for twice this duration. + UInt64 lingerDuration = (resipMax(document.mExpirationTime, eTagIt->second.mExpirationTime) - now) * 2; + if (document.mContents.get() == 0) // If this is a pub refresh then ensure we don't get rid of existing doc body + { + // If previous document was expired then ensure we push out a notify on the refresh to tell everyone it's back + // This can happen if someone deletes a publication on the web page, then it is refreshed. The delete causes a + // notify of closed state, the refresh should bring the state back. + if (eTagIt->second.mExpirationTime == 0 || + eTagIt->second.mExpirationTime < now) + { + contentsForOnDocumentModified = eTagIt->second.mContents; + securityAttributesForOnDocumentModified = eTagIt->second.mSecurityAttributes; + } + SharedPtr contents = eTagIt->second.mContents; + SharedPtr securityAttributes = eTagIt->second.mSecurityAttributes; + eTagIt->second = document; + eTagIt->second.mContents = contents; + eTagIt->second.mSecurityAttributes = securityAttributes; + } + else + { + eTagIt->second = document; + } + eTagIt->second.mLingerTime = now + lingerDuration; + // Only pass sync as true if this update just came from an inbound sync operation + invokeOnDocumentModified(document.mSyncPublication /* sync publication? */, document.mEventType, document.mDocumentKey, document.mETag, document.mExpirationTime, document.mLastUpdated, contentsForOnDocumentModified.get(), securityAttributesForOnDocumentModified.get()); + } + } + } + + // If we didn't find an existing document and we have a contents, then add this doc. + // Note: Pub refreshes don't contain a contents - so we happen to receive a refresh as our + // first message for an etag we don't want to add it to the store - until we have + // at least a doc body. + if (!found && document.mContents.get() != 0) + { + // Add new + mPublicationDb[mapKey][document.mETag] = document; + // Only pass sync as true if this update just came from an inbound sync operation + invokeOnDocumentModified(document.mSyncPublication /* sync publication? */, document.mEventType, document.mDocumentKey, document.mETag, document.mExpirationTime, document.mLastUpdated, document.mContents.get(), document.mSecurityAttributes.get()); + } +} + +bool +InMemorySyncPubDb::removeDocument(const Data& eventType, const Data& documentKey, const Data& eTag, UInt64 lastUpdated, bool syncPublication) +{ + bool result = false; + Lock g(mDatabaseMutex); + + // First find entity in map + KeyToETagMap::iterator keyIt = mPublicationDb.find(eventType + documentKey); + if (keyIt != mPublicationDb.end()) + { + // Next find eTag in sub-map + ETagToDocumentMap::iterator eTagIt = keyIt->second.find(eTag); + if (eTagIt != keyIt->second.end()) + { + result = true; + // If remove is from sync then ensure it is newer + if (!syncPublication || (lastUpdated > eTagIt->second.mLastUpdated)) + { + // If sync is enabled - then linger the record in memory until it expires + if (mSyncEnabled) + { + // Tag document as expired, but in a linger state + eTagIt->second.mExpirationTime = 0; + eTagIt->second.mLastUpdated = Timer::getTimeSecs(); + } + else + { + // ETag was found - remove it + keyIt->second.erase(eTagIt); + } + // Only pass sync as true if this update just come from an inbound sync operation + invokeOnDocumentRemoved(syncPublication /* sync? */, eventType, documentKey, eTag, lastUpdated); + } + } + // If there are no more eTags then remove entity + if (keyIt->second.size() == 0) + { + mPublicationDb.erase(keyIt); + } + } + return result; +} + +bool +InMemorySyncPubDb::getMergedETags(const Data& eventType, const Data& documentKey, ETagMerger& merger, Contents* destination) +{ + Lock g(mDatabaseMutex); + + // Find entity + KeyToETagMap::iterator keyIt = mPublicationDb.find(eventType + documentKey); + if (keyIt != mPublicationDb.end()) + { + bool isFirst = true; + UInt64 now = Timer::getTimeSecs(); + + // Iterate through all Etags + ETagToDocumentMap::iterator eTagIt = keyIt->second.begin(); + for (; eTagIt != keyIt->second.end(); ) + { + if (!shouldEraseDocument(eTagIt->second, now)) + { + // Just because we don't need to erase it doesn't mean it didn't expire - check for expiration + if (eTagIt->second.mExpirationTime > now && eTagIt->second.mContents.get() != 0) + { + merger.mergeETag(destination, eTagIt->second.mContents.get(), isFirst); + isFirst = false; + } + eTagIt++; + } + else + { + // ETag has expired - remove it + keyIt->second.erase(eTagIt++); + // If no more Etags for key, then remove key entry and bail out + if (keyIt->second.size() == 0) + { + mPublicationDb.erase(keyIt); + break; + } + } + } + // If we have at least on ETag then return true + if (!isFirst) + { + return true; + } + } + return false; +} + +bool +InMemorySyncPubDb::documentExists(const Data& eventType, const Data& documentKey, const Data& eTag) +{ + Lock g(mDatabaseMutex); + + // First find entity in map + KeyToETagMap::iterator keyIt = mPublicationDb.find(eventType + documentKey); + if (keyIt != mPublicationDb.end()) + { + // Next find eTag in sub-map + ETagToDocumentMap::iterator eTagIt = keyIt->second.find(eTag); + if (eTagIt != keyIt->second.end()) + { + // Decided not to check if expired or not. Not checking allows us to handle + // a scenario where the publication refresh went to another repro node and + // syncing was broken for some reason. Then a new publish comes here and + // the record is still lingering. + //if (eTagIt->second.mExpirationTime <= Timer::getTimeSecs()) + { + return true; + } + } + } + return false; +} + +// If lastUpdated != 0 then we make sure that passed in lastUpdated matches the document before returning true +// This method is used in timer expirey and the lastUpdated checks helps us to make sure the timer that just +// expired hasn't been made obsolete due to a new update. +bool InMemorySyncPubDb::checkExpired(const Data& eventType, const Data& documentKey, const Data& eTag, UInt64 lastUpdated) +{ + Lock g(mDatabaseMutex); + + // First find entity in map + KeyToETagMap::iterator keyIt = mPublicationDb.find(eventType + documentKey); + if (keyIt != mPublicationDb.end()) + { + // Next find eTag in sub-map + ETagToDocumentMap::iterator eTagIt = keyIt->second.find(eTag); + if (eTagIt != keyIt->second.end()) + { + UInt64 now = Timer::getTimeSecs(); + if (eTagIt->second.mExpirationTime >= now && + (lastUpdated == 0 || lastUpdated == eTagIt->second.mLastUpdated)) + { + DebugLog(<< "InMemorySyncPubDb::checkExpired: found expired publication, docKey=" << documentKey << ", tag=" << eTag); + bool syncPublication = eTagIt->second.mSyncPublication; + // If sync is enabled - then linger the record in memory until it expires + if (mSyncEnabled) + { + // Tag document as expired, but in a linger state + eTagIt->second.mExpirationTime = 0; + eTagIt->second.mLastUpdated = now; + } + else + { + // ETag was found - remove it + keyIt->second.erase(eTagIt); + // If no more Etags for key, then remove key entry + if (keyIt->second.size() == 0) + { + mPublicationDb.erase(keyIt); + } + } + invokeOnDocumentRemoved(syncPublication /* sync? */, eventType, documentKey, eTag, now); + return true; + } + } + } + return false; +} + +void +InMemorySyncPubDb::lockDocuments() +{ + mDatabaseMutex.lock(); +} + +PublicationPersistenceManager::KeyToETagMap& +InMemorySyncPubDb::getDocuments() +{ + return mPublicationDb; +} + +void +InMemorySyncPubDb::unlockDocuments() +{ + mDatabaseMutex.unlock(); +} + +void +InMemorySyncPubDb::invokeOnDocumentModified(bool sync, const Data& eventType, const Data& documentKey, const Data& eTag, UInt64 expirationTime, UInt64 lastUpdated, const Contents* contents, const SecurityAttributes* securityAttributes) +{ + Lock lock(mHandlerMutex); + for (HandlerList::iterator it = mHandlers.begin(); it != mHandlers.end(); it++) + { + // If handler mode is all, then send notification, otherwise handler mode is sync and we ensure passed + // in syncPublication flag is false - so we don't sync back to originator + if (!sync || (*it)->getMode() == InMemorySyncPubDbHandler::AllChanges) + { + (*it)->onDocumentModified(sync, eventType, documentKey, eTag, expirationTime, lastUpdated, contents, securityAttributes); + } + } +} + +void +InMemorySyncPubDb::invokeOnDocumentRemoved(bool sync, const Data& eventType, const Data& documentKey, const Data& eTag, UInt64 lastUpdated) +{ + Lock lock(mHandlerMutex); + for (HandlerList::iterator it = mHandlers.begin(); it != mHandlers.end(); it++) + { + // If handler mode is all, then send notification, otherwise handler mode is sync and we ensure passed + // in syncPublication flag is false - so we don't sync back to originator + if (!sync || (*it)->getMode() == InMemorySyncPubDbHandler::AllChanges) + { + (*it)->onDocumentRemoved(sync, eventType, documentKey, eTag, lastUpdated); + } + } +} + +void +InMemorySyncPubDb::invokeOnInitialSyncDocument(unsigned int connectionId, const Data& eventType, const Data& documentKey, const Data& eTag, UInt64 expirationTime, UInt64 lastUpdated, const Contents* contents, const SecurityAttributes* securityAttributes) +{ + Lock lock(mHandlerMutex); + for (HandlerList::iterator it = mHandlers.begin(); it != mHandlers.end(); it++) + { + // If handler mode is all, then send notification, otherwise handler mode is sync and we check the passed + // in sync flag + if ((*it)->getMode() == InMemorySyncPubDbHandler::SyncServer) + { + (*it)->onInitialSyncDocument(connectionId, eventType, documentKey, eTag, expirationTime, lastUpdated, contents, securityAttributes); + } + } +} + + +/* ==================================================================== +* +* Copyright (c) 2015 SIP Spectrum, Inc. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* +* 3. Neither the name of the author(s) nor the names of any contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +* +* ==================================================================== +* +*/ +/* +* vi: set shiftwidth=3 expandtab: +*/ diff --git a/src/libs/resiprocate/resip/dum/InMemorySyncPubDb.hxx b/src/libs/resiprocate/resip/dum/InMemorySyncPubDb.hxx new file mode 100644 index 00000000..6618cad5 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/InMemorySyncPubDb.hxx @@ -0,0 +1,119 @@ +#if !defined(RESIP_INMEMORYSYNCPUBDB_HXX) +#define RESIP_INMEMORYSYNCPUBDB_HXX + +#include + +#include "resip/dum/PublicationPersistenceManager.hxx" +#include "rutil/Mutex.hxx" +#include "rutil/Lock.hxx" + +namespace resip +{ + +class SecurityAttributes; + +class InMemorySyncPubDbHandler +{ +public: + typedef enum + { + SyncServer, + AllChanges + } HandlerMode; + InMemorySyncPubDbHandler(HandlerMode mode = SyncServer) : mMode(mode) {} + virtual ~InMemorySyncPubDbHandler(){} + HandlerMode getMode() { return mMode; } + virtual void onDocumentModified(bool sync, const Data& eventType, const Data& documentKey, const Data& eTag, UInt64 expirationTime, UInt64 lastUpdated, const Contents* contents, const SecurityAttributes* securityAttributes) = 0; + virtual void onDocumentRemoved(bool sync, const Data& eventType, const Data& documentKey, const Data& eTag, UInt64 lastUpdated) = 0; + virtual void onInitialSyncDocument(unsigned int connectionId, const Data& eventType, const Data& documentKey, const Data& eTag, UInt64 expirationTime, UInt64 lastUpdated, const Contents* contents, const SecurityAttributes* securityAttributes) {} +protected: + HandlerMode mMode; +}; + +/** + Implementation of a persistence manager. This class keeps + all publications in memory, and is used for remote replication. + + The InMemorySyncPubDbHandler can be used by an external mechanism to + transport publication documents to a remote peer for replication. + See the RegSyncClient and RegSyncServer implementations in the repro + project. +*/ +class InMemorySyncPubDb : public PublicationPersistenceManager +{ +public: + + InMemorySyncPubDb(bool syncEnabled = false); + virtual ~InMemorySyncPubDb(); + + virtual void addHandler(InMemorySyncPubDbHandler* handler); + virtual void removeHandler(InMemorySyncPubDbHandler* handler); + virtual void initialSync(unsigned int connectionId); + + // PublicationPersistenceManager Methods + virtual void addUpdateDocument(const PubDocument& document); + virtual bool removeDocument(const Data& eventType, const Data& documentKey, const Data& eTag, UInt64 lastUpdated, bool syncPublication = false); + virtual bool getMergedETags(const Data& eventType, const Data& documentKey, ETagMerger& merger, Contents* destination); + virtual bool documentExists(const Data& eventType, const Data& documentKey, const Data& eTag); + virtual bool checkExpired(const Data& eventType, const Data& documentKey, const Data& eTag, UInt64 lastUpdated); + virtual void lockDocuments(); + virtual KeyToETagMap& getDocuments(); // Ensure you lock before calling this and unlock when done + virtual void unlockDocuments(); + +protected: + + void invokeOnDocumentModified(bool sync, const Data& eventType, const Data& documentKey, const Data& eTag, UInt64 expirationTime, UInt64 lastUpdated, const Contents* contents, const SecurityAttributes* securityAttributes); + void invokeOnDocumentRemoved(bool sync, const Data& eventType, const Data& documentKey, const Data& eTag, UInt64 lastUpdated); + void invokeOnInitialSyncDocument(unsigned int connectionId, const Data& eventType, const Data& documentKey, const Data& eTag, UInt64 expirationTime, UInt64 lastUpdated, const Contents* contents, const SecurityAttributes* securityAttributes); + bool shouldEraseDocument(PubDocument& document, UInt64 now); + bool mSyncEnabled; + typedef std::list HandlerList; + HandlerList mHandlers; // use list over set to preserve add order + Mutex mHandlerMutex; + + KeyToETagMap mPublicationDb; + Mutex mDatabaseMutex; +}; + +} + +#endif + +/* ==================================================================== +* +* Copyright (c) 2015 SIP Spectrum, Inc. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* +* 3. Neither the name of the author(s) nor the names of any contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +* +* ==================================================================== +* +*/ +/* +* vi: set shiftwidth=3 expandtab: +*/ diff --git a/src/libs/resiprocate/resip/dum/InMemorySyncRegDb.cxx b/src/libs/resiprocate/resip/dum/InMemorySyncRegDb.cxx index c694a5f1..46322e01 100644 --- a/src/libs/resiprocate/resip/dum/InMemorySyncRegDb.cxx +++ b/src/libs/resiprocate/resip/dum/InMemorySyncRegDb.cxx @@ -54,8 +54,7 @@ contactsRemoveIfRequired(ContactList& contacts, UInt64& now, } InMemorySyncRegDb::InMemorySyncRegDb(unsigned int removeLingerSecs) : - mRemoveLingerSecs(removeLingerSecs), - mHandler(0) + mRemoveLingerSecs(removeLingerSecs) { } @@ -69,6 +68,55 @@ InMemorySyncRegDb::~InMemorySyncRegDb() mDatabase.clear(); } +void +InMemorySyncRegDb::addHandler(InMemorySyncRegDbHandler* handler) +{ + Lock lock(mHandlerMutex); + mHandlers.push_back(handler); +} + +void +InMemorySyncRegDb::removeHandler(InMemorySyncRegDbHandler* handler) +{ + Lock lock(mHandlerMutex); + for(HandlerList::iterator it = mHandlers.begin(); it != mHandlers.end(); it++) + { + if(*it == handler) + { + mHandlers.erase(it); + break; + } + } +} + +void +InMemorySyncRegDb::invokeOnAorModified(bool sync, const resip::Uri& aor, const ContactList& contacts) +{ + Lock lock(mHandlerMutex); + for(HandlerList::iterator it = mHandlers.begin(); it != mHandlers.end(); it++) + { + // If handler mode is all, then send notification, otherwise handler mode is sync and we check the passed + // in sync flag + if (sync || (*it)->getMode() == InMemorySyncRegDbHandler::AllChanges) + { + (*it)->onAorModified(aor, contacts); + } + } +} + +void +InMemorySyncRegDb::invokeOnInitialSyncAor(unsigned int connectionId, const resip::Uri& aor, const ContactList& contacts) +{ + Lock lock(mHandlerMutex); + for (HandlerList::iterator it = mHandlers.begin(); it != mHandlers.end(); it++) + { + if ((*it)->getMode() == InMemorySyncRegDbHandler::SyncServer) + { + (*it)->onInitialSyncAor(connectionId, aor, contacts); + } + } +} + void InMemorySyncRegDb::initialSync(unsigned int connectionId) { @@ -83,7 +131,7 @@ InMemorySyncRegDb::initialSync(unsigned int connectionId) { contactsRemoveIfRequired(contacts, now, mRemoveLingerSecs); } - if(mHandler) mHandler->onInitialSyncAor(connectionId, it->first, contacts); + invokeOnInitialSyncAor(connectionId, it->first, contacts); } } } @@ -109,7 +157,7 @@ InMemorySyncRegDb::addAor(const Uri& aor, { mDatabase[aor] = new ContactList(contacts); } - if(mHandler) mHandler->onAorModified(aor, contacts); + invokeOnAorModified(true /* sync? */, aor, contacts); } void @@ -134,7 +182,7 @@ InMemorySyncRegDb::removeAor(const Uri& aor) it->mRegExpires = 0; it->mLastUpdated = now; } - if(mHandler) mHandler->onAorModified(aor, contacts); + invokeOnAorModified(true /* sync? */, aor, contacts); } else { @@ -142,7 +190,7 @@ InMemorySyncRegDb::removeAor(const Uri& aor) // Setting this to 0 causes it to be removed when we unlock the AOR. i->second = 0; ContactList emptyList; - if(mHandler) mHandler->onAorModified(aor, emptyList); + invokeOnAorModified(true /* sync? */, aor, emptyList); } } } @@ -160,14 +208,21 @@ InMemorySyncRegDb::getAors(InMemorySyncRegDb::UriList& container) } } -bool +bool InMemorySyncRegDb::aorIsRegistered(const Uri& aor) +{ + return aorIsRegistered(aor, 0); +} + +bool +InMemorySyncRegDb::aorIsRegistered(const Uri& aor, UInt64* maxExpires) { Lock g(mDatabaseMutex); + bool registered = false; database_map_t::iterator i = mDatabase.find(aor); - if (i != mDatabase.end() && i->second == 0) + if (i != mDatabase.end() && i->second != 0) { - if(mRemoveLingerSecs > 0) + if (mRemoveLingerSecs > 0 || maxExpires) { ContactList& contacts = *(i->second); UInt64 now = Timer::getTimeSecs(); @@ -175,16 +230,24 @@ InMemorySyncRegDb::aorIsRegistered(const Uri& aor) { if(it->mRegExpires > now) { - return true; + registered = true; + if (maxExpires) + { + *maxExpires = resipMax(*maxExpires, it->mRegExpires); + } + else + { + break; // Not looking for maxExpires - so we can quit iterating now + } } } } else { - return true; + registered = true; } } - return false; + return registered; } void @@ -221,7 +284,7 @@ InMemorySyncRegDb::unlockRecord(const Uri& aor) database_map_t::iterator i = mDatabase.find(aor); // The record must have been inserted when we locked it in the first place - assert (i != mDatabase.end()); + resip_assert (i != mDatabase.end()); if (i->second == 0) { @@ -255,7 +318,7 @@ InMemorySyncRegDb::updateContact(const resip::Uri& aor, } } - assert(contactList); + resip_assert(contactList); ContactList::iterator j; @@ -274,14 +337,16 @@ InMemorySyncRegDb::updateContact(const resip::Uri& aor, status = CONTACT_CREATED; } *j=rec; - if(mHandler && !rec.mSyncContact) mHandler->onAorModified(aor, *contactList); + // Only pass sync as true if this update didn't just come from an inbound sync operation + invokeOnAorModified(!rec.mSyncContact /* sync? */, aor, *contactList); return status; } } // This is a new contact, so we add it to the list. contactList->push_back(rec); - if(mHandler && !rec.mSyncContact) mHandler->onAorModified(aor, *contactList); + // Only pass sync as true if this update didn't just come from an inbound sync operation + invokeOnAorModified(!rec.mSyncContact /* sync? */, aor, *contactList); return CONTACT_CREATED; } @@ -314,7 +379,8 @@ InMemorySyncRegDb::removeContact(const Uri& aor, { j->mRegExpires = 0; j->mLastUpdated = Timer::getTimeSecs(); - if(mHandler && !rec.mSyncContact) mHandler->onAorModified(aor, *contactList); + // Only pass sync as true if this update didn't just come from an inbound sync operation + invokeOnAorModified(!rec.mSyncContact /* sync? */, aor, *contactList); } else { @@ -325,7 +391,8 @@ InMemorySyncRegDb::removeContact(const Uri& aor, } else { - if(mHandler && !rec.mSyncContact) mHandler->onAorModified(aor, *contactList); + // Only pass sync as true if this update didn't just come from an inbound sync operation + invokeOnAorModified(!rec.mSyncContact /* sync? */, aor, *contactList); } } return; diff --git a/src/libs/resiprocate/resip/dum/InMemorySyncRegDb.hxx b/src/libs/resiprocate/resip/dum/InMemorySyncRegDb.hxx index 6e21c718..1c67cd3b 100644 --- a/src/libs/resiprocate/resip/dum/InMemorySyncRegDb.hxx +++ b/src/libs/resiprocate/resip/dum/InMemorySyncRegDb.hxx @@ -3,6 +3,7 @@ #include #include +#include #include "resip/dum/RegistrationPersistenceManager.hxx" #include "rutil/Mutex.hxx" @@ -15,11 +16,21 @@ namespace resip class InMemorySyncRegDbHandler { public: - virtual ~InMemorySyncRegDbHandler(){} - virtual void onAorModified(const resip::Uri& aor, const ContactList& contacts) = 0; - virtual void onInitialSyncAor(unsigned int connectionId, const resip::Uri& aor, const ContactList& contacts) = 0; + typedef enum + { + SyncServer, + AllChanges + } HandlerMode; + InMemorySyncRegDbHandler(HandlerMode mode = SyncServer) : mMode(mode) {} + virtual ~InMemorySyncRegDbHandler(){} + HandlerMode getMode() { return mMode; } + virtual void onAorModified(const resip::Uri& aor, const ContactList& contacts) = 0; + virtual void onInitialSyncAor(unsigned int connectionId, const resip::Uri& aor, const ContactList& contacts) {} +protected: + HandlerMode mMode; }; + /** Implementation of a persistence manager. This class keeps all registrations in memory, and is used for remote replication. @@ -45,12 +56,15 @@ class InMemorySyncRegDb : public RegistrationPersistenceManager InMemorySyncRegDb(unsigned int removeLingerSecs = 0); virtual ~InMemorySyncRegDb(); - virtual void setHandler(InMemorySyncRegDbHandler* handler) { mHandler = handler; } + virtual void addHandler(InMemorySyncRegDbHandler* handler); + virtual void removeHandler(InMemorySyncRegDbHandler* handler); + virtual void initialSync(unsigned int connectionId); virtual void addAor(const Uri& aor, const ContactList& contacts); virtual void removeAor(const Uri& aor); virtual bool aorIsRegistered(const Uri& aor); + virtual bool aorIsRegistered(const Uri& aor, UInt64* maxExpires); virtual void lockRecord(const Uri& aor); virtual void unlockRecord(const Uri& aor); @@ -66,7 +80,7 @@ class InMemorySyncRegDb : public RegistrationPersistenceManager /// return all the AOR in the DB virtual void getAors(UriList& container); - private: + protected: typedef std::map database_map_t; database_map_t mDatabase; Mutex mDatabaseMutex; @@ -75,8 +89,12 @@ class InMemorySyncRegDb : public RegistrationPersistenceManager Mutex mLockedRecordsMutex; Condition mRecordUnlocked; + void invokeOnAorModified(bool sync, const resip::Uri& aor, const ContactList& contacts); + void invokeOnInitialSyncAor(unsigned int connectionId, const resip::Uri& aor, const ContactList& contacts); unsigned int mRemoveLingerSecs; - InMemorySyncRegDbHandler* mHandler; + typedef std::list HandlerList; + HandlerList mHandlers; // use list over set to preserve add order + Mutex mHandlerMutex; }; } diff --git a/src/libs/resiprocate/resip/dum/InviteSession.cxx b/src/libs/resiprocate/resip/dum/InviteSession.cxx index fda03f79..6f1e889b 100644 --- a/src/libs/resiprocate/resip/dum/InviteSession.cxx +++ b/src/libs/resiprocate/resip/dum/InviteSession.cxx @@ -18,7 +18,6 @@ #include "resip/dum/DumHelper.hxx" #include "rutil/Inserter.hxx" #include "rutil/Logger.hxx" -#include "rutil/MD5Stream.hxx" #include "rutil/Timer.hxx" #include "rutil/Random.hxx" #include "rutil/compat.hxx" @@ -51,7 +50,7 @@ const Data& InviteSession::getEndReasonString(InviteSession::EndReason reason) { if(reason != InviteSession::UserSpecified) { - assert(reason >= InviteSession::NotSpecified && reason < InviteSession::ENDREASON_MAX); //!dcm! -- necessary? + resip_assert(reason >= InviteSession::NotSpecified && reason < InviteSession::ENDREASON_MAX); //!dcm! -- necessary? return EndReasons[reason]; } else @@ -82,7 +81,7 @@ InviteSession::InviteSession(DialogUsageManager& dum, Dialog& dialog) mEndReason(NotSpecified) { DebugLog ( << "^^^ InviteSession::InviteSession " << this); - assert(mDum.mInviteSessionHandler); + resip_assert(mDum.mInviteSessionHandler); } InviteSession::~InviteSession() @@ -96,17 +95,6 @@ InviteSession::~InviteSession() } } -void -InviteSession::dialogDestroyed(const SipMessage& msg) -{ - assert(0); - - // !jf! Is this correct? Merged from main... - // !jf! what reason - guessed for now? - //mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::PeerEnded, msg); - //delete this; -} - bool InviteSession::hasLocalOfferAnswer() const { @@ -167,18 +155,18 @@ InviteSession::getProposedRemoteOfferAnswer() const bool InviteSession::hasLocalSdp() const { - assert(!mDum.mInviteSessionHandler->isGenericOfferAnswer()); + resip_assert(!mDum.mInviteSessionHandler->isGenericOfferAnswer()); return (mCurrentLocalOfferAnswer.get()); } const SdpContents& InviteSession::getLocalSdp() const { - assert(!mDum.mInviteSessionHandler->isGenericOfferAnswer()); + resip_assert(!mDum.mInviteSessionHandler->isGenericOfferAnswer()); if(mCurrentLocalOfferAnswer.get()) { const SdpContents* sdp = dynamic_cast(mCurrentLocalOfferAnswer.get()); - assert(sdp); + resip_assert(sdp); return *sdp; } else @@ -190,18 +178,18 @@ InviteSession::getLocalSdp() const bool InviteSession::hasRemoteSdp() const { - assert(!mDum.mInviteSessionHandler->isGenericOfferAnswer()); + resip_assert(!mDum.mInviteSessionHandler->isGenericOfferAnswer()); return (mCurrentRemoteOfferAnswer.get()); } const SdpContents& InviteSession::getRemoteSdp() const { - assert(!mDum.mInviteSessionHandler->isGenericOfferAnswer()); + resip_assert(!mDum.mInviteSessionHandler->isGenericOfferAnswer()); if(mCurrentRemoteOfferAnswer.get()) { const SdpContents* sdp = dynamic_cast(mCurrentRemoteOfferAnswer.get()); - assert(sdp); + resip_assert(sdp); return *sdp; } else @@ -213,18 +201,18 @@ InviteSession::getRemoteSdp() const bool InviteSession::hasProposedRemoteSdp() const { - assert(!mDum.mInviteSessionHandler->isGenericOfferAnswer()); + resip_assert(!mDum.mInviteSessionHandler->isGenericOfferAnswer()); return (mProposedRemoteOfferAnswer.get()); } const SdpContents& InviteSession::getProposedRemoteSdp() const { - assert(!mDum.mInviteSessionHandler->isGenericOfferAnswer()); + resip_assert(!mDum.mInviteSessionHandler->isGenericOfferAnswer()); if(mProposedRemoteOfferAnswer.get()) { const SdpContents* sdp = dynamic_cast(mProposedRemoteOfferAnswer.get()); - assert(sdp); + resip_assert(sdp); return *sdp; } else @@ -319,6 +307,7 @@ InviteSession::isEarly() const case UAC_EarlyWithOffer: case UAC_EarlyWithAnswer: case UAC_SentUpdateEarly: + case UAC_SentUpdateEarlyGlare: case UAC_ReceivedUpdateEarly: case UAC_SentAnswer: case UAC_QueuedUpdate: @@ -335,18 +324,36 @@ InviteSession::isAccepted() const { case UAS_Start: case UAS_Offer: - case UAS_NoOffer: - case UAS_NoOfferReliable: - case UAS_ProvidedOffer: case UAS_OfferProvidedAnswer: case UAS_EarlyOffer: - case UAS_EarlyProvidedOffer: case UAS_EarlyProvidedAnswer: + + case UAS_NoOffer: + case UAS_ProvidedOffer: case UAS_EarlyNoOffer: - case UAS_FirstSentAnswerReliable: + case UAS_EarlyProvidedOffer: + //case UAS_Accepted: // Obvious + //case UAS_WaitingToOffer: // We have accepted here and are waiting for ACK to Offer + //case UAS_WaitingToRequestOffer: // We have accepted here and are waiting for ACK to request an offer + + //case UAS_AcceptedWaitingAnswer: // Obvious + case UAS_OfferReliable: + case UAS_OfferReliableProvidedAnswer: + case UAS_NoOfferReliable: + case UAS_ProvidedOfferReliable: case UAS_FirstSentOfferReliable: + case UAS_FirstSentAnswerReliable: + case UAS_NoAnswerReliableWaitingPrack: case UAS_NegotiatedReliable: + case UAS_NoAnswerReliable: + case UAS_SentUpdate: + //case UAS_SentUpdateAccepted: // we have accepted here + case UAS_SentUpdateGlare: + case UAS_ReceivedUpdate: + //case UAS_ReceivedUpdateWaitingAnswer: // happens only after accept is called + //case UAS_WaitingToHangup: // always from an accepted state return false; + default: return true; } @@ -361,7 +368,6 @@ InviteSession::isTerminated() const case WaitingToTerminate: case WaitingToHangup: case UAC_Cancelled: - case UAS_WaitingToTerminate: case UAS_WaitingToHangup: return true; default: @@ -411,24 +417,6 @@ InviteSession::requestOffer() } } -bool -InviteSession::canProvideOffer() -{ - switch (mState) - { - case Connected: - case WaitingToOffer: - case UAS_WaitingToOffer: - case Answered: - case ReceivedReinviteNoOffer: - return true; - default: - return false; - } -} - - - void InviteSession::provideOffer(const Contents& offer, DialogUsageManager::EncryptionLevel level, @@ -443,7 +431,7 @@ InviteSession::provideOffer(const Contents& offer, mDialog.makeRequest(*mLastLocalSessionModification, INVITE); startStaleReInviteTimer(); - setSessionTimerHeaders(*mLastLocalSessionModification); + setSessionTimerHeaders(*mLastLocalSessionModification); InfoLog (<< "Sending " << mLastLocalSessionModification->brief()); InviteSession::setOfferAnswer(*mLastLocalSessionModification, offer, alternative); @@ -463,7 +451,7 @@ InviteSession::provideOffer(const Contents& offer, break; case ReceivedReinviteNoOffer: - assert(!mProposedRemoteOfferAnswer.get()); + resip_assert(!mProposedRemoteOfferAnswer.get()); transition(ReceivedReinviteSentOffer); mDialog.makeResponse(*mInvite200, *mLastRemoteSessionModification, 200); handleSessionTimerRequest(*mInvite200, *mLastRemoteSessionModification); @@ -485,11 +473,11 @@ InviteSession::provideOffer(const Contents& offer, class InviteSessionProvideOfferExCommand : public DumCommandAdapter { public: - InviteSessionProvideOfferExCommand(InviteSession& inviteSession, + InviteSessionProvideOfferExCommand(const InviteSessionHandle& inviteSessionHandle, const Contents& offer, DialogUsageManager::EncryptionLevel level, const Contents* alternative) - : mInviteSession(inviteSession), + : mInviteSessionHandle(inviteSessionHandle), mOffer(offer.clone()), mLevel(level), mAlternative(alternative ? alternative->clone() : 0) @@ -498,7 +486,10 @@ public: virtual void executeCommand() { - mInviteSession.provideOffer(*mOffer, mLevel, mAlternative.get()); + if(mInviteSessionHandle.isValid()) + { + mInviteSessionHandle->provideOffer(*mOffer, mLevel, mAlternative.get()); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -506,16 +497,16 @@ public: return strm << "InviteSessionProvideOfferExCommand"; } private: - InviteSession& mInviteSession; - std::unique_ptr mOffer; + InviteSessionHandle mInviteSessionHandle; + std::auto_ptr mOffer; DialogUsageManager::EncryptionLevel mLevel; - std::unique_ptr mAlternative; + std::auto_ptr mAlternative; }; void InviteSession::provideOfferCommand(const Contents& offer, DialogUsageManager::EncryptionLevel level, const Contents* alternative) { - mDum.post(new InviteSessionProvideOfferExCommand(*this, offer, level, alternative)); + mDum.post(new InviteSessionProvideOfferExCommand(getSessionHandle(), offer, level, alternative)); } void @@ -527,15 +518,18 @@ InviteSession::provideOffer(const Contents& offer) class InviteSessionProvideOfferCommand : public DumCommandAdapter { public: - InviteSessionProvideOfferCommand(InviteSession& inviteSession, const Contents& offer) - : mInviteSession(inviteSession), + InviteSessionProvideOfferCommand(const InviteSessionHandle& inviteSessionHandle, const Contents& offer) + : mInviteSessionHandle(inviteSessionHandle), mOffer(offer.clone()) { } virtual void executeCommand() { - mInviteSession.provideOffer(*mOffer); + if(mInviteSessionHandle.isValid()) + { + mInviteSessionHandle->provideOffer(*mOffer); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -543,14 +537,14 @@ public: return strm << "InviteSessionProvideOfferCommand"; } private: - InviteSession& mInviteSession; - std::unique_ptr mOffer; + InviteSessionHandle mInviteSessionHandle; + std::auto_ptr mOffer; }; void InviteSession::provideOfferCommand(const Contents& offer) { - mDum.post(new InviteSessionProvideOfferCommand(*this, offer)); + mDum.post(new InviteSessionProvideOfferCommand(getSessionHandle(), offer)); } void @@ -564,11 +558,16 @@ InviteSession::provideAnswer(const Contents& answer) handleSessionTimerRequest(*mInvite200, *mLastRemoteSessionModification); InviteSession::setOfferAnswer(*mInvite200, answer, 0); mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer); - mCurrentRemoteOfferAnswer = std::move(mProposedRemoteOfferAnswer); + mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer; InfoLog (<< "Sending " << mInvite200->brief()); DumHelper::setOutgoingEncryptionLevel(*mInvite200, mCurrentEncryptionLevel); send(mInvite200); startRetransmit200Timer(); + if (mDum.mDialogEventStateManager) + { + // New Offer/Answer - generate a new confirmed callback with updated SDP + mDum.mDialogEventStateManager->onConfirmed(mDialog, getSessionHandle()); + } break; case ReceivedUpdate: // same as ReceivedReinvite case. @@ -578,12 +577,17 @@ InviteSession::provideAnswer(const Contents& answer) SharedPtr response(new SipMessage); mDialog.makeResponse(*response, *mLastRemoteSessionModification, 200); handleSessionTimerRequest(*response, *mLastRemoteSessionModification); - InviteSession::setOfferAnswer(*response, answer, nullptr); + InviteSession::setOfferAnswer(*response, answer, 0); mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer); - mCurrentRemoteOfferAnswer = std::move(mProposedRemoteOfferAnswer); + mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer; InfoLog (<< "Sending " << response->brief()); DumHelper::setOutgoingEncryptionLevel(*response, mCurrentEncryptionLevel); send(response); + if (mDum.mDialogEventStateManager) + { + // New Offer/Answer - generate a new confirmed callback with updated SDP + mDum.mDialogEventStateManager->onConfirmed(mDialog, getSessionHandle()); + } break; } @@ -591,8 +595,13 @@ InviteSession::provideAnswer(const Contents& answer) transition(Connected); sendAck(&answer); - mCurrentRemoteOfferAnswer = std::move(mProposedRemoteOfferAnswer); + mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer; mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer); + if (mDum.mDialogEventStateManager) + { + // New Offer/Answer - generate a new confirmed callback with updated SDP + mDum.mDialogEventStateManager->onConfirmed(mDialog, getSessionHandle()); + } break; default: @@ -604,15 +613,18 @@ InviteSession::provideAnswer(const Contents& answer) class InviteSessionProvideAnswerCommand : public DumCommandAdapter { public: - InviteSessionProvideAnswerCommand(InviteSession& inviteSession, const Contents& answer) - : mInviteSession(inviteSession), + InviteSessionProvideAnswerCommand(const InviteSessionHandle& inviteSessionHandle, const Contents& answer) + : mInviteSessionHandle(inviteSessionHandle), mAnswer(answer.clone()) { } virtual void executeCommand() { - mInviteSession.provideAnswer(*mAnswer); + if(mInviteSessionHandle.isValid()) + { + mInviteSessionHandle->provideAnswer(*mAnswer); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -620,14 +632,14 @@ public: return strm << "InviteSessionProvideAnswerCommand"; } private: - InviteSession& mInviteSession; - std::unique_ptr mAnswer; + InviteSessionHandle mInviteSessionHandle; + std::auto_ptr mAnswer; }; void InviteSession::provideAnswerCommand(const Contents& answer) { - mDum.post(new InviteSessionProvideAnswerCommand(*this, answer)); + mDum.post(new InviteSessionProvideAnswerCommand(getSessionHandle(), answer)); } void @@ -720,7 +732,7 @@ InviteSession::end(EndReason reason) break; default: - assert(0); + resip_assert(0); break; } } @@ -728,15 +740,18 @@ InviteSession::end(EndReason reason) class InviteSessionEndCommand : public DumCommandAdapter { public: - InviteSessionEndCommand(InviteSession& inviteSession, InviteSession::EndReason reason) - : mInviteSession(inviteSession), + InviteSessionEndCommand(const InviteSessionHandle& inviteSessionHandle, InviteSession::EndReason reason) + : mInviteSessionHandle(inviteSessionHandle), mReason(reason) { } virtual void executeCommand() { - mInviteSession.end(mReason); + if(mInviteSessionHandle.isValid()) + { + mInviteSessionHandle->end(mReason); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -744,14 +759,14 @@ public: return strm << "InviteSessionEndCommand"; } private: - InviteSession& mInviteSession; + InviteSessionHandle mInviteSessionHandle; InviteSession::EndReason mReason; }; void InviteSession::endCommand(EndReason reason) { - mDum.post(new InviteSessionEndCommand(*this, reason)); + mDum.post(new InviteSessionEndCommand(getSessionHandle(), reason)); } void @@ -763,6 +778,7 @@ InviteSession::reject(int statusCode, WarningCategory *warning) case ReceivedReinvite: case ReceivedReinviteNoOffer: { + mProposedRemoteOfferAnswer.reset(); // Clear out any potential ProposedRemoteOfferAnswer since we are rejecting transition(Connected); SharedPtr response(new SipMessage); @@ -786,7 +802,7 @@ InviteSession::reject(int statusCode, WarningCategory *warning) break; } default: - assert(0); + resip_assert(0); break; } } @@ -794,8 +810,8 @@ InviteSession::reject(int statusCode, WarningCategory *warning) class InviteSessionRejectCommand : public DumCommandAdapter { public: - InviteSessionRejectCommand(InviteSession& inviteSession, int code, WarningCategory* warning) - : mInviteSession(inviteSession), + InviteSessionRejectCommand(const InviteSessionHandle& inviteSessionHandle, int code, WarningCategory* warning) + : mInviteSessionHandle(inviteSessionHandle), mCode(code), mWarning(warning?new WarningCategory(*warning):0) { @@ -803,7 +819,10 @@ public: virtual void executeCommand() { - mInviteSession.reject(mCode, mWarning.get()); + if(mInviteSessionHandle.isValid()) + { + mInviteSessionHandle->reject(mCode, mWarning.get()); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -811,15 +830,15 @@ public: return strm << "InviteSessionRejectCommand"; } private: - InviteSession& mInviteSession; + InviteSessionHandle mInviteSessionHandle; int mCode; - std::unique_ptr mWarning; + std::auto_ptr mWarning; }; void InviteSession::rejectCommand(int code, WarningCategory *warning) { - mDum.post(new InviteSessionRejectCommand(*this, code, warning)); + mDum.post(new InviteSessionRejectCommand(getSessionHandle(), code, warning)); } void @@ -840,19 +859,29 @@ InviteSession::targetRefresh(const NameAddr& localUri) void InviteSession::refer(const NameAddr& referTo, bool referSub) { - refer(referTo, std::unique_ptr(nullptr),referSub); + refer(referTo,myAddr(),std::auto_ptr(0),referSub); } void -InviteSession::refer(const NameAddr& referTo, std::unique_ptr contents,bool referSub) +InviteSession::refer(const NameAddr& referTo, const NameAddr& referredBy, bool referSub) +{ + refer(referTo,referredBy,std::auto_ptr(0),referSub); +} +void +InviteSession::refer(const NameAddr& referTo, std::auto_ptr contents,bool referSub) +{ + refer(referTo,myAddr(),contents,referSub); +} +void +InviteSession::refer(const NameAddr& referTo, const NameAddr& referredBy, std::auto_ptr contents, bool referSub) { if (isConnected()) // ?slg? likely not safe in any state except Connected - what should behaviour be if state is ReceivedReinvite? { SharedPtr refer(new SipMessage()); - mDialog.makeRequest(*refer, REFER); + mDialog.makeRequest(*refer, REFER, mNitState == NitComplete); // only increment CSeq if not going to queue NIT refer->header(h_ReferTo) = referTo; - refer->header(h_ReferredBy) = myAddr(); + refer->header(h_ReferredBy) = referredBy; refer->header(h_ReferredBy).remove(p_tag); // tag-param not permitted in rfc3892; not the same as generic-param - refer->setContents(std::move(contents)); + refer->setContents(contents); if (!referSub) { refer->header(h_ReferSub).value() = "false"; @@ -874,7 +903,6 @@ InviteSession::refer(const NameAddr& referTo, std::unique_ptr c else { WarningLog (<< "Can't refer before Connected"); - assert(0); throw UsageUseException("REFER not allowed in this context", __FILE__, __LINE__); } } @@ -896,6 +924,7 @@ InviteSession::nitComplete() mNitState = NitProceeding; mReferSub = qn->referSubscription(); mLastSentNITRequest = qn->getNIT(); + mDialog.setRequestNextCSeq(*mLastSentNITRequest.get()); InfoLog(<< "checkNITQueue - sending queued NIT:" << mLastSentNITRequest->brief()); send(mLastSentNITRequest); delete qn; @@ -905,8 +934,8 @@ InviteSession::nitComplete() class InviteSessionReferCommand : public DumCommandAdapter { public: - InviteSessionReferCommand(InviteSession& inviteSession, const NameAddr& referTo, bool referSub) - : mInviteSession(inviteSession), + InviteSessionReferCommand(const InviteSessionHandle& inviteSessionHandle, const NameAddr& referTo, bool referSub) + : mInviteSessionHandle(inviteSessionHandle), mReferTo(referTo), mReferSub(referSub) { @@ -915,7 +944,10 @@ public: virtual void executeCommand() { - mInviteSession.refer(mReferTo, mReferSub); + if(mInviteSessionHandle.isValid()) + { + mInviteSessionHandle->refer(mReferTo, mReferSub); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -924,7 +956,7 @@ public: } private: - InviteSession& mInviteSession; + InviteSessionHandle mInviteSessionHandle; NameAddr mReferTo; bool mReferSub; }; @@ -932,17 +964,17 @@ private: void InviteSession::referCommand(const NameAddr& referTo, bool referSub) { - mDum.post(new InviteSessionReferCommand(*this, referTo, referSub)); + mDum.post(new InviteSessionReferCommand(getSessionHandle(), referTo, referSub)); } void InviteSession::refer(const NameAddr& referTo, InviteSessionHandle sessionToReplace, bool referSub) { - refer(referTo,sessionToReplace, std::unique_ptr(nullptr),referSub); + refer(referTo,sessionToReplace,std::auto_ptr(0),referSub); } void -InviteSession::refer(const NameAddr& referTo, InviteSessionHandle sessionToReplace, std::unique_ptr contents, bool referSub) +InviteSession::refer(const NameAddr& referTo, InviteSessionHandle sessionToReplace, std::auto_ptr contents, bool referSub) { if (!sessionToReplace.isValid()) { @@ -955,23 +987,23 @@ InviteSession::refer(const NameAddr& referTo, InviteSessionHandle sessionToRepla replaces.param(p_toTag) = id.getRemoteTag(); replaces.param(p_fromTag) = id.getLocalTag(); - refer(referTo, replaces, std::move(contents), referSub); + refer(referTo, replaces, contents, referSub); } void InviteSession::refer(const NameAddr& referTo, const CallId& replaces, bool referSub) { - refer(referTo, replaces, std::unique_ptr(nullptr), referSub); + refer(referTo,replaces,std::auto_ptr(0),referSub); } void -InviteSession::refer(const NameAddr& referTo, const CallId& replaces, std::unique_ptr contents, bool referSub) +InviteSession::refer(const NameAddr& referTo, const CallId& replaces, std::auto_ptr contents, bool referSub) { if (isConnected()) // ?slg? likely not safe in any state except Connected - what should behaviour be if state is ReceivedReinvite? { - SharedPtr refer(new SipMessage()); - mDialog.makeRequest(*refer, REFER); - refer->setContents(std::move(contents)); + SharedPtr refer(new SipMessage()); + mDialog.makeRequest(*refer, REFER, mNitState == NitComplete); // only increment CSeq if not going to queue NIT + refer->setContents(contents); refer->header(h_ReferTo) = referTo; refer->header(h_ReferredBy) = myAddr(); refer->header(h_ReferredBy).remove(p_tag); @@ -999,7 +1031,7 @@ InviteSession::refer(const NameAddr& referTo, const CallId& replaces, std::uniqu else { WarningLog (<< "Can't refer before Connected"); - assert(0); + resip_assert(0); throw UsageUseException("REFER not allowed in this context", __FILE__, __LINE__); } } @@ -1007,8 +1039,8 @@ InviteSession::refer(const NameAddr& referTo, const CallId& replaces, std::uniqu class InviteSessionReferExCommand : public DumCommandAdapter { public: - InviteSessionReferExCommand(InviteSession& inviteSession, const NameAddr& referTo, InviteSessionHandle sessionToReplace, bool referSub) - : mInviteSession(inviteSession), + InviteSessionReferExCommand(const InviteSessionHandle& inviteSessionHandle, const NameAddr& referTo, InviteSessionHandle sessionToReplace, bool referSub) + : mInviteSessionHandle(inviteSessionHandle), mSessionToReplace(sessionToReplace), mReferTo(referTo), mReferSub(referSub) @@ -1017,7 +1049,10 @@ public: virtual void executeCommand() { - mInviteSession.refer(mReferTo, mSessionToReplace, mReferSub); + if(mInviteSessionHandle.isValid()) + { + mInviteSessionHandle->refer(mReferTo, mSessionToReplace, mReferSub); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -1026,7 +1061,7 @@ public: } private: - InviteSession& mInviteSession; + InviteSessionHandle mInviteSessionHandle; InviteSessionHandle mSessionToReplace; NameAddr mReferTo; bool mReferSub; @@ -1035,14 +1070,14 @@ private: void InviteSession::referCommand(const NameAddr& referTo, InviteSessionHandle sessionToReplace, bool referSub) { - mDum.post(new InviteSessionReferExCommand(*this, referTo, sessionToReplace, referSub)); + mDum.post(new InviteSessionReferExCommand(getSessionHandle(), referTo, sessionToReplace, referSub)); } void InviteSession::info(const Contents& contents) { SharedPtr info(new SipMessage()); - mDialog.makeRequest(*info, INFO); + mDialog.makeRequest(*info, INFO, mNitState == NitComplete); // only increment CSeq if not going to queue NIT // !jf! handle multipart here info->setContents(&contents); DumHelper::setOutgoingEncryptionLevel(*info, mCurrentEncryptionLevel); @@ -1061,15 +1096,18 @@ InviteSession::info(const Contents& contents) class InviteSessionInfoCommand : public DumCommandAdapter { public: - InviteSessionInfoCommand(InviteSession& inviteSession, const Contents& contents) - : mInviteSession(inviteSession), + InviteSessionInfoCommand(const InviteSessionHandle& inviteSessionHandle, const Contents& contents) + : mInviteSessionHandle(inviteSessionHandle), mContents(contents.clone()) { } virtual void executeCommand() { - mInviteSession.info(*mContents); + if(mInviteSessionHandle.isValid()) + { + mInviteSessionHandle->info(*mContents); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -1077,21 +1115,21 @@ public: return strm << "InviteSessionInfoCommand"; } private: - InviteSession& mInviteSession; - std::unique_ptr mContents; + InviteSessionHandle mInviteSessionHandle; + std::auto_ptr mContents; }; void InviteSession::infoCommand(const Contents& contents) { - mDum.post(new InviteSessionInfoCommand(*this, contents)); + mDum.post(new InviteSessionInfoCommand(getSessionHandle(), contents)); } void InviteSession::message(const Contents& contents) { SharedPtr message(new SipMessage()); - mDialog.makeRequest(*message, MESSAGE); + mDialog.makeRequest(*message, MESSAGE, mNitState == NitComplete); // only increment CSeq if not going to queue NIT // !jf! handle multipart here message->setContents(&contents); DumHelper::setOutgoingEncryptionLevel(*message, mCurrentEncryptionLevel); @@ -1111,15 +1149,18 @@ InviteSession::message(const Contents& contents) class InviteSessionMessageCommand : public DumCommandAdapter { public: - InviteSessionMessageCommand(InviteSession& inviteSession, const Contents& contents) - : mInviteSession(inviteSession), + InviteSessionMessageCommand(const InviteSessionHandle& inviteSessionHandle, const Contents& contents) + : mInviteSessionHandle(inviteSessionHandle), mContents(contents.clone()) { } virtual void executeCommand() { - mInviteSession.message(*mContents); + if(mInviteSessionHandle.isValid()) + { + mInviteSessionHandle->message(*mContents); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -1127,15 +1168,15 @@ public: return strm << "InviteSessionMessageCommand"; } private: - InviteSession& mInviteSession; - std::unique_ptr mContents; + InviteSessionHandle mInviteSessionHandle; + std::auto_ptr mContents; }; void InviteSession::messageCommand(const Contents& contents) { - mDum.post(new InviteSessionMessageCommand(*this, contents)); + mDum.post(new InviteSessionMessageCommand(getSessionHandle(), contents)); } void @@ -1206,7 +1247,7 @@ InviteSession::dispatch(const SipMessage& msg) break; case Undefined: default: - assert(0); + resip_assert(0); break; } } @@ -1252,7 +1293,7 @@ InviteSession::dispatch(const DumTimeout& timeout) else if(mState == WaitingToOffer || mState == UAS_WaitingToOffer) { - assert(mProposedLocalOfferAnswer.get()); + resip_assert(mProposedLocalOfferAnswer.get()); mDum.mInviteSessionHandler->onAckNotReceived(getSessionHandle()); if(!isTerminated()) { @@ -1365,7 +1406,7 @@ void InviteSession::dispatchConnected(const SipMessage& msg) { InviteSessionHandler* handler = mDum.mInviteSessionHandler; - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); switch (toEvent(msg, offerAnswer.get())) { @@ -1381,7 +1422,7 @@ InviteSession::dispatchConnected(const SipMessage& msg) *mLastRemoteSessionModification = msg; transition(ReceivedReinvite); mCurrentEncryptionLevel = getEncryptionLevel(msg); - mProposedRemoteOfferAnswer = std::move(offerAnswer); + mProposedRemoteOfferAnswer = offerAnswer; handler->onOffer(getSessionHandle(), msg, *mProposedRemoteOfferAnswer); break; @@ -1402,7 +1443,7 @@ InviteSession::dispatchConnected(const SipMessage& msg) // See rfc3311 5.2, 4th paragraph. *mLastRemoteSessionModification = msg; mCurrentEncryptionLevel = getEncryptionLevel(msg); - mProposedRemoteOfferAnswer = std::move(offerAnswer); + mProposedRemoteOfferAnswer = offerAnswer; handler->onOffer(getSessionHandle(), msg, *mProposedRemoteOfferAnswer); break; @@ -1410,10 +1451,8 @@ InviteSession::dispatchConnected(const SipMessage& msg) { // ?slg? no offerAnswer in update - just respond immediately (likely session timer) - do we need a callback? SharedPtr response(new SipMessage); - *mLastRemoteSessionModification = msg; - mDialog.makeResponse(*response, *mLastRemoteSessionModification, 200); - - handleSessionTimerRequest(*response, *mLastRemoteSessionModification); + mDialog.makeResponse(*response, msg, 200); + handleSessionTimerRequest(*response, msg); send(response); break; } @@ -1421,7 +1460,7 @@ InviteSession::dispatchConnected(const SipMessage& msg) case OnUpdateRejected: case On200Update: WarningLog (<< "DUM delivered an UPDATE response in an incorrect state " << endl << msg); - assert(0); + resip_assert(0); break; case OnAck: @@ -1440,7 +1479,7 @@ void InviteSession::dispatchSentUpdate(const SipMessage& msg) { InviteSessionHandler* handler = mDum.mInviteSessionHandler; - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); switch (toEvent(msg, offerAnswer.get())) { @@ -1466,7 +1505,12 @@ InviteSession::dispatchSentUpdate(const SipMessage& msg) mCurrentEncryptionLevel = getEncryptionLevel(msg); setCurrentLocalOfferAnswer(msg); - mCurrentRemoteOfferAnswer = std::move(offerAnswer); + mCurrentRemoteOfferAnswer = offerAnswer; + if (mDum.mDialogEventStateManager) + { + // New Offer/Answer - generate a new confirmed callback with updated SDP + mDum.mDialogEventStateManager->onConfirmed(mDialog, getSessionHandle()); + } handler->onAnswer(getSessionHandle(), msg, *mCurrentRemoteOfferAnswer); } else if(mProposedLocalOfferAnswer.get()) @@ -1523,7 +1567,7 @@ void InviteSession::dispatchSentReinvite(const SipMessage& msg) { InviteSessionHandler* handler = mDum.mInviteSessionHandler; - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); switch (toEvent(msg, offerAnswer.get())) { @@ -1546,7 +1590,7 @@ InviteSession::dispatchSentReinvite(const SipMessage& msg) break; case On2xxAnswer: - case On2xxOffer: // .slg. doesn't really make sense + case On2xxOffer: // .slg. doesn't really make sense - should be in SentReinviteNoOffer to get this { mStaleReInviteTimerSeq++; transition(Connected); @@ -1561,21 +1605,25 @@ InviteSession::dispatchSentReinvite(const SipMessage& msg) { mSessionRefreshReInvite = false; - MD5Stream currentRemote; - currentRemote<< *mCurrentRemoteOfferAnswer; - MD5Stream newRemote; - newRemote << *offerAnswer; - bool changed = currentRemote.getHex() != newRemote.getHex(); - - if (changed) + if (*mCurrentRemoteOfferAnswer != *offerAnswer) { - mCurrentRemoteOfferAnswer = std::move(offerAnswer); + mCurrentRemoteOfferAnswer = offerAnswer; + if (mDum.mDialogEventStateManager) + { + // New Offer/Answer - generate a new confirmed callback with updated SDP + mDum.mDialogEventStateManager->onConfirmed(mDialog, getSessionHandle()); + } handler->onRemoteAnswerChanged(getSessionHandle(), msg, *mCurrentRemoteOfferAnswer); } } else { - mCurrentRemoteOfferAnswer = std::move(offerAnswer); + mCurrentRemoteOfferAnswer = offerAnswer; + if (mDum.mDialogEventStateManager) + { + // New Offer/Answer - generate a new confirmed callback with updated SDP + mDum.mDialogEventStateManager->onConfirmed(mDialog, getSessionHandle()); + } handler->onAnswer(getSessionHandle(), msg, *mCurrentRemoteOfferAnswer); } @@ -1644,7 +1692,7 @@ void InviteSession::dispatchSentReinviteNoOffer(const SipMessage& msg) { InviteSessionHandler* handler = mDum.mInviteSessionHandler; - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); switch (toEvent(msg, offerAnswer.get())) { @@ -1666,15 +1714,14 @@ InviteSession::dispatchSentReinviteNoOffer(const SipMessage& msg) // Some UA's send a 100 response to a ReInvite - just ignore it break; - case On2xxAnswer: // .slg. doesn't really make sense + case On2xxAnswer: // .slg. doesn't really make sense - should be in SentReinvite to get this case On2xxOffer: { mStaleReInviteTimerSeq++; transition(SentReinviteAnswered); handleSessionTimerResponse(msg); - // mLastSessionModification = msg; // ?slg? why are we storing 200's? mCurrentEncryptionLevel = getEncryptionLevel(msg); - mProposedRemoteOfferAnswer = std::move(offerAnswer); + mProposedRemoteOfferAnswer = offerAnswer; handler->onOffer(getSessionHandle(), msg, *mProposedRemoteOfferAnswer); break; } @@ -1739,7 +1786,7 @@ void InviteSession::dispatchReceivedReinviteSentOffer(const SipMessage& msg) { InviteSessionHandler* handler = mDum.mInviteSessionHandler; - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); switch (toEvent(msg, offerAnswer.get())) { @@ -1758,10 +1805,15 @@ InviteSession::dispatchReceivedReinviteSentOffer(const SipMessage& msg) case OnAckAnswer: transition(Connected); setCurrentLocalOfferAnswer(msg); - mCurrentRemoteOfferAnswer = std::move(offerAnswer); + mCurrentRemoteOfferAnswer = offerAnswer; mCurrentEncryptionLevel = getEncryptionLevel(msg); mCurrentRetransmit200 = 0; // stop the 200 retransmit timer + if (mDum.mDialogEventStateManager) + { + // New Offer/Answer - generate a new confirmed callback with updated SDP + mDum.mDialogEventStateManager->onConfirmed(mDialog, getSessionHandle()); + } handler->onAnswer(getSessionHandle(), msg, *mCurrentRemoteOfferAnswer); break; case OnAck: @@ -1839,7 +1891,7 @@ void InviteSession::dispatchReceivedUpdateOrReinvite(const SipMessage& msg) { // InviteSessionHandler* handler = mDum.mInviteSessionHandler; // unused - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); switch (toEvent(msg, offerAnswer.get())) { @@ -1909,7 +1961,7 @@ InviteSession::dispatchWaitingToOffer(const SipMessage& msg) { if (msg.isRequest() && msg.header(h_RequestLine).method() == ACK) { - assert(mProposedLocalOfferAnswer.get()); + resip_assert(mProposedLocalOfferAnswer.get()); mCurrentRetransmit200 = 0; // stop the 200 retransmit timer provideProposedOffer(); } @@ -1966,7 +2018,7 @@ InviteSession::dispatchWaitingToTerminate(const SipMessage& msg) void InviteSession::dispatchWaitingToHangup(const SipMessage& msg) { - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); switch (toEvent(msg, offerAnswer.get())) { @@ -2048,7 +2100,7 @@ InviteSession::dispatchOthers(const SipMessage& msg) << " to the InviteSession in state: " << toData(mState) << endl << msg); - assert(0); + resip_assert(0); break; } } @@ -2056,8 +2108,8 @@ InviteSession::dispatchOthers(const SipMessage& msg) void InviteSession::dispatchUnhandledInvite(const SipMessage& msg) { - assert(msg.isRequest()); - assert(msg.header(h_CSeq).method() == INVITE); + resip_assert(msg.isRequest()); + resip_assert(msg.header(h_CSeq).method() == INVITE); // If we get an INVITE request from the wire and we are not in // Connected state, reject the request and send a BYE @@ -2074,7 +2126,7 @@ InviteSession::dispatchUnhandledInvite(const SipMessage& msg) void InviteSession::dispatchPrack(const SipMessage& msg) { - assert(msg.header(h_CSeq).method() == PRACK); + resip_assert(msg.header(h_CSeq).method() == PRACK); if(msg.isRequest()) { SharedPtr rsp(new SipMessage); @@ -2096,7 +2148,7 @@ void InviteSession::dispatchCancel(const SipMessage& msg) { InviteSessionHandler* handler = mDum.mInviteSessionHandler; - assert(msg.header(h_CSeq).method() == CANCEL); + resip_assert(msg.header(h_CSeq).method() == CANCEL); if(msg.isRequest()) { SharedPtr rsp(new SipMessage); @@ -2112,7 +2164,7 @@ InviteSession::dispatchCancel(const SipMessage& msg) else { WarningLog (<< "DUM let me send a CANCEL at an incorrect state " << endl << msg); - assert(0); + resip_assert(0); } } @@ -2153,7 +2205,7 @@ InviteSession::dispatchBye(const SipMessage& msg) else { WarningLog (<< "DUM let me send a BYE at an incorrect state " << endl << msg); - assert(0); + resip_assert(0); } } @@ -2171,6 +2223,7 @@ InviteSession::dispatchInfo(const SipMessage& msg) mDialog.makeResponse(*response, msg, 500); response->header(h_RetryAfter).value() = Random::getRandom() % 10; send(response); + WarningLog(<<"an INFO message was received before the application called acceptNIT() for the previous INFO message"); } else { @@ -2182,7 +2235,7 @@ InviteSession::dispatchInfo(const SipMessage& msg) } else { - assert(mNitState == NitProceeding); + resip_assert(mNitState == NitProceeding); //!dcm! -- toss away 1xx to an info? if (msg.header(h_StatusLine).statusCode() >= 300) { @@ -2219,8 +2272,8 @@ InviteSession::acceptNIT(int statusCode, const Contents * contents) class InviteSessionAcceptNITCommand : public DumCommandAdapter { public: - InviteSessionAcceptNITCommand(InviteSession& inviteSession, int statusCode, const Contents* contents) - : mInviteSession(inviteSession), + InviteSessionAcceptNITCommand(const InviteSessionHandle& inviteSessionHandle, int statusCode, const Contents* contents) + : mInviteSessionHandle(inviteSessionHandle), mStatusCode(statusCode), mContents(contents?contents->clone():0) { @@ -2229,7 +2282,10 @@ public: virtual void executeCommand() { - mInviteSession.acceptNITCommand(mStatusCode, mContents.get()); + if(mInviteSessionHandle.isValid()) + { + mInviteSessionHandle->acceptNIT(mStatusCode, mContents.get()); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -2237,15 +2293,15 @@ public: return strm << "InviteSessionAcceptNITCommand"; } private: - InviteSession& mInviteSession; + InviteSessionHandle mInviteSessionHandle; int mStatusCode; - std::unique_ptr mContents; + std::auto_ptr mContents; }; void InviteSession::acceptNITCommand(int statusCode, const Contents* contents) { - mDum.post(new InviteSessionAcceptNITCommand(*this, statusCode, contents)); + mDum.post(new InviteSessionAcceptNITCommand(getSessionHandle(), statusCode, contents)); } void @@ -2271,15 +2327,18 @@ InviteSession::rejectNIT(int statusCode) class InviteSessionRejectNITCommand : public DumCommandAdapter { public: - InviteSessionRejectNITCommand(InviteSession& inviteSession, int statusCode) - : mInviteSession(inviteSession), + InviteSessionRejectNITCommand(const InviteSessionHandle& inviteSessionHandle, int statusCode) + : mInviteSessionHandle(inviteSessionHandle), mStatusCode(statusCode) { } virtual void executeCommand() { - mInviteSession.rejectNITCommand(mStatusCode); + if(mInviteSessionHandle.isValid()) + { + mInviteSessionHandle->rejectNIT(mStatusCode); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -2287,14 +2346,14 @@ public: return strm << "InviteSessionRejectNITCommand"; } private: - InviteSession& mInviteSession; + InviteSessionHandle mInviteSessionHandle; int mStatusCode; }; void InviteSession::rejectNITCommand(int statusCode) { - mDum.post(new InviteSessionRejectNITCommand(*this, statusCode)); + mDum.post(new InviteSessionRejectNITCommand(getSessionHandle(), statusCode)); } void @@ -2323,7 +2382,7 @@ InviteSession::dispatchMessage(const SipMessage& msg) } else { - assert(mNitState == NitProceeding); + resip_assert(mNitState == NitProceeding); //!dcm! -- toss away 1xx to an message? if (msg.header(h_StatusLine).statusCode() >= 300) { @@ -2402,7 +2461,11 @@ InviteSession::setSessionTimerHeaders(SipMessage &msg) { msg.header(h_SessionExpires).param(p_refresher) = Data(mSessionRefresher ? "uas" : "uac"); } - msg.header(h_MinSE).value() = mMinSE; + if(msg.isRequest() || + (msg.isResponse() && msg.header(h_StatusLine).responseCode() == 422)) + { + msg.header(h_MinSE).value() = mMinSE; + } } else { @@ -2442,7 +2505,7 @@ InviteSession::setSessionTimerPreferences() mSessionInterval = mDialog.mDialogSet.getUserProfile()->getDefaultSessionTime(); // Used only if remote doesn't request a time if(mSessionInterval != 0) { - // If session timers are no disabled then ensure interval is greater than or equal to MinSE + // If session timers are not disabled then ensure interval is greater than or equal to MinSE mSessionInterval = resipMax(mMinSE, mSessionInterval); } switch(mDialog.mDialogSet.getUserProfile()->getDefaultSessionTimerMode()) @@ -2488,7 +2551,7 @@ InviteSession::startSessionTimer() void InviteSession::handleSessionTimerResponse(const SipMessage& msg) { - assert(msg.header(h_CSeq).method() == INVITE || msg.header(h_CSeq).method() == UPDATE); + resip_assert(msg.header(h_CSeq).method() == INVITE || msg.header(h_CSeq).method() == UPDATE); // Allow Re-Invites and Updates to update the Peer P-Asserted-Identity if (msg.exists(h_PAssertedIdentities)) @@ -2538,7 +2601,7 @@ InviteSession::handleSessionTimerResponse(const SipMessage& msg) void InviteSession::handleSessionTimerRequest(SipMessage &response, const SipMessage& request) { - assert(request.header(h_CSeq).method() == INVITE || request.header(h_CSeq).method() == UPDATE); + resip_assert(request.header(h_CSeq).method() == INVITE || request.header(h_CSeq).method() == UPDATE); // Allow Re-Invites and Updates to update the Peer P-Asserted-Identity if (request.exists(h_PAssertedIdentities)) @@ -2549,6 +2612,11 @@ InviteSession::handleSessionTimerRequest(SipMessage &response, const SipMessage& // If session timers are locally supported then add necessary headers to response if(mDum.getMasterProfile()->getSupportedOptionTags().find(Token(Symbols::Timer))) { + // Update MinSE if specified and longer than current value + if(request.exists(h_MinSE)) + { + mMinSE = resipMax(mMinSE, request.header(h_MinSE).value()); + } setSessionTimerPreferences(); // Check if far-end supports @@ -2565,12 +2633,6 @@ InviteSession::handleSessionTimerRequest(SipMessage &response, const SipMessage& mSessionRefresher = (request.header(h_SessionExpires).param(p_refresher) == Data("uas")); } } - - // Update MinSE if specified and longer than current value - if(request.exists(h_MinSE)) - { - mMinSE = resipMax(mMinSE, request.header(h_MinSE).value()); - } } else { @@ -2687,32 +2749,40 @@ InviteSession::toData(State state) case UAS_Start: return "UAS_Start"; - case UAS_ReceivedOfferReliable: - return "UAS_ReceivedOfferReliable"; + case UAS_OfferReliable: + return "UAS_OfferReliable"; + case UAS_OfferReliableProvidedAnswer: + return "UAS_OfferReliableProvidedAnswer"; case UAS_NoOfferReliable: return "UAS_NoOfferReliable"; + case UAS_ProvidedOfferReliable: + return "UAS_ProvidedOfferReliable"; case UAS_FirstSentOfferReliable: return "UAS_FirstSentOfferReliable"; case UAS_FirstSentAnswerReliable: return "UAS_FirstSentAnswerReliable"; + case UAS_NoAnswerReliableWaitingPrack: + return "UAS_NoAnswerReliableWaitingPrack"; + case UAS_NoAnswerReliable: + return "UAS_NoAnswerReliable"; case UAS_NegotiatedReliable: return "UAS_NegotiatedReliable"; case UAS_SentUpdate: return "UAS_SentUpdate"; case UAS_SentUpdateAccepted: return "UAS_SentUpdateAccepted"; + case UAS_SentUpdateGlare: + return "UAS_SentUpdateGlare"; case UAS_ReceivedUpdate: return "UAS_ReceivedUpdate"; case UAS_ReceivedUpdateWaitingAnswer: return "UAS_ReceivedUpdateWaitingAnswer"; - case UAS_WaitingToTerminate: - return "UAS_WaitingToTerminate"; case UAS_WaitingToHangup: return "UAS_WaitingToHangup"; case UAS_WaitingToRequestOffer: return "UAS_WaitingToRequestOffer"; } - assert(0); + resip_assert(0); return "Undefined"; } @@ -2725,7 +2795,7 @@ InviteSession::transition(State target) } bool -InviteSession::isReliable(const SipMessage& msg) +InviteSession::isReliable(const SipMessage& msg) const { if(msg.method() != INVITE) { @@ -2733,45 +2803,47 @@ InviteSession::isReliable(const SipMessage& msg) } if(msg.isRequest()) { - return mDum.getMasterProfile()->getUasReliableProvisionalMode() > MasterProfile::Never - && ((msg.exists(h_Supporteds) && msg.header(h_Supporteds).find(Token(Symbols::C100rel))) - || (msg.exists(h_Requires) && msg.header(h_Requires).find(Token(Symbols::C100rel)))); + return mDum.getMasterProfile()->getUasReliableProvisionalMode() > MasterProfile::Never && + ((msg.exists(h_Supporteds) && msg.header(h_Supporteds).find(Token(Symbols::C100rel))) || + (msg.exists(h_Requires) && msg.header(h_Requires).find(Token(Symbols::C100rel)))); } else { - return mDum.getMasterProfile()->getUacReliableProvisionalMode() > MasterProfile::Never - && msg.exists(h_Requires) && msg.header(h_Requires).find(Token(Symbols::C100rel)); + // RFC3262 says reliable provisionals MUST have a Require: 100rel and an RSeq + return mDum.getMasterProfile()->getUacReliableProvisionalMode() > MasterProfile::Never && + msg.exists(h_Requires) && msg.header(h_Requires).find(Token(Symbols::C100rel)) && + msg.exists(h_RSeq); } } -//static std::unique_ptr emptySdp; -std::unique_ptr +//static std::auto_ptr emptySdp; +std::auto_ptr InviteSession::getOfferAnswer(const SipMessage& msg) { if(mDum.mInviteSessionHandler->isGenericOfferAnswer()) { if(msg.getContents()) { - return std::unique_ptr(msg.getContents()->clone()); + return std::auto_ptr(msg.getContents()->clone()); } else { - return std::unique_ptr(); + return std::auto_ptr(); } } else { - return std::unique_ptr(Helper::getSdp(msg.getContents())); + return std::auto_ptr(Helper::getSdp(msg.getContents())); } } -std::unique_ptr +std::auto_ptr InviteSession::makeOfferAnswer(const Contents& offerAnswer) { - return std::unique_ptr(static_cast(offerAnswer.clone())); + return std::auto_ptr(static_cast(offerAnswer.clone())); } -unique_ptr +auto_ptr InviteSession::makeOfferAnswer(const Contents& offerAnswer, const Contents* alternative) { @@ -2780,11 +2852,11 @@ InviteSession::makeOfferAnswer(const Contents& offerAnswer, MultipartAlternativeContents* mac = new MultipartAlternativeContents; mac->parts().push_back(alternative->clone()); mac->parts().push_back(offerAnswer.clone()); - return unique_ptr(mac); + return auto_ptr(mac); } else { - return unique_ptr(offerAnswer.clone()); + return auto_ptr(offerAnswer.clone()); } } @@ -2800,7 +2872,7 @@ InviteSession::setOfferAnswer(SipMessage& msg, const Contents& offerAnswer, cons MultipartAlternativeContents* mac = new MultipartAlternativeContents; mac->parts().push_back(alternative->clone()); mac->parts().push_back(offerAnswer.clone()); - msg.setContents(unique_ptr(mac)); + msg.setContents(auto_ptr(mac)); } else { @@ -2811,7 +2883,7 @@ InviteSession::setOfferAnswer(SipMessage& msg, const Contents& offerAnswer, cons void InviteSession::setOfferAnswer(SipMessage& msg, const Contents* offerAnswer) { - assert(offerAnswer); + resip_assert(offerAnswer); msg.setContents(offerAnswer); } @@ -3036,7 +3108,7 @@ InviteSession::sendAck(const Contents *answer) source = mLastLocalSessionModification; } - assert(mAcks.count(source->getTransactionId()) == 0); + resip_assert(mAcks.count(source->getTransactionId()) == 0); mDialog.makeRequest(*ack, ACK); @@ -3110,21 +3182,21 @@ InviteSession::getEncryptionLevel(const SipMessage& msg) void InviteSession::setCurrentLocalOfferAnswer(const SipMessage& msg) { - assert(mProposedLocalOfferAnswer.get()); + resip_assert(mProposedLocalOfferAnswer.get()); if (dynamic_cast(mProposedLocalOfferAnswer.get())) { if (DialogUsageManager::Encrypt == getEncryptionLevel(msg) || DialogUsageManager::SignAndEncrypt == getEncryptionLevel(msg)) { - mCurrentLocalOfferAnswer = unique_ptr(static_cast((dynamic_cast(mProposedLocalOfferAnswer.get()))->parts().back()->clone())); + mCurrentLocalOfferAnswer = auto_ptr(static_cast((dynamic_cast(mProposedLocalOfferAnswer.get()))->parts().back()->clone())); } else { - mCurrentLocalOfferAnswer = unique_ptr(static_cast((dynamic_cast(mProposedLocalOfferAnswer.get()))->parts().front()->clone())); + mCurrentLocalOfferAnswer = auto_ptr(static_cast((dynamic_cast(mProposedLocalOfferAnswer.get()))->parts().front()->clone())); } } else { - mCurrentLocalOfferAnswer = unique_ptr(static_cast(mProposedLocalOfferAnswer.get()->clone())); + mCurrentLocalOfferAnswer = auto_ptr(static_cast(mProposedLocalOfferAnswer.get()->clone())); } mProposedLocalOfferAnswer.reset(); } @@ -3145,7 +3217,7 @@ InviteSession::flowTerminated() void InviteSession::referNoSub(const SipMessage& msg) { - assert(msg.isRequest() && msg.header(h_CSeq).method()==REFER); + resip_assert(msg.isRequest() && msg.header(h_CSeq).method()==REFER); mLastReferNoSubRequest = msg; mDum.mInviteSessionHandler->onReferNoSub(getSessionHandle(), mLastReferNoSubRequest); } diff --git a/src/libs/resiprocate/resip/dum/InviteSession.hxx b/src/libs/resiprocate/resip/dum/InviteSession.hxx index 024c23d2..9c35bcbb 100644 --- a/src/libs/resiprocate/resip/dum/InviteSession.hxx +++ b/src/libs/resiprocate/resip/dum/InviteSession.hxx @@ -22,8 +22,6 @@ class SdpContents; class InviteSession : public DialogUsage { public: - bool canProvideOffer(); - /** Called to set the offer that will be used in the next message that sends an offer. If possible, this will synchronously send the appropriate request or response. In some cases, the UAS might have to @@ -72,19 +70,22 @@ class InviteSession : public DialogUsage virtual void reject(int statusCode, WarningCategory *warning = 0); /** will send a reINVITE (current offerAnswer) or UPDATE with new Contact header */ + /** currently only supported when in the Connected state, UAC_Early states are allowed by RFC but not yet supported */ virtual void targetRefresh(const NameAddr& localUri); // Following methods are for sending requests within a dialog /** sends a refer request */ virtual void refer(const NameAddr& referTo, bool referSub = true); - virtual void refer(const NameAddr& referTo, std::unique_ptr contents, bool referSub = true); + virtual void refer(const NameAddr& referTo, const NameAddr& referredBy, bool referSub = true); + virtual void refer(const NameAddr& referTo, std::auto_ptr contents, bool referSub = true); + virtual void refer(const NameAddr& referTo, const NameAddr& referredBy, std::auto_ptr contents, bool referSub = true); /** sends a refer request with a replaces header */ virtual void refer(const NameAddr& referTo, InviteSessionHandle sessionToReplace, bool referSub = true); - virtual void refer(const NameAddr& referTo, InviteSessionHandle sessionToReplace, std::unique_ptr contents, bool referSub = true); + virtual void refer(const NameAddr& referTo, InviteSessionHandle sessionToReplace, std::auto_ptr contents, bool referSub = true); virtual void refer(const NameAddr& referTo, const CallId& replaces, bool referSub = true); - virtual void refer(const NameAddr& referTo, const CallId& replaces, std::unique_ptr contents, bool referSub = true); + virtual void refer(const NameAddr& referTo, const CallId& replaces, std::auto_ptr contents, bool referSub = true); /** sends an info request */ virtual void info(const Contents& contents); @@ -221,17 +222,23 @@ class InviteSession : public DialogUsage UAS_WaitingToRequestOffer, UAS_AcceptedWaitingAnswer, - UAS_ReceivedOfferReliable, + UAS_OfferReliable, + UAS_OfferReliableProvidedAnswer, UAS_NoOfferReliable, + UAS_ProvidedOfferReliable, UAS_FirstSentOfferReliable, UAS_FirstSentAnswerReliable, + UAS_NoAnswerReliableWaitingPrack, UAS_NegotiatedReliable, + UAS_NoAnswerReliable, UAS_SentUpdate, UAS_SentUpdateAccepted, + UAS_SentUpdateGlare, UAS_ReceivedUpdate, UAS_ReceivedUpdateWaitingAnswer, - UAS_WaitingToTerminate, UAS_WaitingToHangup + // !!!!WARNING!!!! when adding new UAS state - make sure you check if they + // need to be added to the isAccepted method } State; typedef enum @@ -279,7 +286,6 @@ class InviteSession : public DialogUsage InviteSession(DialogUsageManager& dum, Dialog& dialog); virtual ~InviteSession(); - virtual void dialogDestroyed(const SipMessage& msg); virtual void onReadyToSend(SipMessage& msg); virtual void flowTerminated(); @@ -320,10 +326,10 @@ class InviteSession : public DialogUsage static Data toData(State state); void transition(State target); - std::unique_ptr getOfferAnswer(const SipMessage& msg); - bool isReliable(const SipMessage& msg); - static std::unique_ptr makeOfferAnswer(const Contents& offerAnswer); - static std::unique_ptr makeOfferAnswer(const Contents& offerAnswer, const Contents* alternative); + std::auto_ptr getOfferAnswer(const SipMessage& msg); + bool isReliable(const SipMessage& msg) const; + static std::auto_ptr makeOfferAnswer(const Contents& offerAnswer); + static std::auto_ptr makeOfferAnswer(const Contents& offerAnswer, const Contents* alternative); static void setOfferAnswer(SipMessage& msg, const Contents& offerAnswer, const Contents* alternative = 0); static void setOfferAnswer(SipMessage& msg, const Contents* offerAnswer); void provideProposedOffer(); @@ -355,17 +361,16 @@ class InviteSession : public DialogUsage NitState mNitState; NitState mServerNitState; - std::unique_ptr mCurrentLocalOfferAnswer; - std::unique_ptr mProposedLocalOfferAnswer; + std::auto_ptr mCurrentLocalOfferAnswer; // This gets set with mProposedLocalOfferAnswer after we receive an SDP answer from the remote end or when we send and SDP answer to the remote end + std::auto_ptr mProposedLocalOfferAnswer; // This get set when we send an offer to the remote end - std::unique_ptr mCurrentRemoteOfferAnswer; - std::unique_ptr mProposedRemoteOfferAnswer; + std::auto_ptr mCurrentRemoteOfferAnswer; // This gets set with mProposedRemoteOfferAnswer after we send an SDP answer, or when we receive an SDP answer from the remote end + std::auto_ptr mProposedRemoteOfferAnswer; // This gets set when we receive an offer from the remote end - SharedPtr mLastLocalSessionModification; // last UPDATE or reINVITE sent + SharedPtr mLastLocalSessionModification; // last UPDATE or reINVITE sent SharedPtr mLastRemoteSessionModification; // last UPDATE or reINVITE received - SharedPtr mInvite200; // 200 OK for reINVITE for retransmissions - SharedPtr mLastNitResponse; // - //?dcm? -- ptr, delete when not needed? + SharedPtr mInvite200; // 200 OK for reINVITE for retransmissions + SharedPtr mLastNitResponse; SipMessage mLastReferNoSubRequest; @@ -396,7 +401,7 @@ class InviteSession : public DialogUsage SharedPtr mLastSentNITRequest; DialogUsageManager::EncryptionLevel mCurrentEncryptionLevel; - DialogUsageManager::EncryptionLevel mProposedEncryptionLevel; // UPDATE or RE-INVITE + DialogUsageManager::EncryptionLevel mProposedEncryptionLevel; // UPDATE or RE-INVITE or PRACK EndReason mEndReason; @@ -406,7 +411,7 @@ class InviteSession : public DialogUsage // Used to respond to 2xx retransmissions. typedef HashMap > AckMap; AckMap mAcks; - + private: friend class Dialog; friend class DialogUsageManager; diff --git a/src/libs/resiprocate/resip/dum/InviteSessionCreator.cxx b/src/libs/resiprocate/resip/dum/InviteSessionCreator.cxx index 5e16d167..8c66368e 100644 --- a/src/libs/resiprocate/resip/dum/InviteSessionCreator.cxx +++ b/src/libs/resiprocate/resip/dum/InviteSessionCreator.cxx @@ -29,7 +29,7 @@ InviteSessionCreator::InviteSessionCreator(DialogUsageManager& dum, DumHelper::setOutgoingEncryptionLevel(*mLastRequest, level); if(mDum.getMasterProfile()->getSupportedOptionTags().find(Token(Symbols::Timer))) { - assert(userProfile.get()); + resip_assert(userProfile.get()); if(userProfile->getDefaultSessionTime() >= 90) { getLastRequest()->header(h_SessionExpires).value() = userProfile->getDefaultSessionTime(); @@ -37,7 +37,7 @@ InviteSessionCreator::InviteSessionCreator(DialogUsageManager& dum, } } - std::unique_ptr initialOffer; + std::auto_ptr initialOffer; if (initial) { if (alternative) @@ -51,7 +51,7 @@ InviteSessionCreator::InviteSessionCreator(DialogUsageManager& dum, { initialOffer.reset(initial->clone()); } - getLastRequest()->setContents(std::move(initialOffer)); + getLastRequest()->setContents(initialOffer); } //100rel switch(mDum.getMasterProfile()->getUacReliableProvisionalMode()) @@ -60,13 +60,14 @@ InviteSessionCreator::InviteSessionCreator(DialogUsageManager& dum, //no support, do nothing break; case MasterProfile::Supported: + case MasterProfile::SupportedEssential: getLastRequest()->header(h_Supporteds).push_back(Token(Symbols::C100rel)); break; case MasterProfile::Required: getLastRequest()->header(h_Requires).push_back(Token(Symbols::C100rel)); break; default: - assert(0); + resip_assert(0); } } @@ -77,7 +78,7 @@ InviteSessionCreator::~InviteSessionCreator() void InviteSessionCreator::end() { - assert(0); + resip_assert(0); } void diff --git a/src/libs/resiprocate/resip/dum/InviteSessionHandler.cxx b/src/libs/resiprocate/resip/dum/InviteSessionHandler.cxx index 167c1099..36bc82b8 100644 --- a/src/libs/resiprocate/resip/dum/InviteSessionHandler.cxx +++ b/src/libs/resiprocate/resip/dum/InviteSessionHandler.cxx @@ -14,7 +14,7 @@ InviteSessionHandler::onEarlyMedia(ClientInviteSessionHandle h, const SipMessage if(!mGenericOfferAnswer) { const SdpContents* sdp = dynamic_cast(&body); - assert(sdp); + resip_assert(sdp); onEarlyMedia(h, msg, *sdp); } } @@ -69,7 +69,7 @@ InviteSessionHandler::onAnswer(InviteSessionHandle h, const SipMessage& msg, con if(!mGenericOfferAnswer) { const SdpContents* sdp = dynamic_cast(&body); - assert(sdp); + resip_assert(sdp); onAnswer(h, msg, *sdp); } } @@ -80,7 +80,7 @@ InviteSessionHandler::onOffer(InviteSessionHandle h, const SipMessage& msg, cons if(!mGenericOfferAnswer) { const SdpContents* sdp = dynamic_cast(&body); - assert(sdp); + resip_assert(sdp); onOffer(h, msg, *sdp); } } @@ -96,7 +96,7 @@ InviteSessionHandler::onRemoteAnswerChanged(InviteSessionHandle h, const SipMess if(!mGenericOfferAnswer) { const SdpContents* sdp = dynamic_cast(&body); - assert(sdp); + resip_assert(sdp); onRemoteSdpChanged(h, msg, *sdp); } } @@ -117,6 +117,11 @@ InviteSessionHandler::onConnectedConfirmed(InviteSessionHandle handle, const Sip { } +void +InviteSessionHandler::onPrack(ServerInviteSessionHandle, const SipMessage &msg) +{ +} + void InviteSessionHandler::onFlowTerminated(InviteSessionHandle) { diff --git a/src/libs/resiprocate/resip/dum/InviteSessionHandler.hxx b/src/libs/resiprocate/resip/dum/InviteSessionHandler.hxx index 05fcc705..844a79bc 100644 --- a/src/libs/resiprocate/resip/dum/InviteSessionHandler.hxx +++ b/src/libs/resiprocate/resip/dum/InviteSessionHandler.hxx @@ -67,6 +67,9 @@ class InviteSessionHandler /// called when ACK (with out an answer) is received for initial invite (UAS) virtual void onConnectedConfirmed(InviteSessionHandle, const SipMessage &msg); + /// called when PRACK is received for a reliable provisional answer (UAS) + virtual void onPrack(ServerInviteSessionHandle, const SipMessage &msg); + /** UAC gets no final response within the stale call timeout (default is 3 * minutes). This is just a notification. After the notification is * called, the InviteSession will then call @@ -91,7 +94,7 @@ class InviteSessionHandler LocalCancel, RemoteCancel, Rejected, //Only as UAS, UAC has distinct onFailure callback - Referred + Referred //!slg! - This is really Redirected - not sure why it is called Referred. Only gets used when we send a redirect (ie: 302). }; virtual void onTerminated(InviteSessionHandle, InviteSessionHandler::TerminatedReason reason, const SipMessage* related=0)=0; @@ -141,6 +144,8 @@ class InviteSessionHandler virtual void onOfferRejected(InviteSessionHandle, const SipMessage* msg)=0; /// called when INFO message is received + /// the application must call acceptNIT() or rejectNIT() + /// once it is ready for another message. virtual void onInfo(InviteSessionHandle, const SipMessage& msg)=0; /// called when response to INFO message is received diff --git a/src/libs/resiprocate/resip/dum/KeepAliveManager.cxx b/src/libs/resiprocate/resip/dum/KeepAliveManager.cxx index 4b10f248..0f34924d 100644 --- a/src/libs/resiprocate/resip/dum/KeepAliveManager.cxx +++ b/src/libs/resiprocate/resip/dum/KeepAliveManager.cxx @@ -5,6 +5,7 @@ #include "resip/dum/DialogUsageManager.hxx" #include "resip/stack/Helper.hxx" #include "rutil/Logger.hxx" +#include "rutil/TransportType.hxx" #include "resip/stack/SipStack.hxx" #define RESIPROCATE_SUBSYSTEM Subsystem::DUM @@ -17,7 +18,7 @@ int KeepAliveManager::mKeepAlivePongTimeoutMs = 10000; // Defaults to 10000ms ( void KeepAliveManager::add(const Tuple& target, int keepAliveInterval, bool targetSupportsOutbound) { - assert(mDum); + resip_assert(mDum); NetworkAssociationMap::iterator it = mNetworkAssociations.find(target); if (it == mNetworkAssociations.end()) { @@ -87,7 +88,7 @@ KeepAliveManager::remove(const Tuple& target) void KeepAliveManager::process(KeepAliveTimeout& timeout) { - assert(mDum); + resip_assert(mDum); static KeepAliveMessage msg; NetworkAssociationMap::iterator it = mNetworkAssociations.find(timeout.target()); if (it != mNetworkAssociations.end() && timeout.id() == it->second.id) @@ -102,10 +103,10 @@ KeepAliveManager::process(KeepAliveTimeout& timeout) { // Assert if keep alive interval is too short in order to properly detect // missing pong responses - ie. interval must be greater than 10s - assert((it->second.keepAliveInterval*1000) > mKeepAlivePongTimeoutMs); + resip_assert((it->second.keepAliveInterval*1000) > mKeepAlivePongTimeoutMs); // Start pong timeout if transport is TCP based (note: pong processing of Stun messaging is currently not implemented) - if(it->first.getType() == TCP || it->first.getType() == TLS) + if(isReliable(it->first.getType())) { DebugLog( << "Starting pong timeout for keepalive id " << it->second.id); KeepAlivePongTimeout t(it->first, it->second.id); @@ -131,7 +132,7 @@ KeepAliveManager::process(KeepAliveTimeout& timeout) void KeepAliveManager::process(KeepAlivePongTimeout& timeout) { - assert(mDum); + resip_assert(mDum); NetworkAssociationMap::iterator it = mNetworkAssociations.find(timeout.target()); if (it != mNetworkAssociations.end() && timeout.id() == it->second.id) { diff --git a/src/libs/resiprocate/resip/dum/Makefile.am b/src/libs/resiprocate/resip/dum/Makefile.am new file mode 100644 index 00000000..6cecd635 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/Makefile.am @@ -0,0 +1,266 @@ +# $Id$ + +EXTRA_DIST = Doxyfile +EXTRA_DIST += *.vcxproj +EXTRA_DIST += doc + +SUBDIRS = . test + +#AM_CXXFLAGS = -DUSE_ARES +AM_CXXFLAGS = -I $(top_srcdir) + +lib_LTLIBRARIES = libdum.la + +libdum_la_LIBADD = ../stack/libresip.la +libdum_la_LIBADD += ../../rutil/librutil.la +libdum_la_LIBADD += @LIBSSL_LIBADD@ @LIBRADIUS_LIBADD@ +libdum_la_LIBADD += @LIBSTL_LIBADD@ +libdum_la_LDFLAGS = @LIBTOOL_VERSION_RELEASE@ -export-dynamic + +libdum_la_SOURCES = \ + AppDialog.cxx \ + AppDialogSet.cxx \ + AppDialogSetFactory.cxx \ + BaseCreator.cxx \ + BaseUsage.cxx \ + UserAuthInfo.cxx \ + BaseSubscription.cxx \ + ChallengeInfo.cxx \ + ClientAuthManager.cxx \ + ClientAuthExtension.cxx \ + ClientInviteSession.cxx \ + ClientOutOfDialogReq.cxx \ + ClientPagerMessage.cxx \ + ClientPublication.cxx \ + ClientRegistration.cxx \ + ClientSubscription.cxx \ + ContactInstanceRecord.cxx \ + DefaultServerReferHandler.cxx \ + DestroyUsage.cxx \ + Dialog.cxx \ + DialogEventInfo.cxx \ + DialogEventStateManager.cxx \ + DialogId.cxx \ + DialogSet.cxx \ + DialogSetId.cxx \ + DialogUsage.cxx \ + DialogUsageManager.cxx \ + DumProcessHandler.cxx \ + DumThread.cxx \ + DumTimeout.cxx \ + EncryptionRequest.cxx \ + HandleException.cxx \ + HandleManager.cxx \ + Handle.cxx \ + Handled.cxx \ + InMemoryRegistrationDatabase.cxx \ + InMemorySyncPubDb.cxx \ + InMemorySyncRegDb.cxx \ + InviteSession.cxx \ + InviteSessionCreator.cxx \ + InviteSessionHandler.cxx \ + MergedRequestKey.cxx \ + NonDialogUsage.cxx \ + OutOfDialogReqCreator.cxx \ + PagerMessageCreator.cxx \ + MasterProfile.cxx \ + UserProfile.cxx \ + Profile.cxx \ + PublicationCreator.cxx \ + RADIUSServerAuthManager.cxx \ + RedirectManager.cxx \ + RegistrationCreator.cxx \ + RegistrationHandler.cxx \ + ServerAuthManager.cxx \ + ServerInviteSession.cxx \ + ServerOutOfDialogReq.cxx \ + ServerPagerMessage.cxx \ + ServerPublication.cxx \ + ServerRegistration.cxx \ + ServerSubscription.cxx \ + SubscriptionHandler.cxx \ + SubscriptionCreator.cxx \ + SubscriptionState.cxx \ + TlsPeerAuthManager.cxx \ + TlsPeerIdentityInfoMessage.cxx \ + WsCookieAuthManager.cxx \ + KeepAliveManager.cxx \ + KeepAliveTimeout.cxx \ + NetworkAssociation.cxx \ + DumDecrypted.cxx \ + CertMessage.cxx \ + DumFeatureChain.cxx \ + DumFeatureMessage.cxx \ + IdentityHandler.cxx \ + TargetCommand.cxx \ + DumFeature.cxx \ + OutgoingEvent.cxx \ + HttpProvider.cxx \ + HttpGetMessage.cxx \ + DumHelper.cxx \ + MergedRequestRemovalCommand.cxx + +if USE_SSL +libdum_la_SOURCES += \ + ssl/EncryptionManager.cxx +endif + + +dumincludedir = $(includedir)/resip/dum +nobase_duminclude_HEADERS = AppDialog.hxx \ + AppDialogSetFactory.hxx \ + AppDialogSet.hxx \ + BaseCreator.hxx \ + BaseSubscription.hxx \ + BaseUsage.hxx \ + CertMessage.hxx \ + ChallengeInfo.hxx \ + ClientAuthExtension.hxx \ + ClientAuthManager.hxx \ + ClientInviteSession.hxx \ + ClientOutOfDialogReq.hxx \ + ClientPagerMessage.hxx \ + ClientPublication.hxx \ + ClientRegistration.hxx \ + ClientSubscriptionFunctor.hxx \ + ClientSubscription.hxx \ + ContactInstanceRecord.hxx \ + DefaultServerReferHandler.hxx \ + DestroyUsage.hxx \ + DialogEventHandler.hxx \ + DialogEventInfo.hxx \ + DialogEventStateManager.hxx \ + Dialog.hxx \ + DialogId.hxx \ + DialogSetHandler.hxx \ + DialogSet.hxx \ + DialogSetId.hxx \ + DialogUsage.hxx \ + DialogUsageManager.hxx \ + DumCommand.hxx \ + DumDecrypted.hxx \ + DumException.hxx \ + DumFeatureChain.hxx \ + DumFeature.hxx \ + DumFeatureMessage.hxx \ + DumHelper.hxx \ + DumProcessHandler.hxx \ + DumShutdownHandler.hxx \ + DumThread.hxx \ + DumTimeout.hxx \ + EncryptionRequest.hxx \ + EventDispatcher.hxx \ + ExternalMessageBase.hxx \ + ExternalMessageHandler.hxx \ + ExternalTimer.hxx \ + Handled.hxx \ + HandleException.hxx \ + Handle.hxx \ + HandleManager.hxx \ + Handles.hxx \ + HttpGetMessage.hxx \ + HttpProvider.hxx \ + IdentityHandler.hxx \ + InMemoryRegistrationDatabase.hxx \ + InMemorySyncPubDb.hxx \ + InMemorySyncRegDb.hxx \ + InviteDialogs.hxx \ + InviteSessionCreator.hxx \ + InviteSessionHandler.hxx \ + InviteSession.hxx \ + KeepAliveManager.hxx \ + KeepAliveTimeout.hxx \ + MasterProfile.hxx \ + MergedRequestKey.hxx \ + MergedRequestRemovalCommand.hxx \ + NetworkAssociation.hxx \ + NonDialogUsage.hxx \ + OutgoingEvent.hxx \ + OutOfDialogHandler.hxx \ + OutOfDialogReqCreator.hxx \ + PagerMessageCreator.hxx \ + PagerMessageHandler.hxx \ + Postable.hxx \ + Profile.hxx \ + PublicationCreator.hxx \ + PublicationHandler.hxx \ + PublicationPersistenceManager.hxx \ + RADIUSServerAuthManager.hxx \ + RedirectHandler.hxx \ + RedirectManager.hxx \ + RefCountedDestroyer.hxx \ + RegistrationCreator.hxx \ + RegistrationHandler.hxx \ + RegistrationPersistenceManager.hxx \ + RemoteCertStore.hxx \ + RequestValidationHandler.hxx \ + ServerAuthManager.hxx \ + ServerInviteSession.hxx \ + ServerOutOfDialogReq.hxx \ + ServerPagerMessage.hxx \ + ServerPublication.hxx \ + ServerRegistration.hxx \ + ServerSubscriptionFunctor.hxx \ + ServerSubscription.hxx \ + ssl/EncryptionManager.hxx \ + SubscriptionCreator.hxx \ + SubscriptionHandler.hxx \ + SubscriptionPersistenceManager.hxx \ + SubscriptionState.hxx \ + TargetCommand.hxx \ + TlsPeerAuthManager.hxx \ + TlsPeerIdentityInfoMessage.hxx \ + WsCookieAuthManager.hxx \ + UsageUseException.hxx \ + UserAuthInfo.hxx \ + UserProfile.hxx + +############################################################################## +# +# The Vovida Software License, Version 1.0 +# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The names "VOCAL", "Vovida Open Communication Application Library", +# and "Vovida Open Communication Application Library (VOCAL)" must +# not be used to endorse or promote products derived from this +# software without prior written permission. For written +# permission, please contact vocal@vovida.org. +# +# 4. Products derived from this software may not be called "VOCAL", nor +# may "VOCAL" appear in their name, without prior written +# permission of Vovida Networks, Inc. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. +# +# ==================================================================== +# +# This software consists of voluntary contributions made by Vovida +# Networks, Inc. and many individuals on behalf of Vovida Networks, +# Inc. For more information on Vovida Networks, Inc., please see +# . +# +############################################################################## diff --git a/src/libs/resiprocate/resip/dum/Makefile.in b/src/libs/resiprocate/resip/dum/Makefile.in new file mode 100644 index 00000000..84b78791 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/Makefile.in @@ -0,0 +1,1430 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# $Id$ + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@USE_SSL_TRUE@am__append_1 = \ +@USE_SSL_TRUE@ ssl/EncryptionManager.cxx + +subdir = resip/dum +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_have_epoll.m4 \ + $(top_srcdir)/m4/gprefver.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(nobase_duminclude_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(dumincludedir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libdum_la_DEPENDENCIES = ../stack/libresip.la ../../rutil/librutil.la +am__libdum_la_SOURCES_DIST = AppDialog.cxx AppDialogSet.cxx \ + AppDialogSetFactory.cxx BaseCreator.cxx BaseUsage.cxx \ + UserAuthInfo.cxx BaseSubscription.cxx ChallengeInfo.cxx \ + ClientAuthManager.cxx ClientAuthExtension.cxx \ + ClientInviteSession.cxx ClientOutOfDialogReq.cxx \ + ClientPagerMessage.cxx ClientPublication.cxx \ + ClientRegistration.cxx ClientSubscription.cxx \ + ContactInstanceRecord.cxx DefaultServerReferHandler.cxx \ + DestroyUsage.cxx Dialog.cxx DialogEventInfo.cxx \ + DialogEventStateManager.cxx DialogId.cxx DialogSet.cxx \ + DialogSetId.cxx DialogUsage.cxx DialogUsageManager.cxx \ + DumProcessHandler.cxx DumThread.cxx DumTimeout.cxx \ + EncryptionRequest.cxx HandleException.cxx HandleManager.cxx \ + Handle.cxx Handled.cxx InMemoryRegistrationDatabase.cxx \ + InMemorySyncPubDb.cxx InMemorySyncRegDb.cxx InviteSession.cxx \ + InviteSessionCreator.cxx InviteSessionHandler.cxx \ + MergedRequestKey.cxx NonDialogUsage.cxx \ + OutOfDialogReqCreator.cxx PagerMessageCreator.cxx \ + MasterProfile.cxx UserProfile.cxx Profile.cxx \ + PublicationCreator.cxx RADIUSServerAuthManager.cxx \ + RedirectManager.cxx RegistrationCreator.cxx \ + RegistrationHandler.cxx ServerAuthManager.cxx \ + ServerInviteSession.cxx ServerOutOfDialogReq.cxx \ + ServerPagerMessage.cxx ServerPublication.cxx \ + ServerRegistration.cxx ServerSubscription.cxx \ + SubscriptionHandler.cxx SubscriptionCreator.cxx \ + SubscriptionState.cxx TlsPeerAuthManager.cxx \ + TlsPeerIdentityInfoMessage.cxx WsCookieAuthManager.cxx \ + KeepAliveManager.cxx KeepAliveTimeout.cxx \ + NetworkAssociation.cxx DumDecrypted.cxx CertMessage.cxx \ + DumFeatureChain.cxx DumFeatureMessage.cxx IdentityHandler.cxx \ + TargetCommand.cxx DumFeature.cxx OutgoingEvent.cxx \ + HttpProvider.cxx HttpGetMessage.cxx DumHelper.cxx \ + MergedRequestRemovalCommand.cxx ssl/EncryptionManager.cxx +am__dirstamp = $(am__leading_dot)dirstamp +@USE_SSL_TRUE@am__objects_1 = ssl/EncryptionManager.lo +am_libdum_la_OBJECTS = AppDialog.lo AppDialogSet.lo \ + AppDialogSetFactory.lo BaseCreator.lo BaseUsage.lo \ + UserAuthInfo.lo BaseSubscription.lo ChallengeInfo.lo \ + ClientAuthManager.lo ClientAuthExtension.lo \ + ClientInviteSession.lo ClientOutOfDialogReq.lo \ + ClientPagerMessage.lo ClientPublication.lo \ + ClientRegistration.lo ClientSubscription.lo \ + ContactInstanceRecord.lo DefaultServerReferHandler.lo \ + DestroyUsage.lo Dialog.lo DialogEventInfo.lo \ + DialogEventStateManager.lo DialogId.lo DialogSet.lo \ + DialogSetId.lo DialogUsage.lo DialogUsageManager.lo \ + DumProcessHandler.lo DumThread.lo DumTimeout.lo \ + EncryptionRequest.lo HandleException.lo HandleManager.lo \ + Handle.lo Handled.lo InMemoryRegistrationDatabase.lo \ + InMemorySyncPubDb.lo InMemorySyncRegDb.lo InviteSession.lo \ + InviteSessionCreator.lo InviteSessionHandler.lo \ + MergedRequestKey.lo NonDialogUsage.lo OutOfDialogReqCreator.lo \ + PagerMessageCreator.lo MasterProfile.lo UserProfile.lo \ + Profile.lo PublicationCreator.lo RADIUSServerAuthManager.lo \ + RedirectManager.lo RegistrationCreator.lo \ + RegistrationHandler.lo ServerAuthManager.lo \ + ServerInviteSession.lo ServerOutOfDialogReq.lo \ + ServerPagerMessage.lo ServerPublication.lo \ + ServerRegistration.lo ServerSubscription.lo \ + SubscriptionHandler.lo SubscriptionCreator.lo \ + SubscriptionState.lo TlsPeerAuthManager.lo \ + TlsPeerIdentityInfoMessage.lo WsCookieAuthManager.lo \ + KeepAliveManager.lo KeepAliveTimeout.lo NetworkAssociation.lo \ + DumDecrypted.lo CertMessage.lo DumFeatureChain.lo \ + DumFeatureMessage.lo IdentityHandler.lo TargetCommand.lo \ + DumFeature.lo OutgoingEvent.lo HttpProvider.lo \ + HttpGetMessage.lo DumHelper.lo MergedRequestRemovalCommand.lo \ + $(am__objects_1) +libdum_la_OBJECTS = $(am_libdum_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libdum_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(libdum_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/AppDialog.Plo \ + ./$(DEPDIR)/AppDialogSet.Plo \ + ./$(DEPDIR)/AppDialogSetFactory.Plo \ + ./$(DEPDIR)/BaseCreator.Plo ./$(DEPDIR)/BaseSubscription.Plo \ + ./$(DEPDIR)/BaseUsage.Plo ./$(DEPDIR)/CertMessage.Plo \ + ./$(DEPDIR)/ChallengeInfo.Plo \ + ./$(DEPDIR)/ClientAuthExtension.Plo \ + ./$(DEPDIR)/ClientAuthManager.Plo \ + ./$(DEPDIR)/ClientInviteSession.Plo \ + ./$(DEPDIR)/ClientOutOfDialogReq.Plo \ + ./$(DEPDIR)/ClientPagerMessage.Plo \ + ./$(DEPDIR)/ClientPublication.Plo \ + ./$(DEPDIR)/ClientRegistration.Plo \ + ./$(DEPDIR)/ClientSubscription.Plo \ + ./$(DEPDIR)/ContactInstanceRecord.Plo \ + ./$(DEPDIR)/DefaultServerReferHandler.Plo \ + ./$(DEPDIR)/DestroyUsage.Plo ./$(DEPDIR)/Dialog.Plo \ + ./$(DEPDIR)/DialogEventInfo.Plo \ + ./$(DEPDIR)/DialogEventStateManager.Plo \ + ./$(DEPDIR)/DialogId.Plo ./$(DEPDIR)/DialogSet.Plo \ + ./$(DEPDIR)/DialogSetId.Plo ./$(DEPDIR)/DialogUsage.Plo \ + ./$(DEPDIR)/DialogUsageManager.Plo \ + ./$(DEPDIR)/DumDecrypted.Plo ./$(DEPDIR)/DumFeature.Plo \ + ./$(DEPDIR)/DumFeatureChain.Plo \ + ./$(DEPDIR)/DumFeatureMessage.Plo ./$(DEPDIR)/DumHelper.Plo \ + ./$(DEPDIR)/DumProcessHandler.Plo ./$(DEPDIR)/DumThread.Plo \ + ./$(DEPDIR)/DumTimeout.Plo ./$(DEPDIR)/EncryptionRequest.Plo \ + ./$(DEPDIR)/Handle.Plo ./$(DEPDIR)/HandleException.Plo \ + ./$(DEPDIR)/HandleManager.Plo ./$(DEPDIR)/Handled.Plo \ + ./$(DEPDIR)/HttpGetMessage.Plo ./$(DEPDIR)/HttpProvider.Plo \ + ./$(DEPDIR)/IdentityHandler.Plo \ + ./$(DEPDIR)/InMemoryRegistrationDatabase.Plo \ + ./$(DEPDIR)/InMemorySyncPubDb.Plo \ + ./$(DEPDIR)/InMemorySyncRegDb.Plo \ + ./$(DEPDIR)/InviteSession.Plo \ + ./$(DEPDIR)/InviteSessionCreator.Plo \ + ./$(DEPDIR)/InviteSessionHandler.Plo \ + ./$(DEPDIR)/KeepAliveManager.Plo \ + ./$(DEPDIR)/KeepAliveTimeout.Plo ./$(DEPDIR)/MasterProfile.Plo \ + ./$(DEPDIR)/MergedRequestKey.Plo \ + ./$(DEPDIR)/MergedRequestRemovalCommand.Plo \ + ./$(DEPDIR)/NetworkAssociation.Plo \ + ./$(DEPDIR)/NonDialogUsage.Plo \ + ./$(DEPDIR)/OutOfDialogReqCreator.Plo \ + ./$(DEPDIR)/OutgoingEvent.Plo \ + ./$(DEPDIR)/PagerMessageCreator.Plo ./$(DEPDIR)/Profile.Plo \ + ./$(DEPDIR)/PublicationCreator.Plo \ + ./$(DEPDIR)/RADIUSServerAuthManager.Plo \ + ./$(DEPDIR)/RedirectManager.Plo \ + ./$(DEPDIR)/RegistrationCreator.Plo \ + ./$(DEPDIR)/RegistrationHandler.Plo \ + ./$(DEPDIR)/ServerAuthManager.Plo \ + ./$(DEPDIR)/ServerInviteSession.Plo \ + ./$(DEPDIR)/ServerOutOfDialogReq.Plo \ + ./$(DEPDIR)/ServerPagerMessage.Plo \ + ./$(DEPDIR)/ServerPublication.Plo \ + ./$(DEPDIR)/ServerRegistration.Plo \ + ./$(DEPDIR)/ServerSubscription.Plo \ + ./$(DEPDIR)/SubscriptionCreator.Plo \ + ./$(DEPDIR)/SubscriptionHandler.Plo \ + ./$(DEPDIR)/SubscriptionState.Plo \ + ./$(DEPDIR)/TargetCommand.Plo \ + ./$(DEPDIR)/TlsPeerAuthManager.Plo \ + ./$(DEPDIR)/TlsPeerIdentityInfoMessage.Plo \ + ./$(DEPDIR)/UserAuthInfo.Plo ./$(DEPDIR)/UserProfile.Plo \ + ./$(DEPDIR)/WsCookieAuthManager.Plo \ + ssl/$(DEPDIR)/EncryptionManager.Plo +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +SOURCES = $(libdum_la_SOURCES) +DIST_SOURCES = $(am__libdum_la_SOURCES_DIST) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(nobase_duminclude_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DEPS_PYTHON_CFLAGS = @DEPS_PYTHON_CFLAGS@ +DEPS_PYTHON_LIBS = @DEPS_PYTHON_LIBS@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GPERF = @GPERF@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBARES_LIBADD = @LIBARES_LIBADD@ +LIBGEOIP_LIBADD = @LIBGEOIP_LIBADD@ +LIBLOG_LIBADD = @LIBLOG_LIBADD@ +LIBMYSQL_LIBADD = @LIBMYSQL_LIBADD@ +LIBNETSNMP_LDADD = @LIBNETSNMP_LDADD@ +LIBOBJS = @LIBOBJS@ +LIBPOPT_LIBADD = @LIBPOPT_LIBADD@ +LIBPOSTGRESQL_LIBADD = @LIBPOSTGRESQL_LIBADD@ +LIBPTHREAD_LIBADD = @LIBPTHREAD_LIBADD@ +LIBRADIUS_LIBADD = @LIBRADIUS_LIBADD@ +LIBS = @LIBS@ +LIBSSL_LIBADD = @LIBSSL_LIBADD@ +LIBSTL_LIBADD = @LIBSTL_LIBADD@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_VERSION_RELEASE = @LIBTOOL_VERSION_RELEASE@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PYCXX_SRCDIR = @PYCXX_SRCDIR@ +QT5_CFLAGS = @QT5_CFLAGS@ +QT5_LIBS = @QT5_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SO_RELEASE = @SO_RELEASE@ +STRIP = @STRIP@ +TP_QT5_CFLAGS = @TP_QT5_CFLAGS@ +TP_QT5_LIBS = @TP_QT5_LIBS@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +reproplugindir = @reproplugindir@ +returnpkglibdir = @returnpkglibdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = Doxyfile *.vcxproj doc +SUBDIRS = . test + +#AM_CXXFLAGS = -DUSE_ARES +AM_CXXFLAGS = -I $(top_srcdir) +lib_LTLIBRARIES = libdum.la +libdum_la_LIBADD = ../stack/libresip.la ../../rutil/librutil.la \ + @LIBSSL_LIBADD@ @LIBRADIUS_LIBADD@ @LIBSTL_LIBADD@ \ + $(am__empty) +libdum_la_LDFLAGS = @LIBTOOL_VERSION_RELEASE@ -export-dynamic +libdum_la_SOURCES = AppDialog.cxx AppDialogSet.cxx \ + AppDialogSetFactory.cxx BaseCreator.cxx BaseUsage.cxx \ + UserAuthInfo.cxx BaseSubscription.cxx ChallengeInfo.cxx \ + ClientAuthManager.cxx ClientAuthExtension.cxx \ + ClientInviteSession.cxx ClientOutOfDialogReq.cxx \ + ClientPagerMessage.cxx ClientPublication.cxx \ + ClientRegistration.cxx ClientSubscription.cxx \ + ContactInstanceRecord.cxx DefaultServerReferHandler.cxx \ + DestroyUsage.cxx Dialog.cxx DialogEventInfo.cxx \ + DialogEventStateManager.cxx DialogId.cxx DialogSet.cxx \ + DialogSetId.cxx DialogUsage.cxx DialogUsageManager.cxx \ + DumProcessHandler.cxx DumThread.cxx DumTimeout.cxx \ + EncryptionRequest.cxx HandleException.cxx HandleManager.cxx \ + Handle.cxx Handled.cxx InMemoryRegistrationDatabase.cxx \ + InMemorySyncPubDb.cxx InMemorySyncRegDb.cxx InviteSession.cxx \ + InviteSessionCreator.cxx InviteSessionHandler.cxx \ + MergedRequestKey.cxx NonDialogUsage.cxx \ + OutOfDialogReqCreator.cxx PagerMessageCreator.cxx \ + MasterProfile.cxx UserProfile.cxx Profile.cxx \ + PublicationCreator.cxx RADIUSServerAuthManager.cxx \ + RedirectManager.cxx RegistrationCreator.cxx \ + RegistrationHandler.cxx ServerAuthManager.cxx \ + ServerInviteSession.cxx ServerOutOfDialogReq.cxx \ + ServerPagerMessage.cxx ServerPublication.cxx \ + ServerRegistration.cxx ServerSubscription.cxx \ + SubscriptionHandler.cxx SubscriptionCreator.cxx \ + SubscriptionState.cxx TlsPeerAuthManager.cxx \ + TlsPeerIdentityInfoMessage.cxx WsCookieAuthManager.cxx \ + KeepAliveManager.cxx KeepAliveTimeout.cxx \ + NetworkAssociation.cxx DumDecrypted.cxx CertMessage.cxx \ + DumFeatureChain.cxx DumFeatureMessage.cxx IdentityHandler.cxx \ + TargetCommand.cxx DumFeature.cxx OutgoingEvent.cxx \ + HttpProvider.cxx HttpGetMessage.cxx DumHelper.cxx \ + MergedRequestRemovalCommand.cxx $(am__append_1) +dumincludedir = $(includedir)/resip/dum +nobase_duminclude_HEADERS = AppDialog.hxx \ + AppDialogSetFactory.hxx \ + AppDialogSet.hxx \ + BaseCreator.hxx \ + BaseSubscription.hxx \ + BaseUsage.hxx \ + CertMessage.hxx \ + ChallengeInfo.hxx \ + ClientAuthExtension.hxx \ + ClientAuthManager.hxx \ + ClientInviteSession.hxx \ + ClientOutOfDialogReq.hxx \ + ClientPagerMessage.hxx \ + ClientPublication.hxx \ + ClientRegistration.hxx \ + ClientSubscriptionFunctor.hxx \ + ClientSubscription.hxx \ + ContactInstanceRecord.hxx \ + DefaultServerReferHandler.hxx \ + DestroyUsage.hxx \ + DialogEventHandler.hxx \ + DialogEventInfo.hxx \ + DialogEventStateManager.hxx \ + Dialog.hxx \ + DialogId.hxx \ + DialogSetHandler.hxx \ + DialogSet.hxx \ + DialogSetId.hxx \ + DialogUsage.hxx \ + DialogUsageManager.hxx \ + DumCommand.hxx \ + DumDecrypted.hxx \ + DumException.hxx \ + DumFeatureChain.hxx \ + DumFeature.hxx \ + DumFeatureMessage.hxx \ + DumHelper.hxx \ + DumProcessHandler.hxx \ + DumShutdownHandler.hxx \ + DumThread.hxx \ + DumTimeout.hxx \ + EncryptionRequest.hxx \ + EventDispatcher.hxx \ + ExternalMessageBase.hxx \ + ExternalMessageHandler.hxx \ + ExternalTimer.hxx \ + Handled.hxx \ + HandleException.hxx \ + Handle.hxx \ + HandleManager.hxx \ + Handles.hxx \ + HttpGetMessage.hxx \ + HttpProvider.hxx \ + IdentityHandler.hxx \ + InMemoryRegistrationDatabase.hxx \ + InMemorySyncPubDb.hxx \ + InMemorySyncRegDb.hxx \ + InviteDialogs.hxx \ + InviteSessionCreator.hxx \ + InviteSessionHandler.hxx \ + InviteSession.hxx \ + KeepAliveManager.hxx \ + KeepAliveTimeout.hxx \ + MasterProfile.hxx \ + MergedRequestKey.hxx \ + MergedRequestRemovalCommand.hxx \ + NetworkAssociation.hxx \ + NonDialogUsage.hxx \ + OutgoingEvent.hxx \ + OutOfDialogHandler.hxx \ + OutOfDialogReqCreator.hxx \ + PagerMessageCreator.hxx \ + PagerMessageHandler.hxx \ + Postable.hxx \ + Profile.hxx \ + PublicationCreator.hxx \ + PublicationHandler.hxx \ + PublicationPersistenceManager.hxx \ + RADIUSServerAuthManager.hxx \ + RedirectHandler.hxx \ + RedirectManager.hxx \ + RefCountedDestroyer.hxx \ + RegistrationCreator.hxx \ + RegistrationHandler.hxx \ + RegistrationPersistenceManager.hxx \ + RemoteCertStore.hxx \ + RequestValidationHandler.hxx \ + ServerAuthManager.hxx \ + ServerInviteSession.hxx \ + ServerOutOfDialogReq.hxx \ + ServerPagerMessage.hxx \ + ServerPublication.hxx \ + ServerRegistration.hxx \ + ServerSubscriptionFunctor.hxx \ + ServerSubscription.hxx \ + ssl/EncryptionManager.hxx \ + SubscriptionCreator.hxx \ + SubscriptionHandler.hxx \ + SubscriptionPersistenceManager.hxx \ + SubscriptionState.hxx \ + TargetCommand.hxx \ + TlsPeerAuthManager.hxx \ + TlsPeerIdentityInfoMessage.hxx \ + WsCookieAuthManager.hxx \ + UsageUseException.hxx \ + UserAuthInfo.hxx \ + UserProfile.hxx + +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .cxx .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign resip/dum/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign resip/dum/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } +ssl/$(am__dirstamp): + @$(MKDIR_P) ssl + @: > ssl/$(am__dirstamp) +ssl/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) ssl/$(DEPDIR) + @: > ssl/$(DEPDIR)/$(am__dirstamp) +ssl/EncryptionManager.lo: ssl/$(am__dirstamp) \ + ssl/$(DEPDIR)/$(am__dirstamp) + +libdum.la: $(libdum_la_OBJECTS) $(libdum_la_DEPENDENCIES) $(EXTRA_libdum_la_DEPENDENCIES) + $(AM_V_CXXLD)$(libdum_la_LINK) -rpath $(libdir) $(libdum_la_OBJECTS) $(libdum_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f ssl/*.$(OBJEXT) + -rm -f ssl/*.lo + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AppDialog.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AppDialogSet.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AppDialogSetFactory.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BaseCreator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BaseSubscription.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BaseUsage.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CertMessage.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ChallengeInfo.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ClientAuthExtension.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ClientAuthManager.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ClientInviteSession.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ClientOutOfDialogReq.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ClientPagerMessage.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ClientPublication.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ClientRegistration.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ClientSubscription.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ContactInstanceRecord.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultServerReferHandler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DestroyUsage.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Dialog.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DialogEventInfo.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DialogEventStateManager.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DialogId.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DialogSet.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DialogSetId.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DialogUsage.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DialogUsageManager.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DumDecrypted.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DumFeature.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DumFeatureChain.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DumFeatureMessage.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DumHelper.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DumProcessHandler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DumThread.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DumTimeout.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/EncryptionRequest.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Handle.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HandleException.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HandleManager.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Handled.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpGetMessage.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HttpProvider.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IdentityHandler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InMemoryRegistrationDatabase.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InMemorySyncPubDb.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InMemorySyncRegDb.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InviteSession.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InviteSessionCreator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InviteSessionHandler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/KeepAliveManager.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/KeepAliveTimeout.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MasterProfile.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MergedRequestKey.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MergedRequestRemovalCommand.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetworkAssociation.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NonDialogUsage.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OutOfDialogReqCreator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OutgoingEvent.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PagerMessageCreator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Profile.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PublicationCreator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RADIUSServerAuthManager.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RedirectManager.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RegistrationCreator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RegistrationHandler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ServerAuthManager.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ServerInviteSession.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ServerOutOfDialogReq.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ServerPagerMessage.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ServerPublication.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ServerRegistration.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ServerSubscription.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SubscriptionCreator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SubscriptionHandler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SubscriptionState.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TargetCommand.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TlsPeerAuthManager.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TlsPeerIdentityInfoMessage.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UserAuthInfo.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UserProfile.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/WsCookieAuthManager.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@ssl/$(DEPDIR)/EncryptionManager.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.cxx.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cxx.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cxx.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf ssl/.libs ssl/_libs +install-nobase_dumincludeHEADERS: $(nobase_duminclude_HEADERS) + @$(NORMAL_INSTALL) + @list='$(nobase_duminclude_HEADERS)'; test -n "$(dumincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(dumincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(dumincludedir)" || exit 1; \ + fi; \ + $(am__nobase_list) | while read dir files; do \ + xfiles=; for file in $$files; do \ + if test -f "$$file"; then xfiles="$$xfiles $$file"; \ + else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ + test -z "$$xfiles" || { \ + test "x$$dir" = x. || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(dumincludedir)/$$dir'"; \ + $(MKDIR_P) "$(DESTDIR)$(dumincludedir)/$$dir"; }; \ + echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(dumincludedir)/$$dir'"; \ + $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(dumincludedir)/$$dir" || exit $$?; }; \ + done + +uninstall-nobase_dumincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nobase_duminclude_HEADERS)'; test -n "$(dumincludedir)" || list=; \ + $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ + dir='$(DESTDIR)$(dumincludedir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(dumincludedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f ssl/$(DEPDIR)/$(am__dirstamp) + -rm -f ssl/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-recursive + -rm -f ./$(DEPDIR)/AppDialog.Plo + -rm -f ./$(DEPDIR)/AppDialogSet.Plo + -rm -f ./$(DEPDIR)/AppDialogSetFactory.Plo + -rm -f ./$(DEPDIR)/BaseCreator.Plo + -rm -f ./$(DEPDIR)/BaseSubscription.Plo + -rm -f ./$(DEPDIR)/BaseUsage.Plo + -rm -f ./$(DEPDIR)/CertMessage.Plo + -rm -f ./$(DEPDIR)/ChallengeInfo.Plo + -rm -f ./$(DEPDIR)/ClientAuthExtension.Plo + -rm -f ./$(DEPDIR)/ClientAuthManager.Plo + -rm -f ./$(DEPDIR)/ClientInviteSession.Plo + -rm -f ./$(DEPDIR)/ClientOutOfDialogReq.Plo + -rm -f ./$(DEPDIR)/ClientPagerMessage.Plo + -rm -f ./$(DEPDIR)/ClientPublication.Plo + -rm -f ./$(DEPDIR)/ClientRegistration.Plo + -rm -f ./$(DEPDIR)/ClientSubscription.Plo + -rm -f ./$(DEPDIR)/ContactInstanceRecord.Plo + -rm -f ./$(DEPDIR)/DefaultServerReferHandler.Plo + -rm -f ./$(DEPDIR)/DestroyUsage.Plo + -rm -f ./$(DEPDIR)/Dialog.Plo + -rm -f ./$(DEPDIR)/DialogEventInfo.Plo + -rm -f ./$(DEPDIR)/DialogEventStateManager.Plo + -rm -f ./$(DEPDIR)/DialogId.Plo + -rm -f ./$(DEPDIR)/DialogSet.Plo + -rm -f ./$(DEPDIR)/DialogSetId.Plo + -rm -f ./$(DEPDIR)/DialogUsage.Plo + -rm -f ./$(DEPDIR)/DialogUsageManager.Plo + -rm -f ./$(DEPDIR)/DumDecrypted.Plo + -rm -f ./$(DEPDIR)/DumFeature.Plo + -rm -f ./$(DEPDIR)/DumFeatureChain.Plo + -rm -f ./$(DEPDIR)/DumFeatureMessage.Plo + -rm -f ./$(DEPDIR)/DumHelper.Plo + -rm -f ./$(DEPDIR)/DumProcessHandler.Plo + -rm -f ./$(DEPDIR)/DumThread.Plo + -rm -f ./$(DEPDIR)/DumTimeout.Plo + -rm -f ./$(DEPDIR)/EncryptionRequest.Plo + -rm -f ./$(DEPDIR)/Handle.Plo + -rm -f ./$(DEPDIR)/HandleException.Plo + -rm -f ./$(DEPDIR)/HandleManager.Plo + -rm -f ./$(DEPDIR)/Handled.Plo + -rm -f ./$(DEPDIR)/HttpGetMessage.Plo + -rm -f ./$(DEPDIR)/HttpProvider.Plo + -rm -f ./$(DEPDIR)/IdentityHandler.Plo + -rm -f ./$(DEPDIR)/InMemoryRegistrationDatabase.Plo + -rm -f ./$(DEPDIR)/InMemorySyncPubDb.Plo + -rm -f ./$(DEPDIR)/InMemorySyncRegDb.Plo + -rm -f ./$(DEPDIR)/InviteSession.Plo + -rm -f ./$(DEPDIR)/InviteSessionCreator.Plo + -rm -f ./$(DEPDIR)/InviteSessionHandler.Plo + -rm -f ./$(DEPDIR)/KeepAliveManager.Plo + -rm -f ./$(DEPDIR)/KeepAliveTimeout.Plo + -rm -f ./$(DEPDIR)/MasterProfile.Plo + -rm -f ./$(DEPDIR)/MergedRequestKey.Plo + -rm -f ./$(DEPDIR)/MergedRequestRemovalCommand.Plo + -rm -f ./$(DEPDIR)/NetworkAssociation.Plo + -rm -f ./$(DEPDIR)/NonDialogUsage.Plo + -rm -f ./$(DEPDIR)/OutOfDialogReqCreator.Plo + -rm -f ./$(DEPDIR)/OutgoingEvent.Plo + -rm -f ./$(DEPDIR)/PagerMessageCreator.Plo + -rm -f ./$(DEPDIR)/Profile.Plo + -rm -f ./$(DEPDIR)/PublicationCreator.Plo + -rm -f ./$(DEPDIR)/RADIUSServerAuthManager.Plo + -rm -f ./$(DEPDIR)/RedirectManager.Plo + -rm -f ./$(DEPDIR)/RegistrationCreator.Plo + -rm -f ./$(DEPDIR)/RegistrationHandler.Plo + -rm -f ./$(DEPDIR)/ServerAuthManager.Plo + -rm -f ./$(DEPDIR)/ServerInviteSession.Plo + -rm -f ./$(DEPDIR)/ServerOutOfDialogReq.Plo + -rm -f ./$(DEPDIR)/ServerPagerMessage.Plo + -rm -f ./$(DEPDIR)/ServerPublication.Plo + -rm -f ./$(DEPDIR)/ServerRegistration.Plo + -rm -f ./$(DEPDIR)/ServerSubscription.Plo + -rm -f ./$(DEPDIR)/SubscriptionCreator.Plo + -rm -f ./$(DEPDIR)/SubscriptionHandler.Plo + -rm -f ./$(DEPDIR)/SubscriptionState.Plo + -rm -f ./$(DEPDIR)/TargetCommand.Plo + -rm -f ./$(DEPDIR)/TlsPeerAuthManager.Plo + -rm -f ./$(DEPDIR)/TlsPeerIdentityInfoMessage.Plo + -rm -f ./$(DEPDIR)/UserAuthInfo.Plo + -rm -f ./$(DEPDIR)/UserProfile.Plo + -rm -f ./$(DEPDIR)/WsCookieAuthManager.Plo + -rm -f ssl/$(DEPDIR)/EncryptionManager.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-nobase_dumincludeHEADERS + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f ./$(DEPDIR)/AppDialog.Plo + -rm -f ./$(DEPDIR)/AppDialogSet.Plo + -rm -f ./$(DEPDIR)/AppDialogSetFactory.Plo + -rm -f ./$(DEPDIR)/BaseCreator.Plo + -rm -f ./$(DEPDIR)/BaseSubscription.Plo + -rm -f ./$(DEPDIR)/BaseUsage.Plo + -rm -f ./$(DEPDIR)/CertMessage.Plo + -rm -f ./$(DEPDIR)/ChallengeInfo.Plo + -rm -f ./$(DEPDIR)/ClientAuthExtension.Plo + -rm -f ./$(DEPDIR)/ClientAuthManager.Plo + -rm -f ./$(DEPDIR)/ClientInviteSession.Plo + -rm -f ./$(DEPDIR)/ClientOutOfDialogReq.Plo + -rm -f ./$(DEPDIR)/ClientPagerMessage.Plo + -rm -f ./$(DEPDIR)/ClientPublication.Plo + -rm -f ./$(DEPDIR)/ClientRegistration.Plo + -rm -f ./$(DEPDIR)/ClientSubscription.Plo + -rm -f ./$(DEPDIR)/ContactInstanceRecord.Plo + -rm -f ./$(DEPDIR)/DefaultServerReferHandler.Plo + -rm -f ./$(DEPDIR)/DestroyUsage.Plo + -rm -f ./$(DEPDIR)/Dialog.Plo + -rm -f ./$(DEPDIR)/DialogEventInfo.Plo + -rm -f ./$(DEPDIR)/DialogEventStateManager.Plo + -rm -f ./$(DEPDIR)/DialogId.Plo + -rm -f ./$(DEPDIR)/DialogSet.Plo + -rm -f ./$(DEPDIR)/DialogSetId.Plo + -rm -f ./$(DEPDIR)/DialogUsage.Plo + -rm -f ./$(DEPDIR)/DialogUsageManager.Plo + -rm -f ./$(DEPDIR)/DumDecrypted.Plo + -rm -f ./$(DEPDIR)/DumFeature.Plo + -rm -f ./$(DEPDIR)/DumFeatureChain.Plo + -rm -f ./$(DEPDIR)/DumFeatureMessage.Plo + -rm -f ./$(DEPDIR)/DumHelper.Plo + -rm -f ./$(DEPDIR)/DumProcessHandler.Plo + -rm -f ./$(DEPDIR)/DumThread.Plo + -rm -f ./$(DEPDIR)/DumTimeout.Plo + -rm -f ./$(DEPDIR)/EncryptionRequest.Plo + -rm -f ./$(DEPDIR)/Handle.Plo + -rm -f ./$(DEPDIR)/HandleException.Plo + -rm -f ./$(DEPDIR)/HandleManager.Plo + -rm -f ./$(DEPDIR)/Handled.Plo + -rm -f ./$(DEPDIR)/HttpGetMessage.Plo + -rm -f ./$(DEPDIR)/HttpProvider.Plo + -rm -f ./$(DEPDIR)/IdentityHandler.Plo + -rm -f ./$(DEPDIR)/InMemoryRegistrationDatabase.Plo + -rm -f ./$(DEPDIR)/InMemorySyncPubDb.Plo + -rm -f ./$(DEPDIR)/InMemorySyncRegDb.Plo + -rm -f ./$(DEPDIR)/InviteSession.Plo + -rm -f ./$(DEPDIR)/InviteSessionCreator.Plo + -rm -f ./$(DEPDIR)/InviteSessionHandler.Plo + -rm -f ./$(DEPDIR)/KeepAliveManager.Plo + -rm -f ./$(DEPDIR)/KeepAliveTimeout.Plo + -rm -f ./$(DEPDIR)/MasterProfile.Plo + -rm -f ./$(DEPDIR)/MergedRequestKey.Plo + -rm -f ./$(DEPDIR)/MergedRequestRemovalCommand.Plo + -rm -f ./$(DEPDIR)/NetworkAssociation.Plo + -rm -f ./$(DEPDIR)/NonDialogUsage.Plo + -rm -f ./$(DEPDIR)/OutOfDialogReqCreator.Plo + -rm -f ./$(DEPDIR)/OutgoingEvent.Plo + -rm -f ./$(DEPDIR)/PagerMessageCreator.Plo + -rm -f ./$(DEPDIR)/Profile.Plo + -rm -f ./$(DEPDIR)/PublicationCreator.Plo + -rm -f ./$(DEPDIR)/RADIUSServerAuthManager.Plo + -rm -f ./$(DEPDIR)/RedirectManager.Plo + -rm -f ./$(DEPDIR)/RegistrationCreator.Plo + -rm -f ./$(DEPDIR)/RegistrationHandler.Plo + -rm -f ./$(DEPDIR)/ServerAuthManager.Plo + -rm -f ./$(DEPDIR)/ServerInviteSession.Plo + -rm -f ./$(DEPDIR)/ServerOutOfDialogReq.Plo + -rm -f ./$(DEPDIR)/ServerPagerMessage.Plo + -rm -f ./$(DEPDIR)/ServerPublication.Plo + -rm -f ./$(DEPDIR)/ServerRegistration.Plo + -rm -f ./$(DEPDIR)/ServerSubscription.Plo + -rm -f ./$(DEPDIR)/SubscriptionCreator.Plo + -rm -f ./$(DEPDIR)/SubscriptionHandler.Plo + -rm -f ./$(DEPDIR)/SubscriptionState.Plo + -rm -f ./$(DEPDIR)/TargetCommand.Plo + -rm -f ./$(DEPDIR)/TlsPeerAuthManager.Plo + -rm -f ./$(DEPDIR)/TlsPeerIdentityInfoMessage.Plo + -rm -f ./$(DEPDIR)/UserAuthInfo.Plo + -rm -f ./$(DEPDIR)/UserProfile.Plo + -rm -f ./$(DEPDIR)/WsCookieAuthManager.Plo + -rm -f ssl/$(DEPDIR)/EncryptionManager.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES \ + uninstall-nobase_dumincludeHEADERS + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--depfiles check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-libLTLIBRARIES install-man \ + install-nobase_dumincludeHEADERS install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES \ + uninstall-nobase_dumincludeHEADERS + +.PRECIOUS: Makefile + + +############################################################################## +# +# The Vovida Software License, Version 1.0 +# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The names "VOCAL", "Vovida Open Communication Application Library", +# and "Vovida Open Communication Application Library (VOCAL)" must +# not be used to endorse or promote products derived from this +# software without prior written permission. For written +# permission, please contact vocal@vovida.org. +# +# 4. Products derived from this software may not be called "VOCAL", nor +# may "VOCAL" appear in their name, without prior written +# permission of Vovida Networks, Inc. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. +# +# ==================================================================== +# +# This software consists of voluntary contributions made by Vovida +# Networks, Inc. and many individuals on behalf of Vovida Networks, +# Inc. For more information on Vovida Networks, Inc., please see +# . +# +############################################################################## + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libs/resiprocate/resip/dum/MasterProfile.cxx b/src/libs/resiprocate/resip/dum/MasterProfile.cxx index e1454531..976d752b 100644 --- a/src/libs/resiprocate/resip/dum/MasterProfile.cxx +++ b/src/libs/resiprocate/resip/dum/MasterProfile.cxx @@ -2,6 +2,7 @@ #include "resip/dum/Profile.hxx" #include "resip/dum/MasterProfile.hxx" #include "resip/stack/HeaderTypes.hxx" +#include "rutil/Logger.hxx" using namespace resip; #define RESIPROCATE_SUBSYSTEM Subsystem::DUM @@ -22,7 +23,8 @@ MasterProfile::MasterProfile() : mUasReliableProvisionalMode(Never), mServerRegistrationMinExpires(0), mServerRegistrationMaxExpires(UINT_MAX), - mServerRegistrationDefaultExpires(3600) + mServerRegistrationDefaultExpires(3600), + mAdditionalTransactionTerminatingResponsesEnabled(false) { // Default settings addSupportedMimeType(INVITE, Mime("application", "sdp")); @@ -64,6 +66,24 @@ MasterProfile::addSupportedMethod(const MethodTypes& method) mSupportedMethods.push_back(Token(getMethodName(method))); } +void +MasterProfile::removeSupportedMethod(const MethodTypes& method) +{ + mSupportedMethodTypes.erase(method); + for (Tokens::iterator i = mSupportedMethods.begin(); + i != mSupportedMethods.end(); ++i) + { + if (getMethodType(i->value()) == method) + { + mSupportedMethods.erase(i); + break; + } + } + + // Should we clear the mimetypes as well? + // clearSupportedMimeTypes(method); +} + bool MasterProfile::isMethodSupported(MethodTypes method) const { @@ -106,8 +126,8 @@ MasterProfile::addSupportedOptionTag(const Token& tag) { if (tag == Token(Symbols::C100rel)) { - //use enablePrackUas and enablePrackUac - assert(0); + //use setUasReliableProvisionalMode and setUacReliableProvisionalMode + resip_assert(0); } mSupportedOptionTags.push_back(tag); } @@ -122,9 +142,12 @@ MasterProfile::getUnsupportedOptionsTags(const Tokens& requiresOptionTags) { tokens.push_back(Token("malformedTag")); } - else if (*i == Token(Symbols::C100rel) && mUasReliableProvisionalMode == Never) + else if (*i == Token(Symbols::C100rel) ) { - tokens.push_back(*i); + if (mUasReliableProvisionalMode == Never) + { + tokens.push_back(*i); + } } // if this option is not supported else if (!mSupportedOptionTags.find(*i)) @@ -157,8 +180,6 @@ MasterProfile::setUacReliableProvisionalMode(ReliableProvisionalMode mode) void MasterProfile::setUasReliableProvisionalMode(ReliableProvisionalMode mode) { - //.dcm. not supported yet - assert(0); mUasReliableProvisionalMode = mode; } @@ -431,6 +452,40 @@ MasterProfile::clone() const return new MasterProfile(*this); } +bool& MasterProfile::additionalTransactionTerminatingResponsesEnabled() +{ + return mAdditionalTransactionTerminatingResponsesEnabled; +} + +bool MasterProfile::additionalTransactionTerminatingResponsesEnabled() const +{ + return mAdditionalTransactionTerminatingResponsesEnabled; +} + +void MasterProfile::addAdditionalTransactionTerminatingResponses(int code) +{ + DebugLog(<< "MasterProfile::addAdditionalTransactionTerminatingResponses" << "added code: " << code); + mAdditionalTransactionTerminatingResponsess.insert(code); +} + +bool MasterProfile::isAdditionalTransactionTerminatingResponse(int code) const +{ + bool isAllowed = (mAdditionalTransactionTerminatingResponsess.end() != mAdditionalTransactionTerminatingResponsess.find(code)); + + DebugLog(<< "MasterProfile::isAdditionalTransactionTerminatingResponse" << "is code " << code << " allowed: " << isAllowed); + return isAllowed; +} + +const std::set& MasterProfile::getAdditionalTransactionTerminatingResponses() const +{ + return mAdditionalTransactionTerminatingResponsess; +} + +void MasterProfile::clearAdditionalTransactionTerminatingResponses(void) +{ + mAdditionalTransactionTerminatingResponsess.clear(); +} + /* ==================================================================== * The Vovida Software License, Version 1.0 * diff --git a/src/libs/resiprocate/resip/dum/MasterProfile.hxx b/src/libs/resiprocate/resip/dum/MasterProfile.hxx index aef3201f..e1e3f897 100644 --- a/src/libs/resiprocate/resip/dum/MasterProfile.hxx +++ b/src/libs/resiprocate/resip/dum/MasterProfile.hxx @@ -28,6 +28,7 @@ class MasterProfile : public UserProfile /// Defaults are: INVITE, ACK, CANCEL, OPTIONS, BYE, UPDATE virtual void addSupportedMethod(const MethodTypes& method); + virtual void removeSupportedMethod(const MethodTypes& method); virtual bool isMethodSupported(MethodTypes method) const; virtual Tokens getAllowedMethods() const; virtual Data getAllowedMethodsData() const; @@ -42,36 +43,48 @@ class MasterProfile : public UserProfile typedef enum { - Never, - Supported, - Required + Never, + SupportedEssential, // If UAS - Only use reliable provisionals if sending a body and far end supports + Supported, // If UAS - Always use reliable provisionals if far end supports + Required // If UAS - Always use reliable provisionals } ReliableProvisionalMode; - // UAC PRACK support. UPDATE must be enabled(currently defaults to on, do // not disable w/out disabling UAC PRACK support). // // Flows where an an answer is received in a 180rel and subsequent O/A // exchanges using UPDATE occur in the early dialog - // have been tested. + // have been tested. // // A subsequent O/A exchange using 180rel/PRACK is also supported. This is // a really bad idea, as an answer must be generated; the offer cannot be // rejected. UPDATE should always be used for O/A exchanges once the // dialog is established. - // Invite/18x(offer)/PRACK(ans) should work but has not been tested. + // + // Invite/18x(offer)/PRACK(ans) also works + // + // Invite(offer)/18x(ans)/PRACK(offer)/200P(ans) issupported, but not recommended. + // The UAC MUST call provideOffer from the onAnswer callback in order to generate + // the offer in the PRACK. // // Explicit limitations are: - // Overlapping reliable provisional responses that contain a body are not - // handled. - // Offers in a 200(PRACK) are not supported, and anyone who generates them - // should be summarily executed. - + // - Overlapping reliable provisional responses that contain a body are not + // handled. + // + // Note: Using SupportedEssential is exactly the same as using Supported, + // SupportedEssential only effects UAS Prack implementation virtual void setUacReliableProvisionalMode(ReliableProvisionalMode mode); virtual ReliableProvisionalMode getUacReliableProvisionalMode() const; - //Not supported as UAS. Calling setUacReliableProvisionalMode will result - //in an assert. + // UAS PRACK support. UPDATE must be enabled(currently defaults to on, do + // not disable w/out disabling UAS PRACK support). + // + // All flows and limitations mentioned in UAC Prack comments apply + // + // Modes work as follows: + // SupportedEssential - Only send reliable provisionals if sending a body and far end supports + // Supported - Always send reliable provisionals if far end supports + // Required - Always send reliable provisionals virtual void setUasReliableProvisionalMode(ReliableProvisionalMode mode); virtual ReliableProvisionalMode getUasReliableProvisionalMode() const; @@ -151,6 +164,29 @@ class MasterProfile : public UserProfile virtual bool& checkReqUriInMergeDetectionEnabled(); virtual bool checkReqUriInMergeDetectionEnabled() const; + /// Enabling this setting will allow the application layer to provide additional SIP responses, from class 4xx, 5xx, 6xx, + /// that will lead to transaction termination instead of other failure effects like dialog termination, as defined by + /// method Helper::determineFailureMessageEffect. (See header Helper.hxx for all transaction failure effects). + /// A scenarui when this is useful is when, for a server subscription, a NOTIFY is responded with an error response due to a timeout + /// condition, but the application needs the subscription to be continued. Even though RFC 3265 prescribes the + /// notifier should remove the subscription in such cases, timeouts may occur for transient conditions like a + /// overloaded proxy, a slow network connection, eventually nobody would benefit if the subscription is terminated by the server. + /// With this setting enabled the subscription will be continued, but only until the subscription expires. + /// Currently, it is only used by ServerSubscriptions. + /// Default is to not allow additional transaction terminating responses + /// To enable it: + /// 1. Set additionalTransactionTerminatingResponsesEnabled() = true on master profile + /// 2. Call method addAdditionalTransactionTerminatingResponses(code) to provide SIP responses for which the application + /// need the transaction to be terminated + virtual bool& additionalTransactionTerminatingResponsesEnabled(); + virtual bool additionalTransactionTerminatingResponsesEnabled() const; + + virtual void addAdditionalTransactionTerminatingResponses(int code); + virtual bool isAdditionalTransactionTerminatingResponse(int code) const; + + virtual const std::set& getAdditionalTransactionTerminatingResponses() const; + virtual void clearAdditionalTransactionTerminatingResponses(void); + private: virtual UserProfile* clone() const; std::set mSupportedSchemes; @@ -173,6 +209,9 @@ class MasterProfile : public UserProfile UInt32 mServerRegistrationMinExpires; UInt32 mServerRegistrationMaxExpires; UInt32 mServerRegistrationDefaultExpires; + + bool mAdditionalTransactionTerminatingResponsesEnabled; + std::set mAdditionalTransactionTerminatingResponsess; }; } diff --git a/src/libs/resiprocate/resip/dum/OutgoingEvent.hxx b/src/libs/resiprocate/resip/dum/OutgoingEvent.hxx index 41b08e78..12ab9b9b 100644 --- a/src/libs/resiprocate/resip/dum/OutgoingEvent.hxx +++ b/src/libs/resiprocate/resip/dum/OutgoingEvent.hxx @@ -12,7 +12,7 @@ namespace resip class OutgoingEvent : public Message { public: - //OutgoingEvent(std::unique_ptr msg); + //OutgoingEvent(std::auto_ptr msg); OutgoingEvent(SharedPtr msg); OutgoingEvent(const OutgoingEvent&); ~OutgoingEvent(); @@ -27,7 +27,7 @@ class OutgoingEvent : public Message virtual EncodeStream& encodeBrief(EncodeStream& strm) const; private: - //mutable std::unique_ptr mMessage; + //mutable std::auto_ptr mMessage; SharedPtr mMessage; }; diff --git a/src/libs/resiprocate/resip/dum/PagerMessageHandler.hxx b/src/libs/resiprocate/resip/dum/PagerMessageHandler.hxx index e37a3fe5..cfd154d1 100644 --- a/src/libs/resiprocate/resip/dum/PagerMessageHandler.hxx +++ b/src/libs/resiprocate/resip/dum/PagerMessageHandler.hxx @@ -22,7 +22,7 @@ class ClientPagerMessageHandler virtual void onSuccess(ClientPagerMessageHandle, const SipMessage& status)=0; //!kh! // Application could re-page the failed contents or just ingore it. - virtual void onFailure(ClientPagerMessageHandle, const SipMessage& status, std::unique_ptr contents)=0; + virtual void onFailure(ClientPagerMessageHandle, const SipMessage& status, std::auto_ptr contents)=0; }; class ServerPagerMessageHandler diff --git a/src/libs/resiprocate/resip/dum/Profile.cxx b/src/libs/resiprocate/resip/dum/Profile.cxx index 6b1a829d..cdbd7904 100644 --- a/src/libs/resiprocate/resip/dum/Profile.cxx +++ b/src/libs/resiprocate/resip/dum/Profile.cxx @@ -16,7 +16,7 @@ Profile::Profile(SharedPtr baseProfile) : mHasOutboundDecorator(false), mBaseProfile(baseProfile) { - assert(baseProfile.get()); + resip_assert(baseProfile.get()); reset(); // default all settings to fallthrough to mBaseProfile } @@ -38,6 +38,7 @@ Profile::reset() unsetDefaultSessionTime(); unsetDefaultSessionTimerMode(); unset1xxRetransmissionTime(); + unset1xxRelResubmitTime(); unsetOverrideHostAndPort(); unsetAdvertisedCapabilities(); unsetOutboundProxy(); @@ -377,6 +378,38 @@ Profile::unset1xxRetransmissionTime() } } +void +Profile::set1xxRelResubmitTime(int secs) +{ + m1xxRelResubmitTime = secs; + mHas1xxRelResubmitTime = true; +} + +int +Profile::get1xxRelResubmitTime() const +{ + // Fall through seting (if required) + if(!mHas1xxRelResubmitTime && mBaseProfile.get()) + { + return mBaseProfile->get1xxRelResubmitTime(); + } + return m1xxRelResubmitTime; +} + +void +Profile::unset1xxRelResubmitTime() +{ + if(mBaseProfile.get()) + { + mHas1xxRelResubmitTime = false; + } + else // No Base profile - so return to default setting + { + mHas1xxRelResubmitTime = true; + m1xxRelResubmitTime = 150; // RFC3262 section says the UAS SHOULD send provisional reliable responses once every two and half minutes + } +} + void Profile::setOverrideHostAndPort(const Uri& hostPort) { @@ -415,10 +448,11 @@ Profile::unsetOverrideHostAndPort() void Profile::addAdvertisedCapability(const Headers::Type header) { - assert(header == Headers::Allow || - header == Headers::AcceptEncoding || - header == Headers::AcceptLanguage || - header == Headers::Supported); + resip_assert(header == Headers::Allow || + header == Headers::AcceptEncoding || + header == Headers::AcceptLanguage || + header == Headers::AllowEvents || + header == Headers::Supported); mAdvertisedCapabilities.insert(header); mHasAdvertisedCapabilities = true; @@ -474,7 +508,7 @@ Profile::getOutboundProxy() const { return mBaseProfile->getOutboundProxy(); } - assert(mHasOutboundProxy); + resip_assert(mHasOutboundProxy); return mOutboundProxy; } @@ -606,7 +640,7 @@ Profile::getUserAgent() const { return mBaseProfile->getUserAgent(); } - assert(mHasUserAgent); + resip_assert(mHasUserAgent); return mUserAgent; } @@ -642,7 +676,7 @@ Profile::getProxyRequires() const { return mBaseProfile->getProxyRequires(); } - assert(mHasProxyRequires); + resip_assert(mHasProxyRequires); return mProxyRequires; } @@ -905,7 +939,7 @@ Profile::getUserAgentCapabilities() const { return mBaseProfile->getUserAgentCapabilities(); } - assert(mHasUserAgentCapabilities); + resip_assert(mHasUserAgentCapabilities); return mUserAgentCapabilities; } diff --git a/src/libs/resiprocate/resip/dum/Profile.hxx b/src/libs/resiprocate/resip/dum/Profile.hxx index 3599508d..32465c09 100644 --- a/src/libs/resiprocate/resip/dum/Profile.hxx +++ b/src/libs/resiprocate/resip/dum/Profile.hxx @@ -104,7 +104,12 @@ class Profile /// The amount of time that can pass before dum will resubmit an unreliable provisional response virtual void set1xxRetransmissionTime(int secs); virtual int get1xxRetransmissionTime() const; - virtual void unset1xxRetransmissionTime(); + virtual void unset1xxRetransmissionTime(); + + /// The amount of time that can pass before dum will resubmit a reliable provisional response + virtual void set1xxRelResubmitTime(int secs); + virtual int get1xxRelResubmitTime() const; + virtual void unset1xxRelResubmitTime(); ///overrides the value used to populate the contact ///?dcm? -- also change via entries? Also, dum currently uses(as a uas) @@ -119,7 +124,7 @@ class Profile ///enable/disable sending of Allow/Supported/Accept-Language/Accept-Encoding headers ///on initial outbound requests (ie. Initial INVITE, REGISTER, etc.) and Invite 200 responses ///Note: Default is to advertise Headers::Allow and Headers::Supported, use clearAdvertisedCapabilities to remove these - /// Currently implemented header values are: Headers::Allow, + /// Currently implemented header values are: Headers::Allow, Headers::AllowEvents /// Headers::AcceptEncoding, Headers::AcceptLanguage, Headers::Supported virtual void addAdvertisedCapability(const Headers::Type header); virtual bool isAdvertisedCapability(const Headers::Type header) const; @@ -262,6 +267,9 @@ class Profile bool mHas1xxRetransmissionTime; int m1xxRetransmissionTime; + bool mHas1xxRelResubmitTime; + int m1xxRelResubmitTime; + bool mHasOutboundProxy; NameAddr mOutboundProxy; diff --git a/src/libs/resiprocate/resip/dum/PublicationHandler.hxx b/src/libs/resiprocate/resip/dum/PublicationHandler.hxx index 69887edf..8c83dc8d 100644 --- a/src/libs/resiprocate/resip/dum/PublicationHandler.hxx +++ b/src/libs/resiprocate/resip/dum/PublicationHandler.hxx @@ -3,6 +3,7 @@ #include "resip/dum/Handles.hxx" #include "resip/stack/Mime.hxx" +#include "resip/stack/Contents.hxx" namespace resip { diff --git a/src/libs/resiprocate/resip/dum/PublicationPersistenceManager.hxx b/src/libs/resiprocate/resip/dum/PublicationPersistenceManager.hxx new file mode 100644 index 00000000..7ce316cc --- /dev/null +++ b/src/libs/resiprocate/resip/dum/PublicationPersistenceManager.hxx @@ -0,0 +1,408 @@ +#if !defined(RESIP_PUBLICATIONPERSISTENCEMANAGER_HXX) +#define RESIP_PUBLICATIONPERSISTENCEMANAGER_HXX + +#include + +#include "rutil/XMLCursor.hxx" +#include "resip/stack/Contents.hxx" +#include "resip/stack/SecurityAttributes.hxx" +#include "rutil/Data.hxx" +#include "rutil/Timer.hxx" +#include "rutil/SharedPtr.hxx" + +namespace resip +{ + +/** Abstract interface of a datastore of all publication documents processed by DUM. Derived classes implement the + actual storage of publication documents. resip::InMemorySyncPubDb is an example of a local datastore. + */ +class PublicationPersistenceManager +{ +public: + + struct PubDocument + { + PubDocument() : mExpirationTime(0), mLastUpdated(0), mLingerTime(0), mSyncPublication(false) {} + PubDocument(const Data& eventType, const Data& documentKey, const Data& eTag, UInt64 expirationTime, const Contents* contents, const SecurityAttributes* securityAttributes, bool syncPublication = false) : + mEventType(eventType), mDocumentKey(documentKey), mETag(eTag), mExpirationTime(expirationTime), mLastUpdated(Timer::getTimeSecs()), mLingerTime(expirationTime), mSyncPublication(syncPublication) + { + if (contents) + { + mContents.reset(contents->clone()); + } + if (securityAttributes) + { + mSecurityAttributes.reset(new SecurityAttributes); + *mSecurityAttributes = *securityAttributes; + } + } + + void stream(std::iostream& s) const + { + UInt64 now = Timer::getTimeSecs(); + + // Note: for compatibility with RegSyncServer/Client, using pubinfo for tag name instead of pubdocument + s << "" << Symbols::CRLF; + s << " " << mEventType.xmlCharDataEncode() << "" << Symbols::CRLF; + s << " " << mDocumentKey.xmlCharDataEncode() << "" << Symbols::CRLF; + s << " " << mETag.xmlCharDataEncode() << "" << Symbols::CRLF; + s << " " << (((mExpirationTime == 0) || (mExpirationTime <= now)) ? 0 : (mExpirationTime - now)) << "" << Symbols::CRLF; + s << " " << now - mLastUpdated << "" << Symbols::CRLF; + if (mExpirationTime != 0 && mContents.get()) // lingering records will have expirationTime as 0 - don't need to send contents - refreshes also have no body + { + + Mime mimeType = mContents->getType(); + + // There is an assumption that the contenttype and contentsubtype tags will always occur + // before the content tag in the deserialization + s << " " << mimeType.type().xmlCharDataEncode() << "" << Symbols::CRLF; + s << " " << mimeType.subType().xmlCharDataEncode() << "" << Symbols::CRLF; + s << " " << mContents->getBodyData().xmlCharDataEncode() << "" << Symbols::CRLF; + + if(mSecurityAttributes.get()) + { + resip_assert(mSecurityAttributes); + s << " " << (mSecurityAttributes->isEncrypted() ? "true" : "false") << "" << Symbols::CRLF; + if (mSecurityAttributes->isEncrypted()) + { + s << " "; + switch (mSecurityAttributes->getSignatureStatus()) + { + case SignatureNone: + s << "none"; + break; + case SignatureIsBad: + s << "bad"; + break; + case SignatureTrusted: + s << "trusted"; + break; + case SignatureCATrusted: + s << "catrusted"; + break; + case SignatureNotTrusted: + s << "nottrusted"; + break; + case SignatureSelfSigned: + s << "selfsigned"; + break; + default: + resip_assert(false); + s << "unknown"; + break; + } + s << "" << Symbols::CRLF; + if (!mSecurityAttributes->getSigner().empty()) + { + s << " " << mSecurityAttributes->getSigner().xmlCharDataEncode() << "" << Symbols::CRLF; + } + if (!mSecurityAttributes->getIdentity().empty()) + { + s << " " << mSecurityAttributes->getIdentity().xmlCharDataEncode() << "" << Symbols::CRLF; + s << " "; + switch (mSecurityAttributes->getIdentityStrength()) + { + case SecurityAttributes::From: + s << "from"; + break; + case SecurityAttributes::FailedIdentity: + s << "failedidentity"; + break; + case SecurityAttributes::Identity: + s << "identity"; + break; + default: + resip_assert(false); + s << "unknown"; + break; + } + s << "" << Symbols::CRLF; + } + // Note: intentionally not syncing mLevel and mEncryptionPerformed from SecurityAttributes since they are for outbound messages only + } + } + } + s << "" << Symbols::CRLF; + } + + bool deserialize(resip::XMLCursor& xml, UInt64 now = 0) + { + bool success = false; + *this = PubDocument(); + if(now <= 0) + { + now = Timer::getTimeSecs(); + } + Data mimeTypeString; + Data mimeSubtypeString; + + if(isEqualNoCase(xml.getTag(), "pubinfo")) + { + if(xml.firstChild()) + { + do + { + if(isEqualNoCase(xml.getTag(), "eventtype")) + { + if(xml.firstChild()) + { + mEventType = xml.getValue().xmlCharDataDecode(); + xml.parent(); + } + } + else if(isEqualNoCase(xml.getTag(), "documentkey")) + { + if(xml.firstChild()) + { + mDocumentKey = xml.getValue().xmlCharDataDecode(); + xml.parent(); + } + } + else if(isEqualNoCase(xml.getTag(), "etag")) + { + if(xml.firstChild()) + { + mETag = xml.getValue().xmlCharDataDecode(); + xml.parent(); + } + } + else if(isEqualNoCase(xml.getTag(), "expires")) + { + if(xml.firstChild()) + { + UInt64 expires = xml.getValue().convertUInt64(); + mExpirationTime = (expires == 0 ? 0 : now + expires); + mLingerTime = mExpirationTime; + xml.parent(); + } + } + else if(isEqualNoCase(xml.getTag(), "lastupdated")) + { + if(xml.firstChild()) + { + mLastUpdated = now - xml.getValue().convertUInt64(); + xml.parent(); + } + } + else if(isEqualNoCase(xml.getTag(), "contentstype")) + { + if(xml.firstChild()) + { + mimeTypeString = xml.getValue().xmlCharDataDecode(); + xml.parent(); + } + } + else if(isEqualNoCase(xml.getTag(), "contentssubtype")) + { + if(xml.firstChild()) + { + mimeSubtypeString = xml.getValue().xmlCharDataDecode(); + xml.parent(); + } + } + else if(isEqualNoCase(xml.getTag(), "contents")) + { + if(xml.firstChild()) + { + // There is an assumption that the contenttype and contentsubtype tags will always occur + // before the content tag + Mime mimeType(mimeTypeString, mimeSubtypeString); + // Need explilcit Data decodedBody as serializedContents refers to it in parser + Data decodedBody(xml.getValue().xmlCharDataDecode()); + Contents* serializedContents = Contents::createContents(mimeType, decodedBody); + // Need to clone, as serializedContents is still referring to decodedBody, via the LazyParser, + // which will go out of scope. + mContents.reset(serializedContents->clone()); + delete serializedContents; + serializedContents = 0; + xml.parent(); + success = true; + } + } + else if (isEqualNoCase(xml.getTag(), "isencrypted")) + { + if (xml.firstChild()) + { + if (mSecurityAttributes.get() == 0) + { + mSecurityAttributes.reset(new SecurityAttributes); + } + if (isEqualNoCase(xml.getValue(), "true")) + { + mSecurityAttributes->setEncrypted(); + } + xml.parent(); + } + } + else if (isEqualNoCase(xml.getTag(), "sigstatus")) + { + if (xml.firstChild()) + { + if (mSecurityAttributes.get() == 0) + { + mSecurityAttributes.reset(new SecurityAttributes); + } + if (isEqualNoCase(xml.getValue(), "none")) + { + mSecurityAttributes->setSignatureStatus(SignatureNone); + } + else if (isEqualNoCase(xml.getValue(), "bad")) + { + mSecurityAttributes->setSignatureStatus(SignatureIsBad); + } + else if (isEqualNoCase(xml.getValue(), "trusted")) + { + mSecurityAttributes->setSignatureStatus(SignatureTrusted); + } + else if (isEqualNoCase(xml.getValue(), "catrusted")) + { + mSecurityAttributes->setSignatureStatus(SignatureCATrusted); + } + else if (isEqualNoCase(xml.getValue(), "nottrusted")) + { + mSecurityAttributes->setSignatureStatus(SignatureNotTrusted); + } + else if (isEqualNoCase(xml.getValue(), "selfsigned")) + { + mSecurityAttributes->setSignatureStatus(SignatureSelfSigned); + } + xml.parent(); + } + } + else if (isEqualNoCase(xml.getTag(), "signer")) + { + if (xml.firstChild()) + { + if (mSecurityAttributes.get() == 0) + { + mSecurityAttributes.reset(new SecurityAttributes); + } + mSecurityAttributes->setSigner(xml.getValue().xmlCharDataDecode()); + xml.parent(); + } + } + else if (isEqualNoCase(xml.getTag(), "identity")) + { + if (xml.firstChild()) + { + if (mSecurityAttributes.get() == 0) + { + mSecurityAttributes.reset(new SecurityAttributes); + } + mSecurityAttributes->setIdentity(xml.getValue().xmlCharDataDecode()); + xml.parent(); + } + } + else if (isEqualNoCase(xml.getTag(), "identitystrength")) + { + if (xml.firstChild()) + { + if (mSecurityAttributes.get() == 0) + { + mSecurityAttributes.reset(new SecurityAttributes); + } + if (isEqualNoCase(xml.getValue(), "from")) + { + mSecurityAttributes->setIdentityStrength(SecurityAttributes::From); + } + else if (isEqualNoCase(xml.getValue(), "failedidentity")) + { + mSecurityAttributes->setIdentityStrength(SecurityAttributes::FailedIdentity); + } + else if (isEqualNoCase(xml.getValue(), "identity")) + { + mSecurityAttributes->setIdentityStrength(SecurityAttributes::Identity); + } + xml.parent(); + } + } + + } while(xml.nextSibling()); + xml.parent(); + } + } + + return(success); + } + + + Data mEventType; + Data mDocumentKey; + Data mETag; + UInt64 mExpirationTime; + UInt64 mLastUpdated; + UInt64 mLingerTime; // No need to sync this - this is essentially the latest expiration time we have seen for this ETag + SharedPtr mContents; + SharedPtr mSecurityAttributes; + bool mSyncPublication; // No need to sync this + }; + + typedef std::map ETagToDocumentMap; + typedef std::map KeyToETagMap; + + class ETagMerger + { + public: + virtual ~ETagMerger() {} + virtual bool mergeETag(Contents* eTagDest, Contents* eTagSrc, bool isFirst) = 0; + }; + + PublicationPersistenceManager() {} + virtual ~PublicationPersistenceManager() {} + + virtual void addUpdateDocument(const PubDocument& document) = 0; + virtual void addUpdateDocument(const Data& eventType, const Data& documentKey, const Data& eTag, UInt64 expirationTime, const Contents* contents, const SecurityAttributes* securityAttributes, bool syncPublication = false) + { + addUpdateDocument(PubDocument(eventType, documentKey, eTag, expirationTime, contents, securityAttributes, syncPublication)); + } + virtual bool removeDocument(const Data& eventType, const Data& documentKey, const Data& eTag, UInt64 lastUpdated, bool syncPublication = false) = 0; + virtual bool getMergedETags(const Data& eventType, const Data& documentKey, ETagMerger& merger, Contents* destination) = 0; + virtual bool documentExists(const Data& eventType, const Data& documentKey, const Data& eTag) = 0; + virtual bool getDocument(const resip::Data& eventType, const resip::Data& documentKey, const resip::Data& eTag, PubDocument& document) { return false; } + virtual bool checkExpired(const Data& eventType, const Data& documentKey, const Data& eTag, UInt64 lastUpdated) = 0; + virtual void lockDocuments() = 0; + virtual KeyToETagMap& getDocuments() = 0; // Ensure you lock before calling this and unlock when done + virtual void unlockDocuments() = 0; +}; +} + +#endif + +/* ==================================================================== +* +* Copyright (c) 2015 SIP Spectrum, Inc. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* +* 3. Neither the name of the author(s) nor the names of any contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +* +* ==================================================================== +* +*/ +/* +* vi: set shiftwidth=3 expandtab: +*/ diff --git a/src/libs/resiprocate/resip/dum/RADIUSServerAuthManager.cxx b/src/libs/resiprocate/resip/dum/RADIUSServerAuthManager.cxx index efc6d386..78e624bb 100644 --- a/src/libs/resiprocate/resip/dum/RADIUSServerAuthManager.cxx +++ b/src/libs/resiprocate/resip/dum/RADIUSServerAuthManager.cxx @@ -22,131 +22,208 @@ using namespace std; #define RESIPROCATE_SUBSYSTEM Subsystem::DUM -RADIUSServerAuthManager::RADIUSServerAuthManager(resip::DialogUsageManager& dum) : ServerAuthManager(dum, dum.dumIncomingTarget()), dum(dum) { - - RADIUSDigestAuthenticator::init(NULL); +RADIUSServerAuthManager::RADIUSServerAuthManager( + resip::DialogUsageManager& dum, + TargetCommand::Target& target, + const Data& configurationFile, + bool challengeThirdParties, + const Data& staticRealm) : + ServerAuthManager(dum, target, challengeThirdParties, staticRealm), + dum(dum) +{ + RADIUSDigestAuthenticator::init( + configurationFile.empty() ? 0 : configurationFile.c_str()); } -RADIUSServerAuthManager::~RADIUSServerAuthManager() { -} - -ServerAuthManager::AsyncBool RADIUSServerAuthManager::requiresChallenge(const SipMessage& msg) { - - ostringstream s; - s << msg.header(h_RequestLine).uri(); - DebugLog(<<"RADIUSServerAuthManager::requiresChallenge, uri = " << s.str().c_str()); - - // default behaviour is to challenge - ChallengeInfo *cmsg = new ChallengeInfo(false, true, msg.getTransactionId()); - dum.post(cmsg); - return Async; -} - -void RADIUSServerAuthManager::requestCredential(const resip::Data& user, const resip::Data& realm, const resip::SipMessage& msg, const resip::Auth& auth, const resip::Data& transactionId) { - - ostringstream s; - s << msg.header(h_RequestLine).uri(); - DebugLog(<<"RADIUSServerAuthManager::requestCredential, uri = " << s << " authUser = " << user); - - MyRADIUSDigestAuthListener *radiusListener = NULL; - try { - - radiusListener = new MyRADIUSDigestAuthListener(user, realm, dum, transactionId); - Data radiusUser(user + "@" + realm); - DebugLog(<< "radiusUser = " << radiusUser.c_str() << ", " << "user = " << user.c_str()); - Data reqUri(""); - Data reqMethod(""); - if(msg.isRequest()) { - //reqUri = Data(msg.header(h_RequestLine).uri()); - // ostringstream s; - // s << msg.header(h_RequestLine).uri(); - //reqUri = Data(s.str()); - reqUri = auth.param(p_uri); - reqMethod = Data(resip::getMethodName(msg.header(h_RequestLine).getMethod())); - } - RADIUSDigestAuthenticator *radius = NULL; - if(auth.exists(p_qop)) { - if(auth.param(p_qop) == Symbols::auth) { - Data myQop("auth"); - radius = new RADIUSDigestAuthenticator(radiusUser, user, realm, auth.param(p_nonce), reqUri, reqMethod, myQop, auth.param(p_nc), auth.param(p_cnonce), auth.param(p_response), radiusListener); - } else if(auth.param(p_qop) == Symbols::authInt) { - Data myQop("auth-int"); - radius = new RADIUSDigestAuthenticator(radiusUser, user, realm, auth.param(p_nonce), reqUri, reqMethod, myQop, auth.param(p_nc), auth.param(p_cnonce), auth.param(p_opaque), auth.param(p_response), radiusListener); - } - } - if(radius == NULL) { - radius = new RADIUSDigestAuthenticator(radiusUser, user, realm, auth.param(p_nonce), reqUri, reqMethod, auth.param(p_response), radiusListener); - } - int result = radius->doRADIUSCheck(); - if(result < 0) { - ErrLog(<<"RADIUSServerAuthManager::requestCredential, uri = " << s <<" failed to start thread, error = " << result); - } - } catch(...) { - WarningLog(<<"RADIUSServerAuthManager::requestCredential, uri = " << s <<" exception"); - delete radiusListener; - } -} - -bool RADIUSServerAuthManager::useAuthInt() const { - return true; -} - -bool RADIUSServerAuthManager::authorizedForThisIdentity(const resip::Data &user, const resip::Data &realm, resip::Uri &fromUri) { - // Always returns true: in other words, any user can send any from URI - // or forge any CLI - return true; +RADIUSServerAuthManager::~RADIUSServerAuthManager() +{ } void -RADIUSServerAuthManager::onAuthSuccess(const resip::SipMessage& msg) { +RADIUSServerAuthManager::requestCredential( + const resip::Data& user, + const resip::Data& realm, + const resip::SipMessage& msg, + const resip::Auth& auth, + const resip::Data& transactionId) +{ + DebugLog(<<"RADIUSServerAuthManager::requestCredential, uri = " << msg.header(h_RequestLine).uri() << " authUser = " << user); + + MyRADIUSDigestAuthListener *radiusListener = NULL; + try + { + radiusListener = new MyRADIUSDigestAuthListener(user, realm, dum, transactionId); + Data radiusUser = user; + DebugLog(<< "radiusUser = " << radiusUser.c_str() << ", " << "user = " << user.c_str()); + + resip_assert(msg.isRequest()); + Data reqUri = auth.param(p_uri); + Data reqMethod = Data(resip::getMethodName(msg.header(h_RequestLine).getMethod())); + + RADIUSDigestAuthenticator *radius = NULL; + if(auth.exists(p_qop)) + { + if(auth.param(p_qop) == Symbols::auth) + { + Data myQop("auth"); + radius = new RADIUSDigestAuthenticator( + radiusUser, user, realm, auth.param(p_nonce), + reqUri, reqMethod, myQop, auth.param(p_nc), auth.param(p_cnonce), + auth.param(p_response), + radiusListener); + } + else if(auth.param(p_qop) == Symbols::authInt) + { + Data myQop("auth-int"); + radius = new RADIUSDigestAuthenticator( + radiusUser, user, realm, auth.param(p_nonce), + reqUri, reqMethod, myQop, auth.param(p_nc), auth.param(p_cnonce), + auth.param(p_opaque), + auth.param(p_response), + radiusListener); + } + } + if(radius == NULL) + { + radius = new RADIUSDigestAuthenticator( + radiusUser, user, realm, auth.param(p_nonce), + reqUri, reqMethod, + auth.param(p_response), + radiusListener); + } + int result = radius->doRADIUSCheck(); + if(result < 0) + { + ErrLog(<<"RADIUSServerAuthManager::requestCredential, uri = " << msg.header(h_RequestLine).uri() <<" failed to start thread, error = " << result); + } + } + catch(...) + { + WarningLog(<<"RADIUSServerAuthManager::requestCredential, uri = " << msg.header(h_RequestLine).uri() <<" exception"); + delete radiusListener; + } +} + +bool +RADIUSServerAuthManager::useAuthInt() const +{ + return true; +} + +void +RADIUSServerAuthManager::onAuthSuccess(const resip::SipMessage& msg) +{ } void -RADIUSServerAuthManager::onAuthFailure(resip::ServerAuthManager::AuthFailureReason reason, const resip::SipMessage& msg) { - Data failureMsg("unknown failure"); - switch(reason) { - case InvalidRequest: - failureMsg = Data("InvalidRequest"); - break; - case BadCredentials: - failureMsg = Data("BadCredentials"); - break; - case Error: - failureMsg = Data("Error"); - break; - } - Tuple sourceTuple = msg.getSource(); - Data sourceIp = Data(inet_ntoa(sourceTuple.toGenericIPAddress().v4Address.sin_addr)); - WarningLog(<<"auth failure: " << failureMsg << ": src IP=" << sourceIp << ", uri=" << msg.header(h_RequestLine).uri().user() << ", from=" <requestRefresh(); +} -#define RESIPROCATE_SUBSYSTEM Subsystem::DUM - -using namespace resip; - -void -ClientRegistrationHandler::onFlowTerminated(ClientRegistrationHandle h) +bool +ClientRegistrationHandler::onRefreshRequired(ClientRegistrationHandle h, const SipMessage& lastRequest) { - InfoLog (<< "ClientRegistrationHandler::onFlowTerminated, refreshing registration to open new flow"); - h->requestRefresh(); + InfoLog(<<"ClientRegistrationHandler::onRefreshRequired, returning true"); + return true; } - -void -ServerRegistrationHandler::getGlobalExpires(const SipMessage& msg, SharedPtr masterProfile, - UInt32 &expires, UInt32 &returnCode) -{ - if (!masterProfile) - { - returnCode = 500; - assert(0); - return; - } - - expires=3600; - returnCode=0; - - if (!msg.empty(h_Expires) && msg.header(h_Expires).isWellFormed()) - { - //only client specified Expires value is subject to the min/max constraints, default is used if none specified. - expires = msg.header(h_Expires).value(); - - if (expires != 0) - { - //check min expires first since max expires will not return an error and will just change the expires value. - UInt32 minExpires = masterProfile->serverRegistrationMinExpiresTime(); - - if (expires < minExpires) - { - returnCode = 423; - expires = minExpires; - } - else - { - UInt32 maxExpires = masterProfile->serverRegistrationMaxExpiresTime(); - - if (expires > maxExpires) - { - expires = maxExpires; - } - } - } - } - else - { - expires = masterProfile->serverRegistrationDefaultExpiresTime(); - } -} - -void -ServerRegistrationHandler::getContactExpires(const NameAddr &contact, SharedPtr masterProfile, - UInt32 &expires, UInt32 &returnCode) -{ - if (!masterProfile) - { - returnCode = 500; - assert(0); - return; - } - - returnCode=0; - - if (contact.exists(p_expires)) - { - expires = contact.param(p_expires); - - if (expires != 0) - { - //check min expires first since max expires will not return an error and will just change the expires value. - UInt32 minExpires = masterProfile->serverRegistrationMinExpiresTime(); - - if (expires < minExpires) - { - returnCode = 423; - expires = minExpires; - } - else - { - UInt32 maxExpires = masterProfile->serverRegistrationMaxExpiresTime(); - - if (expires > maxExpires) - { - expires = maxExpires; - } - } - } - } -} - - -/* ==================================================================== - * The Vovida Software License, Version 1.0 - * - * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The names "VOCAL", "Vovida Open Communication Application Library", - * and "Vovida Open Communication Application Library (VOCAL)" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact vocal@vovida.org. - * - * 4. Products derived from this software may not be called "VOCAL", nor - * may "VOCAL" appear in their name, without prior written - * permission of Vovida Networks, Inc. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND - * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA - * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES - * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ==================================================================== - * - * This software consists of voluntary contributions made by Vovida - * Networks, Inc. and many individuals on behalf of Vovida Networks, - * Inc. For more information on Vovida Networks, Inc., please see - * . - * - */ + +void +ServerRegistrationHandler::getGlobalExpires(const SipMessage& msg, SharedPtr masterProfile, + UInt32 &expires, UInt32 &returnCode) +{ + if (!masterProfile) + { + returnCode = 500; + resip_assert(0); + return; + } + + expires=3600; + returnCode=0; + + if (!msg.empty(h_Expires) && msg.header(h_Expires).isWellFormed()) + { + //only client specified Expires value is subject to the min/max constraints, default is used if none specified. + expires = msg.header(h_Expires).value(); + + if (expires != 0) + { + //check min expires first since max expires will not return an error and will just change the expires value. + UInt32 minExpires = masterProfile->serverRegistrationMinExpiresTime(); + + if (expires < minExpires) + { + returnCode = 423; + expires = minExpires; + } + else + { + UInt32 maxExpires = masterProfile->serverRegistrationMaxExpiresTime(); + + if (expires > maxExpires) + { + expires = maxExpires; + } + } + } + } + else + { + expires = masterProfile->serverRegistrationDefaultExpiresTime(); + } +} + +void +ServerRegistrationHandler::getContactExpires(const NameAddr &contact, SharedPtr masterProfile, + UInt32 &expires, UInt32 &returnCode) +{ + if (!masterProfile) + { + returnCode = 500; + resip_assert(0); + return; + } + + returnCode=0; + + if (contact.exists(p_expires)) + { + expires = contact.param(p_expires); + + if (expires != 0) + { + //check min expires first since max expires will not return an error and will just change the expires value. + UInt32 minExpires = masterProfile->serverRegistrationMinExpiresTime(); + + if (expires < minExpires) + { + returnCode = 423; + expires = minExpires; + } + else + { + UInt32 maxExpires = masterProfile->serverRegistrationMaxExpiresTime(); + + if (expires > maxExpires) + { + expires = maxExpires; + } + } + } + } +} + + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * . + * + */ diff --git a/src/libs/resiprocate/resip/dum/RegistrationHandler.hxx b/src/libs/resiprocate/resip/dum/RegistrationHandler.hxx index 2f1cc916..3f5a8b48 100644 --- a/src/libs/resiprocate/resip/dum/RegistrationHandler.hxx +++ b/src/libs/resiprocate/resip/dum/RegistrationHandler.hxx @@ -37,6 +37,11 @@ class ClientRegistrationHandler /// supports RFC5626 (outbound). /// Default implementation is to immediately re-Register in an attempt to form a new flow. virtual void onFlowTerminated(ClientRegistrationHandle); + + /// Called before attempting to refresh a registration + /// Return true if the refresh should go ahead or false otherwise + /// Default implementation always returns true + virtual bool onRefreshRequired(ClientRegistrationHandle, const SipMessage& lastRequest); }; class ServerRegistrationHandler @@ -102,8 +107,8 @@ class ServerRegistrationHandler */ virtual void asyncUpdateContacts(ServerRegistrationHandle, const Uri& aor, - std::unique_ptr modifiedContactList, - std::unique_ptr transactionLog) + std::auto_ptr modifiedContactList, + std::auto_ptr transactionLog) { } @@ -112,7 +117,7 @@ class ServerRegistrationHandler */ virtual void asyncRemoveExpired(ServerRegistrationHandle, const resip::Uri& aor, - std::unique_ptr contacts) + std::auto_ptr contacts) { } }; diff --git a/src/libs/resiprocate/resip/dum/ServerAuthManager.cxx b/src/libs/resiprocate/resip/dum/ServerAuthManager.cxx index a7ecb08a..5c105356 100644 --- a/src/libs/resiprocate/resip/dum/ServerAuthManager.cxx +++ b/src/libs/resiprocate/resip/dum/ServerAuthManager.cxx @@ -1,4 +1,4 @@ -#include +#include "rutil/ResipAssert.h" #include "resip/dum/ChallengeInfo.hxx" #include "resip/dum/DumFeature.hxx" @@ -16,9 +16,10 @@ using namespace resip; using namespace std; -ServerAuthManager::ServerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target, bool challengeThirdParties) : +ServerAuthManager::ServerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target, bool challengeThirdParties, const Data& staticRealm) : DumFeature(dum, target), - mChallengeThirdParties(challengeThirdParties) + mChallengeThirdParties(challengeThirdParties), + mStaticRealm(staticRealm) { } @@ -64,8 +65,8 @@ ServerAuthManager::process(Message* msg) { InfoLog(<< "ServerAuth got ChallengeInfo " << challengeInfo->brief()); MessageMap::iterator it = mMessages.find(challengeInfo->getTransactionId()); - assert(it != mMessages.end()); - std::unique_ptr sipMsg(it->second); + resip_assert(it != mMessages.end()); + std::auto_ptr sipMsg(it->second); mMessages.erase(it); if(challengeInfo->isFailed()) @@ -88,7 +89,7 @@ ServerAuthManager::process(Message* msg) else { // challenge is not required, re-instate original message - postCommand(std::move(sipMsg)); + postCommand(auto_ptr(sipMsg)); return FeatureDoneAndEventDone; } } @@ -103,7 +104,7 @@ ServerAuthManager::process(Message* msg) Message* result = handleUserAuthInfo(userAuth); if (result) { - postCommand(unique_ptr(result)); + postCommand(auto_ptr(result)); return FeatureDoneAndEventDone; } else @@ -119,10 +120,10 @@ ServerAuthManager::process(Message* msg) SipMessage* ServerAuthManager::handleUserAuthInfo(UserAuthInfo* userAuth) { - assert(userAuth); + resip_assert(userAuth); MessageMap::iterator it = mMessages.find(userAuth->getTransactionId()); - assert(it != mMessages.end()); + resip_assert(it != mMessages.end()); SipMessage* requestWithAuth = it->second; mMessages.erase(it); @@ -269,7 +270,7 @@ ServerAuthManager::rejectBadNonces() const } -ServerAuthManager::AsyncBool +AsyncBool ServerAuthManager::requiresChallenge(const SipMessage& msg) { if(!mChallengeThirdParties) @@ -300,7 +301,7 @@ ServerAuthManager::authorizedForThisIdentity(const resip::Data &user, // header is the full fromUri, e.g. // Proxy-Authorization: Digest username="user@domain" ... // - if ((fromUri.getAorNoPort() == user) && (fromUri.host() == realm)) + if (fromUri.getAorNoPort() == user) return true; // catch-all: access denied @@ -311,6 +312,19 @@ ServerAuthManager::authorizedForThisIdentity(const resip::Data &user, const Data& ServerAuthManager::getChallengeRealm(const SipMessage& msg) { + // (1) Check if static realm is defined + if (!mStaticRealm.empty()) + { + return mStaticRealm; + } + + // (2) Check From domain + if (mDum.isMyDomain(msg.header(h_From).uri().host())) + { + return msg.header(h_From).uri().host(); + } + + // (3) Punt: Use Request URI return msg.header(h_RequestLine).uri().host(); } @@ -318,6 +332,10 @@ ServerAuthManager::getChallengeRealm(const SipMessage& msg) bool ServerAuthManager::isMyRealm(const Data& realm) { + if(!mStaticRealm.empty()) + { + return mStaticRealm == realm; + } return mDum.isMyDomain(realm); } @@ -327,58 +345,93 @@ ServerAuthManager::Result ServerAuthManager::handle(SipMessage* sipMsg) { //InfoLog( << "trying to do auth" ); - if (sipMsg->isRequest() && - sipMsg->header(h_RequestLine).method() != ACK && - sipMsg->header(h_RequestLine).method() != CANCEL) // Do not challenge ACKs or CANCELs + if (sipMsg->isRequest()) { - ParserContainer* auths; - if (proxyAuthenticationMode()) + if(sipMsg->method() == CANCEL) { - if(!sipMsg->exists(h_ProxyAuthorizations)) + // If we receive a cancel - check to see if we have the matching INVITE in our message map. + // If we do, then we haven't created a DUM dialog for it yet, since we are still waiting + // for the credential information to arrive. We need to properly respond to the CANCEL here + // since it won't be handled externally. + MessageMap::iterator it = mMessages.find(sipMsg->getTransactionId()); + if(it != mMessages.end()) { - return issueChallengeIfRequired(sipMsg); - } - auths = &sipMsg->header(h_ProxyAuthorizations); - } - else - { - if(!sipMsg->exists(h_Authorizations)) - { - return issueChallengeIfRequired(sipMsg); - } - auths = &sipMsg->header(h_Authorizations); - } - - try - { - for(Auths::iterator it = auths->begin(); it != auths->end(); it++) - { - if (isMyRealm(it->param(p_realm))) + // Ensure message is an INVITE - if not then something fishy is going on. Either + // someone has cancelled a non-INVITE transaction or we have a tid collision. + if(it->second->isRequest() && it->second->method() == INVITE) { - InfoLog (<< "Requesting credential for " - << it->param(p_username) << " @ " << it->param(p_realm)); - - requestCredential(it->param(p_username), - it->param(p_realm), - *sipMsg, - *it, - sipMsg->getTransactionId()); - mMessages[sipMsg->getTransactionId()] = sipMsg; - return RequestedCredentials; + std::auto_ptr inviteMsg(it->second); + mMessages.erase(it); // Remove the INVITE from the message map and respond to it + + InfoLog (<< "Received a CANCEL for an INVITE request that we are still waiting on auth " + << "info for, responding appropriately, tid=" + << sipMsg->getTransactionId()); + + // Send 487/Inv + SharedPtr inviteResponse(new SipMessage); + Helper::makeResponse(*inviteResponse, *inviteMsg, 487); // Request Cancelled + mDum.send(inviteResponse); + + // Send 200/Cancel + SharedPtr cancelResponse(new SipMessage); + Helper::makeResponse(*cancelResponse, *sipMsg, 200); + mDum.send(cancelResponse); + + return Rejected; // Use rejected since handling is what we want - stop DUM from processing the cancel any further } } - - InfoLog (<< "Didn't find matching realm "); - return issueChallengeIfRequired(sipMsg); } - catch(BaseException& e) + else if(sipMsg->method() != ACK) // Do not challenge ACKs or CANCELs (picked off above) { - InfoLog (<< "Invalid auth header provided " << e); - SharedPtr response(new SipMessage); - Helper::makeResponse(*response, *sipMsg, 400, "Invalid auth header"); - mDum.send(response); - onAuthFailure(InvalidRequest, *sipMsg); - return Rejected; + ParserContainer* auths; + if (proxyAuthenticationMode()) + { + if(!sipMsg->exists(h_ProxyAuthorizations)) + { + return issueChallengeIfRequired(sipMsg); + } + auths = &sipMsg->header(h_ProxyAuthorizations); + } + else + { + if(!sipMsg->exists(h_Authorizations)) + { + return issueChallengeIfRequired(sipMsg); + } + auths = &sipMsg->header(h_Authorizations); + } + + try + { + for(Auths::iterator it = auths->begin(); it != auths->end(); it++) + { + if (isMyRealm(it->param(p_realm))) + { + InfoLog (<< "Requesting credential for " + << it->param(p_username) << " @ " << it->param(p_realm)); + + requestCredential(it->param(p_username), + it->param(p_realm), + *sipMsg, + *it, + sipMsg->getTransactionId()); + mMessages[sipMsg->getTransactionId()] = sipMsg; + return RequestedCredentials; + } + } + + InfoLog (<< "Didn't find matching realm "); + return issueChallengeIfRequired(sipMsg); + } + catch(BaseException& e) + { + InfoLog (<< "Invalid auth header provided " << e); + SharedPtr response(new SipMessage); + Helper::makeResponse(*response, *sipMsg, 400, "Invalid auth header"); + mDum.send(response); + onAuthFailure(InvalidRequest, *sipMsg); + return Rejected; + } } } return Skipped; diff --git a/src/libs/resiprocate/resip/dum/ServerAuthManager.hxx b/src/libs/resiprocate/resip/dum/ServerAuthManager.hxx index cd30b2b2..83728c0d 100644 --- a/src/libs/resiprocate/resip/dum/ServerAuthManager.hxx +++ b/src/libs/resiprocate/resip/dum/ServerAuthManager.hxx @@ -3,6 +3,7 @@ #include +#include "rutil/AsyncBool.hxx" #include "resip/stack/Auth.hxx" #include "resip/stack/SipMessage.hxx" #include "DumFeature.hxx" @@ -26,7 +27,7 @@ class ServerAuthManager : public DumFeature Rejected }; - ServerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target, bool challengeThirdParties = true); + ServerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target, bool challengeThirdParties = true, const resip::Data& staticRealm = ""); virtual ~ServerAuthManager(); virtual ProcessingResult process(Message* msg); @@ -43,13 +44,6 @@ class ServerAuthManager : public DumFeature protected: - enum AsyncBool - { - True, // response is true - False, // response is false - Async // response will be sent asynchronously - }; - enum AuthFailureReason { InvalidRequest, // some aspect of the request (e.g. nonce) @@ -100,8 +94,8 @@ class ServerAuthManager : public DumFeature virtual void onAuthSuccess(const SipMessage& msg); virtual void onAuthFailure(AuthFailureReason reason, const SipMessage& msg); - private: bool mChallengeThirdParties; + resip::Data mStaticRealm; }; diff --git a/src/libs/resiprocate/resip/dum/ServerInviteSession.cxx b/src/libs/resiprocate/resip/dum/ServerInviteSession.cxx index ca377f0c..ea8f4c07 100644 --- a/src/libs/resiprocate/resip/dum/ServerInviteSession.cxx +++ b/src/libs/resiprocate/resip/dum/ServerInviteSession.cxx @@ -10,6 +10,7 @@ #include "resip/dum/UsageUseException.hxx" #include "resip/dum/DumHelper.hxx" #include "resip/dum/DumCommand.hxx" +#include "rutil/Random.hxx" #include "rutil/Logger.hxx" #include "rutil/compat.hxx" #include "rutil/WinLeakCheck.hxx" @@ -22,9 +23,11 @@ ServerInviteSession::ServerInviteSession(DialogUsageManager& dum, Dialog& dialog : InviteSession(dum, dialog), mFirstRequest(request), m1xx(new SipMessage), - mCurrentRetransmit1xx(0) + mCurrentRetransmit1xxSeq(0), + mLocalRSeq(0), + mAnswerSentReliably(false) { - assert(request.isRequest()); + resip_assert(request.isRequest()); mState = UAS_Start; } @@ -50,12 +53,15 @@ ServerInviteSession::redirect(const NameAddrs& contacts, int code) case UAS_FirstSentOfferReliable: case UAS_NoOffer: case UAS_NoOfferReliable: + case UAS_ProvidedOfferReliable: + case UAS_OfferReliableProvidedAnswer: + case UAS_NoAnswerReliableWaitingPrack: + case UAS_NoAnswerReliable: case UAS_Offer: case UAS_OfferProvidedAnswer: - case UAS_ReceivedOfferReliable: + case UAS_OfferReliable: case UAS_ProvidedOffer: case UAS_ReceivedUpdate: - case UAS_ReceivedUpdateWaitingAnswer: case UAS_SentUpdate: { // !jf! the cleanup for 3xx may be a bit strange if we are in the middle of @@ -83,11 +89,11 @@ ServerInviteSession::redirect(const NameAddrs& contacts, int code) case UAS_WaitingToOffer: case UAS_WaitingToRequestOffer: case UAS_WaitingToHangup: - case UAS_WaitingToTerminate: case UAS_SentUpdateAccepted: + case UAS_ReceivedUpdateWaitingAnswer: case UAS_Start: default: - assert(0); + resip_assert(0); throw UsageUseException("Can't redirect after accepted", __FILE__, __LINE__); break; } @@ -96,8 +102,8 @@ ServerInviteSession::redirect(const NameAddrs& contacts, int code) class ServerInviteSessionRedirectCommand : public DumCommandAdapter { public: - ServerInviteSessionRedirectCommand(ServerInviteSession& serverInviteSession, const NameAddrs& contacts, int code) - : mServerInviteSession(serverInviteSession), + ServerInviteSessionRedirectCommand(const ServerInviteSessionHandle& serverInviteSessionHandle, const NameAddrs& contacts, int code) + : mServerInviteSessionHandle(serverInviteSessionHandle), mContacts(contacts), mCode(code) { @@ -106,7 +112,10 @@ public: virtual void executeCommand() { - mServerInviteSession.redirect(mContacts, mCode); + if(mServerInviteSessionHandle.isValid()) + { + mServerInviteSessionHandle->redirect(mContacts, mCode); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -114,7 +123,7 @@ public: return strm << "ServerInviteSessionRedirectCommand"; } private: - ServerInviteSession& mServerInviteSession; + ServerInviteSessionHandle mServerInviteSessionHandle; NameAddrs mContacts; int mCode; }; @@ -122,7 +131,7 @@ private: void ServerInviteSession::redirectCommand(const NameAddrs& contacts, int code) { - mDum.post(new ServerInviteSessionRedirectCommand(*this, contacts, code)); + mDum.post(new ServerInviteSessionRedirectCommand(getHandle(), contacts, code)); } void @@ -160,28 +169,63 @@ ServerInviteSession::provisional(int code, bool earlyFlag) sendProvisional(code, earlyFlag); break; - case UAS_NoOfferReliable: case UAS_NegotiatedReliable: - // TBD - assert(0); + case UAS_FirstSentAnswerReliable: + case UAS_NoAnswerReliableWaitingPrack: + case UAS_FirstSentOfferReliable: + if(mUnacknowledgedReliableProvisional.get()) + { + InfoLog (<< "Waiting for PRACK. queued provisional, code=" << code << ", early=" << (earlyFlag ? "YES" : "NO") ); + queueResponse(code, earlyFlag); + } + else + { + sendProvisional(code, earlyFlag); + } + break; + + case UAS_NoAnswerReliable: + case UAS_OfferReliable: + if(sendProvisional(code, earlyFlag)) + { + // If sent reliably then change state + transition(UAS_NoAnswerReliableWaitingPrack); + } + break; + + case UAS_ProvidedOfferReliable: + if(sendProvisional(code, earlyFlag)) + { + // If sent reliably then change state + transition(UAS_FirstSentOfferReliable); + } + break; + + case UAS_OfferReliableProvidedAnswer: + if(mUnacknowledgedReliableProvisional.get()) // First 18x may not have containted answer and still be outstanding + { + InfoLog (<< "Waiting for PRACK. queued provisional, code=" << code << ", early=" << (earlyFlag ? "YES" : "NO") ); + queueResponse(code, earlyFlag); + } + else if(sendProvisional(code, earlyFlag) && earlyFlag) + { + // If sent reliably and earlyFlag set (answer actually sent) then change state + transition(UAS_FirstSentAnswerReliable); + } break; case UAS_Accepted: case UAS_WaitingToOffer: case UAS_WaitingToRequestOffer: - case UAS_FirstSentAnswerReliable: - case UAS_FirstSentOfferReliable: - case UAS_ReceivedOfferReliable: case UAS_ReceivedUpdate: case UAS_ReceivedUpdateWaitingAnswer: case UAS_SentUpdate: case UAS_SentUpdateAccepted: case UAS_Start: case UAS_WaitingToHangup: - case UAS_WaitingToTerminate: default: - assert(0); + resip_assert(0); break; } } @@ -189,15 +233,19 @@ ServerInviteSession::provisional(int code, bool earlyFlag) class ServerInviteSessionProvisionalCommand : public DumCommandAdapter { public: - ServerInviteSessionProvisionalCommand(ServerInviteSession& serverInviteSession, int statusCode) - : mServerInviteSession(serverInviteSession), - mStatusCode(statusCode) + ServerInviteSessionProvisionalCommand(const ServerInviteSessionHandle& serverInviteSessionHandle, int statusCode, bool earlyFlag) + : mServerInviteSessionHandle(serverInviteSessionHandle), + mStatusCode(statusCode), + mEarlyFlag(earlyFlag) { } virtual void executeCommand() { - mServerInviteSession.provisional(mStatusCode); + if(mServerInviteSessionHandle.isValid()) + { + mServerInviteSessionHandle->provisional(mStatusCode, mEarlyFlag); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -205,20 +253,22 @@ public: return strm << "ServerInviteSessionProvisionalCommand"; } private: - ServerInviteSession& mServerInviteSession; + ServerInviteSessionHandle mServerInviteSessionHandle; int mStatusCode; + bool mEarlyFlag; }; void -ServerInviteSession::provisionalCommand(int statusCode) +ServerInviteSession::provisionalCommand(int statusCode, bool earlyFlag) { - mDum.post(new ServerInviteSessionProvisionalCommand(*this, statusCode)); + mDum.post(new ServerInviteSessionProvisionalCommand(getHandle(), statusCode, earlyFlag)); } void ServerInviteSession::provideOffer(const Contents& offer, DialogUsageManager::EncryptionLevel level, - const Contents* alternative) + const Contents* alternative, + bool sendOfferAtAccept) { InfoLog (<< toData(mState) << ": provideOffer"); switch (mState) @@ -236,17 +286,23 @@ ServerInviteSession::provideOffer(const Contents& offer, break; case UAS_NoOfferReliable: + transition(UAS_ProvidedOfferReliable); mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(offer, alternative); mProposedEncryptionLevel = level; - // !jf! transition ? break; case UAS_NegotiatedReliable: - // queue offer - transition(UAS_SentUpdate); mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(offer, alternative); mProposedEncryptionLevel = level; - sendUpdate(offer); + if (sendOfferAtAccept) + { + transition(UAS_ProvidedOffer); + } + else + { + transition(UAS_SentUpdate); + sendUpdate(offer); + } break; case UAS_Accepted: @@ -260,25 +316,31 @@ ServerInviteSession::provideOffer(const Contents& offer, InviteSession::provideOffer(offer, level, alternative); break; + case UAS_FirstSentAnswerReliable: + // Queue up offer to be sent after PRACK arrives + mProposedLocalOfferAnswer = InviteSession::makeOfferAnswer(offer); + mProposedEncryptionLevel = level; + break; + case UAS_EarlyProvidedAnswer: case UAS_EarlyProvidedOffer: - case UAS_FirstSentAnswerReliable: case UAS_FirstSentOfferReliable: case UAS_Offer: case UAS_EarlyOffer: - case UAS_ReceivedOfferReliable: + case UAS_OfferReliable: case UAS_OfferProvidedAnswer: case UAS_ProvidedOffer: + case UAS_ProvidedOfferReliable: case UAS_ReceivedUpdate: case UAS_ReceivedUpdateWaitingAnswer: case UAS_SentUpdate: case UAS_SentUpdateAccepted: case UAS_Start: case UAS_WaitingToHangup: - case UAS_WaitingToTerminate: case UAS_WaitingToRequestOffer: case UAS_AcceptedWaitingAnswer: - assert(0); + WarningLog (<< "Incorrect state to provideOffer: " << toData(mState)); + throw DialogUsage::Exception("Can't provide an offer", __FILE__,__LINE__); break; default: InviteSession::provideOffer(offer, level, alternative); @@ -286,13 +348,27 @@ ServerInviteSession::provideOffer(const Contents& offer, } } +void +ServerInviteSession::provideOffer(const Contents& offer, + DialogUsageManager::EncryptionLevel level, + const Contents* alternative) +{ + this->provideOffer(offer, level, alternative, false); +} + +void +ServerInviteSession::provideOffer(const Contents& offer, + bool sendOfferAtAccept) +{ + this->provideOffer(offer, mCurrentEncryptionLevel, 0, sendOfferAtAccept); +} + void ServerInviteSession::provideOffer(const Contents& offer) { - this->provideOffer(offer, mCurrentEncryptionLevel, 0); + this->provideOffer(offer, mCurrentEncryptionLevel, 0, false); } - void ServerInviteSession::requestOffer() { @@ -317,37 +393,90 @@ ServerInviteSession::requestOffer() void ServerInviteSession::provideAnswer(const Contents& answer) { - InviteSessionHandler* handler = mDum.mInviteSessionHandler; InfoLog (<< toData(mState) << ": provideAnswer"); + mAnswerSentReliably = false; switch (mState) { case UAS_Offer: transition(UAS_OfferProvidedAnswer); - mCurrentRemoteOfferAnswer = std::move(mProposedRemoteOfferAnswer); + mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer; mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer); break; case UAS_EarlyOffer: transition(UAS_EarlyProvidedAnswer); - mCurrentRemoteOfferAnswer = std::move(mProposedRemoteOfferAnswer); + mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer; mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer); break; - case UAS_ReceivedOfferReliable: - // send1XX-answer, timer::1xx - transition(UAS_FirstSentAnswerReliable); + case UAS_OfferReliable: + mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer; + mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer); + transition(UAS_OfferReliableProvidedAnswer); + break; + + case UAS_NoAnswerReliableWaitingPrack: + // Store answer and wait for PRACK + mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer; + mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer); break; case UAS_ReceivedUpdate: - // send::200U-answer - transition(UAS_NegotiatedReliable); + { + transition(UAS_NegotiatedReliable); + + // Send answer in 200/Update + SharedPtr response(new SipMessage); + mDialog.makeResponse(*response, *mLastRemoteSessionModification, 200); + InviteSession::setOfferAnswer(*response, answer, 0); + mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer); + mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer; + InfoLog (<< "Sending " << response->brief()); + DumHelper::setOutgoingEncryptionLevel(*response, mCurrentEncryptionLevel); + send(response); + } break; case UAS_ReceivedUpdateWaitingAnswer: - // send::2XXU-answer - // send::2XXI - transition(Connected); - handler->onConnected(getSessionHandle(), *mInvite200); + { + SharedPtr response(new SipMessage); + mDialog.makeResponse(*response, *mLastRemoteSessionModification, 200); + InviteSession::setOfferAnswer(*response, answer, 0); + mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer); + mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer; + InfoLog (<< "Sending " << response->brief()); + DumHelper::setOutgoingEncryptionLevel(*response, mCurrentEncryptionLevel); + send(response); + + // send the queued 200/Invite + updateCheckQueue(); + } + break; + + case UAS_NoAnswerReliable: + mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer; + mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer); + transition(UAS_OfferReliableProvidedAnswer); + break; + + // If we received an offer in a PRACK then we transition to NegotiateReliable and expect + // provideAnswer to be called to send the 200/Prack containing the answer. + case UAS_NegotiatedReliable: + if(mPrackWithOffer.get()) + { + mCurrentRemoteOfferAnswer = mProposedRemoteOfferAnswer; + mCurrentLocalOfferAnswer = InviteSession::makeOfferAnswer(answer); + SharedPtr p200(new SipMessage); + mDialog.makeResponse(*p200, *mPrackWithOffer, 200); + setOfferAnswer(*p200, mCurrentLocalOfferAnswer.get()); + mAnswerSentReliably = true; + mPrackWithOffer.reset(); + send(p200); + } + else + { + resip_assert(0); + } break; case UAS_Accepted: @@ -356,20 +485,20 @@ ServerInviteSession::provideAnswer(const Contents& answer) case UAS_EarlyNoOffer: case UAS_EarlyProvidedAnswer: case UAS_EarlyProvidedOffer: - case UAS_NegotiatedReliable: case UAS_FirstSentAnswerReliable: case UAS_FirstSentOfferReliable: case UAS_NoOffer: case UAS_NoOfferReliable: case UAS_OfferProvidedAnswer: case UAS_ProvidedOffer: + case UAS_ProvidedOfferReliable: case UAS_SentUpdate: case UAS_SentUpdateAccepted: case UAS_Start: case UAS_WaitingToHangup: - case UAS_WaitingToTerminate: case UAS_AcceptedWaitingAnswer: - assert(0); + WarningLog (<< "Incorrect state to provideAnswer: " << toData(mState)); + throw DialogUsage::Exception("Can't provide an answer", __FILE__,__LINE__); break; default: InviteSession::provideAnswer(answer); @@ -409,29 +538,33 @@ ServerInviteSession::end(EndReason reason) case UAS_Offer: case UAS_OfferProvidedAnswer: case UAS_ProvidedOffer: + case UAS_ProvidedOfferReliable: reject(480); break; - case UAS_ReceivedOfferReliable: + case UAS_OfferReliable: + case UAS_OfferReliableProvidedAnswer: case UAS_NegotiatedReliable: case UAS_FirstSentOfferReliable: case UAS_FirstSentAnswerReliable: + case UAS_NoAnswerReliableWaitingPrack: + case UAS_NoAnswerReliable: case UAS_NoOfferReliable: case UAS_ReceivedUpdate: // !slg! todo: send 488U case UAS_ReceivedUpdateWaitingAnswer: // !slg! todo: send 488U case UAS_SentUpdate: - case UAS_WaitingToTerminate: + case UAS_SentUpdateGlare: + case UAS_SentUpdateAccepted: reject(480); break; case UAS_Start: - assert(0); + resip_assert(0); break; case UAS_Accepted: case UAS_WaitingToOffer: case UAS_WaitingToRequestOffer: - case UAS_SentUpdateAccepted: case UAS_AcceptedWaitingAnswer: if(mCurrentRetransmit200) // If retransmit200 timer is active then ACK is not received yet - wait for it { @@ -439,7 +572,7 @@ ServerInviteSession::end(EndReason reason) } else { - // ACK has likely timedout - hangup immediately + // ACK has likely timed out - hangup immediately SharedPtr msg = sendBye(); transition(Terminated); mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::LocalBye, msg.get()); @@ -470,14 +603,22 @@ ServerInviteSession::reject(int code, WarningCategory *warning) case UAS_Offer: case UAS_OfferProvidedAnswer: case UAS_ProvidedOffer: + case UAS_ProvidedOfferReliable: + case UAS_AcceptedWaitingAnswer: case UAS_NegotiatedReliable: case UAS_FirstSentAnswerReliable: + case UAS_NoAnswerReliableWaitingPrack: + case UAS_NoAnswerReliable: case UAS_FirstSentOfferReliable: case UAS_NoOfferReliable: - case UAS_ReceivedOfferReliable: - case UAS_ReceivedUpdate: + case UAS_OfferReliable: + case UAS_OfferReliableProvidedAnswer: + case UAS_ReceivedUpdate: // Note: This rejects the entire InviteSession - there is no way right now to reject only the Offer that was received via an Update + case UAS_ReceivedUpdateWaitingAnswer: // yes it's wrong to call reject after accept - however we can get here from end() as well. We haven't sent our 200/Inv on the wire yet, so we can just reject the Invite session to end it case UAS_SentUpdate: + case UAS_SentUpdateGlare: + case UAS_SentUpdateAccepted: // yes it's wrong to call reject after accept - however we can get here from end() as well. We haven't sent our 200/Inv on the wire yet, so we can just reject the Invite session to end it { // !jf! the cleanup for 3xx may be a bit strange if we are in the middle of // an offer/answer exchange with PRACK. @@ -491,6 +632,11 @@ ServerInviteSession::reject(int code, WarningCategory *warning) } send(response); + if (mDum.mDialogEventStateManager) + { + mDum.mDialogEventStateManager->onTerminated(mDialog, *response, InviteSessionHandler::Rejected); + } + transition(Terminated); mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::Rejected); mDum.destroy(this); @@ -500,12 +646,9 @@ ServerInviteSession::reject(int code, WarningCategory *warning) case UAS_Accepted: case UAS_WaitingToOffer: case UAS_WaitingToRequestOffer: - case UAS_ReceivedUpdateWaitingAnswer: - case UAS_SentUpdateAccepted: case UAS_Start: case UAS_WaitingToHangup: - case UAS_WaitingToTerminate: - assert(0); + resip_assert(0); break; default: @@ -523,7 +666,8 @@ ServerInviteSession::accept(int code) { case UAS_Offer: case UAS_EarlyOffer: - assert(0); + case UAS_FirstSentOfferReliable: + resip_assert(0); break; case UAS_OfferProvidedAnswer: @@ -535,10 +679,11 @@ ServerInviteSession::accept(int code) case UAS_NoOffer: case UAS_EarlyNoOffer: - assert(0); + resip_assert(0); break; case UAS_ProvidedOffer: + case UAS_ProvidedOfferReliable: case UAS_EarlyProvidedOffer: transition(UAS_AcceptedWaitingAnswer); sendAccept(code, mProposedLocalOfferAnswer.get()); @@ -547,44 +692,56 @@ ServerInviteSession::accept(int code) case UAS_Accepted: case UAS_WaitingToOffer: case UAS_WaitingToRequestOffer: - assert(0); // Already Accepted + resip_assert(0); // Already Accepted break; case UAS_FirstSentAnswerReliable: + case UAS_NoAnswerReliableWaitingPrack: // queue 2xx // waiting for PRACK - transition(UAS_Accepted); - mDialog.makeResponse(*mInvite200, mFirstRequest, code); - handleSessionTimerRequest(*mInvite200, mFirstRequest); + InfoLog (<< "Waiting for PRACK. queued 200 OK" ); + queueResponse(code, false); break; case UAS_NegotiatedReliable: - transition(Connected); - sendAccept(code, 0); + if(mUnacknowledgedReliableProvisional.get()) + { + InfoLog (<< "Waiting for PRACK. queued provisional" ); + queueResponse(code, false); + } + else + { + transition(UAS_Accepted); + sendAccept(code, 0); + handler->onConnected(getSessionHandle(), *mInvite200); + } + break; + + case UAS_OfferReliableProvidedAnswer: + transition(UAS_Accepted); + sendAccept(code, mCurrentLocalOfferAnswer.get()); handler->onConnected(getSessionHandle(), *mInvite200); break; case UAS_SentUpdate: transition(UAS_SentUpdateAccepted); - sendAccept(code, 0); + queueResponse(code, false); break; case UAS_ReceivedUpdate: transition(UAS_ReceivedUpdateWaitingAnswer); - mDialog.makeResponse(*mInvite200, mFirstRequest, code);// queue 2xx - handleSessionTimerRequest(*mInvite200, mFirstRequest); + queueResponse(code, false); break; - case UAS_FirstSentOfferReliable: + case UAS_NoAnswerReliable: case UAS_NoOfferReliable: - case UAS_ReceivedOfferReliable: + case UAS_OfferReliable: case UAS_ReceivedUpdateWaitingAnswer: case UAS_SentUpdateAccepted: case UAS_Start: case UAS_WaitingToHangup: - case UAS_WaitingToTerminate: default: - assert(0); + resip_assert(0); break; } } @@ -592,15 +749,18 @@ ServerInviteSession::accept(int code) class ServerInviteSessionAcceptCommand : public DumCommandAdapter { public: - ServerInviteSessionAcceptCommand(ServerInviteSession& serverInviteSession, int statusCode) - : mServerInviteSession(serverInviteSession), + ServerInviteSessionAcceptCommand(const ServerInviteSessionHandle& serverInviteSessionHandle, int statusCode) + : mServerInviteSessionHandle(serverInviteSessionHandle), mStatusCode(statusCode) { } virtual void executeCommand() { - mServerInviteSession.accept(mStatusCode); + if(mServerInviteSessionHandle.isValid()) + { + mServerInviteSessionHandle->accept(mStatusCode); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -608,14 +768,14 @@ public: return strm << "ServerInviteSessionAcceptCommand"; } private: - ServerInviteSession& mServerInviteSession; + ServerInviteSessionHandle mServerInviteSessionHandle; int mStatusCode; }; void ServerInviteSession::acceptCommand(int statusCode) { - mDum.post(new ServerInviteSessionAcceptCommand(*this, statusCode)); + mDum.post(new ServerInviteSessionAcceptCommand(getHandle(), statusCode)); } void @@ -646,11 +806,18 @@ ServerInviteSession::dispatch(const SipMessage& msg) case UAS_EarlyProvidedAnswer: case UAS_NoOffer: case UAS_ProvidedOffer: + case UAS_ProvidedOfferReliable: case UAS_EarlyNoOffer: case UAS_EarlyProvidedOffer: case UAS_OfferProvidedAnswer: + case UAS_NoOfferReliable: + case UAS_OfferReliable: + case UAS_NoAnswerReliable: dispatchOfferOrEarly(msg); - break; + break; + case UAS_OfferReliableProvidedAnswer: + dispatchOfferReliableProvidedAnswer(msg); + break; case UAS_Accepted: dispatchAccepted(msg); break; @@ -663,21 +830,15 @@ ServerInviteSession::dispatch(const SipMessage& msg) case UAS_AcceptedWaitingAnswer: dispatchAcceptedWaitingAnswer(msg); break; - case UAS_NegotiatedReliable: - dispatchEarlyReliable(msg); - break; case UAS_FirstSentAnswerReliable: - dispatchFirstEarlyReliable(msg); + dispatchFirstSentAnswerReliable(msg); + break; + case UAS_NoAnswerReliableWaitingPrack: + dispatchNoAnswerReliableWaitingPrack(msg); break; case UAS_FirstSentOfferReliable: dispatchFirstSentOfferReliable(msg); break; - case UAS_NoOfferReliable: - dispatchNoOfferReliable(msg); - break; - case UAS_ReceivedOfferReliable: - dispatchOfferReliable(msg); - break; case UAS_ReceivedUpdate: dispatchReceivedUpdate(msg); break; @@ -687,15 +848,18 @@ ServerInviteSession::dispatch(const SipMessage& msg) case UAS_SentUpdate: dispatchSentUpdate(msg); break; + case UAS_SentUpdateGlare: + dispatchSentUpdateGlare(msg); + break; case UAS_WaitingToHangup: dispatchWaitingToHangup(msg); break; - case UAS_WaitingToTerminate: - dispatchWaitingToTerminate(msg); - break; case UAS_SentUpdateAccepted: dispatchSentUpdateAccepted(msg); break; + case UAS_NegotiatedReliable: + dispatchNegotiatedReliable(msg); + break; default: InviteSession::dispatch(msg); break; @@ -707,12 +871,78 @@ ServerInviteSession::dispatch(const DumTimeout& timeout) { if (timeout.type() == DumTimeout::Retransmit1xx) { - if (mCurrentRetransmit1xx && m1xx->header(h_CSeq).sequence() == timeout.seq()) // If timer isn't stopped and this timer is for last 1xx sent, then resend + if (timeout.seq() == mCurrentRetransmit1xxSeq) // If timer isn't stopped and this timer is for last 1xx sent, then resend { send(m1xx); startRetransmit1xxTimer(); } } + else if (timeout.type() == DumTimeout::Resubmit1xxRel) + { + if (timeout.seq() == mCurrentRetransmit1xxSeq) // If timer isn't stopped and this timer is for last 1xx sent, then resend + { + // This is not a retransmission, it is a resubmission - ensure the RSeq number is incremented + if(m1xx->exists(h_RSeq)) + { + // increment RSeq + m1xx->header(h_RSeq).value()++; + + // Remove any body/sdp + m1xx->setContents(0); + + mUnacknowledgedReliableProvisional = m1xx; + send(m1xx); + startResubmit1xxRelTimer(); + } + } + } + else if (timeout.type() == DumTimeout::Retransmit1xxRel) + { + if (mUnacknowledgedReliableProvisional.get() && + mUnacknowledgedReliableProvisional->header(h_RSeq).value() == timeout.seq()) + { + unsigned int duration = 2*timeout.secondarySeq(); + if(duration>=64*Timer::T1) + { + InfoLog (<< "Reliable provisional timeout" ); + SharedPtr i504(new SipMessage); + mDialog.makeResponse(*i504, mFirstRequest, 504); + send(i504); + + transition(Terminated); + + if (mDum.mDialogEventStateManager) + { + SipMessage msg; // should onTerminated require this msg? + mDum.mDialogEventStateManager->onTerminated(mDialog, msg, InviteSessionHandler::Timeout); + } + + mDum.mInviteSessionHandler->onTerminated(getSessionHandle(), InviteSessionHandler::Timeout); + mDum.destroy(this); + return; + } + else + { + InfoLog (<< "Reliable provisional retransmit" ); + send(mUnacknowledgedReliableProvisional); + mDum.addTimerMs(DumTimeout::Retransmit1xxRel, duration, getBaseHandle(), timeout.seq(), duration); + } + } + } + else if (timeout.type() == DumTimeout::Glare) + { + if (mState == UAS_SentUpdateGlare) + { + transition(UAS_SentUpdate); + InfoLog (<< "Retransmitting the UPDATE (glare condition timer)"); + mDialog.makeRequest(*mLastLocalSessionModification, UPDATE); // increments CSeq + send(mLastLocalSessionModification); + } + else + { + InviteSession::dispatch(timeout); + } + } else { InviteSession::dispatch(timeout); @@ -722,11 +952,11 @@ ServerInviteSession::dispatch(const DumTimeout& timeout) void ServerInviteSession::dispatchStart(const SipMessage& msg) { - assert(msg.isRequest()); - assert(msg.header(h_CSeq).method() == INVITE); + resip_assert(msg.isRequest()); + resip_assert(msg.header(h_CSeq).method() == INVITE); InviteSessionHandler* handler = mDum.mInviteSessionHandler; - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); storePeerCapabilities(msg); if (mDum.mDialogEventStateManager) @@ -758,7 +988,7 @@ ServerInviteSession::dispatchStart(const SipMessage& msg) break; case OnInviteReliableOffer: *mLastRemoteSessionModification = msg; - transition(UAS_ReceivedOfferReliable); + transition(UAS_OfferReliable); mProposedRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer); mCurrentEncryptionLevel = getEncryptionLevel(msg); handler->onNewSession(getHandle(), InviteSession::Offer, msg); @@ -777,16 +1007,18 @@ ServerInviteSession::dispatchStart(const SipMessage& msg) } break; default: - assert(0); + resip_assert(0); break; } } -// Offer, Early, EarlyNoOffer, NoOffer +// UAS_Offer, UAS_EarlyOffer, UAS_EarlyProvidedAnswer, UAS_NoOffer, UAS_ProvidedOffer, +// UAS_ProvidedOfferReliable, UAS_EarlyNoOffer, UAS_EarlyProvidedOffer, UAS_OfferProvidedAnswer, +// UAS_NoOfferReliable, UAS_OfferReliable, UAS_NoAnswerReliable void ServerInviteSession::dispatchOfferOrEarly(const SipMessage& msg) { - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); switch (toEvent(msg, offerAnswer.get())) { case OnCancel: @@ -795,9 +1027,20 @@ ServerInviteSession::dispatchOfferOrEarly(const SipMessage& msg) case OnBye: dispatchBye(msg); break; + case OnUpdate: + { + // Update with no SDP is a target refresh ?slg? just respond immediately - do we need a callback? + // Note: target refresh handling is in Dialog::handleTargetRefresh + SharedPtr response(new SipMessage); + mDialog.makeResponse(*response, msg, 200); + send(response); + break; + } default: - assert(msg.isRequest()); - dispatchUnknown(msg); + if(msg.isRequest()) + { + dispatchUnknown(msg); + } break; } } @@ -806,7 +1049,7 @@ void ServerInviteSession::dispatchAccepted(const SipMessage& msg) { InviteSessionHandler* handler = mDum.mInviteSessionHandler; - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); InfoLog (<< "dispatchAccepted: " << msg.brief()); switch (toEvent(msg, offerAnswer.get())) @@ -826,12 +1069,10 @@ ServerInviteSession::dispatchAccepted(const SipMessage& msg) case OnAck: case OnAckAnswer: // .bwc. unsolicited body in ACK; it would probably make sense to just ignore. - { mCurrentRetransmit200 = 0; // stop the 200 retransmit timer transition(Connected); handler->onConnectedConfirmed(getSessionHandle(), msg); break; - } case OnCancel: { @@ -854,6 +1095,15 @@ ServerInviteSession::dispatchAccepted(const SipMessage& msg) break; } + case OnPrack: + { + // should never get a prack here - we always queue up our 200/Inv response + InfoLog (<< "spurious PRACK in state=" << toData(mState)); + SharedPtr p481(new SipMessage); + mDialog.makeResponse(*p481, msg, 481); + send(p481); + break; + } default: if(msg.isRequest()) @@ -868,7 +1118,7 @@ void ServerInviteSession::dispatchWaitingToOffer(const SipMessage& msg) { InviteSessionHandler* handler = mDum.mInviteSessionHandler; - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); InfoLog (<< "dispatchWaitingToOffer: " << msg.brief()); switch (toEvent(msg, offerAnswer.get())) @@ -887,21 +1137,17 @@ ServerInviteSession::dispatchWaitingToOffer(const SipMessage& msg) } case OnAck: - { - assert(mProposedLocalOfferAnswer.get()); + resip_assert(mProposedLocalOfferAnswer.get()); mCurrentRetransmit200 = 0; // stop the 200 retransmit timer provideProposedOffer(); break; - } - + case OnAckAnswer: - { mCurrentRetransmit200 = 0; // stop the 200 retransmit timer sendBye(); transition(Terminated); handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); break; - } case OnCancel: { @@ -937,7 +1183,7 @@ void ServerInviteSession::dispatchWaitingToRequestOffer(const SipMessage& msg) { InviteSessionHandler* handler = mDum.mInviteSessionHandler; - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); InfoLog (<< "dispatchWaitingToRequestOffer: " << msg.brief()); switch (toEvent(msg, offerAnswer.get())) @@ -956,20 +1202,16 @@ ServerInviteSession::dispatchWaitingToRequestOffer(const SipMessage& msg) } case OnAck: - { mCurrentRetransmit200 = 0; // stop the 200 retransmit timer requestOffer(); break; - } case OnAckAnswer: - { mCurrentRetransmit200 = 0; // stop the 200 retransmit timer sendBye(); transition(Terminated); handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); break; - } case OnCancel: { @@ -1005,7 +1247,7 @@ void ServerInviteSession::dispatchAcceptedWaitingAnswer(const SipMessage& msg) { InviteSessionHandler* handler = mDum.mInviteSessionHandler; - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); switch (toEvent(msg, offerAnswer.get())) { @@ -1023,7 +1265,6 @@ ServerInviteSession::dispatchAcceptedWaitingAnswer(const SipMessage& msg) } case OnAckAnswer: - { mCurrentRetransmit200 = 0; // stop the 200 retransmit timer transition(Connected); setCurrentLocalOfferAnswer(msg); @@ -1035,37 +1276,31 @@ ServerInviteSession::dispatchAcceptedWaitingAnswer(const SipMessage& msg) handler->onConnected(getSessionHandle(), msg); } break; - } case OnAck: - { mCurrentRetransmit200 = 0; // stop the 200 retransmit timer mEndReason = IllegalNegotiation; sendBye(); transition(Terminated); handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); break; - } case OnCancel: { // no transition - SharedPtr c200(new SipMessage); mDialog.makeResponse(*c200, msg, 200); send(c200); break; } - case OnPrack: // broken + case OnPrack: { - // no transition - - SharedPtr p200(new SipMessage); - mDialog.makeResponse(*p200, msg, 200); - send(p200); - - sendAccept(200, 0); + // should never get a prack here - we always queue up our 200/Inv response + InfoLog (<< "spurious PRACK in state=" << toData(mState)); + SharedPtr p481(new SipMessage); + mDialog.makeResponse(*p481, msg, 481); + send(p481); break; } @@ -1078,64 +1313,682 @@ ServerInviteSession::dispatchAcceptedWaitingAnswer(const SipMessage& msg) } } -void -ServerInviteSession::dispatchOfferReliable(const SipMessage& msg) -{ -} - -void -ServerInviteSession::dispatchNoOfferReliable(const SipMessage& msg) -{ -} - void ServerInviteSession::dispatchFirstSentOfferReliable(const SipMessage& msg) { + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnCancel: + dispatchCancel(msg); + break; + + case OnBye: + dispatchBye(msg); + break; + + case OnUpdate: + { + // Update with no SDP is a target refresh ?slg? just respond immediately - do we need a callback? + // Note: target refresh handling is in Dialog::handleTargetRefresh + SharedPtr response(new SipMessage); + mDialog.makeResponse(*response, msg, 200); + send(response); + break; + } + + case OnPrack: + if(handlePrack(msg)) + { + if(offerAnswer.get()) // Answer + { + transition(UAS_NegotiatedReliable); + SharedPtr p200(new SipMessage); + mDialog.makeResponse(*p200, msg, 200); + send(p200); + + setCurrentLocalOfferAnswer(msg); + mCurrentRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer); + mCurrentEncryptionLevel = getEncryptionLevel(msg); + handler->onPrack(getHandle(), msg); + handler->onAnswer(getSessionHandle(), msg, *offerAnswer); + } + else + { + mEndReason = IllegalNegotiation; + transition(Terminated); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + + // 406 the Prack + SharedPtr p406(new SipMessage); + mDialog.makeResponse(*p406, msg, 406); + send(p406); + + // 406 the Invite + SharedPtr i406(new SipMessage); + mDialog.makeResponse(*i406, mFirstRequest, 406); + send(i406); + + mDum.destroy(this); + } + } + break; + + default: + if(msg.isRequest()) + { + dispatchUnknown(msg); + } + break; + } +} + +bool +ServerInviteSession::handlePrack(const SipMessage& msg) +{ + InfoLog (<< "handlePrack"); + + if(mUnacknowledgedReliableProvisional.get() && + mUnacknowledgedReliableProvisional->header(h_RSeq).value() == msg.header(h_RAck).rSequence() && + mUnacknowledgedReliableProvisional->header(h_CSeq).sequence() == msg.header(h_RAck).cSequence() && + mUnacknowledgedReliableProvisional->header(h_CSeq).method() == msg.header(h_RAck).method()) + { + mUnacknowledgedReliableProvisional.reset(); // Clear storage we have received our PRACK + + InfoLog (<< "Found matching provisional for PRACK."); + return true; + } + + InfoLog (<< "spurious PRACK in state=" << toData(mState)); + SharedPtr p481(new SipMessage); + mDialog.makeResponse(*p481, msg, 481); + send(p481); + return false; } void -ServerInviteSession::dispatchFirstEarlyReliable(const SipMessage& msg) +ServerInviteSession::prackCheckQueue() { + InfoLog (<< "prackCheckQueue: " << mQueuedResponses.size() ); + if(mQueuedResponses.size() > 0 && mQueuedResponses.front().first < 200) + { + InfoLog (<< "Sending queued provisional" ); + sendProvisional(mQueuedResponses.front().first, mQueuedResponses.front().second); + mQueuedResponses.pop_front(); + } + else if(mQueuedResponses.size() > 0 && mQueuedResponses.front().first < 300) + { + InfoLog (<< "Sending queued 200 OK" ); + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + transition(UAS_Accepted); + Contents* sdp = 0; + if( !mAnswerSentReliably && mCurrentLocalOfferAnswer.get()) + { + sdp = mCurrentLocalOfferAnswer.get(); + } + sendAccept(mQueuedResponses.front().first, sdp); + handler->onConnected(getSessionHandle(), *mInvite200); + mQueuedResponses.clear(); // shouldn't be any provisionals or 200's behind us in queue - just clear the entire queue + } } void -ServerInviteSession::dispatchEarlyReliable(const SipMessage& msg) +ServerInviteSession::updateCheckQueue() { + // TODO - should we be skipping over or ignoring any provisionals in the queue? + InfoLog (<< "updateCheckQueue: " << mQueuedResponses.size() ); + if(mQueuedResponses.size() > 0 && + mQueuedResponses.front().first >= 200 && + mQueuedResponses.front().first < 300) + { + InfoLog (<< "Sending queued 200 OK" ); + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + transition(UAS_Accepted); + sendAccept(mQueuedResponses.front().first, 0); + handler->onConnected(getSessionHandle(), *mInvite200); + mQueuedResponses.pop_front(); + } +} + +void +ServerInviteSession::dispatchOfferReliableProvidedAnswer(const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnCancel: + dispatchCancel(msg); + break; + + case OnBye: + dispatchBye(msg); + break; + + case OnUpdate: + { + // Update with no SDP is a target refresh ?slg? just respond immediately - do we need a callback? + // Note: target refresh handling is in Dialog::handleTargetRefresh + SharedPtr response(new SipMessage); + mDialog.makeResponse(*response, msg, 200); + send(response); + break; + } + + case OnPrack: + if(handlePrack(msg)) + { + if(offerAnswer.get()) + { + // 2nd offer, we haven't answered the first one - log error an proceed by igoring body + ErrLog (<< "PRACK with new offer when in state=" << toData(mState)); + + mEndReason = IllegalNegotiation; + transition(Terminated); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + + // 406 the Prack + SharedPtr p406(new SipMessage); + mDialog.makeResponse(*p406, msg, 406); + send(p406); + + // 406 the Invite + SharedPtr i406(new SipMessage); + mDialog.makeResponse(*i406, mFirstRequest, 406); + send(i406); + + mDum.destroy(this); + } + else + { + // Send 200/PRACK + SharedPtr p200(new SipMessage); + mDialog.makeResponse(*p200, msg, 200); + send(p200); + + // If we have a provisional to send with answer then transition to UAS_FirstSentAnswerReliable + if(mQueuedResponses.size() > 0 && + mQueuedResponses.front().first < 200 && + mQueuedResponses.front().second) // Early flag is on + { + transition(UAS_FirstSentAnswerReliable); + } + handler->onPrack(getHandle(), msg); + prackCheckQueue(); + } + } + break; + + default: + if(msg.isRequest()) + { + dispatchUnknown(msg); + } + break; + } +} + +void +ServerInviteSession::dispatchFirstSentAnswerReliable(const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnCancel: + dispatchCancel(msg); + break; + + case OnBye: + dispatchBye(msg); + break; + + case OnUpdate: + { + // Update with no SDP is a target refresh ?slg? just respond immediately - do we need a callback? + // Note: target refresh handling is in Dialog::handleTargetRefresh + SharedPtr response(new SipMessage); + mDialog.makeResponse(*response, msg, 200); + send(response); + break; + } + + case OnPrack: + if(handlePrack(msg)) + { + if(offerAnswer.get()) // New offer + { + // If we have an offer in the prack and the dum user also tried to provide a new offer, then + // reject the dum api offer and pass the one from the wire to the application + if(mProposedLocalOfferAnswer.get()) + { + //!slg! -- should this be onIllegalNegotiation? + handler->onOfferRejected(getSessionHandle(), 0); + } + // dispatch offer here and respond with 200OK in provideAnswer + transition(UAS_NegotiatedReliable); + mPrackWithOffer = resip::SharedPtr(new SipMessage(msg)); + mProposedRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer); + mCurrentEncryptionLevel = getEncryptionLevel(msg); + handler->onPrack(getHandle(), msg); + if(!isTerminated()) + { + handler->onOffer(getSessionHandle(), msg, *offerAnswer); + } + } + else + { + SharedPtr p200(new SipMessage); + mDialog.makeResponse(*p200, msg, 200); + send(p200); + // check if we have a queued up offer then sent it - if not check prack queue + if(mProposedLocalOfferAnswer.get()) + { + transition(UAS_SentUpdate); + handler->onPrack(getHandle(), msg); + sendUpdate(*mProposedLocalOfferAnswer.get()); + } + else + { + transition(UAS_NegotiatedReliable); + handler->onPrack(getHandle(), msg); + prackCheckQueue(); + } + } + } + break; + + default: + if(msg.isRequest()) + { + dispatchUnknown(msg); + } + break; + } +} + +void +ServerInviteSession::dispatchNoAnswerReliableWaitingPrack(const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnCancel: + dispatchCancel(msg); + break; + + case OnBye: + dispatchBye(msg); + break; + + case OnUpdate: + { + // Update with no SDP is a target refresh ?slg? just respond immediately - do we need a callback? + // Note: target refresh handling is in Dialog::handleTargetRefresh + SharedPtr response(new SipMessage); + mDialog.makeResponse(*response, msg, 200); + send(response); + break; + } + + case OnPrack: + if(handlePrack(msg)) + { + if(offerAnswer.get()) + { + // 2nd offer, we haven't answered the first one - log error an proceed by igoring body + ErrLog (<< "PRACK with new offer when in state=" << toData(mState)); + + mEndReason = IllegalNegotiation; + transition(Terminated); + handler->onTerminated(getSessionHandle(), InviteSessionHandler::Error, &msg); + + // 406 the Prack + SharedPtr p406(new SipMessage); + mDialog.makeResponse(*p406, msg, 406); + send(p406); + + // 406 the Invite + SharedPtr i406(new SipMessage); + mDialog.makeResponse(*i406, mFirstRequest, 406); + send(i406); + + mDum.destroy(this); + } + else + { + // Send 200/PRACK + SharedPtr p200(new SipMessage); + mDialog.makeResponse(*p200, msg, 200); + send(p200); + + transition(UAS_NoAnswerReliable); + handler->onPrack(getHandle(), msg); + prackCheckQueue(); + } + } + break; + + default: + if(msg.isRequest()) + { + dispatchUnknown(msg); + } + break; + } } void ServerInviteSession::dispatchSentUpdate(const SipMessage& msg) { + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnCancel: + dispatchCancel(msg); + break; + + case OnBye: + dispatchBye(msg); + break; + + case OnUpdate: + case OnUpdateOffer: + { + // Glare + SharedPtr response(new SipMessage); + mDialog.makeResponse(*response, msg, 491); + send(response); + break; + } + + case On200Update: + transition(UAS_NegotiatedReliable); + if (offerAnswer.get()) + { + setCurrentLocalOfferAnswer(msg); + mCurrentRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer); + mCurrentEncryptionLevel = getEncryptionLevel(msg); + handler->onAnswer(getSessionHandle(), msg, *offerAnswer); + } + prackCheckQueue(); // needed for when provideOffer then accept are both called in FirstSentAnswerReliable + break; + + case OnUpdateRejected: + case OnGeneralFailure: // handle 481 or 408 responses + transition(UAS_NegotiatedReliable); + mProposedLocalOfferAnswer.reset(); + handler->onOfferRejected(getSessionHandle(), &msg); + prackCheckQueue(); // needed for when provideOffer then accept are both called in FirstSentAnswerReliable + break; + + case On491Update: + transition(UAS_SentUpdateGlare); + start491Timer(); + break; + + default: + if(msg.isRequest()) + { + dispatchUnknown(msg); + } + break; + } +} + +void +ServerInviteSession::dispatchSentUpdateGlare(const SipMessage& msg) +{ + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnCancel: + dispatchCancel(msg); + break; + + case OnBye: + dispatchBye(msg); + break; + + case OnUpdate: + case OnUpdateOffer: + handler->onOfferRejected(getSessionHandle(), &msg); + // handle as if we received in NegotiatedReliable + dispatchNegotiatedReliable(msg); + break; + + default: + if(msg.isRequest()) + { + dispatchUnknown(msg); + } + break; + } } void ServerInviteSession::dispatchSentUpdateAccepted(const SipMessage& msg) { + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnCancel: + dispatchCancel(msg); + break; + + case OnBye: + dispatchBye(msg); + break; + + case OnUpdate: + { + // Update with no SDP is a target refresh ?slg? just respond immediately - do we need a callback? + // Note: target refresh handling is in Dialog::handleTargetRefresh + SharedPtr response(new SipMessage); + mDialog.makeResponse(*response, msg, 200); + send(response); + break; + } + + case On200Update: + transition(UAS_Accepted); + if (offerAnswer.get()) + { + setCurrentLocalOfferAnswer(msg); + mCurrentRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer); + mCurrentEncryptionLevel = getEncryptionLevel(msg); + handler->onAnswer(getSessionHandle(), msg, *offerAnswer); + } + updateCheckQueue(); + break; + + case OnUpdateRejected: + case OnGeneralFailure: // handle 481 or 408 responses + transition(UAS_Accepted); + mProposedLocalOfferAnswer.reset(); + handler->onOfferRejected(getSessionHandle(), &msg); + updateCheckQueue(); + break; + + case On491Update: + // strange case - we send an offer then called accept and the offer/update got 491'd - treating the same as any offer error + transition(UAS_Accepted); + mProposedLocalOfferAnswer.reset(); + handler->onOfferRejected(getSessionHandle(), &msg); + updateCheckQueue(); + break; + + default: + if(msg.isRequest()) + { + dispatchUnknown(msg); + } + break; + } } void ServerInviteSession::dispatchReceivedUpdate(const SipMessage& msg) { + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnCancel: + dispatchCancel(msg); + break; + + case OnBye: + dispatchBye(msg); + break; + + case OnUpdate: + case OnUpdateOffer: + // If we receive an UPDATE before we have generated a final response to a previous UPDATE on the + // same dialog, then we MUST return a 500 response with a Retry-After header (random duration 0-10 seconds) + { + SharedPtr u500(new SipMessage); + mDialog.makeResponse(*u500, msg, 500); + u500->header(h_RetryAfter).value() = Random::getRandom() % 10; + send(u500); + } + break; + + default: + if(msg.isRequest()) + { + dispatchUnknown(msg); + } + break; + } } void ServerInviteSession::dispatchReceivedUpdateWaitingAnswer(const SipMessage& msg) { + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnCancel: + dispatchCancel(msg); + break; + + case OnBye: + dispatchBye(msg); + break; + + case OnUpdate: + case OnUpdateOffer: + // A UAS that receives an UPDATE before it has generated a final response to a previous UPDATE on the + // same dialog MUST return a 500 response + { + SharedPtr u500(new SipMessage); + mDialog.makeResponse(*u500, msg, 500); + send(u500); + } + break; + + default: + if(msg.isRequest()) + { + dispatchUnknown(msg); + } + break; + } } void -ServerInviteSession::dispatchWaitingToTerminate(const SipMessage& msg) +ServerInviteSession::dispatchNegotiatedReliable(const SipMessage& msg) { + InviteSessionHandler* handler = mDum.mInviteSessionHandler; + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + + switch (toEvent(msg, offerAnswer.get())) + { + case OnCancel: + dispatchCancel(msg); + break; + + case OnBye: + dispatchBye(msg); + break; + + case OnPrack: + if(handlePrack(msg)) + { + if(offerAnswer.get()) // New offer + { + // dispatch offer here and respond with 200OK in provideAnswer + mPrackWithOffer = resip::SharedPtr(new SipMessage(msg)); + mProposedRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer); + mCurrentEncryptionLevel = getEncryptionLevel(msg); + handler->onPrack(getHandle(), msg); + if(!isTerminated()) + { + handler->onOffer(getSessionHandle(), msg, *offerAnswer); + } + } + else + { + SharedPtr p200(new SipMessage); + mDialog.makeResponse(*p200, msg, 200); + send(p200); + handler->onPrack(getHandle(), msg); + prackCheckQueue(); + } + } + break; + + case OnUpdateOffer: + *mLastRemoteSessionModification = msg; + transition(UAS_ReceivedUpdate); + mProposedRemoteOfferAnswer = InviteSession::makeOfferAnswer(*offerAnswer); + mCurrentEncryptionLevel = getEncryptionLevel(msg); + if(!isTerminated()) + { + handler->onOffer(getSessionHandle(), msg, *offerAnswer); + } + break; + + case OnUpdate: + { + // Update with no SDP is a target refresh ?slg? just respond immediately - do we need a callback? + // Note: target refresh handling is in Dialog::handleTargetRefresh + SharedPtr response(new SipMessage); + mDialog.makeResponse(*response, msg, 200); + send(response); + break; + } + + default: + if(msg.isRequest()) + { + dispatchUnknown(msg); + } + break; + } } void ServerInviteSession::dispatchWaitingToHangup(const SipMessage& msg) { - std::unique_ptr offerAnswer = InviteSession::getOfferAnswer(msg); + std::auto_ptr offerAnswer = InviteSession::getOfferAnswer(msg); switch (toEvent(msg, offerAnswer.get())) { - case OnPrack: case OnAck: case OnAckAnswer: { @@ -1194,9 +2047,11 @@ ServerInviteSession::dispatchBye(const SipMessage& msg) void ServerInviteSession::dispatchUnknown(const SipMessage& msg) { - SharedPtr r481(new SipMessage); // !jf! what should we send here? - mDialog.makeResponse(*r481, msg, 481); - send(r481); + InfoLog (<< "Unknown request (" << msg.brief() << ") received in state=" << toData(mState) << ", rejecting request and terminating call."); + + SharedPtr r500(new SipMessage); + mDialog.makeResponse(*r500, msg, 500); + send(r500); SharedPtr i400(new SipMessage); mDialog.makeResponse(*i400, mFirstRequest, 400); @@ -1211,47 +2066,137 @@ void ServerInviteSession::startRetransmit1xxTimer() { // RFC3261 13.3.1 says the UAS must send a non-100 provisional response every minute, to handle the possiblity of lost provisional responses - mCurrentRetransmit1xx = mDialog.mDialogSet.getUserProfile()->get1xxRetransmissionTime(); - if(mCurrentRetransmit1xx > 0) - { - unsigned int seq = m1xx->header(h_CSeq).sequence(); - mDum.addTimer(DumTimeout::Retransmit1xx, mCurrentRetransmit1xx, getBaseHandle(), seq); + int retransmissionTime = mDialog.mDialogSet.getUserProfile()->get1xxRetransmissionTime(); + if(retransmissionTime > 0 && m1xx->header(resip::h_StatusLine).statusCode() > 100) + { + mDum.addTimer(DumTimeout::Retransmit1xx, retransmissionTime, getBaseHandle(), ++mCurrentRetransmit1xxSeq); + } +} + +void +ServerInviteSession::startResubmit1xxRelTimer() +{ + // RFC3262 section says the UAS SHOULD send reliable provisional responses once every two and half minutes + int resubmitTime = mDialog.mDialogSet.getUserProfile()->get1xxRelResubmitTime(); + if(resubmitTime > 0 && m1xx->header(resip::h_StatusLine).statusCode() > 100) + { + mDum.addTimer(DumTimeout::Resubmit1xxRel, resubmitTime, getBaseHandle(), ++mCurrentRetransmit1xxSeq); // This timer serves the same purpose at the unreliable retransmit timer - use the same sequence number } } void +ServerInviteSession::startRetransmit1xxRelTimer() +{ + unsigned int seq = m1xx->header(h_RSeq).value(); + mDum.addTimerMs(DumTimeout::Retransmit1xxRel, Timer::T1, getBaseHandle(), seq, Timer::T1); +} + +bool ServerInviteSession::sendProvisional(int code, bool earlyFlag) { + m1xx->setContents(0); mDialog.makeResponse(*m1xx, mFirstRequest, code); - if(!earlyFlag) + + bool sendReliably = code > 100 && // Must be a non-100 response + ((mFirstRequest.exists(h_Requires) && mFirstRequest.header(h_Requires).find(Token(Symbols::C100rel))) || // Far end requires it (note: we must at least support it or the invite would have been rejected already) + mDum.getMasterProfile()->getUasReliableProvisionalMode() == MasterProfile::Required || // OR we require it (note: far end must at least support it or the invite would have been rejected) + (mFirstRequest.exists(h_Supporteds) && mFirstRequest.header(h_Supporteds).find(Token(Symbols::C100rel)) && // OR far ends supports it and we support it + mDum.getMasterProfile()->getUasReliableProvisionalMode() == MasterProfile::Supported)); // (note: SupportedEssential is not trapped here, cases for it are added below) + + switch (mState) { - m1xx->setContents(0); // clear contents if present + case UAS_OfferProvidedAnswer: + case UAS_EarlyProvidedAnswer: + if (code > 100 && earlyFlag && mCurrentLocalOfferAnswer.get()) // early media + { + setOfferAnswer(*m1xx, mCurrentLocalOfferAnswer.get()); + } + break; + + case UAS_FirstSentAnswerReliable: // This is possible if someone called provisional() from the onPrack callback (since we change states after we call onPrack) + case UAS_OfferReliableProvidedAnswer: // MAY send answer in reliable response - send only if earlyFlag is set + if (code > 100 && earlyFlag && !mAnswerSentReliably && mCurrentLocalOfferAnswer.get()) // early media + { + setOfferAnswer(*m1xx, mCurrentLocalOfferAnswer.get()); + mAnswerSentReliably = true; + sendReliably = true; // If UasReliableProvisionalMode is SupportEssential this may flip sendReliably to true + } + break; + + case UAS_NoOfferReliable: + if(sendReliably) + { + // Invite requires reliable responses - since there was no offer in the INVITE we MUST + // provide an offer in the first reliable response. We would be in the ProvidedOfferReliable + // state if that was the case. Looks like provisional was called too early! + DebugLog( << "Sending a reliable provisional after receiving an INVITE with no offer, requires provideOffer to be called first (RFC3262-Section 5)."); + resip_assert(false); + return false; + } + break; + + case UAS_ProvidedOfferReliable: + // ignore early flag if we must sendReliably, since first reliable 1xx MUST contain Offer + if (code > 100 && (earlyFlag || sendReliably) && mProposedLocalOfferAnswer.get()) + { + setOfferAnswer(*m1xx, mProposedLocalOfferAnswer.get()); + sendReliably = true; // If UasReliableProvisionalMode is SupportEssential this may flip sendReliably to true + } + break; + + case UAS_ProvidedOffer: + case UAS_EarlyProvidedOffer: + if (code > 100 && earlyFlag && mProposedLocalOfferAnswer.get()) + { + setOfferAnswer(*m1xx, mProposedLocalOfferAnswer.get()); + } + break; + + default: + break; + } + DumHelper::setOutgoingEncryptionLevel(*m1xx, mProposedEncryptionLevel); + + if(sendReliably) + { + DebugLog ( << "Sending provisional reliably" ); + if (!m1xx->exists(h_Requires) || + !m1xx->header(h_Requires).find(Token(Symbols::C100rel))) + { + m1xx->header(h_Requires).push_back(Token(Symbols::C100rel)); + } + m1xx->header(h_RSeq).value() = ++mLocalRSeq; + + // We are supposed to advertised our Allow header in reliable provisionals - Add Advertised + // Capabilities - allows UAC to detect UPDATE support before 200 response + mDum.setAdvertisedCapabilities(*m1xx.get(), mDialog.mDialogSet.getUserProfile()); + + resip_assert(!mUnacknowledgedReliableProvisional.get()); + mUnacknowledgedReliableProvisional = m1xx; + startRetransmit1xxRelTimer(); // handles retransmissions until PRACK arrives + startResubmit1xxRelTimer(); // handles - RFC3262 section says the UAS SHOULD send provisional reliable responses once every two and half minutes } else { - switch (mState) + // Make sure there is no RSeq or Requires 100rel + if(m1xx->exists(h_RSeq)) { - case UAS_OfferProvidedAnswer: - case UAS_EarlyProvidedAnswer: - if (mCurrentLocalOfferAnswer.get()) // early media - { - setOfferAnswer(*m1xx, mCurrentLocalOfferAnswer.get()); - } - break; - case UAS_ProvidedOffer: - case UAS_EarlyProvidedOffer: - if (mProposedLocalOfferAnswer.get()) - { - setOfferAnswer(*m1xx, mProposedLocalOfferAnswer.get()); - } - break; - - default: - break; + m1xx->remove(h_RSeq); } + if(m1xx->exists(h_Requires)) + { + ParserContainer::iterator it = m1xx->header(h_Requires).begin(); + for(; it != m1xx->header(h_Requires).end(); it++) + { + if((*it) == Token(Symbols::C100rel)) + { + m1xx->header(h_Requires).erase(it); + break; + } + } + } + startRetransmit1xxTimer(); } - startRetransmit1xxTimer(); - DumHelper::setOutgoingEncryptionLevel(*m1xx, mProposedEncryptionLevel); if (mDum.mDialogEventStateManager) { @@ -1259,6 +2204,14 @@ ServerInviteSession::sendProvisional(int code, bool earlyFlag) } send(m1xx); + return sendReliably; +} + +void +ServerInviteSession::queueResponse(int code, bool earlyFlag) +{ + InfoLog (<< "Response " << code << " queued." ); + mQueuedResponses.push_back( std::make_pair(code, earlyFlag) ); } void @@ -1266,12 +2219,13 @@ ServerInviteSession::sendAccept(int code, Contents* offerAnswer) { mDialog.makeResponse(*mInvite200, mFirstRequest, code); handleSessionTimerRequest(*mInvite200, mFirstRequest); - if (offerAnswer) + if (offerAnswer && !mAnswerSentReliably ) { setOfferAnswer(*mInvite200, offerAnswer); + mAnswerSentReliably = true; } - mCurrentRetransmit1xx = 0; // Stop the 1xx timer - startRetransmit200Timer(); // 2xx timer + mCurrentRetransmit1xxSeq++; // Stop the 1xx timer - causes timer to be ignored on expirey + startRetransmit200Timer(); // 2xx timer DumHelper::setOutgoingEncryptionLevel(*mInvite200, mCurrentEncryptionLevel); if (mDum.mDialogEventStateManager) diff --git a/src/libs/resiprocate/resip/dum/ServerInviteSession.hxx b/src/libs/resiprocate/resip/dum/ServerInviteSession.hxx index 7cb05c61..c33ab6a5 100644 --- a/src/libs/resiprocate/resip/dum/ServerInviteSession.hxx +++ b/src/libs/resiprocate/resip/dum/ServerInviteSession.hxx @@ -26,9 +26,14 @@ class ServerInviteSession: public InviteSession /** Called to set the offer that will be used in the next message that sends an offer. If possible, this will synchronously send the appropriate request or response. In some cases, the UAS might have to - call accept in order to cause the message to be sent. */ + call accept in order to cause the message to be sent. + If sendOfferAtAccept is true, no UPDATE will be sent if media is negotiated reliable, + it will be sent at accept */ virtual void provideOffer(const Contents& offer); virtual void provideOffer(const Contents& offer, DialogUsageManager::EncryptionLevel level, const Contents* alternative); + virtual void provideOffer(const Contents& offer, bool sendOfferAtAccept); + virtual void provideOffer(const Contents& offer, DialogUsageManager::EncryptionLevel level, + const Contents* alternative, bool sendOfferAtAccept); /** Called to request that the far end provide an offer. This will cause a reinvite with no body to be sent. */ @@ -55,7 +60,7 @@ class ServerInviteSession: public InviteSession * Provide asynchronous method access by using command */ void redirectCommand(const NameAddrs& contacts, int code=302); - void provisionalCommand(int code=180); + void provisionalCommand(int code=180, bool earlyFlag=true); void acceptCommand(int statusCode=200); private: @@ -70,17 +75,17 @@ class ServerInviteSession: public InviteSession void dispatchWaitingToOffer(const SipMessage& msg); void dispatchWaitingToRequestOffer(const SipMessage& msg); void dispatchAcceptedWaitingAnswer(const SipMessage& msg); - void dispatchOfferReliable(const SipMessage& msg); - void dispatchNoOfferReliable(const SipMessage& msg); void dispatchFirstSentOfferReliable(const SipMessage& msg); - void dispatchFirstEarlyReliable(const SipMessage& msg); - void dispatchEarlyReliable(const SipMessage& msg); + void dispatchOfferReliableProvidedAnswer(const SipMessage& msg); + void dispatchFirstSentAnswerReliable(const SipMessage& msg); + void dispatchNoAnswerReliableWaitingPrack(const SipMessage& msg); void dispatchSentUpdate(const SipMessage& msg); + void dispatchSentUpdateGlare(const SipMessage& msg); void dispatchSentUpdateAccepted(const SipMessage& msg); void dispatchReceivedUpdate(const SipMessage& msg); void dispatchReceivedUpdateWaitingAnswer(const SipMessage& msg); - void dispatchWaitingToTerminate(const SipMessage& msg); void dispatchWaitingToHangup(const SipMessage& msg); + void dispatchNegotiatedReliable(const SipMessage& msg); void dispatchCancel(const SipMessage& msg); void dispatchBye(const SipMessage& msg); @@ -88,9 +93,15 @@ class ServerInviteSession: public InviteSession // utilities void startRetransmit1xxTimer(); + void startResubmit1xxRelTimer(); + void startRetransmit1xxRelTimer(); void sendAccept(int code, Contents* offerAnswer); // sends 2xxI - void sendProvisional(int code, bool earlyFlag); + bool sendProvisional(int code, bool earlyFlag); // returns true if sent reliably + void queueResponse(int code, bool earlyFlag); void sendUpdate(const Contents& offerAnswer); + bool handlePrack(const SipMessage& msg); // verify that prack matches our last send reliable 1xx + void prackCheckQueue(); // send a queued message after prack + void updateCheckQueue(); // send a queued message after update ServerInviteSession(DialogUsageManager& dum, Dialog& dialog, const SipMessage& msg); @@ -101,10 +112,14 @@ class ServerInviteSession: public InviteSession // stores the original request const SipMessage mFirstRequest; SharedPtr m1xx; // for 1xx retransmissions - unsigned long mCurrentRetransmit1xx; + unsigned long mCurrentRetransmit1xxSeq; - //std::deque mUnacknowledgedProvisionals; // all of them - //SipMessage m200; // for retransmission + // UAS Prack members + unsigned int mLocalRSeq; + SharedPtr mUnacknowledgedReliableProvisional; // We won't send a new reliable provisional until the previous one is acknowledge - used for re-transmissions + std::deque< std::pair > mQueuedResponses; + bool mAnswerSentReliably; + SharedPtr mPrackWithOffer; // for 1xx retransmissions }; } diff --git a/src/libs/resiprocate/resip/dum/ServerOutOfDialogReq.cxx b/src/libs/resiprocate/resip/dum/ServerOutOfDialogReq.cxx index be95b130..c023dd5a 100644 --- a/src/libs/resiprocate/resip/dum/ServerOutOfDialogReq.cxx +++ b/src/libs/resiprocate/resip/dum/ServerOutOfDialogReq.cxx @@ -42,35 +42,35 @@ ServerOutOfDialogReq::end() void ServerOutOfDialogReq::dispatch(const SipMessage& msg) { - assert(msg.isRequest()); + resip_assert(msg.isRequest()); - OutOfDialogHandler *pHandler = mDum.getOutOfDialogHandler(msg.header(h_CSeq).method()); - if(pHandler != NULL) - { - // Let handler deal with message - mRequest = msg; - DebugLog ( << "ServerOutOfDialogReq::dispatch - handler found for " << getMethodName(msg.header(h_CSeq).method()) << " method."); - pHandler->onReceivedRequest(getHandle(), msg); // Wait for application to send response - } - else - { - if(msg.header(h_CSeq).method() == OPTIONS) - { - DebugLog ( << "ServerOutOfDialogReq::dispatch - handler not found for OPTIONS - sending autoresponse."); - // If no handler exists for OPTIONS then handle internally - mRequest = msg; - mDum.send(answerOptions()); - delete this; - } - else - { - DebugLog ( << "ServerOutOfDialogReq::dispatch - handler not found for " << getMethodName(msg.header(h_CSeq).method()) << " method - sending 405."); - // No handler found for out of dialog request - return a 405 - mDum.makeResponse(*mResponse, msg, 405); - mDum.send(mResponse); - delete this; - } - } + OutOfDialogHandler *pHandler = mDum.getOutOfDialogHandler(msg.header(h_CSeq).method()); + if(pHandler != NULL) + { + // Let handler deal with message + mRequest = msg; + DebugLog ( << "ServerOutOfDialogReq::dispatch - handler found for " << getMethodName(msg.header(h_CSeq).method()) << " method."); + pHandler->onReceivedRequest(getHandle(), msg); // Wait for application to send response + } + else + { + if(msg.header(h_CSeq).method() == OPTIONS) + { + DebugLog ( << "ServerOutOfDialogReq::dispatch - handler not found for OPTIONS - sending autoresponse."); + // If no handler exists for OPTIONS then handle internally + mRequest = msg; + mDum.send(answerOptions()); + delete this; + } + else + { + DebugLog ( << "ServerOutOfDialogReq::dispatch - handler not found for " << getMethodName(msg.header(h_CSeq).method()) << " method - sending 405."); + // No handler found for out of dialog request - return a 405 + mDum.makeResponse(*mResponse, msg, 405); + mDum.send(mResponse); + delete this; + } + } } void @@ -81,23 +81,23 @@ ServerOutOfDialogReq::dispatch(const DumTimeout& msg) SharedPtr ServerOutOfDialogReq::answerOptions() { - mDum.makeResponse(*mResponse, mRequest, 200); + mDum.makeResponse(*mResponse, mRequest, 200); - // Add in Allow, Accept, Accept-Encoding, Accept-Language, and Supported Headers from Profile - mResponse->header(h_Allows) = mDum.getMasterProfile()->getAllowedMethods(); - mResponse->header(h_Accepts) = mDum.getMasterProfile()->getSupportedMimeTypes(INVITE); - mResponse->header(h_AcceptEncodings) = mDum.getMasterProfile()->getSupportedEncodings(); - mResponse->header(h_AcceptLanguages) = mDum.getMasterProfile()->getSupportedLanguages(); - mResponse->header(h_AllowEvents) = mDum.getMasterProfile()->getAllowedEvents(); - mResponse->header(h_Supporteds) = mDum.getMasterProfile()->getSupportedOptionTags(); + // Add in Allow, Accept, Accept-Encoding, Accept-Language, and Supported Headers from Profile + mResponse->header(h_Allows) = mDum.getMasterProfile()->getAllowedMethods(); + mResponse->header(h_Accepts) = mDum.getMasterProfile()->getSupportedMimeTypes(INVITE); + mResponse->header(h_AcceptEncodings) = mDum.getMasterProfile()->getSupportedEncodings(); + mResponse->header(h_AcceptLanguages) = mDum.getMasterProfile()->getSupportedLanguages(); + mResponse->header(h_AllowEvents) = mDum.getMasterProfile()->getAllowedEvents(); + mResponse->header(h_Supporteds) = mDum.getMasterProfile()->getSupportedOptionTags(); - return mResponse; + return mResponse; } void ServerOutOfDialogReq::send(SharedPtr response) { - assert(response->isResponse()); + resip_assert(response->isResponse()); mDum.send(response); delete this; } diff --git a/src/libs/resiprocate/resip/dum/ServerPagerMessage.cxx b/src/libs/resiprocate/resip/dum/ServerPagerMessage.cxx index 8245905a..fc0707a2 100644 --- a/src/libs/resiprocate/resip/dum/ServerPagerMessage.cxx +++ b/src/libs/resiprocate/resip/dum/ServerPagerMessage.cxx @@ -42,15 +42,18 @@ ServerPagerMessage::end() class ServerPagerMessageEndCommand : public DumCommandAdapter { public: - ServerPagerMessageEndCommand(ServerPagerMessage& serverPagerMessage) - : mServerPagerMessage(serverPagerMessage) + ServerPagerMessageEndCommand(const ServerPagerMessageHandle& serverPagerMessageHandle) + : mServerPagerMessageHandle(serverPagerMessageHandle) { } virtual void executeCommand() { - mServerPagerMessage.end(); + if(mServerPagerMessageHandle.isValid()) + { + mServerPagerMessageHandle->end(); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -58,18 +61,18 @@ public: return strm << "ServerPagerMessageEndCommand"; } private: - ServerPagerMessage& mServerPagerMessage; + ServerPagerMessageHandle mServerPagerMessageHandle; }; void ServerPagerMessage::endCommand() { - mDum.post(new ServerPagerMessageEndCommand(*this)); + mDum.post(new ServerPagerMessageEndCommand(getHandle())); } void ServerPagerMessage::dispatch(const SipMessage& msg) { - assert(msg.isRequest()); + resip_assert(msg.isRequest()); ServerPagerMessageHandler* handler = mDum.mServerPagerMessageHandler; //?dcm? check in DialogUsageManager @@ -91,7 +94,7 @@ ServerPagerMessage::dispatch(const DumTimeout& msg) void ServerPagerMessage::send(SharedPtr response) { - assert(response->isResponse()); + resip_assert(response->isResponse()); mDum.send(response); delete this; } @@ -108,15 +111,18 @@ ServerPagerMessage::accept(int statusCode) class ServerPagerMessageAcceptCommand : public DumCommandAdapter { public: - ServerPagerMessageAcceptCommand(ServerPagerMessage& serverPagerMessage, int statusCode) - : mServerPagerMessage(serverPagerMessage), + ServerPagerMessageAcceptCommand(const ServerPagerMessageHandle& serverPagerMessageHandle, int statusCode) + : mServerPagerMessageHandle(serverPagerMessageHandle), mStatusCode(statusCode) { } virtual void executeCommand() { - mServerPagerMessage.accept(mStatusCode); + if(mServerPagerMessageHandle.isValid()) + { + mServerPagerMessageHandle->send(mServerPagerMessageHandle->accept(mStatusCode)); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -124,14 +130,14 @@ public: return strm << "ServerPagerMessageAcceptCommand"; } private: - ServerPagerMessage& mServerPagerMessage; + ServerPagerMessageHandle mServerPagerMessageHandle; int mStatusCode; }; void ServerPagerMessage::acceptCommand(int statusCode) { - mDum.post(new ServerPagerMessageAcceptCommand(*this, statusCode)); + mDum.post(new ServerPagerMessageAcceptCommand(getHandle(), statusCode)); } SharedPtr @@ -145,15 +151,18 @@ ServerPagerMessage::reject(int statusCode) class ServerPagerMessageRejectCommand : public DumCommandAdapter { public: - ServerPagerMessageRejectCommand(ServerPagerMessage& serverPagerMessage, int statusCode) - : mServerPagerMessage(serverPagerMessage), + ServerPagerMessageRejectCommand(const ServerPagerMessageHandle& serverPagerMessageHandle, int statusCode) + : mServerPagerMessageHandle(serverPagerMessageHandle), mStatusCode(statusCode) { } virtual void executeCommand() { - mServerPagerMessage.reject(mStatusCode); + if(mServerPagerMessageHandle.isValid()) + { + mServerPagerMessageHandle->send(mServerPagerMessageHandle->reject(mStatusCode)); + } } virtual EncodeStream& encodeBrief(EncodeStream& strm) const @@ -161,14 +170,14 @@ public: return strm << "ServerPagerMessageRejectCommand"; } private: - ServerPagerMessage& mServerPagerMessage; + ServerPagerMessageHandle mServerPagerMessageHandle; int mStatusCode; }; void ServerPagerMessage::rejectCommand(int statusCode) { - mDum.post(new ServerPagerMessageRejectCommand(*this, statusCode)); + mDum.post(new ServerPagerMessageRejectCommand(getHandle(), statusCode)); } EncodeStream& @@ -180,7 +189,6 @@ ServerPagerMessage::dump(EncodeStream& strm) const } - /* ==================================================================== * The Vovida Software License, Version 1.0 * diff --git a/src/libs/resiprocate/resip/dum/ServerPublication.cxx b/src/libs/resiprocate/resip/dum/ServerPublication.cxx index aa2e4449..8d9db523 100644 --- a/src/libs/resiprocate/resip/dum/ServerPublication.cxx +++ b/src/libs/resiprocate/resip/dum/ServerPublication.cxx @@ -3,6 +3,7 @@ #include "resip/dum/PublicationHandler.hxx" #include "resip/dum/ServerSubscription.hxx" #include "resip/dum/SubscriptionHandler.hxx" +#include "resip/dum/PublicationPersistenceManager.hxx" #include "resip/stack/Helper.hxx" #include "resip/stack/SecurityAttributes.hxx" #include "rutil/WinLeakCheck.hxx" @@ -16,6 +17,7 @@ ServerPublication::ServerPublication(DialogUsageManager& dum, mLastResponse(new SipMessage), mEtag(etag), mEventType(msg.header(h_Event).value()), + mDocumentKey(msg.header(h_RequestLine).uri().getAor()), mTimerSeq(0) { } @@ -52,7 +54,7 @@ ServerPublication::getPublisher() const void ServerPublication::updateMatchingSubscriptions() { - Data key = mEventType + mLastRequest.header(h_RequestLine).uri().getAor(); + Data key = mEventType + mDocumentKey; std::pair subs; subs = mDum.mServerSubscriptions.equal_range(key); @@ -75,8 +77,6 @@ ServerPublication::accept(int statusCode) Helper::makeResponse(*mLastResponse, mLastRequest, statusCode); mLastResponse->header(h_Expires).value() = mExpires; - updateMatchingSubscriptions(); - return mLastResponse; } @@ -97,7 +97,7 @@ ServerPublication::end() void ServerPublication::dispatch(const SipMessage& msg) { - assert(msg.isRequest()); + resip_assert(msg.isRequest()); ServerPublicationHandler* handler = mDum.getServerPublicationHandler(mEventType); mLastRequest = msg; mExpires = 3600; //bad @@ -113,6 +113,15 @@ ServerPublication::dispatch(const SipMessage& msg) Helper::makeResponse(*mLastResponse, mLastRequest, 200); mLastResponse->header(h_Expires).value() = mExpires; mDum.send(mLastResponse); + + if (mDum.mPublicationPersistenceManager) + { + // Remove document from persistence manager + mDum.mPublicationPersistenceManager->removeDocument(mEventType, mDocumentKey, mEtag, Timer::getTimeSecs()); + } + // Notify all matching subscriptions removal - by sending a null body + updateMatchingSubscriptions(); + delete this; return; } @@ -134,6 +143,18 @@ ServerPublication::dispatch(const SipMessage& msg) } else { + if (mExpires == 0) + { + // This can happen if we receive an unpublish after startup with an e-tag. + // We will then 412 the request. The sender will likely resend with no e-tag + // and we will end up here. There is nothing really to do. The sender is + // essentially unpublishing a publication we don't have, so we can just ignore it. + Helper::makeResponse(*mLastResponse, mLastRequest, 200); + mLastResponse->header(h_Expires).value() = mExpires; + mDum.send(mLastResponse); + delete this; + return; + } mLastBody = Helper::extractFromPkcs7(msg, *mDum.getSecurity()); handler->onInitial(getHandle(), mEtag, msg, mLastBody.mContents.get(), @@ -145,10 +166,19 @@ ServerPublication::dispatch(const SipMessage& msg) void ServerPublication::dispatch(const DumTimeout& msg) { + // If this timer expires with a matching seq - it indicates the publisher didn't + // rePUBLISH within the expiry time and the publication has expired. if (msg.seq() == mTimerSeq) { ServerPublicationHandler* handler = mDum.getServerPublicationHandler(mEventType); handler->onExpired(getHandle(), mEtag); + + if (mDum.mPublicationPersistenceManager) + { + // Remove document from persistence manager + mDum.mPublicationPersistenceManager->removeDocument(mEventType, mDocumentKey, mEtag, Timer::getTimeSecs()); + } + delete this; } } @@ -156,7 +186,7 @@ ServerPublication::dispatch(const DumTimeout& msg) void ServerPublication::send(SharedPtr response) { - assert(response->isResponse()); + resip_assert(response->isResponse()); response->header(h_SIPETag).value() = mEtag; mDum.send(response); if (response->header(h_StatusLine).statusCode() >= 300) @@ -165,7 +195,23 @@ ServerPublication::send(SharedPtr response) } else { - mDum.addTimer(DumTimeout::Publication, response->header(h_Expires).value(), getBaseHandle(), ++mTimerSeq); + UInt32 expires = response->header(h_Expires).value(); // ServerPublicationHandler may have changed expiration time + mDum.addTimer(DumTimeout::Publication, expires, getBaseHandle(), ++mTimerSeq); + + if (mDum.mPublicationPersistenceManager) + { + // Add document to persistence manager + UInt64 now = Timer::getTimeSecs(); + mDum.mPublicationPersistenceManager->addUpdateDocument(mEventType, mDocumentKey, mEtag, now + expires, mLastBody.mContents.get(), mLastBody.mAttributes.get()); + } + + // If we don't have a contents then it was a refresh (note: Unpublishes don't go through here) + if (mLastBody.mContents.get()) + { + // Notify all matching subscriptions of new document + // Note: we do this after all uses of mLastBody, since calling this will release the contents stored in mLastBody + updateMatchingSubscriptions(); + } } } diff --git a/src/libs/resiprocate/resip/dum/ServerPublication.hxx b/src/libs/resiprocate/resip/dum/ServerPublication.hxx index ea36124a..f02c7184 100644 --- a/src/libs/resiprocate/resip/dum/ServerPublication.hxx +++ b/src/libs/resiprocate/resip/dum/ServerPublication.hxx @@ -17,6 +17,7 @@ class ServerPublication : public BaseUsage const Data& getEtag() const; const Data& getDocumentKey() const; + const Data& getEventType() const {return(mEventType);} SharedPtr accept(int statusCode = 200); SharedPtr reject(int responseCode); @@ -38,7 +39,6 @@ class ServerPublication : public BaseUsage private: friend class DialogUsageManager; ServerPublication(DialogUsageManager& dum, const Data& etag, const SipMessage& request); - SipMessage mLastRequest; SharedPtr mLastResponse; const Data mEtag; diff --git a/src/libs/resiprocate/resip/dum/ServerRegistration.cxx b/src/libs/resiprocate/resip/dum/ServerRegistration.cxx index 60d2e332..d94ea3c7 100644 --- a/src/libs/resiprocate/resip/dum/ServerRegistration.cxx +++ b/src/libs/resiprocate/resip/dum/ServerRegistration.cxx @@ -11,6 +11,7 @@ #include "rutil/DnsUtil.hxx" #include "rutil/Logger.hxx" #include "rutil/Timer.hxx" +#include "rutil/TransportType.hxx" #include "rutil/WinLeakCheck.hxx" #define RESIPROCATE_SUBSYSTEM Subsystem::DUM @@ -81,12 +82,12 @@ ServerRegistration::accept(SipMessage& ok) { if (!mAsyncLocalStore.get()) { - assert(0); + resip_assert(0); } else { - std::unique_ptr log; - std::unique_ptr contacts; + std::auto_ptr log; + std::auto_ptr contacts; mAsyncLocalStore->releaseLog(log,contacts); @@ -104,20 +105,20 @@ ServerRegistration::accept(SipMessage& ok) { if (!mAsyncLocalStore.get()) { - assert(0); + resip_assert(0); return; } //This register was accepted, but still need to apply the changes made by this register and then //receive a final contact list before sending the 200. mAsyncState = asyncStateAcceptedWaitingForFinalContactList; - std::unique_ptr log; - std::unique_ptr modifiedContacts; + std::auto_ptr log; + std::auto_ptr modifiedContacts; mAsyncLocalStore->releaseLog(log,modifiedContacts); mAsyncOkMsg = SharedPtr(static_cast(ok.clone())); - mDum.mServerRegistrationHandler->asyncUpdateContacts(getHandle(), mAor, std::move(modifiedContacts), std::move(log)); + mDum.mServerRegistrationHandler->asyncUpdateContacts(getHandle(),mAor,modifiedContacts,log); //!WARN! Must not access this object beyond this point. The client my call reject() or accept(), deleting this object. Also, watch out for local objects that are still in scope and access this object on destruction. return; } @@ -175,7 +176,7 @@ ServerRegistration::dispatch(const SipMessage& msg) { DebugLog( << "got a registration" ); - assert(msg.isRequest()); + resip_assert(msg.isRequest()); ServerRegistrationHandler* handler = mDum.mServerRegistrationHandler; RegistrationPersistenceManager *database = mDum.mRegistrationPersistenceManager; @@ -330,7 +331,10 @@ ServerRegistration::processRegistration(const SipMessage& msg) { rec.mInstance=i->param(p_Instance); } - + if (msg.exists(h_UserAgent)) + { + rec.mUserAgent = msg.header(h_UserAgent).value(); + } if(!msg.empty(h_Paths)) { rec.mSipPath=msg.header(h_Paths); @@ -431,7 +435,7 @@ ServerRegistration::processRegistration(const SipMessage& msg) return; default: - assert(0); + resip_assert(0); } } @@ -499,6 +503,13 @@ ServerRegistration::tryFlow(ContactInstanceRecord& rec, return true; } } + + if(msg.header(h_Vias).size() > 1 && InteropHelper::getAssumeFirstHopSupportsFlowTokensEnabled()) + { + rec.mUseFlowRouting = true; + rec.mReceivedFrom.onlyUseExistingConnection=false; + return true; + } } catch(resip::ParseBuffer::Exception&) {} @@ -512,7 +523,10 @@ ServerRegistration::testFlowRequirements(ContactInstanceRecord &rec, { const resip::NameAddr& contact(rec.mContact); - if(contact.exists(p_Instance) && contact.exists(p_regid)) + if(!msg.empty(h_Supporteds) && + msg.header(h_Supporteds).find(Token(Symbols::Outbound)) && + contact.exists(p_Instance) && + contact.exists(p_regid)) { // Client has explicitly requested Outbound processing, which requires us // to have a flow. @@ -560,7 +574,7 @@ ServerRegistration::flowTokenNeededForTls(const ContactInstanceRecord &rec) cons if(contact.uri().exists(p_transport)) { TransportType type = Tuple::toTransport(contact.uri().param(p_transport)); - if(type==TLS || type == DTLS) + if(isSecure(type)) { // secure transport and IP-address. Almost certainly won't work, but // we'll try anyway. @@ -612,7 +626,7 @@ ServerRegistration::asyncProcessFinalOkMsg(SipMessage &msg, ContactPtrList &cont ContactPtrList::iterator it(contacts.begin()); ContactPtrList::iterator itEnd(contacts.end()); - std::unique_ptr expired; + std::auto_ptr expired; UInt64 now=Timer::getTimeSecs(); @@ -622,7 +636,7 @@ ServerRegistration::asyncProcessFinalOkMsg(SipMessage &msg, ContactPtrList &cont if (!rec) { - assert(0); + resip_assert(0); continue; } @@ -630,7 +644,7 @@ ServerRegistration::asyncProcessFinalOkMsg(SipMessage &msg, ContactPtrList &cont { if (!expired.get()) { - expired = std::unique_ptr(new ContactPtrList()); + expired = std::auto_ptr(new ContactPtrList()); } expired->push_back(rec); continue; @@ -642,7 +656,7 @@ ServerRegistration::asyncProcessFinalOkMsg(SipMessage &msg, ContactPtrList &cont if (expired.get() && expired->size() > 0) { - mDum.mServerRegistrationHandler->asyncRemoveExpired(getHandle(), mAor, std::move(expired)); + mDum.mServerRegistrationHandler->asyncRemoveExpired(getHandle(),mAor,expired); //!WARN! Must not access this object beyond this point. The client my call reject() or accept(), deleting this object. Also, watch out for local objects that are still in scope and access this object on destruction. return; } @@ -677,32 +691,32 @@ ServerRegistration::processFinalOkMsg(SipMessage &msg, ContactList &contacts) } bool -ServerRegistration::asyncProvideContacts(std::unique_ptr contacts) +ServerRegistration::asyncProvideContacts(std::auto_ptr contacts) { switch (mAsyncState) { case asyncStateWaitingForInitialContactList: { - assert(mAsyncLocalStore.get() == 0); - mAsyncLocalStore = resip::SharedPtr(new AsyncLocalStore(std::move(contacts))); + resip_assert(mAsyncLocalStore.get() == 0); + mAsyncLocalStore = resip::SharedPtr(new AsyncLocalStore(contacts)); mAsyncState = asyncStateProcessingRegistration; processRegistration(mRequest); break; } case asyncStateWaitingForAcceptReject: { - assert(0); //need to call accept() or reject(), wait for asyncUpdateContacts(), then call this function. + resip_assert(0); //need to call accept() or reject(), wait for asyncUpdateContacts(), then call this function. return false; } case asyncStateAcceptedWaitingForFinalContactList: { mAsyncState = asyncStateProvidedFinalContacts; - asyncProcessFinalContacts(std::move(contacts)); + asyncProcessFinalContacts(contacts); break; } default: { - assert(0); + resip_assert(0); return false; } } @@ -711,13 +725,13 @@ ServerRegistration::asyncProvideContacts(std::unique_ptr } void -ServerRegistration::asyncProcessFinalContacts(std::unique_ptr contacts) +ServerRegistration::asyncProcessFinalContacts(std::auto_ptr contacts) { if (contacts.get()) { if (!mAsyncOkMsg.get()) { - assert(0); + resip_assert(0); } else { @@ -732,10 +746,10 @@ ServerRegistration::asyncProcessFinalContacts(std::unique_ptr originalContacts) +ServerRegistration::AsyncLocalStore::create(std::auto_ptr originalContacts) { - mModifiedContacts = std::move(originalContacts); - mLog = std::unique_ptr(new ContactRecordTransactionLog()); + mModifiedContacts = originalContacts; + mLog = std::auto_ptr(new ContactRecordTransactionLog()); } void @@ -750,7 +764,7 @@ ServerRegistration::AsyncLocalStore::updateContact(const ContactInstanceRecord & { if (!mModifiedContacts.get() || !mLog.get()) { - assert(0); + resip_assert(0); return RegistrationPersistenceManager::CONTACT_UPDATED; } @@ -789,7 +803,7 @@ ServerRegistration::AsyncLocalStore::removeContact(const ContactInstanceRecord & { if (!mModifiedContacts.get() || !mLog.get()) { - assert(0); + resip_assert(0); return; } diff --git a/src/libs/resiprocate/resip/dum/ServerRegistration.hxx b/src/libs/resiprocate/resip/dum/ServerRegistration.hxx index 77411b69..dc11b03d 100644 --- a/src/libs/resiprocate/resip/dum/ServerRegistration.hxx +++ b/src/libs/resiprocate/resip/dum/ServerRegistration.hxx @@ -47,7 +47,7 @@ class ServerRegistration: public NonDialogUsage !CAUTION! This function must be called from the DUM thread. */ - bool asyncProvideContacts(std::unique_ptr contacts); + bool asyncProvideContacts(std::auto_ptr contacts); resip::SharedPtr getOriginalContacts() { return mOriginalContacts; } // WARNING - use this only if async mode is not used const ContactList& getRequestContacts() { return mRequestContacts; } @@ -132,7 +132,7 @@ class ServerRegistration: public NonDialogUsage * contact list. Once the final list is received via asyncProvideContacts(), this function finishes the REGISTER * processing. */ - void asyncProcessFinalContacts(std::unique_ptr contacts); + void asyncProcessFinalContacts(std::auto_ptr contacts); /** Local datastore used to aggregate all changes to the current contact list when using the asynchronous logic. */ @@ -140,9 +140,9 @@ class ServerRegistration: public NonDialogUsage { public: - AsyncLocalStore(std::unique_ptr originalContacts) + AsyncLocalStore(std::auto_ptr originalContacts) { - create(std::move(originalContacts)); + create(originalContacts); } ~AsyncLocalStore(void) @@ -153,7 +153,7 @@ class ServerRegistration: public NonDialogUsage /** Setup this object in preparation for updating the records. Updates occur when processing a REGISTER message. */ - void create(std::unique_ptr originalContacts); + void create(std::auto_ptr originalContacts); void destroy(void); @@ -170,16 +170,16 @@ class ServerRegistration: public NonDialogUsage /** Remove the transacation log and updated contact list. This object should be considered destroyed and not used after releasing. */ - void releaseLog(std::unique_ptr &log, std::unique_ptr &modifiedContacts) + void releaseLog(std::auto_ptr &log, std::auto_ptr &modifiedContacts) { - log = std::move(mLog); - modifiedContacts = std::move(mModifiedContacts); + log = mLog; + modifiedContacts = mModifiedContacts; } unsigned int numContacts() { if(mModifiedContacts.get()) return (unsigned int)mModifiedContacts->size(); return 0; } private: - std::unique_ptr mLog; - std::unique_ptr mModifiedContacts; + std::auto_ptr mLog; + std::auto_ptr mModifiedContacts; }; resip::SharedPtr mAsyncLocalStore; diff --git a/src/libs/resiprocate/resip/dum/ServerSubscription.cxx b/src/libs/resiprocate/resip/dum/ServerSubscription.cxx index 8a3775d7..520a0c8c 100644 --- a/src/libs/resiprocate/resip/dum/ServerSubscription.cxx +++ b/src/libs/resiprocate/resip/dum/ServerSubscription.cxx @@ -4,6 +4,7 @@ #include "resip/dum/ServerSubscription.hxx" #include "resip/dum/SubscriptionHandler.hxx" #include "resip/dum/UsageUseException.hxx" +#include "resip/dum/MasterProfile.hxx" #include "resip/stack/Helper.hxx" #include "rutil/Logger.hxx" @@ -73,7 +74,9 @@ ServerSubscription::getTimeLeft() SharedPtr ServerSubscription::accept(int statusCode) { - mDialog.makeResponse(*mLastResponse, mLastSubscribe, statusCode); + // Response is built in dispatch when request arrives, just need to adjust the status code here + mLastResponse->header(h_StatusLine).responseCode() = statusCode; + Helper::getResponseCodeReason(statusCode, mLastResponse->header(h_StatusLine).reason()); mLastResponse->header(h_Expires).value() = mExpires; return mLastResponse; } @@ -85,18 +88,27 @@ ServerSubscription::reject(int statusCode) { throw UsageUseException("Must reject with a code greater than or equal to 300", __FILE__, __LINE__); } - mDialog.makeResponse(*mLastResponse, mLastSubscribe, statusCode); + // Response is built in dispatch when request arrives, just need to adjust the status code here + mLastResponse->header(h_StatusLine).responseCode() = statusCode; + Helper::getResponseCodeReason(statusCode, mLastResponse->header(h_StatusLine).reason()); + mLastResponse->remove(h_Contacts); // Remove any contact header for non-success response return mLastResponse; } +void ServerSubscription::terminateSubscription(ServerSubscriptionHandler* handler) +{ + handler->onTerminated(getHandle()); + delete this; +} void ServerSubscription::send(SharedPtr msg) { ServerSubscriptionHandler* handler = mDum.getServerSubscriptionHandler(mEventType); - assert(handler); + resip_assert(handler); if (msg->isResponse()) { + mLastResponse.reset(); // Release ref count on memory - so message goes away when send is done int code = msg->header(h_StatusLine).statusCode(); if (code < 200) { @@ -119,8 +131,7 @@ ServerSubscription::send(SharedPtr msg) else if (code < 400) { DialogUsage::send(msg); - handler->onTerminated(getHandle()); - delete this; + terminateSubscription(handler); return; } else @@ -128,8 +139,7 @@ ServerSubscription::send(SharedPtr msg) if (shouldDestroyAfterSendingFailure(*msg)) { DialogUsage::send(msg); - handler->onTerminated(getHandle()); - delete this; + terminateSubscription(handler); return; } else @@ -143,8 +153,7 @@ ServerSubscription::send(SharedPtr msg) DialogUsage::send(msg); if (mSubscriptionState == Terminated) { - handler->onTerminated(getHandle()); - delete this; + terminateSubscription(handler); } } } @@ -158,7 +167,7 @@ ServerSubscription::shouldDestroyAfterSendingFailure(const SipMessage& msg) case SubDlgInitial: return true; case SubDlgTerminating: //terminated state not using in ServerSubscription - assert(0); + resip_assert(0); return true; case SubDlgEstablished: { @@ -166,7 +175,7 @@ ServerSubscription::shouldDestroyAfterSendingFailure(const SipMessage& msg) { return true; } - switch (Helper::determineFailureMessageEffect(*mLastResponse)) + switch (Helper::determineFailureMessageEffect(msg)) { case Helper::TransactionTermination: case Helper::RetryAfter: @@ -187,9 +196,8 @@ ServerSubscription::shouldDestroyAfterSendingFailure(const SipMessage& msg) break; } default: // !jf! - assert(0); + resip_assert(0); break; - } return false; } @@ -197,23 +205,31 @@ ServerSubscription::shouldDestroyAfterSendingFailure(const SipMessage& msg) void ServerSubscription::setSubscriptionState(SubscriptionState state) { - mSubscriptionState = state; + // Don't allow a transition out of Terminated state + if (mSubscriptionState != Terminated) + { + mSubscriptionState = state; + } } void ServerSubscription::dispatch(const SipMessage& msg) { - DebugLog( << "ServerSubscriptionHandler::dispatch: " << msg.brief()); + DebugLog( << "ServerSubscription::dispatch: " << msg.brief()); ServerSubscriptionHandler* handler = mDum.getServerSubscriptionHandler(mEventType); - assert(handler); + resip_assert(handler); if (msg.isRequest()) { //!dcm! -- need to have a mechanism to retrieve default & acceptable //expiration times for an event package--part of handler API? //added to handler for now. - mLastSubscribe = msg; + if (mLastResponse.get() == 0) + { + mLastResponse.reset(new SipMessage); + } + mDialog.makeResponse(*mLastResponse, msg, 200); // Generate response now and wait for user to accept or reject, then adjust status code int errorResponseCode = 0; handler->getExpires(msg,mExpires,errorResponseCode); @@ -244,7 +260,11 @@ ServerSubscription::dispatch(const SipMessage& msg) */ if (mSubscriptionState == Invalid) { + // Move to terminated state - application is not allowed to switch out of this state. This + // allows applications to treat polling requests just like normal subscriptions. Any attempt + // to call setSubscriptionState will NoOp. mSubscriptionState = Terminated; + if (mEventType != "refer" ) { handler->onNewSubscription(getHandle(), msg); @@ -253,16 +273,21 @@ ServerSubscription::dispatch(const SipMessage& msg) { handler->onNewSubscriptionFromRefer(getHandle(), msg); } + // note: it might be nice to call onExpiredByClient here, but it's dangerous, since inline calls + // to reject or the inline sending of a Notify in the onNewSubscription handler will cause + // 'this' to be deleted + return; } - makeNotifyExpires(); + makeNotifyExpires(); // builds a NOTIFY message into mLastRequest handler->onExpiredByClient(getHandle(), msg, *mLastRequest); - - mDialog.makeResponse(*mLastResponse, mLastSubscribe, 200); + + // Send 200 response to sender mLastResponse->header(h_Expires).value() = mExpires; send(mLastResponse); - send(mLastRequest); // Send Notify Expires + // Send Notify Expires + send(mLastRequest); return; } if (mSubscriptionState == Invalid) @@ -289,25 +314,33 @@ ServerSubscription::dispatch(const SipMessage& msg) else { //.dcm. - will need to change if retry-afters are reaching here - mLastRequest->releaseContents(); + //mLastRequest->releaseContents(); + mLastRequest.reset(); // Release ref count on memory - so message goes away when send is done int code = msg.header(h_StatusLine).statusCode(); - if (code < 300) - { + + if(code < 200) + { + return; + } + else if (code < 300) + { + handler->onNotifyAccepted(getHandle(), msg); return; } else if (code < 400) { //in dialog NOTIFY got redirected? Bizarre... handler->onError(getHandle(), msg); - handler->onTerminated(getHandle()); - delete this; + terminateSubscription(handler); } else { - switch(Helper::determineFailureMessageEffect(msg)) + switch(Helper::determineFailureMessageEffect(msg, + (mDum.getMasterProfile()->additionalTransactionTerminatingResponsesEnabled()) ? + &mDum.getMasterProfile()->getAdditionalTransactionTerminatingResponses() : NULL)) { case Helper::TransactionTermination: - DebugLog( << "ServerSubscriptionHandler::TransactionTermination: " << msg.brief()); + DebugLog( << "ServerSubscription::TransactionTermination: " << msg.brief()); handler->onNotifyRejected(getHandle(), msg); break; case Helper::UsageTermination: @@ -315,10 +348,9 @@ ServerSubscription::dispatch(const SipMessage& msg) case Helper::OptionalRetryAfter: case Helper::ApplicationDependant: case Helper::DialogTermination: - DebugLog( << "ServerSubscriptionHandler::UsageTermination: " << msg.brief()); + DebugLog( << "ServerSubscription::UsageTermination: " << msg.brief()); handler->onError(getHandle(), msg); - handler->onTerminated(getHandle()); - delete this; + terminateSubscription(handler); break; } } @@ -336,6 +368,10 @@ ServerSubscription::makeNotifyExpires() void ServerSubscription::makeNotify() { + if (mLastRequest.get() == 0) + { + mLastRequest.reset(new SipMessage); + } mDialog.makeRequest(*mLastRequest, NOTIFY); mLastRequest->header(h_SubscriptionState).value() = getSubscriptionStateString(mSubscriptionState); if (mSubscriptionState == Terminated) @@ -356,16 +392,23 @@ ServerSubscription::makeNotify() void -ServerSubscription::end(TerminateReason reason, const Contents* document) +ServerSubscription::end(TerminateReason reason, const Contents* document, int retryAfter) { - mSubscriptionState = Terminated; - makeNotify(); - mLastRequest->header(h_SubscriptionState).param(p_reason) = getTerminateReasonString(reason); - if (document) + if (mSubscriptionState != Terminated) // NoOp if called twice or already ending { - mLastRequest->setContents(document); + mSubscriptionState = Terminated; + makeNotify(); + mLastRequest->header(h_SubscriptionState).param(p_reason) = getTerminateReasonString(reason); + if (document) + { + mLastRequest->setContents(document); + } + if (retryAfter != 0) + { + mLastRequest->header(h_SubscriptionState).param(p_retryAfter) = retryAfter; + } + send(mLastRequest); } - send(mLastRequest); } void @@ -377,11 +420,11 @@ ServerSubscription::end() void ServerSubscription::dispatch(const DumTimeout& timeout) { - assert(timeout.type() == DumTimeout::Subscription); + resip_assert(timeout.type() == DumTimeout::Subscription); if (timeout.seq() == mTimerSeq) { ServerSubscriptionHandler* handler = mDum.getServerSubscriptionHandler(mEventType); - assert(handler); + resip_assert(handler); makeNotifyExpires(); handler->onExpired(getHandle(), *mLastRequest); send(mLastRequest); @@ -404,21 +447,11 @@ ServerSubscription::neutralNotify() return mLastRequest; } -void -ServerSubscription::dialogDestroyed(const SipMessage& msg) -{ - ServerSubscriptionHandler* handler = mDum.getServerSubscriptionHandler(mEventType); - assert(handler); - handler->onError(getHandle(), msg); - handler->onTerminated(getHandle()); - delete this; -} - void ServerSubscription::onReadyToSend(SipMessage& msg) { ServerSubscriptionHandler* handler = mDum.getServerSubscriptionHandler(mEventType); - assert(handler); + resip_assert(handler); handler->onReadyToSend(getHandle(), msg); } @@ -427,7 +460,7 @@ ServerSubscription::flowTerminated() { // notify handler ServerSubscriptionHandler* handler = mDum.getServerSubscriptionHandler(mEventType); - assert(handler); + resip_assert(handler); handler->onFlowTerminated(getHandle()); } @@ -438,7 +471,6 @@ ServerSubscription::dump(EncodeStream& strm) const return strm; } - /* ==================================================================== * The Vovida Software License, Version 1.0 * diff --git a/src/libs/resiprocate/resip/dum/ServerSubscription.hxx b/src/libs/resiprocate/resip/dum/ServerSubscription.hxx index a990b06d..d1231992 100644 --- a/src/libs/resiprocate/resip/dum/ServerSubscription.hxx +++ b/src/libs/resiprocate/resip/dum/ServerSubscription.hxx @@ -1,12 +1,14 @@ #if !defined(RESIP_SERVERSUBSCRIPTION_HXX) #define RESIP_SERVERSUBSCRIPTION_HXX +#include "resip/stack/Helper.hxx" #include "resip/dum/BaseSubscription.hxx" namespace resip { class DialogUsageManager; +class ServerSubscriptionHandler; //!dcm! -- no Subscription State expires parameter generation yet. class ServerSubscription : public BaseSubscription @@ -30,7 +32,7 @@ class ServerSubscription : public BaseSubscription void setSubscriptionState(SubscriptionState state); SharedPtr update(const Contents* document); - void end(TerminateReason reason, const Contents* document = 0); + void end(TerminateReason reason, const Contents* document = 0, int retryAfter = 0); virtual void end(); virtual void send(SharedPtr msg); @@ -49,7 +51,6 @@ class ServerSubscription : public BaseSubscription protected: virtual ~ServerSubscription(); - virtual void dialogDestroyed(const SipMessage& msg); void onReadyToSend(SipMessage& msg); virtual void flowTerminated(); @@ -63,11 +64,9 @@ class ServerSubscription : public BaseSubscription bool shouldDestroyAfterSendingFailure(const SipMessage& msg); + void terminateSubscription(ServerSubscriptionHandler* handler); + Data mSubscriber; - -// const Contents* mCurrentEventDocument; - SipMessage mLastSubscribe; - UInt32 mExpires; // disabled diff --git a/src/libs/resiprocate/resip/dum/SubscriptionHandler.cxx b/src/libs/resiprocate/resip/dum/SubscriptionHandler.cxx index b3ca43f8..cb671279 100644 --- a/src/libs/resiprocate/resip/dum/SubscriptionHandler.cxx +++ b/src/libs/resiprocate/resip/dum/SubscriptionHandler.cxx @@ -133,6 +133,10 @@ ServerSubscriptionHandler::onPublished(ServerSubscriptionHandle associated, // do nothing by default } +void +ServerSubscriptionHandler::onNotifyAccepted(ServerSubscriptionHandle h, const SipMessage& msg) +{ +} void ServerSubscriptionHandler::onNotifyRejected(ServerSubscriptionHandle h, const SipMessage& msg) diff --git a/src/libs/resiprocate/resip/dum/SubscriptionHandler.hxx b/src/libs/resiprocate/resip/dum/SubscriptionHandler.hxx index 98e31263..12fa104c 100644 --- a/src/libs/resiprocate/resip/dum/SubscriptionHandler.hxx +++ b/src/libs/resiprocate/resip/dum/SubscriptionHandler.hxx @@ -25,7 +25,7 @@ class ClientSubscriptionHandler //subscription can be ended through a notify or a failure response. virtual void onTerminated(ClientSubscriptionHandle, const SipMessage* msg)=0; - //not sure if this has any value. + //not sure if this has any value - can be called for either a 200/SUBSCRIBE or a NOTIFY - whichever arrives first virtual void onNewSubscription(ClientSubscriptionHandle, const SipMessage& notify)=0; /// called to allow app to adorn a message. @@ -48,11 +48,15 @@ class ServerSubscriptionHandler virtual void onNewSubscription(ServerSubscriptionHandle, const SipMessage& sub)=0; virtual void onNewSubscriptionFromRefer(ServerSubscriptionHandle, const SipMessage& sub); virtual void onRefresh(ServerSubscriptionHandle, const SipMessage& sub); + //called when a new document is Published that matches this subscription. Also + //called when the publication is removed or expires, in which case contents + //and attrs are passed as null pointers. virtual void onPublished(ServerSubscriptionHandle associated, ServerPublicationHandle publication, const Contents* contents, const SecurityAttributes* attrs); + virtual void onNotifyAccepted(ServerSubscriptionHandle, const SipMessage& msg); virtual void onNotifyRejected(ServerSubscriptionHandle, const SipMessage& msg); //called when this usage is destroyed for any reason. One of the following diff --git a/src/libs/resiprocate/resip/dum/TargetCommand.cxx b/src/libs/resiprocate/resip/dum/TargetCommand.cxx index 7b15babf..152286f5 100644 --- a/src/libs/resiprocate/resip/dum/TargetCommand.cxx +++ b/src/libs/resiprocate/resip/dum/TargetCommand.cxx @@ -7,21 +7,21 @@ using namespace std; TargetCommand::TargetCommand(Target& target, - unique_ptr message) + auto_ptr message) : mTarget(target), - mMessage(std::move(message)) + mMessage(message) { } TargetCommand::TargetCommand(const TargetCommand& from) : mTarget(from.mTarget), - mMessage(std::move(from.mMessage)) + mMessage(from.mMessage) { } void TargetCommand::executeCommand() { - mTarget.post(std::move(mMessage)); + mTarget.post(mMessage); } Message* TargetCommand::clone() const diff --git a/src/libs/resiprocate/resip/dum/TargetCommand.hxx b/src/libs/resiprocate/resip/dum/TargetCommand.hxx index 6ab70c76..e980796a 100644 --- a/src/libs/resiprocate/resip/dum/TargetCommand.hxx +++ b/src/libs/resiprocate/resip/dum/TargetCommand.hxx @@ -19,13 +19,13 @@ class TargetCommand : public DumCommand { } virtual ~Target()=0; - virtual void post(std::unique_ptr)=0; + virtual void post(std::auto_ptr)=0; protected: DialogUsageManager& mDum; }; - TargetCommand(Target& target, std::unique_ptr message); + TargetCommand(Target& target, std::auto_ptr message); TargetCommand(const TargetCommand&); void executeCommand(); @@ -36,7 +36,7 @@ class TargetCommand : public DumCommand private: Target& mTarget; - mutable std::unique_ptr mMessage; + mutable std::auto_ptr mMessage; }; } diff --git a/src/libs/resiprocate/resip/dum/TlsPeerAuthManager.cxx b/src/libs/resiprocate/resip/dum/TlsPeerAuthManager.cxx index 6a592284..57f6cc43 100644 --- a/src/libs/resiprocate/resip/dum/TlsPeerAuthManager.cxx +++ b/src/libs/resiprocate/resip/dum/TlsPeerAuthManager.cxx @@ -1,4 +1,4 @@ -#include +#include "rutil/ResipAssert.h" #include "resip/dum/DumFeature.hxx" #include "resip/dum/DumFeatureChain.hxx" @@ -14,14 +14,14 @@ using namespace resip; using namespace std; -TlsPeerAuthManager::TlsPeerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target, std::set& trustedPeers, bool thirdPartyRequiresCertificate) : +TlsPeerAuthManager::TlsPeerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target, const std::set& trustedPeers, bool thirdPartyRequiresCertificate) : DumFeature(dum, target), mTrustedPeers(trustedPeers), mThirdPartyRequiresCertificate(thirdPartyRequiresCertificate) { } -TlsPeerAuthManager::TlsPeerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target, std::set& trustedPeers, bool thirdPartyRequiresCertificate, CommonNameMappings& commonNameMappings) : +TlsPeerAuthManager::TlsPeerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target, const std::set& trustedPeers, bool thirdPartyRequiresCertificate, CommonNameMappings& commonNameMappings) : DumFeature(dum, target), mTrustedPeers(trustedPeers), mThirdPartyRequiresCertificate(thirdPartyRequiresCertificate), @@ -31,7 +31,7 @@ TlsPeerAuthManager::TlsPeerAuthManager(DialogUsageManager& dum, TargetCommand::T TlsPeerAuthManager::~TlsPeerAuthManager() { - InfoLog(<< "~TlsPeerAuthManager"); + InfoLog(<< "~TlsPeerAuthManager: " << mMessages.size() << " messages in memory when destroying."); } // !bwc! We absolutely, positively, MUST NOT throw here. This is because in @@ -42,6 +42,7 @@ DumFeature::ProcessingResult TlsPeerAuthManager::process(Message* msg) { SipMessage* sipMessage = dynamic_cast(msg); + TlsPeerIdentityInfoMessage* tpiMessage = dynamic_cast(msg); if (sipMessage) { @@ -51,17 +52,35 @@ TlsPeerAuthManager::process(Message* msg) case TlsPeerAuthManager::Rejected: InfoLog(<< "TlsPeerAuth rejected request " << sipMessage->brief()); return DumFeature::ChainDoneAndEventDone; + case TlsPeerAuthManager::RequestedInfo: + return DumFeature::EventTaken; default: // includes Authorized, Skipped return DumFeature::FeatureDone; } } + if (tpiMessage) + { + Message* result = handleTlsPeerIdentityInfo(tpiMessage); + if (result) + { + postCommand(auto_ptr(result)); + return FeatureDoneAndEventDone; + } + else + { + InfoLog(<< "TlsPeerAuth rejected request " << *tpiMessage); + return ChainDoneAndEventDone; + } + } + // Catch-all (handles something that was not a SipMessage) return FeatureDone; } -bool +AsyncBool TlsPeerAuthManager::authorizedForThisIdentity( + const Data& transactionId, const std::list &peerNames, resip::Uri &fromUri) { @@ -72,20 +91,15 @@ TlsPeerAuthManager::authorizedForThisIdentity( for(; it != peerNames.end(); ++it) { const Data& i = *it; - if(mTrustedPeers.find(i) != mTrustedPeers.end()) - { - DebugLog(<< "Matched certificate name " << i << " is a trusted peer, not checking against From URI"); - return true; - } if(i == aor) { DebugLog(<< "Matched certificate name " << i << " against full AoR " << aor); - return true; + return True; } if(i == domain) { DebugLog(<< "Matched certificate name " << i << " against domain " << domain); - return true; + return True; } CommonNameMappings::iterator _mapping = mCommonNameMappings.find(i); @@ -96,19 +110,33 @@ TlsPeerAuthManager::authorizedForThisIdentity( if(permitted.find(aor) != permitted.end()) { DebugLog(<< "Matched certificate name " << i << " against full AoR " << aor << " by common name mappings"); - return true; + return True; } if(permitted.find(domain) != permitted.end()) { DebugLog(<< "Matched certificate name " << i << " against domain " << domain << " by common name mappings"); - return true; + return True; } } DebugLog(<< "Certificate name " << i << " doesn't match AoR " << aor << " or domain " << domain); } + if(mCommonNameMappings.size() == 0) + { + DebugLog(<<"mCommonNameMappings is empty, trying async"); + TlsPeerIdentityInfoMessage* tpaInfo = new TlsPeerIdentityInfoMessage(transactionId, &mDum); + for(it = peerNames.begin(); it != peerNames.end(); ++it) + { + tpaInfo->peerNames().insert(*it); + } + tpaInfo->identities().insert(aor); + tpaInfo->identities().insert(domain); + return asyncLookup(tpaInfo); + } + // catch-all: access denied - return false; + DebugLog(<< "message content didn't match any peer name"); + return False; } // return true if request has been consumed @@ -133,30 +161,70 @@ TlsPeerAuthManager::handle(SipMessage* sipMessage) mDum.send(response); return Rejected; } + Uri claimedUri = sipMessage->header(h_From).uri(); + if(sipMessage->method() == REFER && sipMessage->exists(h_ReferredBy)) + { + if(!sipMessage->header(h_ReferredBy).isWellFormed() || + sipMessage->header(h_ReferredBy).isAllContacts() ) + { + InfoLog(<<"Malformed Referred-By header: cannot verify against any certificate. Rejecting."); + SharedPtr response(new SipMessage); + Helper::makeResponse(*response, *sipMessage, 400, "Malformed Referred-By header"); + mDum.send(response); + return Rejected; + } + // For REFER requests, we authenticate the Referred-By header + // instead of the From header + claimedUri = sipMessage->header(h_ReferredBy).uri(); + } // We are only concerned with connections over TLS - if(!sipMessage->isExternal() || sipMessage->getSource().getType() != TLS) + if(!sipMessage->isExternal() || !isSecure(sipMessage->getSource().getType())) { DebugLog(<<"Can't validate certificate on non-TLS connection"); return Skipped; } + if(isTrustedSource(*sipMessage)) + { + DebugLog(<<"from trusted node, skipping checks"); + return Authorized; + } + const std::list &peerNames = sipMessage->getTlsPeerNames(); - if (mDum.isMyDomain(sipMessage->header(h_From).uri().host())) + if (mDum.isMyDomain(claimedUri.host())) { // peerNames is empty if client certificate mode is `optional' // or if the message didn't come in on TLS transport - if (requiresAuthorization(*sipMessage) && !peerNames.empty()) + if (!requiresAuthorization(*sipMessage)) { - if(authorizedForThisIdentity(peerNames, sipMessage->header(h_From).uri())) - return Authorized; - SharedPtr response(new SipMessage); - Helper::makeResponse(*response, *sipMessage, 403, "Authorization Failed for peer cert"); - mDum.send(response); - return Rejected; - } - else + DebugLog(<<"authorization not required for this message"); return Skipped; + } + + if(peerNames.empty()) + { + DebugLog(<<"peerNames is empty, allowing the message without further inspection"); + return Skipped; + } + + AsyncBool _auth = authorizedForThisIdentity(sipMessage->getTransactionId(), peerNames, claimedUri); + if(_auth == True) + { + DebugLog(<<"authorized"); + return Authorized; + } + else if(_auth == Async) + { + mMessages[sipMessage->getTransactionId()] = sipMessage; + DebugLog(<<"waiting for async authorization"); + return RequestedInfo; + } + DebugLog(<<"not authorized"); + SharedPtr response(new SipMessage); + Helper::makeResponse(*response, *sipMessage, 403, "Authorization Failed for peer cert"); + mDum.send(response); + return Rejected; } else { @@ -166,16 +234,31 @@ TlsPeerAuthManager::handle(SipMessage* sipMessage) { if(mThirdPartyRequiresCertificate) { + DebugLog(<<"third party requires certificate"); SharedPtr response(new SipMessage); Helper::makeResponse(*response, *sipMessage, 403, "Mutual TLS required to handle that message"); mDum.send(response); return Rejected; } else + { + DebugLog(<<"third party does not require certificate, allowing the message without further inspection"); return Skipped; + } } - if(authorizedForThisIdentity(peerNames, sipMessage->header(h_From).uri())) + AsyncBool _auth = authorizedForThisIdentity(sipMessage->getTransactionId(), peerNames, claimedUri); + if(_auth == True) + { + DebugLog(<<"authorized"); return Authorized; + } + else if(_auth == Async) + { + mMessages[sipMessage->getTransactionId()] = sipMessage; + DebugLog(<<"waiting for async authorization"); + return RequestedInfo; + } + DebugLog(<<"not authorized"); SharedPtr response(new SipMessage); Helper::makeResponse(*response, *sipMessage, 403, "Authorization Failed for peer cert"); mDum.send(response); @@ -186,6 +269,37 @@ TlsPeerAuthManager::handle(SipMessage* sipMessage) return Skipped; } +SipMessage* +TlsPeerAuthManager::handleTlsPeerIdentityInfo(TlsPeerIdentityInfoMessage *tpiInfo) +{ + resip_assert(tpiInfo); + + MessageMap::iterator it = mMessages.find(tpiInfo->getTransactionId()); + resip_assert(it != mMessages.end()); + SipMessage* request = it->second; + mMessages.erase(it); + + if(tpiInfo->authorized()) + { + DebugLog(<<"authorized"); + return request; + } + + DebugLog(<<"not authorized"); + SharedPtr response(new SipMessage); + Helper::makeResponse(*response, *request, 403, "Authentication Failed for peer cert."); + mDum.send(response); + delete request; + return 0; +} + +AsyncBool +TlsPeerAuthManager::asyncLookup(TlsPeerIdentityInfoMessage *info) +{ + delete info; + return False; +} + bool TlsPeerAuthManager::requiresAuthorization(const SipMessage& msg) { @@ -194,6 +308,26 @@ TlsPeerAuthManager::requiresAuthorization(const SipMessage& msg) return true; } +bool +TlsPeerAuthManager::isTrustedSource(const SipMessage& msg) +{ + // over-ride this method to implement some other policy + + const std::list &peerNames = msg.getTlsPeerNames(); + std::list::const_iterator it = peerNames.begin(); + for(; it != peerNames.end(); ++it) + { + const Data& i = *it; + if(mTrustedPeers.find(i) != mTrustedPeers.end()) + { + DebugLog(<< "Matched certificate name " << i << " is a trusted peer"); + return true; + } + } + + return false; +} + /* ==================================================================== * * Copyright (c) 2012 Daniel Pocock All rights reserved. diff --git a/src/libs/resiprocate/resip/dum/TlsPeerAuthManager.hxx b/src/libs/resiprocate/resip/dum/TlsPeerAuthManager.hxx index ddb377c3..665ef46a 100644 --- a/src/libs/resiprocate/resip/dum/TlsPeerAuthManager.hxx +++ b/src/libs/resiprocate/resip/dum/TlsPeerAuthManager.hxx @@ -4,8 +4,10 @@ #include #include +#include "rutil/AsyncBool.hxx" #include "resip/stack/SipMessage.hxx" #include "DumFeature.hxx" +#include "resip/dum/TlsPeerIdentityInfoMessage.hxx" namespace resip { @@ -21,11 +23,12 @@ class TlsPeerAuthManager : public DumFeature { Authorized, Skipped, - Rejected + Rejected, + RequestedInfo }; - TlsPeerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target, std::set& trustedPeers, bool thirdPartyRequiresCertificate = true); - TlsPeerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target, std::set& trustedPeers, bool thirdPartyRequiresCertificate, CommonNameMappings& commonNameMappings); + TlsPeerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target, const std::set& trustedPeers, bool thirdPartyRequiresCertificate = true); + TlsPeerAuthManager(DialogUsageManager& dum, TargetCommand::Target& target, const std::set& trustedPeers, bool thirdPartyRequiresCertificate, CommonNameMappings& commonNameMappings); virtual ~TlsPeerAuthManager(); virtual ProcessingResult process(Message* msg); @@ -34,19 +37,28 @@ class TlsPeerAuthManager : public DumFeature // can return Authorized, Rejected, Skipped virtual Result handle(SipMessage* sipMsg); + virtual SipMessage* handleTlsPeerIdentityInfo(TlsPeerIdentityInfoMessage *tpiInfo); /// should return true if the passed in user is authorized for the provided uri - virtual bool authorizedForThisIdentity(const std::list &peerNames, + virtual AsyncBool authorizedForThisIdentity(const resip::Data& transactionId, const std::list &peerNames, resip::Uri &fromUri); /// should return true if the request must be challenged /// The default is to challenge all requests - override this class to change this beviour virtual bool requiresAuthorization(const SipMessage& msg); + virtual AsyncBool asyncLookup(TlsPeerIdentityInfoMessage *info); + /// should return true if the request should be trusted based on + /// the source/transport + /// default implementation uses mTrustedPeers + virtual bool isTrustedSource(const SipMessage& msg); private: + typedef std::map MessageMap; + MessageMap mMessages; + std::set mTrustedPeers; - CommonNameMappings mCommonNameMappings; bool mThirdPartyRequiresCertificate; + CommonNameMappings mCommonNameMappings; }; diff --git a/src/libs/resiprocate/resip/dum/TlsPeerIdentityInfoMessage.cxx b/src/libs/resiprocate/resip/dum/TlsPeerIdentityInfoMessage.cxx new file mode 100644 index 00000000..28d894fa --- /dev/null +++ b/src/libs/resiprocate/resip/dum/TlsPeerIdentityInfoMessage.cxx @@ -0,0 +1,97 @@ + +#include "rutil/ResipAssert.h" + +#include "resip/dum/TlsPeerIdentityInfoMessage.hxx" +#include "rutil/Data.hxx" +#include "rutil/Logger.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + + +TlsPeerIdentityInfoMessage::TlsPeerIdentityInfoMessage(const Data& transactionId, + resip::TransactionUser* transactionUser) : + DumFeatureMessage(transactionId), + mAuthorized(false) +{ + mTu = transactionUser; +} + +TlsPeerIdentityInfoMessage::~TlsPeerIdentityInfoMessage() +{ +} + +Data +TlsPeerIdentityInfoMessage::brief() const +{ + Data buffer; + DataStream strm(buffer); + strm << "TlsPeerIdentityInfoMessage " << mAuthorized; + strm.flush(); + return buffer; +} + +resip::Message* +TlsPeerIdentityInfoMessage::clone() const +{ + resip_assert(false); return NULL; +} + +std::ostream& +TlsPeerIdentityInfoMessage::encode(std::ostream& strm) const +{ + strm << brief(); + return strm; +} + +std::ostream& +TlsPeerIdentityInfoMessage::encodeBrief(std::ostream& strm) const +{ + return encode(strm); +} + +std::ostream& +resip::operator<<(std::ostream& strm, const TlsPeerIdentityInfoMessage& msg) +{ + return msg.encode(strm); +} + +/* ==================================================================== + * + * Copyright 2014 Daniel Pocock http://danielpocock.com All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/resip/dum/TlsPeerIdentityInfoMessage.hxx b/src/libs/resiprocate/resip/dum/TlsPeerIdentityInfoMessage.hxx new file mode 100644 index 00000000..c0cee003 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/TlsPeerIdentityInfoMessage.hxx @@ -0,0 +1,83 @@ +#if !defined(RESIP_TLSPEERIDENTITYINFOMESSAGE_HXX) +#define RESIP_TLSPEERIDENTITYINFOMESSAGE_HXX + +#include + +#include "rutil/Data.hxx" +#include "resip/dum/DumFeatureMessage.hxx" + +namespace resip +{ + +class TlsPeerIdentityInfoMessage : public resip::DumFeatureMessage +{ + public: + TlsPeerIdentityInfoMessage(const Data& transactionId, + resip::TransactionUser* transactionUser); + ~TlsPeerIdentityInfoMessage(); + + const std::set& peerNames() const{return mPeerNames;} + std::set& peerNames(){return mPeerNames;} + + const std::set& identities() const{return mIdentities;} + std::set& identities(){return mIdentities;} + + const bool authorized() const{return mAuthorized;} + bool& authorized(){return mAuthorized;} + + virtual resip::Data brief() const; + virtual resip::Message* clone() const; + + virtual std::ostream& encode(std::ostream& strm) const; + virtual std::ostream& encodeBrief(std::ostream& strm) const; + + private: + std::set mPeerNames; + std::set mIdentities; + bool mAuthorized; +}; + +std::ostream& +operator<<(std::ostream& strm, const TlsPeerIdentityInfoMessage& msg); + +} + +#endif + +/* ==================================================================== + * + * Copyright 2014 Daniel Pocock http://danielpocock.com All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/resip/dum/UserAuthInfo.cxx b/src/libs/resiprocate/resip/dum/UserAuthInfo.cxx index bb448516..04cfef69 100644 --- a/src/libs/resiprocate/resip/dum/UserAuthInfo.cxx +++ b/src/libs/resiprocate/resip/dum/UserAuthInfo.cxx @@ -1,5 +1,5 @@ -#include +#include "rutil/ResipAssert.h" #include "resip/dum/UserAuthInfo.hxx" #include "rutil/Data.hxx" @@ -98,7 +98,7 @@ UserAuthInfo::brief() const resip::Message* UserAuthInfo::clone() const { - assert(false); return NULL; + resip_assert(false); return NULL; } EncodeStream& diff --git a/src/libs/resiprocate/resip/dum/UserProfile.cxx b/src/libs/resiprocate/resip/dum/UserProfile.cxx index c20a9cf1..1f20965e 100644 --- a/src/libs/resiprocate/resip/dum/UserProfile.cxx +++ b/src/libs/resiprocate/resip/dum/UserProfile.cxx @@ -14,7 +14,8 @@ const resip::NameAddr UserProfile::mAnonymous("\"Anonymous\" baseProfile) : Profile(baseProfile), mGruuEnabled(false), mRegId(0), - mClientOutboundEnabled(false) + mClientOutboundEnabled(false), + mDigestCacheUseLimit(0) { //InfoLog (<< "************ UserProfile created (with base)!: " << *this); } @@ -114,7 +116,7 @@ UserProfile::hasGruu(const Data& aor, const Data& instance) const NameAddr& UserProfile:: getGruu(const Data& aor) { - assert(0); + resip_assert(0); static NameAddr gruu; return gruu; } @@ -122,7 +124,7 @@ UserProfile:: getGruu(const Data& aor) NameAddr& UserProfile:: getGruu(const Data& aor, const NameAddr& contact) { - assert(0); + resip_assert(0); static NameAddr gruu; return gruu; } @@ -150,6 +152,7 @@ UserProfile::getDigestCredential( const Data& realm ) if(mDigestCredentials.empty()) { // !jf! why not just throw here? + WarningLog(<< "No digest credentials available"); return emptyDigestCredential; } diff --git a/src/libs/resiprocate/resip/dum/UserProfile.hxx b/src/libs/resiprocate/resip/dum/UserProfile.hxx index 622d5143..7ac1fba6 100644 --- a/src/libs/resiprocate/resip/dum/UserProfile.hxx +++ b/src/libs/resiprocate/resip/dum/UserProfile.hxx @@ -88,6 +88,16 @@ class UserProfile : public Profile const Data& password, bool isPasswordA1Hash=false); virtual const DigestCredential& getDigestCredential( const Data& realm ); + // DigestCacheUseLimit is used to indicate the maximum number of times a particular Proxy or WWW Authorization + // header will be used in requests within a dialogset. When this limit is reached then the + // next request in the DiaglogSet will go out without digest credentials. This setting can be used to + // work around bugs/limitations in third-party implementations that have difficulty properly dealing with + // cached credentials. A setting of 0 (default) will disable the limit and all requests in a Dialogset will + // have the same cached Authorization header on them, until they are re-challenged by the far end. A setting of + // 1 disables caching entirely and future requests within the dialog set will go out without any authorization + // headers. + virtual void setDigestCacheUseLimit(unsigned long digestCacheUseLimit) { mDigestCacheUseLimit = digestCacheUseLimit; } + virtual unsigned long getDigestCacheUseLimit() { return mDigestCacheUseLimit; } // Enable this to enable RFC5626 support in DUM - adds regId to registrations, and // ;ob parameter to Path, Route, and Contact headers @@ -112,6 +122,7 @@ class UserProfile : public Profile // that use this profile const Tuple& getClientOutboundFlowTuple() const { return mClientOutboundFlowTuple; } void clearClientOutboundFlowTuple() { mClientOutboundFlowTuple = Tuple(); } + void setClientOutboundFlowTuple(const Tuple& outboundFlowTuple) { mClientOutboundFlowTuple = outboundFlowTuple; } // Only for advanced users protected: virtual UserProfile* clone() const; @@ -136,6 +147,7 @@ class UserProfile : public Profile typedef std::set DigestCredentials; DigestCredentials mDigestCredentials; + unsigned long mDigestCacheUseLimit; friend EncodeStream& operator<<(EncodeStream&, const UserProfile& profile); }; diff --git a/src/libs/resiprocate/resip/dum/WsCookieAuthManager.cxx b/src/libs/resiprocate/resip/dum/WsCookieAuthManager.cxx new file mode 100644 index 00000000..ffa4f719 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/WsCookieAuthManager.cxx @@ -0,0 +1,200 @@ +#include "rutil/ResipAssert.h" + +#include "resip/dum/DumFeature.hxx" +#include "resip/dum/DumFeatureChain.hxx" +#include "resip/dum/DialogUsageManager.hxx" +#include "resip/dum/TargetCommand.hxx" +#include "resip/dum/WsCookieAuthManager.hxx" +#include "resip/stack/Helper.hxx" +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::DUM + +using namespace resip; +using namespace std; + +WsCookieAuthManager::WsCookieAuthManager(DialogUsageManager& dum, TargetCommand::Target& target) : + DumFeature(dum, target) +{ +} + +WsCookieAuthManager::~WsCookieAuthManager() +{ + InfoLog(<< "~WsCookieAuthManager"); +} + +// !bwc! We absolutely, positively, MUST NOT throw here. This is because in +// DialogUsageManager::process(), we do not know if a DumFeature has taken +// ownership of msg until we get a return. If we throw, the ownership of msg +// is unknown. This is unacceptable. +DumFeature::ProcessingResult +WsCookieAuthManager::process(Message* msg) +{ + SipMessage* sipMessage = dynamic_cast(msg); + + if (sipMessage) + { + //!dcm! -- unecessary happens in handle + switch ( handle(sipMessage) ) + { + case WsCookieAuthManager::Rejected: + InfoLog(<< "WsCookieAuth rejected request " << sipMessage->brief()); + return DumFeature::ChainDoneAndEventDone; + default: // includes Authorized, Skipped + return DumFeature::FeatureDone; + } + } + + // Catch-all (handles something that was not a SipMessage) + return FeatureDone; +} + +bool +WsCookieAuthManager::cookieUriMatch(const resip::Uri &first, const resip::Uri &second) +{ + return( + (isEqualNoCase(first.user(), second.user()) || first.user() == "*") && + (isEqualNoCase(first.host(), second.host()) || first.host() == "*") + ); +} + +bool +WsCookieAuthManager::authorizedForThisIdentity( + const MethodTypes method, + const WsCookieContext &wsCookieContext, + const resip::Uri &fromUri, + const resip::Uri &toUri) +{ + if(difftime(wsCookieContext.getExpiresTime(), time(NULL)) < 0) + { + WarningLog(<< "Received expired cookie"); + return false; + } + + Uri wsFromUri = wsCookieContext.getWsFromUri(); + Uri wsDestUri = wsCookieContext.getWsDestUri(); + if(cookieUriMatch(wsFromUri, fromUri)) + { + DebugLog(<< "Matched cookie source URI field" << wsFromUri << " against request From header field URI " << fromUri); + // When registering, "From" URI == "To" URI, so we can ignore the + // "To" URI restriction from the cookie when processing REGISTER + if(method == REGISTER && isEqualNoCase(fromUri.user(), toUri.user()) && isEqualNoCase(fromUri.host(), toUri.host())) + { + return true; + } + if(cookieUriMatch(wsDestUri, toUri)) + { + DebugLog(<< "Matched cookie destination URI field" << wsDestUri << " against request To header field URI " << toUri); + return true; + } + } + + // catch-all: access denied + return false; +} + +// return true if request has been consumed +WsCookieAuthManager::Result +WsCookieAuthManager::handle(SipMessage* sipMessage) +{ + // Only check message coming over WebSockets + if(!isWebSocket(sipMessage->getReceivedTransportTuple().getType())) + { + return Skipped; + } + //InfoLog( << "trying to do auth" ); + if (!sipMessage->isRequest() || + sipMessage->header(h_RequestLine).method() == ACK || + sipMessage->header(h_RequestLine).method() == CANCEL) + { + // Do not inspect ACKs or CANCELs + return Skipped; + } + + if(!sipMessage->header(h_From).isWellFormed() || + sipMessage->header(h_From).isAllContacts() ) + { + InfoLog(<<"Malformed From header: cannot verify against cookie. Rejecting."); + SharedPtr response(new SipMessage); + Helper::makeResponse(*response, *sipMessage, 400, "Malformed From header"); + mDum.send(response); + return Rejected; + } + + const WsCookieContext &wsCookieContext = *(sipMessage->getWsCookieContext()); + if (mDum.isMyDomain(sipMessage->header(h_From).uri().host())) + { + if (requiresAuthorization(*sipMessage)) + { + if(authorizedForThisIdentity(sipMessage->header(h_RequestLine).method(), wsCookieContext, sipMessage->header(h_From).uri(), sipMessage->header(h_To).uri())) + { + return Authorized; + } + SharedPtr response(new SipMessage); + Helper::makeResponse(*response, *sipMessage, 403, "Cookie-based authorization failed"); + mDum.send(response); + return Rejected; + } + else + { + return Skipped; + } + } + else + { + SharedPtr response(new SipMessage); + Helper::makeResponse(*response, *sipMessage, 403, "Cookie-based authorization failed"); + mDum.send(response); + return Rejected; + } + + InfoLog(<< "Skipping some message that we didn't explicitly handle"); + return Skipped; +} + +bool +WsCookieAuthManager::requiresAuthorization(const SipMessage& msg) +{ + // everything must be authorized, over-ride this method + // to implement some other policy + return true; +} + + +/* ==================================================================== + * BSD License + * + * Copyright (c) 2013 Catalin Constantin Usurelu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + */ diff --git a/src/libs/resiprocate/resip/dum/WsCookieAuthManager.hxx b/src/libs/resiprocate/resip/dum/WsCookieAuthManager.hxx new file mode 100644 index 00000000..1088c03f --- /dev/null +++ b/src/libs/resiprocate/resip/dum/WsCookieAuthManager.hxx @@ -0,0 +1,88 @@ +#if !defined(RESIP_WSCOOKIEAUTHMANAGER_HXX) +#define RESIP_WSCOOKIEAUTHMANAGER_HXX + +#include +#include + +#include "resip/stack/SipMessage.hxx" +#include "DumFeature.hxx" +#include "resip/stack/Cookie.hxx" +#include "resip/stack/WsCookieContext.hxx" + +namespace resip +{ +class DialogUsageManager; + +class WsCookieAuthManager : public DumFeature +{ + public: + enum Result + { + Authorized, + Skipped, + Rejected + }; + + WsCookieAuthManager(DialogUsageManager& dum, TargetCommand::Target& target); + virtual ~WsCookieAuthManager(); + + virtual ProcessingResult process(Message* msg); + + protected: + + // can return Authorized, Rejected, Skipped + virtual Result handle(SipMessage* sipMsg); + + /// compares URI user and host, allows wildcards in first URI + bool cookieUriMatch(const resip::Uri &first, const resip::Uri &second); + + /// should return true if the passed in user is authorized for the provided uri + bool authorizedForThisIdentity(const MethodTypes method, const WsCookieContext &wsCookieContext, const resip::Uri &fromUri, const resip::Uri &toUri); + + /// should return true if the request must be challenged + /// The default is to challenge all requests - override this class to change this beviour + virtual bool requiresAuthorization(const SipMessage& msg); +}; + + +} + +#endif + + +/* ==================================================================== + * BSD License + * + * Copyright (c) 2013 Catalin Constantin Usurelu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + */ diff --git a/src/libs/resiprocate/resip/dum/dum.pro b/src/libs/resiprocate/resip/dum/dum.pro deleted file mode 100644 index e26d8a51..00000000 --- a/src/libs/resiprocate/resip/dum/dum.pro +++ /dev/null @@ -1,206 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2010-11-29T22:23:29 -# -#------------------------------------------------- - -QT -= core gui - -TARGET = dum -TEMPLATE = lib -CONFIG += staticlib -INCLUDEPATH += ../../ -DEFINES += USE_IPV6 WINVER=0x0501 - -win32 { - DESTDIR = ../../../../Libs/compiled/win/ -} - -SOURCES += \ - UserProfile.cxx \ - UserAuthInfo.cxx \ - TargetCommand.cxx \ - SubscriptionState.cxx \ - SubscriptionHandler.cxx \ - SubscriptionCreator.cxx \ - ServerSubscription.cxx \ - ServerRegistration.cxx \ - ServerPublication.cxx \ - ServerPagerMessage.cxx \ - ServerOutOfDialogReq.cxx \ - ServerInviteSession.cxx \ - ServerAuthManager.cxx \ - RegistrationHandler.cxx \ - RegistrationCreator.cxx \ - RedirectManager.cxx \ - RADIUSServerAuthManager.cxx \ - PublicationCreator.cxx \ - Profile.cxx \ - PagerMessageCreator.cxx \ - OutOfDialogReqCreator.cxx \ - OutgoingEvent.cxx \ - NonDialogUsage.cxx \ - NetworkAssociation.cxx \ - MergedRequestRemovalCommand.cxx \ - MergedRequestKey.cxx \ - MasterProfile.cxx \ - KeepAliveTimeout.cxx \ - KeepAliveManager.cxx \ - InviteSessionHandler.cxx \ - InviteSessionCreator.cxx \ - InviteSession.cxx \ - InMemoryRegistrationDatabase.cxx \ - IdentityHandler.cxx \ - HttpProvider.cxx \ - HttpGetMessage.cxx \ - HandleManager.cxx \ - HandleException.cxx \ - Handled.cxx \ - Handle.cxx \ - EncryptionRequest.cxx \ - DumTimeout.cxx \ - DumThread.cxx \ - DumProcessHandler.cxx \ - DumHelper.cxx \ - DumFeatureMessage.cxx \ - DumFeatureChain.cxx \ - DumFeature.cxx \ - DumDecrypted.cxx \ - DialogUsageManager.cxx \ - DialogUsage.cxx \ - DialogSetId.cxx \ - DialogSet.cxx \ - DialogId.cxx \ - DialogEventStateManager.cxx \ - DialogEventInfo.cxx \ - Dialog.cxx \ - DestroyUsage.cxx \ - DefaultServerReferHandler.cxx \ - ContactInstanceRecord.cxx \ - ClientSubscription.cxx \ - ClientRegistration.cxx \ - ClientPublication.cxx \ - ClientPagerMessage.cxx \ - ClientOutOfDialogReq.cxx \ - ClientInviteSession.cxx \ - ClientAuthManager.cxx \ - ClientAuthExtension.cxx \ - ChallengeInfo.cxx \ - CertMessage.cxx \ - BaseUsage.cxx \ - BaseSubscription.cxx \ - BaseCreator.cxx \ - AppDialogSetFactory.cxx \ - AppDialogSet.cxx \ - AppDialog.cxx - -HEADERS += \ - UserProfile.hxx \ - UserAuthInfo.hxx \ - UsageUseException.hxx \ - TargetCommand.hxx \ - SubscriptionState.hxx \ - SubscriptionPersistenceManager.hxx \ - SubscriptionHandler.hxx \ - SubscriptionCreator.hxx \ - ServerSubscriptionFunctor.hxx \ - ServerSubscription.hxx \ - ServerRegistration.hxx \ - ServerPublication.hxx \ - ServerPagerMessage.hxx \ - ServerOutOfDialogReq.hxx \ - ServerInviteSession.hxx \ - ServerAuthManager.hxx \ - RemoteCertStore.hxx \ - RegistrationPersistenceManager.hxx \ - RegistrationHandler.hxx \ - RegistrationCreator.hxx \ - RefCountedDestroyer.hxx \ - RedirectManager.hxx \ - RedirectHandler.hxx \ - RADIUSServerAuthManager.hxx \ - PublicationHandler.hxx \ - PublicationCreator.hxx \ - Profile.hxx \ - Postable.hxx \ - PagerMessageHandler.hxx \ - PagerMessageCreator.hxx \ - OutOfDialogReqCreator.hxx \ - OutOfDialogHandler.hxx \ - OutgoingEvent.hxx \ - NonDialogUsage.hxx \ - NetworkAssociation.hxx \ - MergedRequestRemovalCommand.hxx \ - MergedRequestKey.hxx \ - MasterProfile.hxx \ - KeepAliveTimeout.hxx \ - KeepAliveManager.hxx \ - InviteSessionHandler.hxx \ - InviteSessionCreator.hxx \ - InviteSession.hxx \ - InviteDialogs.hxx \ - InMemoryRegistrationDatabase.hxx \ - IdentityHandler.hxx \ - HttpProvider.hxx \ - HttpGetMessage.hxx \ - Handles.hxx \ - HandleManager.hxx \ - HandleException.hxx \ - Handled.hxx \ - Handle.hxx \ - ExternalTimer.hxx \ - ExternalMessageHandler.hxx \ - ExternalMessageBase.hxx \ - EventDispatcher.hxx \ - EncryptionRequest.hxx \ - DumTimeout.hxx \ - DumThread.hxx \ - DumShutdownHandler.hxx \ - DumProcessHandler.hxx \ - DumHelper.hxx \ - DumFeatureMessage.hxx \ - DumFeatureChain.hxx \ - DumFeature.hxx \ - DumException.hxx \ - DumDecrypted.hxx \ - DumCommand.hxx \ - DialogUsageManager.hxx \ - DialogUsage.hxx \ - DialogSetId.hxx \ - DialogSetHandler.hxx \ - DialogSet.hxx \ - DialogId.hxx \ - DialogEventStateManager.hxx \ - DialogEventInfo.hxx \ - DialogEventHandler.hxx \ - Dialog.hxx \ - DestroyUsage.hxx \ - DefaultServerReferHandler.hxx \ - ContactInstanceRecord.hxx \ - ClientSubscriptionFunctor.hxx \ - ClientSubscription.hxx \ - ClientRegistration.hxx \ - ClientPublication.hxx \ - ClientPagerMessage.hxx \ - ClientOutOfDialogReq.hxx \ - ClientInviteSession.hxx \ - ClientAuthManager.hxx \ - ClientAuthExtension.hxx \ - ChallengeInfo.hxx \ - CertMessage.hxx \ - BaseUsage.hxx \ - BaseSubscription.hxx \ - BaseCreator.hxx \ - AppDialogSetFactory.hxx \ - AppDialogSet.hxx \ - AppDialog.hxx -unix:!symbian { - maemo5 { - target.path = /opt/usr/lib - } else { - target.path = /usr/local/lib - } - INSTALLS += target -} - -OTHER_FILES += diff --git a/src/libs/resiprocate/resip/dum/dum_10_0.vcxproj.filters b/src/libs/resiprocate/resip/dum/dum_10_0.vcxproj.filters deleted file mode 100644 index d6ad4579..00000000 --- a/src/libs/resiprocate/resip/dum/dum_10_0.vcxproj.filters +++ /dev/null @@ -1,546 +0,0 @@ - - - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/src/libs/resiprocate/resip/dum/dum_12_0.vcxproj b/src/libs/resiprocate/resip/dum/dum_12_0.vcxproj new file mode 100644 index 00000000..97bd52b3 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/dum_12_0.vcxproj @@ -0,0 +1,615 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + SSL-Debug-MT + Win32 + + + SSL-Debug-MT + x64 + + + SSL-Debug + Win32 + + + SSL-Debug + x64 + + + SSL-Release-MT + Win32 + + + SSL-Release-MT + x64 + + + SSL-Release + Win32 + + + SSL-Release + x64 + + + + dum + {31B0654F-E08E-405F-909F-80F86CB14B9D} + dum + ManagedCProj + + + + StaticLibrary + MultiByte + false + v120 + + + StaticLibrary + MultiByte + false + v120 + + + StaticLibrary + MultiByte + false + v120 + + + StaticLibrary + MultiByte + false + v120 + + + StaticLibrary + MultiByte + false + v120 + + + StaticLibrary + MultiByte + false + v120 + + + StaticLibrary + MultiByte + false + v120 + + + StaticLibrary + MultiByte + false + v120 + + + StaticLibrary + MultiByte + false + v120 + + + StaticLibrary + MultiByte + false + v120 + + + StaticLibrary + MultiByte + false + v120 + + + StaticLibrary + MultiByte + false + v120 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.21006.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + + + + + + Disabled + $(ProjectDir)/../../;$(ProjectDir)/../../../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions) + false + + + MultiThreadedDebugDLL + true + + + Level3 + ProgramDatabase + + + + + Disabled + $(ProjectDir)/../../;$(ProjectDir)/../../../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions) + false + + + MultiThreadedDebugDLL + true + + + Level3 + ProgramDatabase + + + + + $(ProjectDir)/../../;$(ProjectDir)/../../../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) + false + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + + + $(ProjectDir)/../../;$(ProjectDir)/../../../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) + false + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + + + Disabled + $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + false + + + MultiThreadedDebugDLL + true + + + Level3 + ProgramDatabase + + + + + Disabled + $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + false + + + MultiThreadedDebug + true + + + Level3 + ProgramDatabase + + + + + Disabled + $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/opensslx64/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + false + + + MultiThreadedDebugDLL + true + + + Level3 + ProgramDatabase + + + + + Disabled + $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/opensslx64/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + false + + + MultiThreadedDebug + true + + + Level3 + ProgramDatabase + + + + + $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + false + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + + + $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + false + MultiThreaded + true + + + Level3 + ProgramDatabase + + + + + $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/opensslx64/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + false + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + + + $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/opensslx64/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + false + MultiThreaded + true + + + Level3 + ProgramDatabase + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/libs/resiprocate/resip/dum/dum_10_0.vcxproj b/src/libs/resiprocate/resip/dum/dum_14_0.vcxproj similarity index 69% rename from src/libs/resiprocate/resip/dum/dum_10_0.vcxproj rename to src/libs/resiprocate/resip/dum/dum_14_0.vcxproj index 43897b8d..6e713ee2 100644 --- a/src/libs/resiprocate/resip/dum/dum_10_0.vcxproj +++ b/src/libs/resiprocate/resip/dum/dum_14_0.vcxproj @@ -17,6 +17,14 @@ Release x64 + + SSL-Debug-MT + Win32 + + + SSL-Debug-MT + x64 + SSL-Debug Win32 @@ -25,6 +33,14 @@ SSL-Debug x64 + + SSL-Release-MT + Win32 + + + SSL-Release-MT + x64 + SSL-Release Win32 @@ -47,24 +63,48 @@ false v140 + + StaticLibrary + MultiByte + false + v140 + StaticLibrary MultiByte false v140 + + StaticLibrary + MultiByte + false + v140 + StaticLibrary MultiByte false v140 + + StaticLibrary + MultiByte + false + v140 + StaticLibrary MultiByte false v140 + + StaticLibrary + MultiByte + false + v140 + StaticLibrary MultiByte @@ -96,18 +136,34 @@ + + + + + + + + + + + + + + + + @@ -127,22 +183,30 @@ <_ProjectFileVersion>10.0.21006.1 - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ AllRules.ruleset AllRules.ruleset @@ -156,23 +220,35 @@ AllRules.ruleset + AllRules.ruleset AllRules.ruleset + AllRules.ruleset + + + + AllRules.ruleset + AllRules.ruleset AllRules.ruleset + AllRules.ruleset + + + + Disabled $(ProjectDir)/../../;$(ProjectDir)/../../../;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions) + WIN32;_DEBUG;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions) false @@ -188,7 +264,7 @@ Disabled $(ProjectDir)/../../;$(ProjectDir)/../../../;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions) + WIN32;_DEBUG;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions) false @@ -203,7 +279,7 @@ $(ProjectDir)/../../;$(ProjectDir)/../../../;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) + WIN32;NDEBUG;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) false MultiThreadedDLL true @@ -216,7 +292,7 @@ $(ProjectDir)/../../;$(ProjectDir)/../../../;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) + WIN32;NDEBUG;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) false MultiThreadedDLL true @@ -230,7 +306,7 @@ Disabled $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) false @@ -242,11 +318,27 @@ ProgramDatabase + + + Disabled + $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + false + + + MultiThreadedDebug + true + + + Level3 + ProgramDatabase + + Disabled - $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/opensslx64/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) false @@ -258,10 +350,26 @@ ProgramDatabase + + + Disabled + $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/opensslx64/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + false + + + MultiThreadedDebug + true + + + Level3 + ProgramDatabase + + $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) false MultiThreadedDLL true @@ -271,10 +379,23 @@ ProgramDatabase + + + $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + false + MultiThreaded + true + + + Level3 + ProgramDatabase + + - $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/opensslx64/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) false MultiThreadedDLL true @@ -284,20 +405,19 @@ ProgramDatabase - - - true - true - - - true - true - - - true - true - - + + + $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/opensslx64/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + false + MultiThreaded + true + + + Level3 + ProgramDatabase + + @@ -334,6 +454,7 @@ + true true @@ -380,8 +501,10 @@ + + @@ -424,6 +547,8 @@ + + @@ -478,15 +603,11 @@ + - - - - {2a8be839-6466-4001-b224-8f1c3168d04a} - false - + diff --git a/src/libs/resiprocate/resip/dum/dum_15_0.vcxproj b/src/libs/resiprocate/resip/dum/dum_15_0.vcxproj new file mode 100644 index 00000000..b2f1f4b9 --- /dev/null +++ b/src/libs/resiprocate/resip/dum/dum_15_0.vcxproj @@ -0,0 +1,616 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + SSL-Debug-MT + Win32 + + + SSL-Debug-MT + x64 + + + SSL-Debug + Win32 + + + SSL-Debug + x64 + + + SSL-Release-MT + Win32 + + + SSL-Release-MT + x64 + + + SSL-Release + Win32 + + + SSL-Release + x64 + + + + dum + {31B0654F-E08E-405F-909F-80F86CB14B9D} + dum + ManagedCProj + 10.0.17134.0 + + + + StaticLibrary + MultiByte + false + v141 + + + StaticLibrary + MultiByte + false + v141 + + + StaticLibrary + MultiByte + false + v141 + + + StaticLibrary + MultiByte + false + v141 + + + StaticLibrary + MultiByte + false + v141 + + + StaticLibrary + MultiByte + false + v141 + + + StaticLibrary + MultiByte + false + v141 + + + StaticLibrary + MultiByte + false + v141 + + + StaticLibrary + MultiByte + false + v141 + + + StaticLibrary + MultiByte + false + v141 + + + StaticLibrary + MultiByte + false + v141 + + + StaticLibrary + MultiByte + false + v141 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.21006.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + + + + + + Disabled + $(ProjectDir)/../../;$(ProjectDir)/../../../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions) + false + + + MultiThreadedDebugDLL + true + + + Level3 + ProgramDatabase + + + + + Disabled + $(ProjectDir)/../../;$(ProjectDir)/../../../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions) + false + + + MultiThreadedDebugDLL + true + + + Level3 + ProgramDatabase + + + + + $(ProjectDir)/../../;$(ProjectDir)/../../../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) + false + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + + + $(ProjectDir)/../../;$(ProjectDir)/../../../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) + false + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + + + Disabled + $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + false + + + MultiThreadedDebugDLL + true + + + Level3 + ProgramDatabase + + + + + Disabled + $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + false + + + MultiThreadedDebug + true + + + Level3 + ProgramDatabase + + + + + Disabled + $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/opensslx64/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + false + + + MultiThreadedDebugDLL + true + + + Level3 + ProgramDatabase + + + + + Disabled + $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/opensslx64/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + false + + + MultiThreadedDebug + true + + + Level3 + ProgramDatabase + + + + + $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + false + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + + + $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + false + MultiThreaded + true + + + Level3 + ProgramDatabase + + + + + $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/opensslx64/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + false + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + + + $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../contrib/opensslx64/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL;NO_IPHLPAPI;%(PreprocessorDefinitions) + false + MultiThreaded + true + + + Level3 + ProgramDatabase + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/libs/resiprocate/resip/dum/dum_7_1.vcproj b/src/libs/resiprocate/resip/dum/dum_7_1.vcproj deleted file mode 100644 index ead08395..00000000 --- a/src/libs/resiprocate/resip/dum/dum_7_1.vcproj +++ /dev/null @@ -1,744 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/libs/resiprocate/resip/dum/dum_8_0.vcproj b/src/libs/resiprocate/resip/dum/dum_8_0.vcproj deleted file mode 100644 index 8dc07263..00000000 --- a/src/libs/resiprocate/resip/dum/dum_8_0.vcproj +++ /dev/null @@ -1,1027 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/libs/resiprocate/resip/dum/dum_9_0.vcproj b/src/libs/resiprocate/resip/dum/dum_9_0.vcproj deleted file mode 100644 index c77209d7..00000000 --- a/src/libs/resiprocate/resip/dum/dum_9_0.vcproj +++ /dev/null @@ -1,1035 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/libs/resiprocate/resip/dum/dum_9_0.vcxproj b/src/libs/resiprocate/resip/dum/dum_9_0.vcxproj deleted file mode 100644 index b27a9536..00000000 --- a/src/libs/resiprocate/resip/dum/dum_9_0.vcxproj +++ /dev/null @@ -1,346 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - SSL-Debug - Win32 - - - SSL-Release - Win32 - - - - dum - {12720B4D-F4FC-4502-8FA9-589BF5166216} - dum - ManagedCProj - - - - StaticLibrary - v120 - MultiByte - false - - - StaticLibrary - v120 - MultiByte - false - - - StaticLibrary - v120_xp - MultiByte - false - - - StaticLibrary - v120 - MultiByte - false - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>12.0.21005.1 - - - $(SolutionDir)\output\$(Platform)\$(Configuration)\$(ProjectName)\ - $(SolutionDir)\intermediate\$(Platform)\$(Configuration)\$(ProjectName)\ - - - $(SolutionDir)\output\$(Platform)\$(Configuration)\$(ProjectName)\ - $(SolutionDir)\intermediate\$(Platform)\$(Configuration)\$(ProjectName)\ - - - $(Configuration)\ - $(Configuration)\ - - - $(Configuration)\ - $(Configuration)\ - - - - /MP %(AdditionalOptions) - Disabled - $(ProjectDir)/../../;$(ProjectDir)/../../../;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;USE_ARES;USE_IPV6;LEAK_CHECK;USE_SSL;%(PreprocessorDefinitions) - false - Default - MultiThreadedDebugDLL - true - - Level3 - ProgramDatabase - - - - - /MP %(AdditionalOptions) - $(ProjectDir)/../../;$(ProjectDir)/../../../;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions) - false - MultiThreadedDLL - true - - Level3 - ProgramDatabase - - - - - /MP %(AdditionalOptions) - Disabled - $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../../openssl/include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;USE_ARES;LEAK_CHECK;USE_IPV6;USE_SSL;%(PreprocessorDefinitions) - false - Default - MultiThreadedDebugDLL - true - - Level3 - ProgramDatabase - - - - - /MP %(AdditionalOptions) - $(ProjectDir)/../../;$(ProjectDir)/../../../;$(ProjectDir)../../../openssl/include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions) - false - MultiThreadedDLL - true - - Level3 - ProgramDatabase - - - - - true - true - - - true - true - - - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/libs/resiprocate/resip/dum/dum_9_0.vcxproj.filters b/src/libs/resiprocate/resip/dum/dum_9_0.vcxproj.filters deleted file mode 100644 index 0f299758..00000000 --- a/src/libs/resiprocate/resip/dum/dum_9_0.vcxproj.filters +++ /dev/null @@ -1,546 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - \ No newline at end of file diff --git a/src/libs/resiprocate/resip/dum/dum_9_0.vcxproj.user b/src/libs/resiprocate/resip/dum/dum_9_0.vcxproj.user deleted file mode 100644 index abe8dd89..00000000 --- a/src/libs/resiprocate/resip/dum/dum_9_0.vcxproj.user +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/libs/resiprocate/resip/dum/ssl/EncryptionManager.cxx b/src/libs/resiprocate/resip/dum/ssl/EncryptionManager.cxx index aba249fb..82826398 100644 --- a/src/libs/resiprocate/resip/dum/ssl/EncryptionManager.cxx +++ b/src/libs/resiprocate/resip/dum/ssl/EncryptionManager.cxx @@ -7,7 +7,7 @@ #include "resip/stack/ssl/Security.hxx" -#include +#include "rutil/ResipAssert.h" #include #include "rutil/BaseException.hxx" #include "resip/stack/SipMessage.hxx" @@ -66,10 +66,10 @@ EncryptionManager::~EncryptionManager() mRequests.clear(); } -void EncryptionManager::setRemoteCertStore(std::unique_ptr store) +void EncryptionManager::setRemoteCertStore(std::auto_ptr store) { ErrLog(<< "Async currently is not supported"); - assert(0); + resip_assert(0); //mRemoteCertStore = store; } @@ -149,7 +149,7 @@ DumFeature::ProcessingResult EncryptionManager::process(Message* msg) { if (setContents) { - event->message()->setContents(unique_ptr(contents)); + event->message()->setContents(auto_ptr(contents)); DumHelper::setEncryptionPerformed(*event->message()); } return DumFeature::FeatureDone; @@ -287,7 +287,7 @@ bool EncryptionManager::decrypt(SipMessage* msg) { if (csa.mContents.get()) { - msg->setContents(std::move(csa.mContents)); + msg->setContents(csa.mContents); if (csa.mAttributes.get()) { @@ -298,7 +298,7 @@ bool EncryptionManager::decrypt(SipMessage* msg) { csa.mAttributes->setIdentityStrength(origSecurityAttributes->getIdentityStrength()); } - msg->setSecurityAttributes(std::move(csa.mAttributes)); + msg->setSecurityAttributes(csa.mAttributes); } } else @@ -418,8 +418,8 @@ EncryptionManager::Result EncryptionManager::Sign::received(bool success, const Data& aor, const Data& data) { - assert(mSenderAor==aor); - assert(mPendingRequests>0&&mPendingRequests<=2); + resip_assert(mSenderAor==aor); + resip_assert(mPendingRequests>0&&mPendingRequests<=2); Result result = Pending; if (success) @@ -438,11 +438,11 @@ EncryptionManager::Result EncryptionManager::Sign::received(bool success, { InfoLog(<< "Signing message" << endl); MultipartSignedContents* msc = mDum.getSecurity()->sign(aor, mMsgToEncrypt->getContents()); - mMsgToEncrypt->setContents(unique_ptr(msc)); + mMsgToEncrypt->setContents(auto_ptr(msc)); DumHelper::setEncryptionPerformed(*mMsgToEncrypt); OutgoingEvent* event = new OutgoingEvent(mMsgToEncrypt); //mTaken = false; - mDum.post(new TargetCommand(mDum.dumOutgoingTarget(), unique_ptr(event))); + mDum.post(new TargetCommand(mDum.dumOutgoingTarget(), auto_ptr(event))); result = Complete; } } @@ -523,9 +523,9 @@ EncryptionManager::Result EncryptionManager::Encrypt::received(bool success, const Data& aor, const Data& data) { - assert(mRecipientAor==aor); - assert(type==MessageId::UserCert); - assert(mPendingRequests==1); + resip_assert(mRecipientAor==aor); + resip_assert(type==MessageId::UserCert); + resip_assert(mPendingRequests==1); if (success) { InfoLog(<< "Adding user cert for " << aor << endl); @@ -533,11 +533,11 @@ EncryptionManager::Result EncryptionManager::Encrypt::received(bool success, --mPendingRequests; InfoLog(<< "Encrypting message" << endl); Pkcs7Contents* encrypted = mDum.getSecurity()->encrypt(mMsgToEncrypt->getContents(), aor); - mMsgToEncrypt->setContents(unique_ptr(encrypted)); + mMsgToEncrypt->setContents(auto_ptr(encrypted)); DumHelper::setEncryptionPerformed(*mMsgToEncrypt); OutgoingEvent* event = new OutgoingEvent(mMsgToEncrypt); //mTaken = false; - mDum.post(new TargetCommand(mDum.dumOutgoingTarget(), unique_ptr(event))); + mDum.post(new TargetCommand(mDum.dumOutgoingTarget(), auto_ptr(event))); } else { @@ -620,19 +620,19 @@ EncryptionManager::Result EncryptionManager::SignAndEncrypt::received(bool succe const Data& aor, const Data& data) { - assert(mPendingRequests>0&&mPendingRequests<=3); + resip_assert(mPendingRequests>0&&mPendingRequests<=3); Result result = Pending; if (success) { if (type == MessageId::UserCert) { - assert(aor==mSenderAor||aor==mRecipientAor); + resip_assert(aor==mSenderAor||aor==mRecipientAor); InfoLog(<< "Adding user cert for " << aor << endl); mDum.getSecurity()->addUserCertDER(aor, data); } else { - assert(aor==mSenderAor); + resip_assert(aor==mSenderAor); InfoLog(<< "Adding private key for " << aor << endl); mDum.getSecurity()->addUserPrivateKeyDER(aor, data); } @@ -641,11 +641,11 @@ EncryptionManager::Result EncryptionManager::SignAndEncrypt::received(bool succe { InfoLog(<< "Encrypting and signing message" << endl); Contents* contents = doWork(); - mMsgToEncrypt->setContents(unique_ptr(contents)); + mMsgToEncrypt->setContents(auto_ptr(contents)); DumHelper::setEncryptionPerformed(*mMsgToEncrypt); OutgoingEvent* event = new OutgoingEvent(mMsgToEncrypt); //mTaken = false; - mDum.post(new TargetCommand(mDum.dumOutgoingTarget(), unique_ptr(event))); + mDum.post(new TargetCommand(mDum.dumOutgoingTarget(), auto_ptr(event))); result = Complete; } } @@ -795,20 +795,20 @@ EncryptionManager::Result EncryptionManager::Decrypt::received(bool success, const Data& data) { Result result = Complete; - assert(mPendingRequests>0 && mPendingRequests<=2); + resip_assert(mPendingRequests>0 && mPendingRequests<=2); if (success) { if (aor == mSigner) { - assert(MessageId::UserCert == type); - assert(mPendingRequests==1); + resip_assert(MessageId::UserCert == type); + resip_assert(mPendingRequests==1); --mPendingRequests; InfoLog(<< "Adding user cert for " << aor << endl); mDum.getSecurity()->addUserCertDER(aor, data); } else { - assert(aor == mDecryptor); + resip_assert(aor == mDecryptor); if (MessageId::UserCert == type) { InfoLog(<< "Adding user cert for " << aor << endl); @@ -855,11 +855,11 @@ EncryptionManager::Result EncryptionManager::Decrypt::received(bool success, if (csa.mContents.get()) { csa.mContents->checkParsed(); - mMsgToDecrypt->setContents(std::move(csa.mContents)); + mMsgToDecrypt->setContents(csa.mContents); if (csa.mAttributes.get()) { - mMsgToDecrypt->setSecurityAttributes(std::move(csa.mAttributes)); + mMsgToDecrypt->setSecurityAttributes(csa.mAttributes); } } else @@ -925,7 +925,7 @@ bool EncryptionManager::Decrypt::isEncryptedRecurse(Contents** contents) if (*contents == mMsgToDecrypt->getContents()) { - mMsgToDecrypt->setContents(unique_ptr(createInvalidContents(mps))); + mMsgToDecrypt->setContents(auto_ptr(createInvalidContents(mps))); } else { @@ -950,7 +950,7 @@ bool EncryptionManager::Decrypt::isEncryptedRecurse(Contents** contents) ErrLog(<< e.name() << endl << e.getMessage()); if (*contents == mMsgToDecrypt->getContents()) { - mMsgToDecrypt->setContents(unique_ptr(createInvalidContents(alt))); + mMsgToDecrypt->setContents(auto_ptr(createInvalidContents(alt))); } else { @@ -1022,7 +1022,7 @@ bool EncryptionManager::Decrypt::isSignedRecurse(Contents** contents, { if (*contents == mMsgToDecrypt->getContents()) { - mMsgToDecrypt->setContents(unique_ptr(decrypted)); + mMsgToDecrypt->setContents(auto_ptr(decrypted)); *contents = mMsgToDecrypt->getContents(); } else @@ -1040,7 +1040,7 @@ bool EncryptionManager::Decrypt::isSignedRecurse(Contents** contents, if (*contents == mMsgToDecrypt->getContents()) { - mMsgToDecrypt->setContents(unique_ptr(createInvalidContents(decrypted))); + mMsgToDecrypt->setContents(auto_ptr(createInvalidContents(decrypted))); } else { @@ -1076,7 +1076,7 @@ bool EncryptionManager::Decrypt::isSignedRecurse(Contents** contents, if (*contents == mMsgToDecrypt->getContents()) { - mMsgToDecrypt->setContents(unique_ptr(createInvalidContents(alt))); + mMsgToDecrypt->setContents(auto_ptr(createInvalidContents(alt))); } else { @@ -1127,9 +1127,9 @@ Helper::ContentsSecAttrs EncryptionManager::Decrypt::getContents(SipMessage* mes } } - std::unique_ptr c(contents); - std::unique_ptr a(attr); - return Helper::ContentsSecAttrs(std::move(c), std::move(a)); + std::auto_ptr c(contents); + std::auto_ptr a(attr); + return Helper::ContentsSecAttrs(c, a); } Contents* EncryptionManager::Decrypt::getContentsRecurse(Contents** tree, @@ -1167,7 +1167,7 @@ Contents* EncryptionManager::Decrypt::getContentsRecurse(Contents** tree, { if (*tree == mMsgToDecrypt->getContents()) { - mMsgToDecrypt->setContents(unique_ptr(contents)); + mMsgToDecrypt->setContents(auto_ptr(contents)); *tree = mMsgToDecrypt->getContents(); } else @@ -1189,7 +1189,7 @@ Contents* EncryptionManager::Decrypt::getContentsRecurse(Contents** tree, if (*tree == mMsgToDecrypt->getContents()) { - mMsgToDecrypt->setContents(unique_ptr(createInvalidContents(contents))); + mMsgToDecrypt->setContents(auto_ptr(createInvalidContents(contents))); } else { @@ -1233,7 +1233,7 @@ Contents* EncryptionManager::Decrypt::getContentsRecurse(Contents** tree, if (*tree == mMsgToDecrypt->getContents()) { - mMsgToDecrypt->setContents(unique_ptr(createInvalidContents(alt))); + mMsgToDecrypt->setContents(auto_ptr(createInvalidContents(alt))); } else { @@ -1272,7 +1272,7 @@ Contents* EncryptionManager::Decrypt::getContentsRecurse(Contents** tree, if (*tree == mMsgToDecrypt->getContents()) { - mMsgToDecrypt->setContents(unique_ptr(createInvalidContents(mult))); + mMsgToDecrypt->setContents(auto_ptr(createInvalidContents(mult))); } else { @@ -1300,7 +1300,7 @@ Contents* EncryptionManager::Decrypt::getContentsRecurse(Contents** tree, if (*tree == mMsgToDecrypt->getContents()) { - mMsgToDecrypt->setContents(unique_ptr(createInvalidContents(*tree))); + mMsgToDecrypt->setContents(auto_ptr(createInvalidContents(*tree))); } else { @@ -1341,7 +1341,7 @@ EncryptionManager::Decrypt::handleInvalidContents() { DebugLog(<< "No valid contents in the request" << endl); InvalidContents* invalid = new InvalidContents(mOriginalMsgContents, mOriginalMsgContentsType); - mMsgToDecrypt->setContents(unique_ptr(invalid)); + mMsgToDecrypt->setContents(auto_ptr(invalid)); } else { @@ -1355,7 +1355,7 @@ EncryptionManager::Decrypt::handleInvalidContents() { DebugLog(<< "No valid contents in the response" << endl); InvalidContents* invalid = new InvalidContents(mOriginalMsgContents, mOriginalMsgContentsType); - mMsgToDecrypt->setContents(unique_ptr(invalid)); + mMsgToDecrypt->setContents(auto_ptr(invalid)); } } diff --git a/src/libs/resiprocate/resip/dum/ssl/EncryptionManager.hxx b/src/libs/resiprocate/resip/dum/ssl/EncryptionManager.hxx index 95b45c4d..10015e89 100644 --- a/src/libs/resiprocate/resip/dum/ssl/EncryptionManager.hxx +++ b/src/libs/resiprocate/resip/dum/ssl/EncryptionManager.hxx @@ -35,7 +35,7 @@ class EncryptionManager : public DumFeature EncryptionManager(DialogUsageManager& dum, TargetCommand::Target& target); virtual ~EncryptionManager(); - void setRemoteCertStore(std::unique_ptr store); + void setRemoteCertStore(std::auto_ptr store); virtual DumFeature::ProcessingResult process(Message* msg); private: @@ -143,7 +143,7 @@ class EncryptionManager : public DumFeature bool mMessageTaken; }; - std::unique_ptr mRemoteCertStore; + std::auto_ptr mRemoteCertStore; typedef std::list RequestList; RequestList mRequests; diff --git a/src/libs/resiprocate/resip/stack/.cvsignore b/src/libs/resiprocate/resip/stack/.cvsignore deleted file mode 100644 index 7e143910..00000000 --- a/src/libs/resiprocate/resip/stack/.cvsignore +++ /dev/null @@ -1,74 +0,0 @@ -*-raw.cxx -*.d -*.la -*.lo -*~ -dox -.DS_Store -.dependlibs -.deps -.gdb_history -.libs -Debug -English.lproj -ExpandedSipMessage -JF -Makefile.in -Release -SSL-Debug -SSL-Release -UserAgentCore.hxx -a.out -backup -bak -bar -bin.* -build -config.hxx -dumpasn1 -enc64 -foo -foo2 -foo3 -foo4 -fooMsg -gmon.out -headers-hash.c -hotsip_stun1 -hotsip_stun2 -html -j2 -junk -log -log1 -log1.txt -log2 -log2.txt -log3.txt -memprof.sh -new-pp.tgz -obj.* -pp-safe.tgz -pp-todo -save -save2 -sipit14_ntt1 -sipit14_ntt2 -sipit14_ntt3 -sipit14_ntt4 -sipit14_ntt5 -sipit14_ntt6 -sipit14_radvision1 -sipit_ntt7 -stamp-h1 -testSipStack1 -testUdp -tmp -un64 -doxygen -*.stackdump -*.diff -*.tar -*.gz -TAGS -*.tmp diff --git a/src/libs/resiprocate/resip/stack/SelectInterruptor.hxx b/src/libs/resiprocate/resip/stack/AddTransport.hxx similarity index 58% rename from src/libs/resiprocate/resip/stack/SelectInterruptor.hxx rename to src/libs/resiprocate/resip/stack/AddTransport.hxx index 13206c2e..94d5ef86 100644 --- a/src/libs/resiprocate/resip/stack/SelectInterruptor.hxx +++ b/src/libs/resiprocate/resip/stack/AddTransport.hxx @@ -1,126 +1,93 @@ -#ifndef RESIP_SelectInterruptor_HXX -#define RESIP_SelectInterruptor_HXX - -#include "rutil/AsyncProcessHandler.hxx" -#include "rutil/Socket.hxx" - -#if 0 -#if defined(WIN32) -#include -#else -#include -#endif -#endif - -namespace resip -{ - -/** - Used to 'artificially' interrupt a select call -*/ -class SelectInterruptor : public AsyncProcessHandler -{ - public: - SelectInterruptor(); - virtual ~SelectInterruptor(); - - /** - Called by the stack when messages are posted to it. - Calls interrupt. - */ - virtual void handleProcessNotification(); - - /** - cause the 'artificial' fd to signal - */ - void interrupt(); - - /** - Used to add the 'artificial' fd to the fdset that - will be responsible for interrupting a subsequent select - call. - */ - void buildFdSet(FdSet& fdset); - - /** - cleanup signalled fd - */ - void process(FdSet& fdset); - protected: - /* Get fd of read-side, for use within PollInterruptor, - * Declared as Socket for easier cross-platform even though pipe fd - * under linux. - */ - Socket getReadSocket() const { return mReadThing; } - - /* Cleanup the read side of the interruptor - * If fdset is provided, it will only try cleaning up if our pipe - * is ready in fdset. If NULL, it will unconditionally try reading. - * This last feature is for use within PollInterruptor. - */ - void processCleanup(); - private: -#ifndef WIN32 - int mPipe[2]; -#else - Socket mSocket; - sockaddr mWakeupAddr; -#endif - // either mPipe[0] or mSocket - Socket mReadThing; -}; - -} - -#endif - -/* ==================================================================== - * The Vovida Software License, Version 1.0 - * - * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The names "VOCAL", "Vovida Open Communication Application Library", - * and "Vovida Open Communication Application Library (VOCAL)" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact vocal@vovida.org. - * - * 4. Products derived from this software may not be called "VOCAL", nor - * may "VOCAL" appear in their name, without prior written - * permission of Vovida Networks, Inc. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND - * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA - * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES - * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ==================================================================== - * - * This software consists of voluntary contributions made by Vovida - * Networks, Inc. and many individuals on behalf of Vovida Networks, - * Inc. For more information on Vovida Networks, Inc., please see - * . - * - * vi: set shiftwidth=3 expandtab: - */ +#ifndef AddTransport_Include_Guard +#define AddTransport_Include_Guard + +#include "resip/stack/TransactionMessage.hxx" +#include "resip/stack/Transport.hxx" + +namespace resip +{ +class AddTransport : public TransactionMessage +{ + public: + explicit AddTransport(std::auto_ptr transport) : + mTransport(transport) + {} + virtual ~AddTransport(){} + + virtual const Data& getTransactionId() const {return Data::Empty;} + std::auto_ptr getTransport() { return mTransport; } + + virtual bool isClientTransaction() const {return true;} + virtual EncodeStream& encode(EncodeStream& strm) const + { + return strm << "AddTransport: " << mTransport->getTuple(); + } + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "AddTransport: " << mTransport->getTuple(); + } + + virtual Message* clone() const + { + resip_assert(false); return NULL; + } + + protected: + std::auto_ptr mTransport; +}; // class AddTransport + +} // namespace resip + +#endif // include guard + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2014 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * . + * + * vi: set shiftwidth=3 expandtab: + */ + diff --git a/src/libs/resiprocate/resip/stack/ApplicationMessage.hxx b/src/libs/resiprocate/resip/stack/ApplicationMessage.hxx index d2f2a5f8..3eaf3008 100644 --- a/src/libs/resiprocate/resip/stack/ApplicationMessage.hxx +++ b/src/libs/resiprocate/resip/stack/ApplicationMessage.hxx @@ -21,7 +21,7 @@ class ApplicationMessage : public Message ApplicationMessage() {}; virtual ~ApplicationMessage() {}; - virtual const Data& getTransactionId() const { assert(0); return Data::Empty; } + virtual const Data& getTransactionId() const { resip_assert(0); return Data::Empty; } }; } diff --git a/src/libs/resiprocate/resip/stack/Auth.cxx b/src/libs/resiprocate/resip/stack/Auth.cxx index a09e36c2..153cad58 100644 --- a/src/libs/resiprocate/resip/stack/Auth.cxx +++ b/src/libs/resiprocate/resip/stack/Auth.cxx @@ -136,14 +136,20 @@ Auth::parseAuthParameters(ParseBuffer& pb) // invoke the particular factory mParameters.push_back(p); } - pb.skipWhitespace(); - if (pb.eof() || *pb.position() != Symbols::COMMA[0]) - { - break; - } - pb.skipChar(); - pb.skipWhitespace(); } + else + { + // empty parameter name - skip and advance pb to next parameter + pb.skipToOneOf(terminators); + } + + pb.skipWhitespace(); + if (pb.eof() || *pb.position() != Symbols::COMMA[0]) + { + break; + } + pb.skipChar(); + pb.skipWhitespace(); } } diff --git a/src/libs/resiprocate/resip/stack/BasicDomainMatcher.cxx b/src/libs/resiprocate/resip/stack/BasicDomainMatcher.cxx new file mode 100644 index 00000000..09cf1f55 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/BasicDomainMatcher.cxx @@ -0,0 +1,76 @@ +#include "resip/stack/BasicDomainMatcher.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::SIP + +using namespace resip; + +BasicDomainMatcher::BasicDomainMatcher() : + mDomainList() +{ +} + +BasicDomainMatcher::~BasicDomainMatcher() +{ +} + +bool +BasicDomainMatcher::isMyDomain(const Data& domain) const +{ + // Domain search should be case insensitive - search in lowercase only + return mDomainList.count(Data(domain).lowercase()) > 0; +} + +void +BasicDomainMatcher::addDomain(const Data& domain) +{ + // Domain search should be case insensitive - store in lowercase only + mDomainList.insert(Data(domain).lowercase()); +} + +void +BasicDomainMatcher::removeDomain(const Data& domain) +{ + DomainList::iterator it = mDomainList.find(Data(domain).lowercase()); + if (it != mDomainList.end()) + { + mDomainList.erase(it); + } +} + +/* ==================================================================== + * + * Copyright 2017 Daniel Pocock http://danielpocock.com All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/resip/stack/BasicDomainMatcher.hxx b/src/libs/resiprocate/resip/stack/BasicDomainMatcher.hxx new file mode 100644 index 00000000..5624899b --- /dev/null +++ b/src/libs/resiprocate/resip/stack/BasicDomainMatcher.hxx @@ -0,0 +1,70 @@ +#if !defined(RESIP_BASICDOMAINMATCHER_HXX) +#define RESIP_BASICDOMAINMATCHER_HXX + +#include "resip/stack/DomainMatcher.hxx" +#include "rutil/Data.hxx" +#include "rutil/HashMap.hxx" +#include "rutil/ParseBuffer.hxx" + +namespace resip +{ + +class BasicDomainMatcher : public DomainMatcher +{ + + public: + + BasicDomainMatcher(); + virtual ~BasicDomainMatcher(); + virtual bool isMyDomain(const Data& domain) const; + virtual void addDomain(const Data& domain); + virtual void removeDomain(const Data& domain); + + private: + + typedef std::set DomainList; + DomainList mDomainList; +}; + +} + + +#endif + +/* ==================================================================== + * + * Copyright 2017 Daniel Pocock http://danielpocock.com All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/resip/stack/BranchParameter.cxx b/src/libs/resiprocate/resip/stack/BranchParameter.cxx index 7f6802f0..169cb418 100644 --- a/src/libs/resiprocate/resip/stack/BranchParameter.cxx +++ b/src/libs/resiprocate/resip/stack/BranchParameter.cxx @@ -2,7 +2,7 @@ #include "config.h" #endif -#include +#include "rutil/ResipAssert.h" #include "resip/stack/BranchParameter.hxx" #include "resip/stack/Symbols.hxx" #include "rutil/ParseBuffer.hxx" @@ -35,18 +35,21 @@ BranchParameter::BranchParameter(ParameterTypes::Type type, pb.skipWhitespace(); pb.skipChar(Symbols::EQUALS[0]); pb.skipWhitespace(); - if(memcmp(pb.position(), Symbols::MagicCookie, 7) == 0) + if (pb.lengthRemaining() >= 7) { - mHasMagicCookie=true; - pb.skipN(7); - } - // !bwc! This no-case comparison is expensive; only do it if the case- - // sensitive comparison fails. - else if(strncasecmp(pb.position(), Symbols::MagicCookie, 7) == 0) - { - mHasMagicCookie=true; - mInteropMagicCookie = new Data(pb.position(), 7); - pb.skipN(7); + if(memcmp(pb.position(), Symbols::MagicCookie, 7) == 0) + { + mHasMagicCookie=true; + pb.skipN(7); + } + // !bwc! This no-case comparison is expensive; only do it if the case- + // sensitive comparison fails. + else if(strncasecmp(pb.position(), Symbols::MagicCookie, 7) == 0) + { + mHasMagicCookie=true; + mInteropMagicCookie = new Data(pb.position(), 7); + pb.skipN(7); + } } const char* start = pb.position(); @@ -185,7 +188,7 @@ BranchParameter::getTransactionId() const void BranchParameter::incrementTransportSequence() { - assert(mIsMyBranch); + resip_assert(mIsMyBranch); mTransportSeq++; } diff --git a/src/libs/resiprocate/resip/stack/CancelClientInviteTransaction.hxx b/src/libs/resiprocate/resip/stack/CancelClientInviteTransaction.hxx index 6defbee8..adc5995b 100644 --- a/src/libs/resiprocate/resip/stack/CancelClientInviteTransaction.hxx +++ b/src/libs/resiprocate/resip/stack/CancelClientInviteTransaction.hxx @@ -3,6 +3,7 @@ #include "resip/stack/TransactionMessage.hxx" #include "resip/stack/MessageDecorator.hxx" +#include "resip/stack/Token.hxx" #include "rutil/Data.hxx" @@ -11,13 +12,14 @@ namespace resip class CancelClientInviteTransaction : public TransactionMessage { public: - explicit CancelClientInviteTransaction(const resip::Data& tid) : mTid(tid) {} - virtual ~CancelClientInviteTransaction(){} + explicit CancelClientInviteTransaction(const Data& tid, const Tokens* reasons) : mTid(tid), mReasons(reasons ? new Tokens(*reasons) : 0) {} + virtual ~CancelClientInviteTransaction() { delete mReasons; } /////////////////// Must implement unless abstract /// virtual const Data& getTransactionId() const {return mTid;} virtual bool isClientTransaction() const {return true;} + virtual const Tokens* getReasons() const { return mReasons; } virtual EncodeStream& encode(EncodeStream& strm) const { return strm << "CancelClientInviteTransaction: " << mTid; @@ -36,6 +38,7 @@ class CancelClientInviteTransaction : public TransactionMessage protected: const resip::Data mTid; + const Tokens* mReasons; // Optional reason header to be added to any resulting CANCEL requests created can be specified. }; // class CancelClientInviteTransaction } // namespace resip diff --git a/src/libs/resiprocate/resip/stack/CancelableTimerQueue.hxx b/src/libs/resiprocate/resip/stack/CancelableTimerQueue.hxx index 8b72d9e5..17102930 100644 --- a/src/libs/resiprocate/resip/stack/CancelableTimerQueue.hxx +++ b/src/libs/resiprocate/resip/stack/CancelableTimerQueue.hxx @@ -54,8 +54,9 @@ class CancelableTimerQueue //cerr << "mIdToTimer: " << Inserter(mIdToTimer) << endl; //cerr << "Searching for ID: " << id << endl; //cerr << "TimerMap state: " << Inserter(mTimerMap) << endl; - assert(mIdToTimer.size() == mTimerMap.size()); - assert(0); + resip_assert(mIdToTimer.size() == mTimerMap.size()); + resip_assert(0); + return false; } //get the number of milliseconds until the next event, returns -1 if no @@ -68,13 +69,14 @@ class CancelableTimerQueue } else { - if (mTimerMap.begin()->first - resip::Timer::getTimeMs() < 0) + int timeout = (int)(mTimerMap.begin()->first - resip::Timer::getTimeMs()); + if (timeout < 0) { return 0; } else { - return mTimerMap.begin()->first - resip::Timer::getTimeMs(); + return timeout; } } } @@ -87,9 +89,9 @@ class CancelableTimerQueue T getNext() { - assert(mIdToTimer.size() == mTimerMap.size()); + resip_assert(mIdToTimer.size() == mTimerMap.size()); - assert(available()); + resip_assert(available()); typename TimerMap::iterator it = mTimerMap.begin(); mIdToTimer.erase(it->second.second); @@ -97,7 +99,7 @@ class CancelableTimerQueue T msg = it->second.first; mTimerMap.erase(it); - assert(mIdToTimer.size() == mTimerMap.size()); + resip_assert(mIdToTimer.size() == mTimerMap.size()); return msg; } @@ -125,7 +127,7 @@ class CancelableTimerQueue Id id = getNextId(); mTimerMap.insert(std::make_pair(expiry, std::make_pair(msg, id))); mIdToTimer[id] = expiry; - assert(mIdToTimer.size() == mTimerMap.size()); + resip_assert(mIdToTimer.size() == mTimerMap.size()); return id; } diff --git a/src/libs/resiprocate/resip/stack/ChangeLog b/src/libs/resiprocate/resip/stack/ChangeLog deleted file mode 100644 index 29f5ebd8..00000000 --- a/src/libs/resiprocate/resip/stack/ChangeLog +++ /dev/null @@ -1,9506 +0,0 @@ -2004-01-12 - * os/Timer.cxx: - Minor timer cleanup. - - * TransactionState.hxx: - Added mNetSource for explicit tracking of sources. - Fixes for force target support. - - * SipMessage.hxx: renamed ...Target to ...ForceTarget. - - * ParserCategories.hxx (class Via): - Changed default transport to - be empty. - - * Helper.cxx: cleanup of reason phrase code. - (getPortForReply): renamed getSentPort to be in line with use. - (getPortForReply): added notion of symmetric response. - -2003-10-09 12:59 davidb - - * test/testData.cxx: added some tests - -2003-10-09 12:58 davidb - - * test/limpc.cxx: corrected --help text - -2003-10-09 12:58 jason - - * Transport.cxx: added call to Helper::validateMessage to validate - more than just existence of Via header - -2003-10-09 12:58 davidb - - * os/Data.cxx: generalize for any value of LocalAlloc - -2003-10-09 12:57 davidb - - * ParserCategories.hxx: Token constructor against Data - -2003-10-09 12:57 jason - - * test/testDns.cxx: added command line args - -2003-10-09 12:57 davidb - - * ParserCategories.cxx: set the unknownMethodName even if it is - know for backward compatibility - -2003-10-09 12:57 jason - - * Helper.cxx, Helper.hxx: added a validate message check - -2003-10-09 12:56 davidb - - * Headers.hxx, MethodTypes.hxx: added RFCs - -2003-10-09 12:54 jason - - * DnsResult.cxx: fix problem with DnsResult calling handle() when - results are already available - -2003-10-08 01:38 alan - - * test/testMsgHeaderDiagram.cxx: impound - -2003-10-07 16:49 alan - - * Helper.cxx, MsgHeaderScanner.cxx, MsgHeaderScanner.hxx, TODO, - Transport.cxx, Transport.hxx, UdpTransport.cxx, test/Makefile.am, - test/testStack.cxx: Added via-less changes to HEAD Modified Files: - resiprocate/Helper.cxx resiprocate/MsgHeaderScanner.cxx - resiprocate/MsgHeaderScanner.hxx resiprocate/TODO - resiprocate/Transport.cxx resiprocate/Transport.hxx - resiprocate/UdpTransport.cxx resiprocate/test/Makefile.am - resiprocate/test/testStack.cxx - -2003-10-07 16:35 alan - - * Connection.cxx, Connection.hxx, SipMessage.cxx, - TcpBaseTransport.cxx, Transport.cxx, os/Tuple.hxx, - test/Makefile.am, test/testData.cxx, test/testResponses.cxx, - test/testUdp.cxx: Completed via-less malformed message recovery. - Framework for other recoveries in Transport::basicCheck() Modified - Files: configure.ac resiprocate/Connection.cxx - resiprocate/Connection.hxx resiprocate/SipMessage.cxx - resiprocate/TcpBaseTransport.cxx Tag: b-dev-ah-20031006-viafix - resiprocate/Transport.cxx No tag - resiprocate/os/Tuple.hxx resiprocate/test/Makefile.am - resiprocate/test/testData.cxx resiprocate/test/testUdp.cxx Added - Files: resiprocate/test/testResponses.cxx VS: - ------------------------------------------------------------------- - --- - -2003-10-07 11:02 alan - - * test/Makefile.am: autotools minor tweaks - -2003-10-07 08:03 alan - - * MsgHeaderScanner.cxx, MsgHeaderScanner.hxx, TODO, Transport.cxx, - Transport.hxx, UdpTransport.cxx, test/Makefile.am, - test/testStack.cxx: Made MsgHeaderScanner compile cleanly on OS/X. - Made Changes to testStack so bindaddr was used better. Minor - changes to Makefile.am for popts Adding via-less response fixes. - Modified Files: Tag: b-dev-ah-20031006-viafix - resiprocate/MsgHeaderScanner.cxx - resiprocate/MsgHeaderScanner.hxx resiprocate/TODO - resiprocate/Transport.cxx resiprocate/Transport.hxx - resiprocate/UdpTransport.cxx resiprocate/test/Makefile.am - resiprocate/test/testStack.cxx - -2003-10-06 17:57 alan - - * Helper.cxx, Transport.cxx, Transport.hxx, UdpTransport.cxx: - Changes for via-less messages. DO NOT USE. ON BRANCH TO CHECK ON - VARIOUS PLATFORMS AND TO MIGRATE TESTING TO NEW MACHINE. - (alan@jasomi.com) Modified Files: Tag: b-dev-20031006-via-fix - Helper.cxx Transport.cxx Transport.hxx UdpTransport.cxx - -2003-10-06 11:59 davidb - - * os/DnsUtil.cxx, test/testUri.cxx: ::1 is a valid IPV6 address - -2003-10-04 21:47 fluffy - - * test/Makefile: made POP optional - wish this defaulted off so - that stuff compiled by default - -2003-10-04 21:09 fluffy - - * test/: test.vcproj, testIntrusiveList.cxx, testStack.cxx: updated - -2003-10-04 21:08 fluffy - - * Connection.hxx, ConnectionManager.cxx, ConnectionManager.hxx: - Fixed intrusinve lists in windows - -2003-10-04 20:52 fluffy - - * test/testIntrusiveList.cxx: changed to work in windows - -2003-10-04 19:41 jason - - * DnsResult.cxx: [no log message] - -2003-10-04 19:34 fluffy - - * test/: limpc.cxx, test.vcproj: no change - -2003-10-04 19:34 fluffy - - * test/testStack.cxx: took out the || 1 in HAVE_POPT_H #if defs - -2003-10-04 19:32 fluffy - - * UdpTransport.cxx, Transport.cxx, TcpBaseTransport.cxx: don't - print error for EWOULDBLOCK - -2003-10-04 19:09 jason - - * DnsResult.cxx, DnsResult.hxx: fix a memory corruption error in - set by changing to vector - -2003-10-04 18:29 jason - - * DnsInterface.cxx, DnsInterface.hxx: simplify how supported - transport types work - -2003-10-04 16:47 fluffy - - * os/DnsUtil.cxx: fix endian problem - -2003-10-04 15:50 jason - - * ConnectionManager.cxx: try a different delete - -2003-10-04 15:50 jason - - * os/Tuple.cxx: fix compile issue - -2003-10-04 15:50 jason - - * DnsResult.cxx: remove USE_ARES flag from dns resolver only do - AAAA lookup if USE_IPV6 - -2003-10-04 14:34 fluffy - - * ConnectionManager.cxx, DnsInterface.cxx, DnsInterface.hxx, - DnsResolver.hxx, DnsResult.cxx, TransportSelector.cxx, Uri.cxx: fix - so ares.h is not exported to things that use resiprocate - -2003-10-04 14:33 fluffy - - * os/Tuple.cxx: fix printing of IP addr for windows - -2003-10-04 14:33 fluffy - - * os/Tuple.hxx: inlcude for scoklen_t type - -2003-10-04 14:32 fluffy - - * test/test.vcproj, resiprocate.vcproj: Release and Debug work but - SSL version are broken - -2003-10-04 10:51 jason - - * TcpBaseTransport.cxx, Transport.cxx, UdpTransport.cxx, - os/Socket.cxx: fix shutdown of transports in multithreaded case - -2003-10-03 13:47 jason - - * test/testStack.cxx: support for v6 in test - -2003-10-03 13:47 jason - - * os/Tuple.cxx: fix bug in length() - -2003-10-03 13:46 jason - - * Transport.cxx, TransportSelector.cxx: debug - -2003-10-02 22:08 jason - - * SipStack.cxx, SipStack.hxx, TransactionController.cxx, - TransactionController.hxx, TransportSelector.cxx, - TransportSelector.hxx, os/TransportType.hxx, os/Tuple.hxx: - reorganized how v6 is specified to be more clear - -2003-10-02 20:11 jason - - * UdpTransport.cxx: move errno stuff into base class - -2003-10-02 20:11 jason - - * TransportSelector.cxx, TransportSelector.hxx: return default - transport if no specific ones match based on transport type - -2003-10-02 19:43 davidb - - * test/testUri.cxx: test operator== for reflexivity add tests from - 3261 19.1.4 - -2003-10-02 19:39 davidb - - * test/testTransactionFSM.cxx: use skipToChar when we can - -2003-10-02 19:38 davidb - - * test/testParserCategories.cxx: fixed Uri comparison - -2003-10-02 19:37 davidb - - * test/testParseBuffer.cxx: added tests for skip primitives - -2003-10-02 19:36 davidb - - * test/testMultipartMixedContents.cxx: cosmetic - -2003-10-02 19:36 davidb - - * test/testData.cxx: a few more tests - -2003-10-02 19:35 davidb - - * os/: Data.cxx, Data.hxx: Data has own char buffer[128] for - efficient heap use - -2003-10-02 19:30 davidb - - * Uri.cxx: !nasty bug fixes! added case break added missing - comparison in integer comparison made operator== reflexive list => - vector for efficiency - -2003-10-02 19:28 davidb - - * ParserCategory.hxx: list => vector for efficiency - -2003-10-02 18:53 jason - - * test/testTimer.cxx: fix test - -2003-10-02 18:52 jason - - * os/Data.cxx, DnsResult.cxx, os/Inserter.hxx, - os/RecursiveMutex.cxx, os/Tuple.cxx: fix compat with intel compiler - -2003-10-02 16:28 jason - - * TcpBaseTransport.cxx, Transport.cxx, Transport.hxx, - TransportSelector.cxx, TransportSelector.hxx, os/Tuple.cxx, - os/Tuple.hxx: reorganize ipv6 stuff in TransportSelector, - Transports and Tuple change datastructure for storing the - Transports in the TransportSelector to be more efficient - -2003-10-02 16:24 jason - - * DnsInterface.cxx, DnsInterface.hxx, DnsResult.cxx, DnsResult.hxx: - change license to VOCAL - -2003-10-02 16:24 jason - - * Connection.cxx: debug - -2003-10-01 11:07 davidb - - * test/testEmbedded.cxx: rport automatically added in Via -- fix - comparison string - -2003-10-01 10:53 jason - - * test/testTypedef.cxx: compile on linux - -2003-10-01 10:53 jason - - * test/testParserCategories.cxx: make the test pass - -2003-10-01 10:53 jason - - * Connection.cxx, TcpBaseTransport.cxx, os/Socket.hxx, - os/Tuple.cxx, os/Tuple.hxx, os/Socket.cxx: fix the cullen whirlwind - -2003-10-01 08:35 fluffy - - * TransportSelector.cxx, TransportSelector.hxx: fix opening of - socket and errno stuff - -2003-10-01 08:33 fluffy - - * os/Fifo.hxx, os/Socket.cxx, os/Socket.hxx, os/DnsUtil.cxx, - Transport.cxx, Transport.hxx, UdpTransport.cxx, - ParserCategories.cxx, TcpBaseTransport.cxx, TcpConnection.cxx: fix - errno stuff - -2003-10-01 08:33 fluffy - - * test/: limpc.cxx, test.vcproj: compile windows - -2003-09-30 12:31 jason - - * ConnectionManager.cxx, DnsResult.cxx, Headers.hxx, SipStack.cxx, - os/Inserter.hxx, os/IntrusiveListElement.hxx, test/Makefile, - test/testIntrusiveList.cxx, test/testTypedef.cxx: fixes for solaris - -2003-09-29 19:59 jason - - * os/Socket.cxx: for solaris compiler - -2003-09-29 19:38 jason - - * os/DnsUtil.cxx: getdomainname() and int e = - ioctl(s,SIOCGIFCONF,&ifc) are not supported in solaris - -2003-09-29 18:53 fluffy - - * os/IntrusiveListElement.hxx: change to compile windows - had to - move private memeber to protected - no idea why this fixed the - problem - -2003-09-29 18:49 fluffy - - * TransportSelector.cxx, Transport.hxx, os/Tuple.hxx: fix for when - there is no IPV6 - -2003-09-29 18:48 fluffy - - * TransactionController.cxx: fix compiler warning in windows - -2003-09-29 16:07 alan - - * TransportSelector.cxx, os/Tuple.cxx, test/Makefile.am: minor - compilation fixes for Linux - -2003-09-29 15:56 alan - - * Makefile.am: fixed duplicate SUBDIRS - -2003-09-29 15:51 alan - - * Makefile.am, Transport.hxx, TransportSelector.cxx, - TransportSelector.hxx, config.hxx.in, os/Tuple.cxx, os/Tuple.hxx, - test/Makefile.am, test/testStack.cxx, test/testUdp.cxx: - TransportSelector changes. sentPort() to clue for specifics. - Otherwise, will select tightest bound transport. Populates topmost - via with correct IP address. - - Modified Files: - Connection.cxx Connection.hxx ConnectionManager.cxx - DnsResult.cxx DnsResult.hxx Helper.cxx Makefile.am - StatelessHandler.cxx TcpBaseTransport.cxx TcpConnection.cxx - TcpConnection.hxx TcpTransport.cxx TlsConnection.hxx - TransactionState.cxx Transport.cxx Transport.hxx - TransportMessage.hxx TransportSelector.cxx - TransportSelector.hxx UdpTransport.cxx config.hxx.in - resiprocate.vcproj os/DnsUtil.cxx os/DnsUtil.hxx - os/Random.cxx os/Socket.cxx - os/Socket.hxx os/Tuple.cxx os/Tuple.hxx test/Makefile.am - test/testStack.cxx test/testUdp.cxx - -2003-09-29 15:40 alan - - * Transport.hxx, TransportSelector.cxx, TransportSelector.hxx, - os/Tuple.cxx, os/Tuple.hxx, test/Makefile.am, test/testStack.cxx: - transport selector overhaul - -2003-09-29 13:25 davidb - - * Connection.hxx: unse simplified IntrusiveListElement templates - -2003-09-29 13:25 davidb - - * test/Makefile: added testIntrusiveList - -2003-09-29 13:25 davidb - - * test/testIntrusiveList.cxx: [no log message] - -2003-09-29 13:25 davidb - - * os/IntrusiveListElement.hxx: simplified templates, added license - -2003-09-29 13:23 davidb - - * os/ParseBuffer.cxx: output parse errors to Info - -2003-09-29 08:23 alan - - * Makefile.am: re-ordered build - -2003-09-29 07:56 alan - - * Connection.cxx, Connection.hxx, ConnectionManager.cxx, - DnsResult.cxx, DnsResult.hxx, Helper.cxx, StatelessHandler.cxx, - TcpBaseTransport.cxx, TcpConnection.cxx, TcpConnection.hxx, - TcpTransport.cxx, TlsConnection.hxx, TransactionState.cxx, - Transport.cxx, Transport.hxx, TransportMessage.hxx, - TransportSelector.cxx, UdpTransport.cxx, resiprocate.vcproj, - os/DnsUtil.cxx, os/DnsUtil.hxx, os/IntrusiveListElement.hxx, - os/Random.cxx, os/Socket.cxx, os/Socket.hxx, os/Tuple.cxx, - os/Tuple.hxx, test/testStack.cxx: safety check-in before - integrating Jasons changes - -2003-09-28 17:37 jason - - * test/testStack.cxx: allow specification of protocol with -p - -2003-09-28 17:36 jason - - * os/Socket.hxx: fix compile on linux - -2003-09-28 17:36 jason - - * UdpTransport.cxx: [no log message] - -2003-09-28 13:26 fluffy - - * os/DnsUtil.cxx, os/Socket.hxx, os/Tuple.cxx, Connection.hxx, - DnsResult.cxx, DnsResult.hxx, TcpConnection.hxx, TlsConnection.hxx, - resiprocate.vcproj: compiles under windows - added bunch of - USE_IPV6 #ifdefs - -2003-09-28 13:25 fluffy - - * os/IntrusiveListElement.hxx: This needs help before it will work - under windoes - right not it just comiples by commenting stuff out - - it would not run in widnows. Other versiosns should still work - -2003-09-27 17:21 jason - - * Connection.cxx, TcpBaseTransport.cxx, TcpConnection.cxx, - Transport.cxx: fix bug when read returns 0 bytes - means far side - closed - -2003-09-27 14:53 jason - - * os/: Random.cxx, Socket.cxx, Socket.hxx: change to use shutdown - instead of close - -2003-09-27 14:50 jason - - * Connection.cxx, TcpBaseTransport.cxx, TcpConnection.cxx, - TcpTransport.cxx, TransportMessage.hxx: change some debug levels - -2003-09-27 14:45 jason - - * ConnectionManager.cxx: fix memory leak in deleteConnection from - mAddrMap and mIdMap - -2003-09-27 10:27 jason - - * DnsResult.cxx: fixed bug with setting port for numeric ip query - -2003-09-27 10:05 jason - - * os/Tuple.cxx: fixed bug with not converting port from host to - network - -2003-09-27 09:52 jason - - * os/: DnsUtil.cxx, DnsUtil.hxx: added capability to get local ip - address also added capability to find ip address for a named - interface - -2003-09-26 18:49 jason - - * ConnectionManager.cxx, DnsResult.cxx, Helper.cxx, - StatelessHandler.cxx, TcpBaseTransport.cxx, TransactionState.cxx, - Transport.cxx, Transport.hxx, TransportSelector.cxx, - UdpTransport.cxx, os/DnsUtil.cxx, os/DnsUtil.hxx, os/Tuple.cxx, - os/Tuple.hxx: refactored the Tuple required interface changes to - the Tuple store network address in a sockaddr structure to be - generic for v4 and v6 fixed a bug in Tuple::operator< - -2003-09-26 18:44 alan - - * TcpBaseTransport.cxx, Transport.cxx, Transport.hxx, - TransportSelector.cxx, UdpTransport.cxx, config.hxx.in, - os/Tuple.cxx, test/testUdp.cxx: Safety check-in so I can work on - the w/e on the Mac. Modified Files: Tag: b-dev-ah-20030925-ts - TcpBaseTransport.cxx Transport.cxx Transport.hxx - TransportSelector.cxx UdpTransport.cxx config.hxx.in - os/Tuple.cxx test/testUdp.cxx - -2003-09-26 09:47 jason - - * TcpBaseTransport.cxx, Transport.cxx, Transport.hxx, - UdpTransport.cxx: added a method Transport::bind to replace the - static so we can store the bound sockaddr in the Transport for use - by TransportSelector - -2003-09-25 19:14 alan - - * Makefile.am, TransportSelector.cxx, TransportSelector.hxx, - test/Makefile.am, test/testStack.cxx: Not ready for prime-time -- - personal integration branch. Modified Files: Tag: - b-dev-ah-20030925-ts configure.ac aclocal.m4 - resiprocate/Makefile.am resiprocate/TransportSelector.cxx - resiprocate/TransportSelector.hxx resiprocate/test/Makefile.am - resiprocate/test/testStack.cxx - -2003-09-25 17:50 jason - - * test/testStack.cxx: combine message creation with sends - -2003-09-25 14:42 jason - - * test/testStack.cxx: use dns - -2003-09-25 14:30 jason - - * test/: Makefile, testStack.cxx: added a new performance test for - the stack - -2003-09-25 14:30 jason - - * TransactionState.cxx: fix some memory issues with delete this - -2003-09-25 10:47 jason - - * test/: testTcp.cxx, testUdp.cxx, Makefile: added command line - args using popt - -2003-09-25 10:47 jason - - * test/testDns.cxx: delete DnsResults - -2003-09-25 10:46 jason - - * os/: Log.cxx, Log.hxx: added Log::initialize that takes char* for - command line arg ease of use - -2003-09-25 10:46 jason - - * DnsInterface.cxx: fix memory leak with ares - -2003-09-25 10:45 jason - - * DnsResult.cxx: change to LOG_DEBUG - -2003-09-24 14:31 alan - - * Connection.cxx, Connection.hxx, ConnectionMap.cxx, - ConnectionMap.hxx: removing obsolete files and references to them - -2003-09-24 13:33 alan - - * test/testTcp.cxx: dummy use for err - -2003-09-24 13:33 alan - - * config.hxx.in: missing USE options - -2003-09-24 11:07 davidb - - * test/testUri.cxx: test IPV6 handling - -2003-09-24 11:06 davidb - - * test/testSipFrag.cxx: added test for tricky end of SipFrag - -2003-09-24 11:05 davidb - - * os/ParseBuffer.cxx: added file name to logging on failure -- how - helpful - -2003-09-24 11:04 davidb - - * os/: DnsUtil.cxx, DnsUtil.hxx: IPV6 mods - -2003-09-24 11:04 davidb - - * os/: AbstractFifo.cxx, AbstractFifo.hxx, FiniteFifo.hxx: - refactored fifo for finite length -- returns false if can't push - (how will this interact with priorty queue?) (do timers ever go - into finite queues?) - -2003-09-24 10:59 davidb - - * Uri.cxx, Uri.hxx: allow IP6 hosts -- includes comparison - -2003-09-24 10:58 davidb - - * SipFrag.cxx: hacked SipFrag to allow MsgHeaderScanner to be - unhappy with how the fragment ends -- probably wrong - -2003-09-23 13:25 jason - - * Connection.cxx, TcpBaseTransport.cxx, TcpConnection.cxx, - Transport.cxx, Transport.hxx: [no log message] - -2003-09-22 00:05 jason - - * Connection.cxx, ConnectionManager.cxx, TcpBaseTransport.cxx, - TcpConnection.cxx: fix some problems with cleanup when delete - TcpTransport and/or Connection - -2003-09-19 17:33 davidb - - * test/testIntrusiveList.cxx: use static makeList - -2003-09-19 17:32 davidb - - * os/IntrusiveListElement.hxx: valiant attempt to synch comments - with code - -2003-09-19 17:32 davidb - - * ConnectionManager.cxx, ConnectionManager.hxx: using a single - Connection for all list heads; fixed iterator validation - -2003-09-19 16:30 davidb - - * test/testTcp.cxx: spelling in output - -2003-09-19 16:29 davidb - - * os/Data.cxx: fixed weird cast bug in hash - -2003-09-19 16:29 davidb - - * Connection.cxx, Connection.hxx, ConnectionManager.cxx, - ConnectionManager.hxx: converted Connection lists (read, write, - least recently used) to intrusive - -2003-09-19 16:28 davidb - - * os/IntrusiveListElement.hxx: rationalized initialization, added - some paranoid asserts - -2003-09-19 14:51 davidb - - * os/IntrusiveListElement.hxx, test/testIntrusiveList.cxx: [no log - message] - -2003-09-18 14:10 davidb - - * ConnectionManager.cxx: [no log message] - -2003-09-18 14:08 jason - - * Makefile: added new files to old build system - -2003-09-18 10:15 davidb - - * Connection.cxx, Connection.hxx, ConnectionManager.cxx, - ConnectionManager.hxx, ConnectionMap.cxx, DnsResult.cxx, - Makefile.am, Security.cxx, Security.hxx, SipStack.cxx, - SipStack.hxx, TcpBaseTransport.cxx, TcpBaseTransport.hxx, - TcpConnection.cxx, TcpConnection.hxx, TcpTransport.cxx, - TcpTransport.hxx, TlsConnection.cxx, TlsConnection.hxx, - TlsTransport.cxx, TlsTransport.hxx, TransactionController.cxx, - TransactionController.hxx, Transport.cxx, Transport.hxx, - TransportSelector.cxx, TransportSelector.hxx, UdpTransport.cxx, - os/DnsUtil.cxx, os/DnsUtil.hxx, os/Socket.cxx, os/Tuple.cxx, - os/Tuple.hxx, test/Makefile.am, test/Transceiver.cxx, - test/testTcp.cxx, test/testUdp.cxx: refactored tcp code refactored - tls code full support for tcpv6 with more general use support for - binding to specific interfaces added many new DnsUtil and utilities - in Tuple class - -2003-09-16 08:22 jason - - * MethodHash.cxx: fix cullen's erasure of this file - -2003-09-16 06:55 fluffy - - * os/: RandomHex.cxx, RandomHex.hxx: no longe used - -2003-09-16 06:53 fluffy - - * .cvsignore, os/.cvsignore, test/.cvsignore: ignore goofy stuff - -2003-09-16 06:50 fluffy - - * PreparseDiagnostic.cxx, PreparseInlines.cxx, SdpContents.cxx, - ShutdownMessage.hxx, SipFrag.cxx, StatelessHandler.cxx, - StatelessHandler.hxx, TransactionController.cxx, - TransactionController.hxx, TransactionTerminated.hxx, TuShim.cxx, - UnknownHeaderType.cxx, UnknownParameterType.cxx, XMLCursor.cxx, - XPidf.cxx, X_msMsgsInvite.cxx, libSipImp.cxx, os/Coders.cxx, - os/Coders.hxx, os/CountStream.cxx, os/DataStream.cxx, - os/DnsUtil.hxx, os/MD5Stream.cxx, os/MD5Stream.hxx, os/Tuple.cxx, - os/Tuple.hxx, test/InviteClient.cxx, test/InviteClient.hxx, - test/InviteServer.cxx, test/InviteServer.hxx, test/Register.cxx, - test/Register.hxx, test/Registrar.cxx, test/Registrar.hxx, - test/Resolver.cxx, test/TestSupport.cxx, test/TestSupport.hxx, - test/Transceiver.cxx, test/Transceiver.hxx, test/digcalc.hxx, - test/lg.cxx, test/limpc.cxx, test/md5.cxx, test/md5.hxx, - test/test1.cxx, test/test2.cxx, test/testBlast.cxx, - test/testClient.cxx, test/testCoders.cxx, test/testCountStream.cxx, - test/testData.cxx, test/testDataPerformance.cxx, - test/testDataStream.cxx, test/testDigestAuthentication.cxx, - test/testDns.cxx, test/testDnsResolver.cxx, test/testEmbedded.cxx, - test/testEmptyHeader.cxx, test/testIM.cxx, test/testIM.hxx, - test/testLockStep.cxx, test/testLogger.cxx, - test/testMessageWaiting.cxx, test/testMultipartMixedContents.cxx, - test/testNameAddrParamExclusions.cxx, - test/testNonInviteClientTx.cxx, test/testNonInviteServerTx.cxx, - test/testParseUtil.cxx, test/testPlainContents.cxx, - test/testRandomHex.cxx, test/testSdp.cxx, test/testSelect.cxx, - test/testServer.cxx, test/testSimpleLeak.cxx, - test/testSipStackInvite.cxx, test/testSource.cxx, - test/testSpeed.cxx, test/testTcpTransport.cxx, - test/testThreadIf.cxx, test/testTlsConnection.cxx, - test/testTransactionFSM.cxx, test/testUdp.cxx, test/testUri.cxx, - test/testXMLCursor.cxx, ApplicationSip.cxx, Connection.cxx, - Connection.hxx, ConnectionMap.cxx, Contents.cxx, DnsHandler.hxx, - DnsResolver.cxx, Embedded.cxx, GenericContents.cxx, HeaderHash.cxx, - HeaderHash.hxx, LazyParser.cxx, MessageWaitingContents.cxx, - MethodHash.cxx, MethodHash.hxx, MsgHeaderScanner.cxx, - MsgHeaderScanner.hxx, MultipartMixedContents.cxx, - MultipartSignedContents.cxx, OctetContents.cxx, ParameterHash.cxx, - ParameterHash.hxx, ParseUtil.hxx, Pidf.cxx, Pkcs7Contents.cxx, - PlainContents.cxx: fixed up license text - -2003-09-16 06:48 fluffy - - * os/DnsUtil.cxx: made to compile on mac - -2003-09-15 20:54 davidb - - * UnknownParameter.cxx: should initialize mIsQuoted - -2003-09-15 20:04 fluffy - - * UdpTransport.cxx: update error codes - -2003-09-15 20:04 fluffy - - * test/test.vcproj: no message - -2003-09-15 12:35 alan - - * Transport.cxx: added initialisation of mV4 member. - -2003-09-15 12:00 jason - - * StatelessHandler.cxx, Transport.cxx, Transport.hxx, - TransportSelector.cxx, os/DnsUtil.cxx, os/DnsUtil.hxx, - os/Tuple.cxx: [no log message] - -2003-09-14 22:07 alan - - * test/testSource.cxx: sockaddr_t fixes - -2003-09-14 21:08 alan - - * TransportSelector.cxx: initial ipv6 via support - -2003-09-14 19:49 fluffy - - * os/Socket.hxx: add assert - -2003-09-14 19:48 fluffy - - * test/testBlast.cxx: does not work yet - -2003-09-14 19:27 fluffy - - * UdpTransport.cxx, os/DnsUtil.cxx: update - -2003-09-14 19:24 fluffy - - * test/: test.vcproj, limpc.cxx: update - -2003-09-14 16:45 alan - - * TransportSelector.cxx: type repair for Linux - -2003-09-14 16:40 davidb - - * os/Data.cxx: new hash fn - -2003-09-14 16:39 jason - - * SipStack.cxx, SipStack.hxx, TransactionController.cxx, - TransactionController.hxx, Transport.cxx, Transport.hxx, - TransportSelector.cxx, TransportSelector.hxx, UdpTransport.cxx: - added multi-threading for transports - -2003-09-14 16:35 jason - - * test/: .cvsignore, Makefile.am: [no log message] - -2003-09-14 16:35 jason - - * test/testUdp.cxx: added a speed test for udp - -2003-09-14 14:05 alan - - * Connection.hxx, MsgHeaderScanner.cxx, MsgHeaderScanner.hxx, - SipFrag.cxx, SipMessage.cxx, TransactionState.cxx, - TransportSelector.cxx, TransportSelector.hxx, test/Makefile.am, - test/testSource.cxx: Added via: setting to TransportSelector.cxx - Fixed includes in MsgScanner Added some flags for configure: - --enable-ipv6 --enable-scanner --with-ares - --with-openssl - - modified Files: configure.ac resiprocate/Connection.hxx - resiprocate/MsgHeaderScanner.cxx - resiprocate/MsgHeaderScanner.hxx resiprocate/SipFrag.cxx - resiprocate/SipMessage.cxx resiprocate/TransactionState.cxx - resiprocate/TransportSelector.cxx - resiprocate/TransportSelector.hxx resiprocate/test/Makefile.am - Added Files: resiprocate/test/testSource.cxx - -2003-09-14 13:42 fluffy - - * test/: Makefile, testSelect.cxx: added testSelect - -2003-09-14 01:42 fluffy - - * Security.cxx: fix error for earlier version of SSL - -2003-09-14 01:39 fluffy - - * Security.cxx: try to stop overwrite of certs - -2003-09-14 01:37 jason - - * TransactionState.cxx: fix bugs - -2003-09-14 01:31 fluffy - - * test/: Makefile, limpc.cxx: [no log message] - -2003-09-14 01:27 jason - - * Makefile, test/Makefile: [no log message] - -2003-09-14 00:54 fluffy - - * os/: DnsUtil.cxx, Tuple.cxx, Tuple.hxx: fixed for windows - -2003-09-14 00:53 fluffy - - * resiprocate.vcproj: added ares - does not link - -2003-09-14 00:22 rjsparks - - * DnsResult.cxx, DnsResult.hxx: Added queries for AAAA records - -2003-09-14 00:21 jason - - * test/testDns.cxx: fix recursive lock error on debug - -2003-09-14 00:10 fluffy - - * DnsResolver.cxx, DnsResult.cxx, TlsTransport.cxx, - TlsTransport.hxx, TransactionState.cxx, Transport.hxx, - UdpTransport.cxx, UdpTransport.hxx: compile under windows - -2003-09-14 00:09 fluffy - - * resiprocate.vcproj: add ares - -2003-09-13 23:30 jason - - * test/: test2.cxx, testClient.cxx, testDnsResolver.cxx, - testLockStep.cxx, testNonInviteClientTx.cxx, - testNonInviteServerTx.cxx, testServer.cxx, testSipStackInvite.cxx, - testSpeed.cxx, testTcpTransport.cxx, testTransactionFSM.cxx: fix - Transport -> Tuple stuff - -2003-09-13 23:25 jason - - * test/Makefile.am: added files - -2003-09-13 23:18 jason - - * os/Tuple.cxx: fix compile - -2003-09-13 22:46 jason - - * Makefile.am: added files - -2003-09-13 22:41 jason - - * test/: Makefile.am, limpc.cxx: [no log message] - -2003-09-13 22:25 jason - - * Connection.cxx, Connection.hxx, ConnectionMap.cxx, - ConnectionMap.hxx, DnsInterface.hxx, DnsResolver.cxx, - DnsResolver.hxx, DnsResult.cxx, DnsResult.hxx, Makefile.am, - SipMessage.hxx, SipStack.cxx, SipStack.hxx, StatelessHandler.cxx, - TcpTransport.cxx, TcpTransport.hxx, TlsTransport.cxx, - TlsTransport.hxx, TransactionController.cxx, - TransactionController.hxx, TransactionState.cxx, - TransactionState.hxx, Transport.cxx, Transport.hxx, - TransportSelector.cxx, TransportSelector.hxx, TuIM.cxx, TuIM.hxx, - UdpTransport.cxx, UdpTransport.hxx, libSipImp.cxx, os/DnsUtil.cxx, - os/DnsUtil.hxx, os/Socket.hxx, test/Resolver.cxx, - test/Resolver.hxx, test/Transceiver.cxx, test/test1.cxx, - test/testClient.cxx, test/testServer.cxx: moved Tuple out of - Transport added preliminary ipv6 support - -2003-09-13 22:20 davidb - - * TransactionState.cxx: removed crazy TimerCleanup that causes - strange crash - -2003-09-13 21:58 davidb - - * os/Timer.cxx: fix error on display of timer - -2003-09-13 21:17 fluffy - - * MethodHash.cxx: remvoed std - -2003-09-13 21:15 fluffy - - * ApplicationSip.cxx, BranchParameter.cxx, Connection.cxx, - ConnectionMap.cxx, Contents.cxx, DataParameter.cxx, Dialog.cxx, - Dialog2.cxx, DialogSet.cxx, Embedded.cxx, Executive.cxx, - ExistsParameter.cxx, FloatParameter.cxx, GenericContents.cxx, - HeaderFieldValue.cxx, HeaderFieldValueList.cxx, HeaderHash.cxx, - HeaderTypes.cxx, Headers.cxx, Helper.cxx, IntegerParameter.cxx, - LazyParser.cxx, Message.cxx, MessageWaitingContents.cxx, - MethodTypes.cxx, MsgHeaderScanner.cxx, MultipartMixedContents.cxx, - MultipartSignedContents.cxx, OctetContents.cxx, Parameter.cxx, - ParameterHash.cxx, ParameterTypes.cxx, ParseUtil.cxx, - ParserCategories.cxx, ParserCategory.cxx, Pidf.cxx, - Pkcs7Contents.cxx, PlainContents.cxx, Preparse.cxx, - PreparseDiagnostic.cxx, PreparseInlines.cxx, QopParameter.cxx, - QuotedDataParameter.cxx, Registration.cxx, RportParameter.cxx, - SdpContents.cxx, SendingMessage.cxx, SipFrag.cxx, SipMessage.cxx, - SipMessageExplicit.cxx, SipSession.cxx, StatelessHandler.cxx, - Subscription.cxx, Symbols.cxx, TcpTransport.cxx, TimerMessage.cxx, - TimerQueue.cxx, TlsTransport.cxx, TransactionController.cxx, - TransactionMap.cxx, TransactionState.cxx, Transport.cxx, - TuShim.cxx, UdpTransport.cxx, UnknownHeaderType.cxx, - UnknownParameter.cxx, UnknownParameterType.cxx, Uri.cxx, - XMLCursor.cxx, XPidf.cxx, X_msMsgsInvite.cxx: added the config.h - include in - -2003-09-13 21:12 fluffy - - * MethodHash-raw.cxx: remove std namespace - not used - -2003-09-13 21:03 fluffy - - * DnsResult.hxx: interface is reserve work in windows - -2003-09-13 21:02 fluffy - - * MethodHash.cxx, SipMessage.cxx: fix windows warnings - -2003-09-13 20:42 jason - - * os/: Tuple.cxx, Tuple.hxx: moved out of Transport - -2003-09-13 20:40 davidb - - * Makefile, MethodHash-raw.cxx: fix hash for old build stuff - -2003-09-13 20:33 fluffy - - * Security.cxx, Security.hxx: made path function public instead of - private - -2003-09-13 20:31 fluffy - - * Makefile: removed old gperf generation stuff - -2003-09-13 18:41 davidb - - * test/testParseUtil.cxx: [no log message] - -2003-09-13 18:41 davidb - - * Makefile, MethodHash.cxx, ParseUtil.cxx, ParseUtil.hxx, Uri.cxx, - os/DnsUtil.cxx, os/DnsUtil.hxx, test/Makefile, - test/testParserCategories.cxx, test/testUri.cxx, - ParserCategories.cxx: first pass at IPV6 syntax - -2003-09-13 14:23 rjsparks - - * os/compat.hxx: Added a definition for the DNS AAAA record type - T_AAAA == 28 - -2003-09-13 13:16 jason - - * DnsInterface.hxx, Makefile.am: fix build for ares and new dns - -2003-09-13 12:57 jason - - * DnsResolver.cxx, DnsResolver.hxx, Executive.cxx, Executive.hxx, - Makefile, Security.cxx, Security.hxx, SipStack.cxx, SipStack.hxx, - StatelessHandler.cxx, StatelessHandler.hxx, TcpTransport.cxx, - TimerMessage.cxx, TlsTransport.cxx, TransactionController.cxx, - TransactionController.hxx, TransactionState.cxx, - TransactionState.hxx, TransportSelector.cxx, TransportSelector.hxx, - TuIM.hxx, UdpTransport.cxx, os/Timer.hxx, test/testDns.cxx, - SipMessage.hxx: working new version of dns resolver using a - TransactionController now no ok() methods in Transports callback - for dns results instead of event - -2003-09-13 12:47 jason - - * DnsHandler.hxx, DnsInterface.cxx, DnsInterface.hxx, - DnsResult.cxx, DnsResult.hxx: working new version of dns resolver - -2003-09-13 10:47 davidb - - * SdpContents.cxx, SdpContents.hxx: change int& - -2003-09-11 21:45 fluffy - - * Headers.cxx, ParserCategories.cxx, SdpContents.cxx: fixed compile - warnings on windows - -2003-09-11 21:38 fluffy - - * resiprocate.vcproj, os/DnsUtil.cxx: fixed to compile on windows - again - -2003-09-11 10:17 alan - - * Makefile.am: added RPM stuff to autotools manifests - -2003-09-08 19:04 jason - - * test/Makefile: remove some tests that aren't building at the - moment - -2003-09-08 15:56 davidb - - * test/testUri.cxx: more tests, test missing scheme failure - -2003-09-08 15:56 davidb - - * test/testSipMessage.cxx: slight fix to test - -2003-09-08 15:55 davidb - - * Uri.cxx: complain if give an uri with a @ and no scheme - -2003-09-08 15:54 davidb - - * UdpTransport.cxx: typo in debug - -2003-09-08 15:54 davidb - - * SipMessage.cxx: type agreement in comparison - -2003-09-08 15:53 davidb - - * HeaderTypes.hxx, Headers.cxx, Headers.hxx, MethodTypes.cxx, - MethodTypes.hxx, ParameterTypeEnums.hxx: unified macros in - preparation for auto generating gperf files - -2003-09-08 15:00 jason - - * os/Fifo.hxx: remove reference to Inserter in Fifo - -2003-09-08 14:43 jason - - * os/Inserter.hxx: change inserter to only comment out code under - windows - -2003-09-05 21:38 fluffy - - * os/Fifo.hxx, os/Inserter.hxx, DnsInterface.cxx, DnsResult.hxx, - MethodHash.cxx, StatelessHandler.cxx, TransportSelector.cxx, - Uri.cxx, resiprocate.vcproj: compile under windows - -2003-09-04 11:20 jason - - * test/.cvsignore: allow addition of new tests - -2003-09-04 11:20 jason - - * test/: testDns.cxx, Makefile: simple test code for new Dns - resolver - -2003-09-04 11:19 jason - - * DnsResult.cxx: added code to handle case where SRV or A records - are not in additional section of dns record - -2003-09-03 15:08 jason - - * HeaderHash.cxx, MethodHash.cxx, MethodHash.gperf: added PRACK and - PUBLISH rebuild the gperf stuff - -2003-09-01 22:00 jason - - * DnsResult.cxx: NAPTR processing seems better now. If no NAPTR, - the algorithm to pick from multiple SRV results is not right - need - clarification - -2003-09-01 21:38 jason - - * DnsInterface.cxx, DnsInterface.hxx, DnsResult.cxx, DnsResult.hxx: - closer to implementation of rfc2782, rfc2915 and rfc3263 (still not - ready for public consumption) - -2003-08-31 18:54 jason - - * DnsInterface.cxx, DnsInterface.hxx, DnsResult.cxx: fixed some - bugs, not for public use yet. interface may still change - -2003-08-31 17:40 jason - - * DnsInterface.cxx, DnsInterface.hxx, DnsResult.cxx, DnsResult.hxx: - fix some link errors - -2003-08-31 16:49 jason - - * os/: Subsystem.cxx, Subsystem.hxx: added DNS subsystem sorted - entries - -2003-08-31 16:49 jason - - * os/: DnsUtil.cxx, DnsUtil.hxx: added some calls for isIpAddress - (v4 & v6) v6 not implemented - -2003-08-31 16:48 jason - - * DnsInterface.cxx, DnsInterface.hxx, DnsResult.cxx, DnsResult.hxx: - first cut at a new set of DNS interfaces/implementation complete - rewrite of DnsResolver class - -2003-08-31 16:43 jason - - * ParserCategories.hxx: add rport parameter by default on Via - -2003-08-29 13:33 ryker - - * MethodHash.gperf: Get some s/sip2/resiprocate/ out of my local - tree. - -2003-08-29 13:33 ryker - - * MethodHash.hxx: Make macro guards consistent. - -2003-08-29 13:27 ryker - - * HeaderHash.gperf, HeaderHash.hxx: Get some s/sip2/resiprocate/ - out of my tree. - -2003-08-26 21:58 fluffy - - * Helper.cxx, TuIM.cxx, TuIM.hxx, test/limpc.cxx: fixed bugs with - TCP - -2003-08-26 20:48 fluffy - - * os/vmd5.cxx: fixed endina bug that caused digest auth to fail on - MAC - -2003-08-26 19:45 wensong - - * os/DnsUtil.cxx: [no log message] - -2003-08-26 17:51 jason - - * TcpTransport.cxx: temporary fix to problem with - blocking/non-blocking creation of tcp socket needs more work - -2003-08-26 17:50 jason - - * ConnectionMap.cxx: remove the delete of connection to avoid a - crash in TCP/TLS - -2003-08-26 17:50 jason - - * Helper.cxx: only add record-route to response if 180 -- 2xx - -2003-08-26 17:49 jason - - * TODO: [no log message] - -2003-08-26 17:49 jason - - * TlsTransport.cxx: fix bug related to using an existing connection - with TLS - -2003-08-26 17:49 jason - - * Transport.cxx: added some debug to operator<< - -2003-08-26 17:48 jason - - * TransportSelector.cxx: added a comment - -2003-08-26 17:48 jason - - * os/Fifo.hxx: added asserts - -2003-08-26 15:04 fluffy - - * SipStack.cxx, SipStack.hxx, libSipImp.cxx, test/limpc.cxx: change - order of addTlsTransport - -2003-08-26 15:03 fluffy - - * TransactionState.cxx: fix compile warning - -2003-08-26 14:03 fluffy - - * os/DnsUtil.cxx: fix for MAC - -2003-08-25 20:21 wensong - - * Makefile.am: [no log message] - -2003-08-21 06:28 jason - - * TransactionState.cxx: when reliability message comes back from - transports, set mIsReliable flag in transaction so retransmissions - don't occur on reliable transports - -2003-08-20 13:47 jason - - * MethodTypes.cxx, MethodTypes.hxx: added PRACK and PUBLISH - -2003-08-20 08:56 jason - - * ParserCategories.cxx, ParserCategory.cxx: Unknown parameters call - -2003-08-20 08:16 jason - - * UnknownParameter.cxx, UnknownParameter.hxx: deal with exists - style unknown parameters - -2003-08-20 08:10 jason - - * SipMessage.cxx: fix brie for UNKNOWN method - -2003-08-20 07:07 ryker - - * TcpTransport.cxx: Fix the comment so that I can understand it - better. - -2003-08-19 16:11 jason - - * HeaderFieldValueList.cxx, ParserContainer.hxx: don't allow empty - headers (still requires support for special multi headers that can - be empty) fix bug in multi output on separate lines - -2003-08-19 16:10 jason - - * TransportSelector.cxx: debug output - -2003-08-19 16:10 jason - - * TransactionState.cxx, TransactionState.hxx: fix handling of dns - errors and running out of dns entries - send a 480 to TU - -2003-08-19 16:09 jason - - * TlsTransport.cxx: return when error occurs to avoid seg fault - -2003-08-19 16:08 jason - - * DnsResolver.cxx, DnsResolver.hxx: when dns error occurs, set - final = true - -2003-08-19 09:56 jason - - * test/: testParserCategories.cxx, testSipMessage.cxx: add exists - style unknown parameters - -2003-08-19 08:17 jason - - * TransportSelector.cxx: include TlsTransports in all process - calls. temporary solution - -2003-08-19 08:17 jason - - * TlsTransport.cxx: handle case where 0 bytes received - -2003-08-19 08:17 jason - - * Connection.cxx: stampReceived not called in one case - -2003-08-19 01:30 wensong - - * ChangeLog, Makefile.am, TcpTransport.cxx, TlsTransport.cxx: [no - log message] - -2003-08-18 15:41 jason - - * Headers.cxx, ParserCategories.hxx, ParserCategory.hxx: rename - weird comma enums fix bug in output of multi headers on separate - lines - -2003-08-18 07:48 ryker - - * ExistsParameter.cxx: When we parse "exists" parameters, be - accepting of a right hand side (e.g. ;lr=1 instead of plain ;lr). - In this case, eat the right hand side so we can continue parsing - normally. - -2003-08-16 18:43 jason - - * Transport.cxx: init to -1 - -2003-08-16 18:43 jason - - * TcpTransport.cxx: handle shutting down the TcpTransport if stuff - is still in the fifo. not correct behavior. shut drain the - transport - -2003-08-16 18:42 jason - - * Connection.cxx, Connection.hxx, ConnectionMap.cxx: fixed a bug in - the Connection where it was deleting some dummy Connections - resulting in closing file descriptor 0 - -2003-08-16 18:17 jason - - * SipStack.cxx: [no log message] - -2003-08-15 16:28 davidb - - * Connection.cxx, Connection.hxx, Makefile, MsgHeaderScanner.cxx, - SipFrag.cxx, SipMessage.cxx, SipMessage.hxx, TcpTransport.cxx, - UdpTransport.cxx, UdpTransport.hxx, test/SipTortureTests.cxx, - test/TestSupport.cxx, test/testMultipartMixedContents.cxx, - test/testTcpTransport.cxx: support both Preparser and - MsgHeaderScanner - -2003-08-14 22:05 davidb - - * os/DnsUtil.cxx: include - -2003-08-14 22:05 davidb - - * os/RecursiveMutex.cxx: indent - -2003-08-14 22:03 davidb - - * Transport.cxx: fixed hash function for tuple - -2003-08-14 22:03 davidb - - * Transport.hxx: added warning comment - -2003-08-14 22:03 davidb - - * MsgHeaderScanner.cxx, MsgHeaderScanner.hxx: new style message - scanner (alternative for preparser) - -2003-08-14 22:02 davidb - - * ConnectionMap.cxx: minor change to assertion - -2003-08-14 21:28 wensong - - * Makefile.am: [no log message] - -2003-08-13 22:49 jason - - * Connection.cxx, SipStack.hxx, TcpTransport.cxx, TlsTransport.cxx, - TlsTransport.hxx, Transport.hxx: tweaks to the TLS stuff so that it - sets the tls domainname when a message is received on a TLS - transport - -2003-08-13 22:48 jason - - * TransportSelector.cxx, TransportSelector.hxx: use the only TLS - transport if there is only one and no TLS domainname specified - -2003-08-13 22:47 jason - - * os/: DnsUtil.cxx, DnsUtil.hxx: added getLocalDomainName - -2003-08-13 20:21 wensong - - * test/Makefile.am: [no log message] - -2003-08-13 19:26 jason - - * Connection.cxx, SipMessage.cxx, SipMessage.hxx, SipStack.cxx, - SipStack.hxx, TlsTransport.cxx, TlsTransport.hxx, - TransportSelector.cxx, TransportSelector.hxx, UdpTransport.cxx, - test/TestSupport.cxx, test/testPreparse.cxx: TLS interface changes - to support one Security object per TlsTransport Change to how - SipMessage is constructed to provide access to the Transport* if it - came from the wire - -2003-08-13 19:18 jason - - * os/: DnsUtil.cxx, DnsUtil.hxx: added an interface to return SRV - records - -2003-08-13 19:17 jason - - * Security.cxx, Security.hxx: make initialize thread-safe - -2003-08-13 19:17 jason - - * DnsResolver.hxx: indentation - -2003-08-13 13:36 davidb - - * test/testSipMessage.cxx: header remove tests - -2003-08-13 13:35 davidb - - * os/MD5Stream.cxx, test/testData.cxx: use Data::Share interface - for overlay - -2003-08-13 13:34 davidb - - * os/: Data.cxx, Data.hxx: depracate bool overlay interface, add - Data::Share interface for overlay - -2003-08-13 13:33 davidb - - * Uri.cxx: share default scheme, avoid temporary Data in + - -2003-08-13 13:33 davidb - - * TransportSelector.cxx: use clear rather than "" assign - -2003-08-13 13:33 davidb - - * Transport.cxx: check Via exists - -2003-08-13 13:32 davidb - - * TimerQueue.cxx: remove Inserter include - -2003-08-13 13:32 davidb - - * SipStack.hxx: comment fix - -2003-08-13 13:32 davidb - - * SipMessage.cxx: check Vias exists - -2003-08-13 13:31 davidb - - * HeaderTypes.hxx: cosmetic - -2003-08-13 13:31 davidb - - * DnsResolver.cxx: avoide temporary Data in + - -2003-08-13 13:06 davidb - - * TransactionMap.cxx: remove include Inserter - -2003-08-13 13:05 davidb - - * Security.cxx: commented out reference to SSL_ERROR_WANT_ACCEPT - -2003-08-13 13:05 davidb - - * SdpContents.hxx: defined getMediumConnectionsm getEncryption - -2003-08-13 13:04 davidb - - * SdpContents.cxx: defined getConnections - -2003-08-13 13:03 davidb - - * Helper.cxx: check header exists - -2003-08-13 12:22 jason - - * Dialog.cxx, Dialog.hxx: added makeRequest - -2003-08-13 11:01 fluffy - - * os/DnsUtil.cxx: compile on Mac OSX - -2003-08-13 10:34 fluffy - - * Security.cxx: better error generation - -2003-08-13 10:33 fluffy - - * TlsTransport.cxx: added output of who peer is - -2003-08-13 10:32 fluffy - - * Contents.cxx: removed second content transfer encoding output - -2003-08-13 09:49 fluffy - - * test/.cvsignore: updated - -2003-08-13 09:49 fluffy - - * os/: Socket.cxx, Socket.hxx: added call no make blocking - -2003-08-13 09:45 fluffy - - * test/Makefile: [no log message] - -2003-08-13 08:38 jason - - * Uri.cxx, ParserCategories.cxx: better debug on parse fail - -2003-08-13 08:38 jason - - * X_msMsgsInvite.cxx: fix bug in parsing of X_msMsgsInvite - -2003-08-12 11:39 jason - - * SipStack.cxx: optimization of isMyDomain - -2003-08-10 03:21 wensong - - * ChangeLog, Makefile.am: [no log message] - -2003-08-09 14:27 jason - - * StatelessHandler.cxx: delete before invalidating iterator (fixed - crash on win32) - -2003-08-09 14:19 jason - - * os/: Log.cxx, Log.hxx, Logger.hxx: added simple file-based - logging - -2003-08-08 19:04 wensong - - * ChangeLog, Makefile.am, config.hxx.in: [no log message] - -2003-08-08 01:33 wensong - - * Makefile.am: [no log message] - -2003-08-08 01:00 wensong - - * ChangeLog, Makefile.am: [no log message] - -2003-08-07 23:15 wensong - - * Makefile.am: [no log message] - -2003-08-07 22:53 wensong - - * ChangeLog, Makefile.am: [no log message] - -2003-08-07 13:50 jason - - * Makefile, os/DnsUtil.cxx, os/DnsUtil.hxx: added simple DnsUtil - class - -2003-08-07 09:20 jason - - * os/HashMap.hxx: define a simple hash function for pointers - -2003-08-07 09:19 jason - - * UdpTransport.cxx: added debug in error case - -2003-08-07 09:18 jason - - * TcpTransport.cxx: reindent - -2003-08-07 09:18 jason - - * SipStack.hxx: make some virtual functions - -2003-08-07 01:17 wensong - - * ChangeLog, TcpTransport.cxx: [no log message] - -2003-08-06 09:25 jason - - * Executive.cxx, Makefile, SipStack.cxx, SipStack.hxx, - StatelessHandler.cxx: added support for stateless proxies - -2003-08-06 09:15 jason - - * SipMessage.hxx: add support for getDestination setDestination - -2003-08-05 08:48 jason - - * TransportSelector.cxx: don't pop the route in the - TransportSelector - this is a TU function - -2003-08-05 08:47 jason - - * GenericContents.cxx: fix assignment - -2003-08-01 01:17 wensong - - * ChangeLog, Makefile.am: [no log message] - -2003-07-28 19:29 jason - - * os/Log.hxx: [no log message] - -2003-07-28 19:29 jason - - * os/Log.cxx: added toType - -2003-07-28 18:55 jason - - * os/.cvsignore: [no log message] - -2003-07-28 18:55 jason - - * UdpTransport.cxx: add debug - -2003-07-28 18:53 jason - - * SipStack.cxx: make it more eficient - -2003-07-28 03:50 jason - - * DnsResolver.cxx: reindent but minor fix for stateless proxy - removed dependency on TransactionState - -2003-07-28 03:45 davidb - - * Contents.cxx, Contents.hxx, GenericContents.cxx, - GenericContents.hxx, Makefile, X_msMsgsInvite.cxx, - X_msMsgsInvite.hxx: generic contents - -2003-07-28 03:43 davidb - - * SdpContents.hxx, SipStack.hxx: [no log message] - -2003-07-28 03:05 wensong - - * Security.hxx: [no log message] - -2003-07-27 21:55 wensong - - * ChangeLog, Security.cxx, Security.hxx: [no log message] - -2003-07-27 19:43 jason - - * StatelessHandler.cxx, StatelessHandler.hxx: for stateless proxies - -2003-07-27 19:35 jason - - * Makefile.am: add support for redhat-9.0 - -2003-07-16 14:04 davidb - - * test/torture-test.txt: fixed some whitespace - -2003-07-16 14:04 davidb - - * test/testSpeed.cxx: don't over ride logging level - -2003-07-16 14:03 davidb - - * test/testParserCategories.cxx: added test for quoted and - non-quoted display name in NameAddr. don't like how it works... - -2003-07-16 14:03 davidb - - * test/testData.cxx: test preallocated append - -2003-07-16 14:01 davidb - - * test/SipTortureTests.cxx: empty header still exists - -2003-07-16 14:01 davidb - - * Uri.cxx: comment - -2003-07-16 14:00 davidb - - * Dialog.cxx: copy Routes only if they exist - -2003-07-16 13:59 davidb - - * os/Data.cxx: removed gratuitous assignments to 0 after delete - -2003-07-14 15:49 davidb - - * test/testSdp.cxx: added test with missing colon in bandwidth (b=) - -2003-07-14 15:48 davidb - - * os/ParseBuffer.cxx: added [CRLF] to escapeAndAnnotate for - readability through syslog - -2003-07-14 15:47 davidb - - * SdpContents.cxx: fail on bad bandwith line rather than scan past - end of line (e.g. missing colon) - -2003-07-14 13:52 davidb - - * TransportSelector.cxx: check for Route existance before checking - if empty - -2003-07-07 20:36 ryker - - * Makefile.am: Fix hash generation when the source directory is not - the build directory. - -2003-07-07 15:27 davidb - - * test/testSipMessage.cxx: comma encoding, cleaned up branch - parameters - -2003-07-07 15:23 davidb - - * test/testDataPerformance.cxx: added characater and char* to test - -2003-07-07 15:22 davidb - - * os/ParseBuffer.cxx, test/testData.cxx: replaced a few asserts - with fails - -2003-07-07 15:22 davidb - - * os/Data.cxx: use append for all operator+= adeed invariant assert - to append - -2003-07-07 15:20 davidb - - * SipMessage.cxx: replaced const access throws with asserts - factored HeaderFieldValueList encode calls - -2003-07-07 15:19 davidb - - * ParserContainer.hxx: comma encoding - -2003-07-07 15:16 davidb - - * ParserCategory.hxx: comma encoding const enforcing - -2003-07-07 15:16 davidb - - * ParserCategory.cxx: const enforcing - -2003-07-07 15:16 davidb - - * ParserCategories.hxx: comma encoding StringCategory constructor - against Data - -2003-07-07 15:15 davidb - - * ParserCategories.cxx: StringCategory constructor against Data - -2003-07-07 15:14 davidb - - * HeaderTypes.hxx, Headers.cxx: added comma encoding - -2003-07-07 15:14 davidb - - * HeaderHash.gperf: shortform of Supported - -2003-07-07 15:14 davidb - - * HeaderFieldValueList.cxx, HeaderFieldValueList.hxx: allow - valueless header encode - -2003-07-05 19:28 ryker - - * test/: testEmbedded.cxx, testEmptyHeader.cxx, testSipMessage.cxx: - Fix some clientData in Via headers. - -2003-07-03 14:10 ryker - - * BranchParameter.cxx, BranchParameter.hxx: Implement a const - version of clientData(). - -2003-07-03 13:11 ryker - - * Makefile.am: Teach the new build system how to generate the gperf - hashes. - -2003-07-03 12:07 ryker - - * os/Data.hxx: Document invariant for Data objects with !mMine. - -2003-07-03 09:25 ryker - - * os/Data.cxx: Fix Data mCapacity tracking in two places. - -2003-06-30 16:28 jason - - * TransactionMap.cxx, SipStack.cxx, DnsResolver.cxx: [no log - message] - -2003-06-30 16:27 jason - - * TransactionState.cxx: don't pass ACK to TU again - -2003-06-30 15:00 ryker - - * TransactionState.cxx: Fix two crashes that could happen during an - extremely coordinated attack on a reSIProcate-based SIP element. - -2003-06-30 09:55 ryker - - * torture.txt: torture.txt does not belong in the sources - directory. It is indirectly already in reSIProcate as - resiprocate/test/SipTortureTests.cxx. - -2003-06-26 18:38 ryker - - * test/.cvsignore: Ignore more. - -2003-06-26 18:08 ryker - - * TransactionState.cxx: Fix a crash that happens when a final - response retransmission is received at the INVITE client - transaction *after* the ACK has been sent. - -2003-06-24 18:02 jason - - * TransactionMap.cxx, TransactionState.cxx, TransactionState.hxx: - ryan's memory leak fixes merged in also fixed a problem with CANCEL - transaction cleanup on stack shutdown - -2003-06-24 18:01 jason - - * ShutdownMessage.hxx, SipStack.cxx, SipStack.hxx: simple shutdown - method (not finished yet, but tested) - -2003-06-24 17:56 davidb - - * test/testParserCategories.cxx: test added user param to set of - parameters that are moved to Uri for NameAddr - -2003-06-24 17:56 davidb - - * ParserCategories.cxx: added user param to set of parameters that - are moved to Uri for NameAddr - -2003-06-24 14:11 ryker - - * test/.cvsignore: Ignore more. - -2003-06-24 12:20 ryker - - * TransactionState.cxx: Respond to the TU with a 481 if a CANCEL is - sent down when no corresponding INVITE transaction is known about. - -2003-06-23 10:35 jason - - * Helper.cxx: remove call-id from nonce - -2003-06-23 10:34 jason - - * ParserCategory.cxx: fix initializer - -2003-06-19 19:48 ryker - - * TransactionState.cxx: Fix a large number of stack leaks. - -2003-06-19 09:40 ryker - - * test/: limpc.cxx, testApplicationSip.cxx, testData.cxx, - testDataPerformance.cxx, testDigestAuthentication.cxx, - testEmbedded.cxx, testEmptyHeader.cxx, testLogger.cxx, - testMessageWaiting.cxx, testMultipartMixedContents.cxx, - testParseBuffer.cxx, testPlainContents.cxx, testRandomHex.cxx, - testSdp.cxx, testServer.cxx, testSipFrag.cxx, testSipMessage.cxx, - testSipMessageMemory.cxx, testTcpTransport.cxx, testTimer.cxx, - testUri.cxx: Make sure tests return 0 on successful completion. - -2003-06-19 09:27 ryker - - * test/Makefile.am: Arrange for all tests to be run. Remove tests - appearing to be bogus (note: revisit these). - -2003-06-19 09:07 ryker - - * test/Makefile.am: Define first test to automagically run as an - example of how to do this. - -2003-06-19 09:07 ryker - - * test/testParserCategories.cxx: Return 0 from this test on - completion. - -2003-06-18 17:20 ryker - - * Makefile.am, test/Makefile.am: Get tests working under autoconf. - -2003-06-18 16:08 ryker - - * test/SipTortureTests.cxx: Make this compile. - -2003-06-18 15:50 ryker - - * UnknownHeaderType.cxx, UnknownHeaderType.hxx: Allow creation from - Data in addition to char*. - -2003-06-18 15:46 ryker - - * UdpTransport.cxx: Change log level of message to be consistent - with the TCP transport. - -2003-06-18 15:42 ryker - - * DnsResolver.cxx, TransactionState.cxx: Plug memory leaks. - -2003-06-18 13:26 ryker - - * test/testParserCategories.cxx: Test clientData which was put back - in the branch. - -2003-06-18 13:26 ryker - - * BranchParameter.cxx, BranchParameter.hxx: Put clientData back in - the branch. - -2003-06-17 18:10 davidb - - * Uri.cxx, test/testUri.cxx: GreaterQ correct - -2003-06-17 17:59 davidb - - * SdpContents.cxx: allow codec parse failure -- discard bad codec - -2003-06-17 17:57 davidb - - * Uri.hxx: GreaterQ - -2003-06-17 17:53 davidb - - * Uri.cxx, test/testSdp.cxx: allow codec parse failures -- discard - codec - -2003-06-17 16:17 davidb - - * os/: Data.cxx, Data.hxx: operator<=, operator>= - -2003-06-12 18:40 alan - - * TlsTransport.cxx: Oops forgot to check in USE_SSL changes here. - -2003-06-12 17:07 alan - - * Security.hxx, SipStack.cxx, SipStack.hxx, TlsTransport.cxx, - TransportSelector.cxx, TuIM.cxx, libSipImp.cxx: Made changes to - USE_SSL defines and added typedefs for types when openssl is not - being used. This preserves object sizes between configurations. - This is a "Good Thing". Right Jason? Modified Files: .cvsignore - resiprocate/Security.hxx resiprocate/SipStack.cxx - resiprocate/SipStack.hxx resiprocate/TlsTransport.cxx - resiprocate/TransportSelector.cxx resiprocate/TuIM.cxx - resiprocate/libSipImp.cxx - -2003-06-11 19:37 jason - - * test/testSpeed.cxx: [no log message] - -2003-06-05 15:12 jason - - * os/: Log.hxx, Logger.hxx: added support for log to cerr - -2003-06-05 13:17 ryker - - * UdpTransport.cxx: Fix some really confusing indentation. - -2003-06-04 10:14 ryker - - * Uri.cxx: An even uglier fix is needed for the Sun Forte compiler. - This one was tested with the checked in testUri unit test and it - compiles and works. - -2003-06-04 09:12 ryker - - * Uri.cxx: Hack in a workaround for the Solaris Forte STL - implementation which does not support a list.sort() function taking - a BinaryPredicate. - -2003-06-04 09:09 ryker - - * test/testUri.cxx: Test order irrelevance of unknown parameters. - -2003-06-03 08:55 ryker - - * os/RecursiveMutex.cxx: Hack to make reSIProcate compile with the - Intel C++ compiler. - -2003-06-03 08:15 ryker - - * os/Fifo.hxx: Squash warning produced by the Intel C++ compiler. - -2003-06-02 20:29 ryker - - * os/compat.hxx: Minor cleanup and temporary hack for Solaris - compilation. - -2003-06-02 20:25 ryker - - * config.hxx.in: Get rid of non-reSIProcate specific stuff. - -2003-06-02 20:24 ryker - - * Makefile.am: Install the library build configuration header. - -2003-06-02 14:14 ryker - - * os/: compat.hxx, vmd5.hxx: Remove Sun-specific conditional code - and replace with autoconf probed results. This might just work on - another non-Sun platform too now. - -2003-06-02 14:13 ryker - - * config.hxx.in: Let autoconf find if it exists. - -2003-06-02 13:52 ryker - - * os/: BaseException.hxx, CircularBuffer.hxx, Coders.hxx, - Condition.hxx, CountStream.hxx, Data.hxx, DataStream.hxx, Fifo.hxx, - HashMap.hxx, Inserter.hxx, Lock.hxx, Lockable.hxx, Log.hxx, - Logger.hxx, MD5Stream.hxx, Mutex.hxx, ParseBuffer.hxx, RWMutex.hxx, - Random.hxx, RecursiveMutex.hxx, Socket.hxx, Subsystem.hxx, - SysLogBuf.hxx, SysLogStream.hxx, ThreadIf.hxx, Timer.hxx, - compat.hxx, vmd5.hxx, vthread.hxx: Fix include guards to avoid - macro namespace conflicts. Some of these are just style changes to - make things consistent across the project. - -2003-06-02 13:33 ryker - - * Transport.cxx, config.hxx.in: Ascertain the existence of - at configure-time. This means a platform other than - Solaris that uses this will pick it up too. - -2003-06-02 13:27 ryker - - * OctetContents.hxx, SdpContents.hxx, SendingMessage.hxx, - SipFrag.hxx, SipMessage.hxx, SipSession.hxx, SipStack.hxx, - Subscription.hxx, Symbols.hxx, TcpTransport.hxx, TimerMessage.hxx, - TimerQueue.hxx, TlsTransport.hxx, TransactionMap.hxx, - TransactionState.hxx, TransactionTerminated.hxx, Transport.hxx, - TransportMessage.hxx, TransportSelector.hxx, TuIM.hxx, TuShim.hxx, - TuUa.hxx, UdpTransport.hxx, UnknownHeaderType.hxx, - UnknownParameter.hxx, UnknownParameterType.hxx, Uri.hxx, - XMLCursor.hxx, XPidf.hxx: Fix include guards to avoid macro - namespace conflicts. - -2003-06-02 13:23 ryker - - * DnsResolver.cxx: Fix Sun macro guard so as to compile with the - GNU toolchain too. - -2003-06-02 13:03 ryker - - * Parameter.hxx, ParameterTypeEnums.hxx, ParameterTypes.hxx, - ParseException.hxx, ParserCategories.hxx, ParserCategory.hxx, - ParserContainer.hxx, ParserContainerBase.hxx, Pidf.hxx, - Pkcs7Contents.hxx, PlainContents.hxx, Preparse.hxx, - QopParameter.hxx, QuotedDataParameter.hxx, Registration.hxx, - ReliabilityMessage.hxx, RportParameter.hxx: Fix include guards to - avoid macro namespace conflicts. - -2003-06-02 12:29 ryker - - * Message.hxx, MessageWaitingContents.hxx, MethodTypes.hxx, - MultipartMixedContents.hxx, MultipartSignedContents.hxx: Fix - include guards to avoid macro namespace conflicts. - -2003-06-02 12:23 ryker - - * Executive.hxx, ExistsParameter.hxx, FloatParameter.hxx, - HeaderFieldValue.hxx, HeaderFieldValueList.hxx, HeaderTypes.hxx, - Headers.hxx, Helper.hxx, IntegerParameter.hxx, LazyParser.hxx: Fix - include guards to avoid macro namespace conflicts. - -2003-06-02 12:23 ryker - - * Embedded.hxx: Fix include guards to avoid macro namespace - conflicts. Add license. - -2003-06-02 12:22 ryker - - * DnsResolver.hxx: Add license. - -2003-06-02 12:22 ryker - - * Dialog.hxx: Fix include guards to avoid macro namespace - conflicts. Move license. - -2003-06-02 12:19 ryker - - * ApplicationSip.hxx, BranchParameter.hxx, Connection.hxx, - ConnectionMap.hxx, Contents.hxx, DataParameter.hxx, Dialog2.hxx, - DialogSet.hxx: Fix include guards to avoid macro namespace - conflicts. - -2003-06-02 12:14 ryker - - * Transport.cxx: Make array index const to placate the - Solaris/Forte compiler. - -2003-06-02 12:12 ryker - - * ParserCategory.cxx: Turn a const_iterator into a plain iterator - as the code that followed wasn't really preserving const-ness. - Fixes compile on Solaris/Forte. - -2003-06-02 11:55 ryker - - * SipMessage.hxx: Remove extra trailing semi-colon. Causes a - warning on Solaris/Forte. - -2003-06-02 11:54 ryker - - * ParserCategories.cxx: Quick Solaris portability hack. The right - thing to do, I think, is #if defined(__sun), #define __EXTENSIONS__ - right before #include . - -2003-06-02 09:23 ryker - - * os/RecursiveMutex.cxx: Conditionalise linux-isms to fix - portability to Solaris and OpenBSD. - -2003-06-02 09:22 ryker - - * TransportSelector.cxx, TuIM.cxx, libSipImp.cxx, os/Random.cxx, - test/limpc.cxx, test/testTlsConnection.cxx: Pull in build - configuration header. - -2003-06-02 09:22 ryker - - * Transport.cxx: Fix Solaris port by #including necessary headers. - -2003-06-02 09:18 ryker - - * DnsResolver.cxx, DnsResolver.hxx, Security.cxx, Security.hxx, - SipStack.cxx, SipStack.hxx, TlsTransport.cxx: Pull in build - configuration header. - -2003-06-02 09:15 ryker - - * config.hxx.in: Add guard. - -2003-06-02 09:08 ryker - - * .cvsignore: Ignore more. Sort too. - -2003-06-02 09:06 ryker - - * .cvsignore: Ignore more. - -2003-06-02 09:04 ryker - - * Makefile.am, config.hxx.in: Impound autotools-based build system. - -2003-05-23 15:20 fluffy - - * sipstack.vcproj: gone - -2003-05-23 14:20 fluffy - - * Dialog.cxx, Dialog.hxx, TuIM.cxx: fix bug with dialogs and - registration - -2003-05-23 14:20 fluffy - - * os/Coders.cxx: comopile on windows - -2003-05-23 12:23 fluffy - - * resiprocate.vcproj: gone - -2003-05-23 12:12 fluffy - - * .cvsignore: update - -2003-05-23 12:05 fluffy - - * os/Logger.cxx: compile on windows - -2003-05-23 12:05 fluffy - - * sipstack.vcproj: no message - -2003-05-23 11:50 fluffy - - * Security.cxx, TimerMessage.cxx, TlsTransport.cxx, Transport.cxx, - sipstack.vcproj: compile on windows - -2003-05-20 16:36 ryker - - * test/.cvsignore: Tidy up the .cvsignore file and make it catch - all architectures. - -2003-05-18 18:58 fluffy - - * libSipImp.cxx: compile on mac - -2003-05-16 15:23 jason - - * TransactionState.cxx: debug - -2003-05-16 15:23 jason - - * SipMessage.cxx: throw when trying to compute a tid for a response - -2003-05-08 11:04 davidb - - * BranchParameter.cxx, BranchParameter.hxx, DnsResolver.cxx, - ParserCategory.cxx, ParserCategory.hxx, ParserContainer.hxx, - ParserContainerBase.hxx, RportParameter.hxx, SipMessage.cxx, - SipMessage.hxx: const header accessors - throw if header doesn't - exist, return const header - -2003-05-08 10:49 davidb - - * IntegerParameter.hxx, QuotedDataParameter.hxx, - UnknownParameter.hxx: explicit - -2003-05-08 10:48 davidb - - * HeaderFieldValueList.cxx, HeaderFieldValueList.hxx: added - parsedEmpty -- header field value list may be empty but have parsed - elements - -2003-05-08 10:45 davidb - - * DataParameter.hxx, ExistsParameter.hxx, FloatParameter.hxx: - explicit - -2003-05-07 11:38 jason - - * Dialog.cxx: [no log message] - -2003-05-07 11:14 jason - - * test/testSipMessage.cxx: fix case - -2003-05-07 11:13 jason - - * test/InviteClient.cxx: changed interface - -2003-05-07 11:13 jason - - * Registration.cxx, Registration.hxx, SipSession.cxx, - SipSession.hxx: fix copyright - -2003-05-07 11:12 jason - - * Dialog.cxx, Dialog.hxx: remove interface to - createDialogAsUAC(request, response) fix problems referencing tags - which don't exist throw when no contact - -2003-05-07 11:10 jason - - * Dialog2.hxx: indent - -2003-05-04 20:19 fluffy - - * Security.cxx: fixed include for compile - -2003-05-04 18:45 fluffy - - * libSipImp.cxx: [no log message] - -2003-05-04 18:39 fluffy - - * TuIM.cxx, TuIM.hxx: added support for 200 response to a register - -2003-05-04 18:39 fluffy - - * test/Makefile: SSL debug stuff - -2003-05-04 17:25 fluffy - - * Makefile: add libSipImp - -2003-05-04 17:24 fluffy - - * test/limpc.cxx: more updates - -2003-05-04 17:24 fluffy - - * .cvsignore: mac stuff - -2003-05-04 17:21 fluffy - - * libSipImp.cxx, libSipImp.h: first cut - don't work yet - -2003-05-02 17:55 jason - - * Transport.cxx: probably broke mac again - -2003-05-02 17:54 jason - - * TransportSelector.cxx: fixed bug where topmost route wasn't being - popped before sending - -2003-05-01 14:57 fluffy - - * Security.cxx, Security.hxx, SipStack.cxx, test/limpc.cxx: added - SSL options for security - -2003-05-01 14:19 fluffy - - * Makefile: [no log message] - -2003-05-01 14:18 fluffy - - * os/RecursiveMutex.cxx: compile on mac - -2003-05-01 14:18 rohan - - * Makefile: unf*cked the Makefile (sorry) -r - -2003-05-01 14:14 fluffy - - * Security.cxx, Security.hxx, SipStack.cxx, SipStack.hxx, - test/limpc.cxx: added option to make tls server or client - -2003-05-01 13:44 rohan - - * Makefile: comment out RecursiveMutex.cxx from the Makefile as it - will not compile. - -2003-05-01 12:11 fluffy - - * Security.cxx: [no log message] - -2003-05-01 10:43 fluffy - - * ParserCategory.cxx: changed to not add a tag if the tag is empty - -2003-05-01 08:20 fluffy - - * test/.cvsignore: [no log message] - -2003-05-01 08:19 fluffy - - * ParserCategory.cxx: fixed problem with responses that have no tag - -2003-05-01 07:25 fluffy - - * Transport.cxx: compile on MAC - may have broken on linux - -2003-04-30 21:55 jason - - * Transport.cxx, Transport.hxx: added support for finding ip - address for interface - -2003-04-30 21:54 jason - - * Helper.cxx: remove debug - -2003-04-30 21:54 jason - - * Dialog.cxx, Dialog.hxx: store the dialogId including totag and - fromtag - -2003-04-30 19:04 ryker - - * Makefile: Don't add OctetContents.cxx twice. - -2003-04-30 16:57 fluffy - - * Security.cxx, TransportSelector.cxx: updated - -2003-04-30 16:57 fluffy - - * XPidf.cxx, XPidf.hxx: does not work yet - -2003-04-30 13:35 fluffy - - * Security.cxx, TlsTransport.cxx: fixed some TLS stuff - -2003-04-30 13:10 rjsparks - - * Makefile: Added Ryan's OctetContents - -2003-04-30 13:10 rjsparks - - * SipMessage.cxx: repaired literal string that wasn't terminated - -2003-04-30 12:32 ryker - - * SipMessage.cxx: Only extract contents if contents are available - to be extracted. - -2003-04-30 12:32 ryker - - * Makefile: Build OctetContents. - -2003-04-30 11:32 ryker - - * OctetContents.cxx, OctetContents.hxx, SipMessage.cxx: Return - application/octet-stream instead of NULL pointer when we don't have - a Content-Type defined. - -2003-04-30 08:53 alan - - * TcpTransport.cxx, TlsTransport.cxx, os/Data.cxx, os/Data.hxx, - os/compat.hxx: removed vocal2 references, added T_NAPTR and T_SRV - defines if missing - -2003-04-30 08:03 davidb - - * os/: Logger.cxx, Logger.hxx: fix to new recursive mutex - -2003-04-30 08:02 davidb - - * os/: RecursiveMutex.cxx, RecursiveMutex.hxx: [no log message] - -2003-04-30 06:57 fluffy - - * PlainContents.cxx, Security.cxx, TcpTransport.cxx, - TlsTransport.cxx, os/Log.cxx, test/limpc.cxx: updatged debuggging - info - -2003-04-29 13:22 davidb - - * Makefile, os/Logger.cxx, os/Logger.hxx, test/testLogger.cxx: use - recursive mutex for !NO_DEBUG - -2003-04-29 13:15 davidb - - * os/Mutex.hxx: removed VOCAL comment - -2003-04-26 21:09 fluffy - - * os/Timer.cxx: tried to add mac timer stuff - does not work yet - -2003-04-26 17:35 fluffy - - * DnsResolver.cxx: fixed for symbol being char* - -2003-04-26 17:30 fluffy - - * test/limpc.cxx: no real changes - -2003-04-26 17:30 fluffy - - * os/Socket.hxx: Support for mac - -2003-04-26 17:29 fluffy - - * Symbols.cxx, Symbols.hxx: Changed from Data to char* (Again) - because otherwise have static intializaiton order problems - -2003-04-26 17:28 fluffy - - * test/testSpeed.cxx: [no log message] - -2003-04-26 16:52 fluffy - - * test/limpc.cxx: fix ~ bug - -2003-04-26 16:52 fluffy - - * Security.cxx: added more debug - -2003-04-26 12:30 fluffy - - * test/: Makefile, limpc.cxx: added limpc back in - -2003-04-26 10:16 davidb - - * test/testLogger.cxx: test recursive logging - -2003-04-26 10:15 davidb - - * os/: ThreadIf.cxx, ThreadIf.hxx: typedef thread identifier type - -2003-04-26 10:15 davidb - - * os/: Logger.cxx, Logger.hxx: allow recursive DebugLogs; detect - deadlock in other logs when debug on - -2003-04-26 10:13 davidb - - * os/Log.hxx: indent - -2003-04-25 18:03 davidb - - * test/testSipMessage.cxx: add tests for brief() and auto_ptr a - leak or two - -2003-04-25 18:02 davidb - - * Uri.cxx: pre-allocate Data for getAor() - -2003-04-25 18:01 davidb - - * SipMessage.cxx: pre-allocate Data for brief() - -2003-04-25 18:01 davidb - - * Helper.cxx: pre-allocate a few Data - -2003-04-25 18:00 davidb - - * DnsResolver.cxx: pre-allocate a Data - -2003-04-24 15:02 ryker - - * DnsResolver.cxx: #include for std::auto_ptr. - -2003-04-24 10:43 davidb - - * test/testEmbedded.cxx: passes - -2003-04-24 10:42 davidb - - * Uri.cxx, test/testParserCategories.cxx: canonicalize host in - Uri::getAor() - -2003-04-21 16:03 jason - - * Uri.cxx, test/testParserCategories.cxx: aor for tel uri fixed - parse for tel uri in requri fixed - -2003-04-21 15:44 jason - - * ParserCategories.cxx, Uri.cxx, test/testParserCategories.cxx: - more fixes for tel uri related stuff - -2003-04-21 14:25 jason - - * test/testUri.cxx: added some more tel uri tests - -2003-04-21 14:25 jason - - * Uri.cxx, Uri.hxx: fixed a bug with tel uri parsing, url - comparisons, fromTel fixed again - -2003-04-17 15:20 davidb - - * test/testSipMessage.cxx: corrected empty header tests - -2003-04-17 15:20 davidb - - * SipMessage.cxx: handle empty headers (more or less) gracefully - -2003-04-17 15:18 davidb - - * ParameterTypes.hxx, ParserCategories.hxx: Token is comma - tokenizing - -2003-04-17 13:17 jason - - * TransactionState.cxx: added some debug - -2003-04-17 13:12 alan - - * Preparse.cxx: fixed empty header data handling at end of message - -2003-04-17 13:12 alan - - * test/testSipMessage.cxx: made pretty - -2003-04-17 12:19 jason - - * test/testSipMessage.cxx: added another test - -2003-04-17 09:01 jason - - * TransactionState.cxx: added a log message before asserting - -2003-04-17 08:58 jason - - * test/testSipMessage.cxx: added some tests for Allow-Events - - still fails - -2003-04-17 07:35 jason - - * Headers.hxx, SipMessage.cxx, SipMessage.hxx: fixes for - AllowEvents header - -2003-04-16 21:46 alan - - * doc/static/: Preparse.pdf, Preparse.png, Preparse.ps, - Preparse.svg: updates - -2003-04-16 21:43 alan - - * Preparse.cxx, Preparse.hxx, PreparseDiagnostic.cxx, - test/Makefile, test/testEmptyHeader.cxx: Added new emptyHeader - flag. Added test driver for empty headers. - -2003-04-16 20:34 alan - - * TransactionState.cxx, Preparse.cxx: Updates for empty headers. - Updates for UTF-8 cleanliness. - -2003-04-16 20:32 alan - - * PreparseDiagnostic.cxx: Added new diagnostic support file. - -2003-04-16 14:50 davidb - - * os/: Data.cxx, Data.hxx: prefix is const - -2003-04-14 15:03 ryker - - * Preparse.cxx: Mask off high-ASCII input to the Preparser. - -2003-04-10 10:57 davidb - - * test/testSipMessage.cxx: test for just in time parsing during - comparison of unparsed headers - -2003-04-10 10:56 davidb - - * ParserCategories.cxx: our just in time parser fix was a little - over zealous sufficient to use accessors to ensure parsed - -2003-04-09 20:24 jason - - * ParserCategories.cxx, Uri.cxx, test/testParserCategories.cxx, - test/testUri.cxx: fixed a particularly nasty bug related to just in - time parsing on comparisons - -2003-04-09 13:07 alan - - * doc/static/: Preparse.pdf, Preparse.png, Preparse.svg, - srv-inv-fsm.pdf, srv-inv-fsm.png, srv-inv-fsm.svg, - srv-inv-tree.pdf, srv-inv-tree.png, srv-inv-tree.svg: updates - -2003-04-07 15:41 davidb - - * os/Logger.hxx: pretty - -2003-04-07 15:41 davidb - - * UdpTransport.cxx: indent - -2003-04-07 15:41 davidb - - * SipMessage.cxx: set mContents to 0 after deleting - -2003-04-06 16:50 jason - - * TransactionState.cxx: fix problem with assert(0) when CANCEL - crosses INVITE/200. ignore the timer in this case. changed some - debug - -2003-04-04 20:09 jason - - * TransactionState.cxx: fix retransmissions of invites on client - transaction removed termination event for stateless - -2003-04-04 20:09 jason - - * Helper.cxx: added debug - -2003-04-04 10:48 ryker - - * os/ParseBuffer.cxx: Really fix the parse error printing problem. - -2003-04-04 09:34 ryker - - * os/ParseBuffer.cxx: Fix off by one underflow when formatting - parse error messages. - -2003-04-03 19:23 jason - - * Helper.cxx, Helper.hxx: fix registration methods. this does - change how register works. the way it used to work was always wrong - -2003-04-03 19:22 jason - - * Uri.cxx, Uri.hxx: fixed tel uri conversion to sip: - -2003-04-03 15:58 ryker - - * TransactionState.cxx: If we see a message arrive from the wire - with no Via, drop it. - -2003-04-03 09:56 ryker - - * UdpTransport.cxx: If the preparse machine tells us a message was - fragmented, reset the preparse machine state instead of running off - the rails on the next message. The alternative is to save the - "unpreparsed" bit of the message for concatenation with the next - datagram (not implemented yet). - -2003-04-02 10:58 ryker - - * os/Logger.hxx: cpp knows about #undef, not #undefine. - -2003-04-01 15:00 ryker - - * Helper.cxx: Recover better from being dealt an out of range port - number. - -2003-03-28 18:30 jason - - * DnsResolver.cxx, DnsResolver.hxx, Message.hxx, - ReliabilityMessage.hxx, SipMessage.cxx, SipMessage.hxx, - SipStack.hxx, TimerMessage.cxx, TimerMessage.hxx, - TransactionState.cxx, TransactionState.hxx, - TransactionTerminated.hxx, TransportMessage.hxx: separate client - and server transaction maps to support spirals in a proxy tu - kind - of gross, but necessary - -2003-03-28 13:14 jason - - * ParserCategories.hxx, ParserContainer.hxx, Uri.hxx: [no log - message] - -2003-03-28 12:47 ryker - - * SipMessage.cxx: Permit setContents(0) and interpret that a - "delete contents". - -2003-03-28 12:44 ryker - - * Helper.cxx: Add a default reason phrase for 202 message, - "Accepted". - -2003-03-27 18:47 jason - - * UdpTransport.cxx: close the udp file descriptor on destruction - -2003-03-27 15:53 jason - - * Helper.cxx, Helper.hxx: added fromAor - -2003-03-24 22:33 jason - - * ApplicationSip.cxx, ApplicationSip.hxx, BranchParameter.cxx, - BranchParameter.hxx, Connection.cxx, Connection.hxx, - ConnectionMap.cxx, ConnectionMap.hxx, Contents.cxx, Contents.hxx, - DataParameter.cxx, DataParameter.hxx, Dialog.cxx, Dialog.hxx, - Dialog2.cxx, Dialog2.hxx, DialogSet.cxx, DialogSet.hxx, - DnsResolver.cxx, DnsResolver.hxx, Embedded.cxx, Embedded.hxx, - Executive.cxx, Executive.hxx, ExistsParameter.cxx, - ExistsParameter.hxx, FloatParameter.cxx, FloatParameter.hxx, - HeaderFieldValue.cxx, HeaderFieldValue.hxx, - HeaderFieldValueList.cxx, HeaderFieldValueList.hxx, HeaderHash.cxx, - HeaderHash.hxx, HeaderTypes.cxx, HeaderTypes.hxx, Headers.cxx, - Headers.hxx, Helper.cxx, Helper.hxx, IntegerParameter.cxx, - IntegerParameter.hxx, LazyParser.cxx, LazyParser.hxx, Message.cxx, - Message.hxx, MessageWaitingContents.cxx, - MessageWaitingContents.hxx, MethodHash.cxx, MethodHash.hxx, - MethodTypes.cxx, MethodTypes.hxx, MultipartMixedContents.cxx, - MultipartMixedContents.hxx, MultipartSignedContents.cxx, - MultipartSignedContents.hxx, Parameter.cxx, Parameter.hxx, - ParameterHash.cxx, ParameterHash.hxx, ParameterTypeEnums.hxx, - ParameterTypes.cxx, ParameterTypes.hxx, ParseException.hxx, - ParserCategories.cxx, ParserCategories.hxx, ParserCategory.cxx, - ParserCategory.hxx, ParserContainer.hxx, ParserContainerBase.hxx, - Pidf.cxx, Pidf.hxx, Pkcs7Contents.cxx, Pkcs7Contents.hxx, - PlainContents.cxx, PlainContents.hxx, Preparse.cxx, Preparse.hxx, - QopParameter.cxx, QopParameter.hxx, QuotedDataParameter.cxx, - QuotedDataParameter.hxx, Registration.cxx, Registration.hxx, - ReliabilityMessage.hxx, RportParameter.cxx, RportParameter.hxx, - SdpContents.cxx, SdpContents.hxx, Security.cxx, Security.hxx, - SendingMessage.cxx, SendingMessage.hxx, SipFrag.cxx, SipFrag.hxx, - SipMessage.cxx, SipMessage.hxx, SipSession.cxx, SipSession.hxx, - SipStack.cxx, SipStack.hxx, Subscription.cxx, Subscription.hxx, - Symbols.cxx, Symbols.hxx, TcpTransport.cxx, TcpTransport.hxx, - TimerMessage.cxx, TimerMessage.hxx, TimerQueue.cxx, TimerQueue.hxx, - TlsTransport.cxx, TlsTransport.hxx, TransactionMap.cxx, - TransactionMap.hxx, TransactionState.cxx, TransactionState.hxx, - TransactionTerminated.hxx, Transport.cxx, Transport.hxx, - TransportMessage.hxx, TransportSelector.cxx, TransportSelector.hxx, - TuIM.cxx, TuIM.hxx, TuShim.hxx, TuUa.hxx, UdpTransport.cxx, - UdpTransport.hxx, UnknownHeaderType.cxx, UnknownHeaderType.hxx, - UnknownParameter.cxx, UnknownParameter.hxx, - UnknownParameterType.cxx, UnknownParameterType.hxx, Uri.cxx, - Uri.hxx, XMLCursor.cxx, XMLCursor.hxx, os/BaseException.cxx, - os/BaseException.hxx, os/CircularBuffer.hxx, os/Coders.cxx, - os/Coders.hxx, os/Condition.cxx, os/Condition.hxx, - os/CountStream.cxx, os/CountStream.hxx, os/Data.cxx, os/Data.hxx, - os/DataStream.cxx, os/DataStream.hxx, os/Fifo.hxx, os/HashMap.hxx, - os/Inserter.hxx, os/Lock.cxx, os/Lock.hxx, os/Lockable.hxx, - os/Log.cxx, os/Log.hxx, os/Logger.cxx, os/Logger.hxx, - os/MD5Stream.cxx, os/MD5Stream.hxx, os/Mutex.cxx, os/Mutex.hxx, - os/ParseBuffer.cxx, os/ParseBuffer.hxx, os/RWMutex.cxx, - os/RWMutex.hxx, os/Random.cxx, os/Random.hxx, os/Socket.cxx, - os/Socket.hxx, os/Subsystem.cxx, os/Subsystem.hxx, - os/SysLogBuf.hxx, os/SysLogStream.hxx, os/ThreadIf.cxx, - os/ThreadIf.hxx, os/Timer.cxx, os/Timer.hxx, os/compat.hxx, - os/vmd5.cxx, os/vmd5.hxx, os/vthread.hxx, test/InviteClient.cxx, - test/InviteClient.hxx, test/InviteServer.cxx, - test/InviteServer.hxx, test/Register.cxx, test/Register.hxx, - test/Registrar.cxx, test/Resolver.cxx, test/Resolver.hxx, - test/SipTortureTests.cxx, test/TestSupport.cxx, - test/TestSupport.hxx, test/Transceiver.cxx, test/Transceiver.hxx, - test/digcalc.hxx, test/lg.cxx, test/limpc.cxx, test/test1.cxx, - test/test2.cxx, test/testApplicationSip.cxx, test/testClient.cxx, - test/testCoders.cxx, test/testCountStream.cxx, test/testData.cxx, - test/testDataPerformance.cxx, test/testDataStream.cxx, - test/testDigestAuthentication.cxx, test/testDnsResolver.cxx, - test/testEmbedded.cxx, test/testHash.cxx, - test/testHeaderFieldValueList.cxx, test/testLockStep.cxx, - test/testLogger.cxx, test/testMessageWaiting.cxx, - test/testMultipartMixedContents.cxx, - test/testNameAddrParamExclusions.cxx, - test/testNonInviteClientTx.cxx, test/testNonInviteServerTx.cxx, - test/testParseBuffer.cxx, test/testParserCategories.cxx, - test/testPlainContents.cxx, test/testPreparse.cxx, - test/testRandomHex.cxx, test/testSdp.cxx, test/testServer.cxx, - test/testSimpleLeak.cxx, test/testSipFrag.cxx, - test/testSipMessage.cxx, test/testSipMessageMemory.cxx, - test/testSipStack1.cxx, test/testSipStackInvite.cxx, - test/testSpeed.cxx, test/testTcpTransport.cxx, - test/testThreadIf.cxx, test/testTimer.cxx, - test/testTlsConnection.cxx, test/testTransactionFSM.cxx, - test/testTypes.cxx, test/testUdp.cxx, test/testUri.cxx, - test/testXMLCursor.cxx, test/testpp.cxx: rename namespace to resip - -2003-03-24 15:37 jason - - * test/Makefile: directory reorg to sip/resiprocate, etc. - -2003-03-24 15:30 jason - - * os/Makefile: directory reorg to sip/resiprocate, etc. - -2003-03-24 15:25 jason - - * ApplicationSip.cxx, ApplicationSip.hxx, BranchParameter.cxx, - BranchParameter.hxx, Connection.cxx, Connection.hxx, - ConnectionMap.cxx, ConnectionMap.hxx, Contents.cxx, Contents.hxx, - DataParameter.cxx, DataParameter.hxx, Dialog.cxx, Dialog.hxx, - Dialog2.cxx, Dialog2.hxx, DialogSet.cxx, DialogSet.hxx, - DnsResolver.cxx, DnsResolver.hxx, Embedded.cxx, Executive.cxx, - Executive.hxx, ExistsParameter.cxx, ExistsParameter.hxx, - FloatParameter.cxx, FloatParameter.hxx, HeaderFieldValue.cxx, - HeaderFieldValue.hxx, HeaderFieldValueList.cxx, HeaderHash.cxx, - HeaderTypes.cxx, HeaderTypes.hxx, Headers.cxx, Headers.hxx, - Helper.cxx, Helper.hxx, IntegerParameter.cxx, IntegerParameter.hxx, - LazyParser.cxx, Makefile, Message.cxx, Message.hxx, - MessageWaitingContents.cxx, MessageWaitingContents.hxx, - MethodHash.cxx, MethodTypes.cxx, MultipartMixedContents.cxx, - MultipartMixedContents.hxx, MultipartSignedContents.cxx, - MultipartSignedContents.hxx, Parameter.cxx, Parameter.hxx, - ParameterHash.cxx, ParameterTypeEnums.hxx, ParameterTypes.cxx, - ParameterTypes.hxx, ParseException.hxx, ParserCategories.cxx, - ParserCategories.hxx, ParserCategory.cxx, ParserCategory.hxx, - ParserContainer.hxx, ParserContainerBase.hxx, Pidf.cxx, Pidf.hxx, - Pkcs7Contents.cxx, Pkcs7Contents.hxx, PlainContents.cxx, - PlainContents.hxx, Preparse.cxx, Preparse.hxx, QopParameter.cxx, - QopParameter.hxx, QuotedDataParameter.cxx, QuotedDataParameter.hxx, - Registration.cxx, Registration.hxx, ReliabilityMessage.hxx, - RportParameter.cxx, RportParameter.hxx, SdpContents.cxx, - SdpContents.hxx, Security.cxx, SendingMessage.cxx, - SendingMessage.hxx, SipFrag.cxx, SipFrag.hxx, SipMessage.cxx, - SipMessage.hxx, SipSession.cxx, SipSession.hxx, SipStack.cxx, - SipStack.hxx, Subscription.cxx, Subscription.hxx, Symbols.cxx, - Symbols.hxx, TcpTransport.cxx, TcpTransport.hxx, TimerMessage.cxx, - TimerMessage.hxx, TimerQueue.cxx, TimerQueue.hxx, TlsTransport.cxx, - TlsTransport.hxx, TransactionMap.cxx, TransactionMap.hxx, - TransactionState.cxx, TransactionState.hxx, Transport.cxx, - Transport.hxx, TransportMessage.hxx, TransportSelector.cxx, - TransportSelector.hxx, TuIM.cxx, TuIM.hxx, TuShim.hxx, TuUa.hxx, - UdpTransport.cxx, UdpTransport.hxx, UnknownHeaderType.cxx, - UnknownHeaderType.hxx, UnknownParameter.cxx, UnknownParameter.hxx, - UnknownParameterType.cxx, UnknownParameterType.hxx, Uri.cxx, - Uri.hxx, XMLCursor.cxx, XMLCursor.hxx, os/BaseException.cxx, - os/BaseException.hxx, os/Coders.cxx, os/Coders.hxx, - os/Condition.cxx, os/CountStream.cxx, os/CountStream.hxx, - os/Data.cxx, os/Data.hxx, os/DataStream.cxx, os/Fifo.hxx, - os/Lock.cxx, os/Lock.hxx, os/Log.cxx, os/Log.hxx, os/Logger.cxx, - os/Logger.hxx, os/MD5Stream.cxx, os/MD5Stream.hxx, os/Mutex.cxx, - os/Mutex.hxx, os/ParseBuffer.cxx, os/ParseBuffer.hxx, - os/Random.cxx, os/Random.hxx, os/Socket.cxx, os/Subsystem.cxx, - os/Subsystem.hxx, os/SysLogStream.hxx, os/ThreadIf.cxx, - os/ThreadIf.hxx, os/Timer.cxx, os/Timer.hxx, os/vmd5.cxx, - os/vmd5.hxx, test/InviteClient.cxx, test/InviteClient.hxx, - test/InviteServer.cxx, test/InviteServer.hxx, test/Makefile, - test/Register.cxx, test/Register.hxx, test/Registrar.cxx, - test/Registrar.hxx, test/Resolver.cxx, test/Resolver.hxx, - test/SipTortureTests.cxx, test/TestSupport.cxx, - test/TestSupport.hxx, test/Transceiver.cxx, test/Transceiver.hxx, - test/digcalc.hxx, test/lg.cxx, test/limpc.cxx, test/test1.cxx, - test/test2.cxx, test/testApplicationSip.cxx, test/testClient.cxx, - test/testCoders.cxx, test/testCountStream.cxx, test/testData.cxx, - test/testDataPerformance.cxx, test/testDataStream.cxx, - test/testDigestAuthentication.cxx, test/testDnsResolver.cxx, - test/testEmbedded.cxx, test/testHash.cxx, - test/testHeaderFieldValueList.cxx, test/testLockStep.cxx, - test/testLogger.cxx, test/testMessageWaiting.cxx, - test/testMultipartMixedContents.cxx, - test/testNameAddrParamExclusions.cxx, - test/testNonInviteClientTx.cxx, test/testNonInviteServerTx.cxx, - test/testParseBuffer.cxx, test/testParserCategories.cxx, - test/testPlainContents.cxx, test/testPreparse.cxx, - test/testRandomHex.cxx, test/testSdp.cxx, test/testServer.cxx, - test/testSimpleLeak.cxx, test/testSipFrag.cxx, - test/testSipMessage.cxx, test/testSipMessageMemory.cxx, - test/testSipStack1.cxx, test/testSipStackInvite.cxx, - test/testSpeed.cxx, test/testTcpTransport.cxx, - test/testThreadIf.cxx, test/testTimer.cxx, - test/testTlsConnection.cxx, test/testTransactionFSM.cxx, - test/testTypes.cxx, test/testUdp.cxx, test/testUri.cxx, - test/testXMLCursor.cxx, test/testpp.cxx: directory reorg to - sip/resiprocate, etc. - -2003-03-24 14:42 jason - - * ApplicationSip.cxx, ApplicationSip.hxx, BranchParameter.cxx, - BranchParameter.hxx, Connection.cxx, Connection.hxx, - ConnectionMap.cxx, ConnectionMap.hxx, Contents.cxx, Contents.hxx, - DataParameter.cxx, DataParameter.hxx, Dialog.cxx, Dialog.hxx, - Dialog2.cxx, Dialog2.hxx, DialogSet.cxx, DialogSet.hxx, - DnsResolver.cxx, DnsResolver.hxx, Embedded.cxx, Executive.cxx, - Executive.hxx, ExistsParameter.cxx, ExistsParameter.hxx, - FloatParameter.cxx, FloatParameter.hxx, HeaderFieldValue.cxx, - HeaderFieldValue.hxx, HeaderFieldValueList.cxx, HeaderHash.cxx, - HeaderTypes.cxx, HeaderTypes.hxx, Headers.cxx, Headers.hxx, - Helper.cxx, Helper.hxx, IntegerParameter.cxx, IntegerParameter.hxx, - LazyParser.cxx, Makefile, Message.cxx, Message.hxx, - MessageWaitingContents.cxx, MessageWaitingContents.hxx, - MethodHash.cxx, MethodTypes.cxx, MultipartMixedContents.cxx, - MultipartMixedContents.hxx, MultipartSignedContents.cxx, - MultipartSignedContents.hxx, Parameter.cxx, Parameter.hxx, - ParameterHash.cxx, ParameterTypeEnums.hxx, ParameterTypes.cxx, - ParameterTypes.hxx, ParseException.hxx, ParserCategories.cxx, - ParserCategories.hxx, ParserCategory.cxx, ParserCategory.hxx, - ParserContainer.hxx, ParserContainerBase.hxx, Pidf.cxx, Pidf.hxx, - Pkcs7Contents.cxx, Pkcs7Contents.hxx, PlainContents.cxx, - PlainContents.hxx, Preparse.cxx, Preparse.hxx, QopParameter.cxx, - QopParameter.hxx, QuotedDataParameter.cxx, QuotedDataParameter.hxx, - Registration.cxx, Registration.hxx, ReliabilityMessage.hxx, - RportParameter.cxx, RportParameter.hxx, SdpContents.cxx, - SdpContents.hxx, Security.cxx, SendingMessage.cxx, - SendingMessage.hxx, SipFrag.cxx, SipFrag.hxx, SipMessage.cxx, - SipMessage.hxx, SipSession.cxx, SipSession.hxx, SipStack.cxx, - SipStack.hxx, Subscription.cxx, Subscription.hxx, Symbols.cxx, - Symbols.hxx, TcpTransport.cxx, TcpTransport.hxx, TimerMessage.cxx, - TimerMessage.hxx, TimerQueue.cxx, TimerQueue.hxx, TlsTransport.cxx, - TlsTransport.hxx, TransactionMap.cxx, TransactionMap.hxx, - TransactionState.cxx, TransactionState.hxx, Transport.cxx, - Transport.hxx, TransportMessage.hxx, TransportSelector.cxx, - TransportSelector.hxx, TuIM.cxx, TuIM.hxx, TuShim.hxx, TuUa.hxx, - UdpTransport.cxx, UdpTransport.hxx, UnknownHeaderType.cxx, - UnknownHeaderType.hxx, UnknownParameter.cxx, UnknownParameter.hxx, - UnknownParameterType.cxx, UnknownParameterType.hxx, Uri.cxx, - Uri.hxx, XMLCursor.cxx, XMLCursor.hxx, os/BaseException.cxx, - os/BaseException.hxx, os/Coders.cxx, os/Coders.hxx, - os/Condition.cxx, os/CountStream.cxx, os/CountStream.hxx, - os/Data.cxx, os/Data.hxx, os/DataStream.cxx, os/Fifo.hxx, - os/Lock.cxx, os/Lock.hxx, os/Log.cxx, os/Log.hxx, os/Logger.cxx, - os/Logger.hxx, os/MD5Stream.cxx, os/MD5Stream.hxx, os/Makefile, - os/Mutex.cxx, os/Mutex.hxx, os/ParseBuffer.cxx, os/ParseBuffer.hxx, - os/Random.cxx, os/Random.hxx, os/Socket.cxx, os/Subsystem.cxx, - os/Subsystem.hxx, os/SysLogStream.hxx, os/ThreadIf.cxx, - os/ThreadIf.hxx, os/Timer.cxx, os/Timer.hxx, os/vmd5.cxx, - os/vmd5.hxx, test/InviteClient.cxx, test/InviteClient.hxx, - test/InviteServer.cxx, test/InviteServer.hxx, test/Makefile, - test/Register.cxx, test/Register.hxx, test/Registrar.cxx, - test/Registrar.hxx, test/Resolver.cxx, test/Resolver.hxx, - test/SipTortureTests.cxx, test/TestSupport.cxx, - test/TestSupport.hxx, test/Transceiver.cxx, test/Transceiver.hxx, - test/digcalc.hxx, test/lg.cxx, test/limpc.cxx, test/test1.cxx, - test/test2.cxx, test/testApplicationSip.cxx, test/testClient.cxx, - test/testCoders.cxx, test/testCountStream.cxx, test/testData.cxx, - test/testDataPerformance.cxx, test/testDataStream.cxx, - test/testDigestAuthentication.cxx, test/testDnsResolver.cxx, - test/testEmbedded.cxx, test/testHash.cxx, - test/testHeaderFieldValueList.cxx, test/testLockStep.cxx, - test/testLogger.cxx, test/testMessageWaiting.cxx, - test/testMultipartMixedContents.cxx, - test/testNameAddrParamExclusions.cxx, - test/testNonInviteClientTx.cxx, test/testNonInviteServerTx.cxx, - test/testParseBuffer.cxx, test/testParserCategories.cxx, - test/testPlainContents.cxx, test/testPreparse.cxx, - test/testRandomHex.cxx, test/testSdp.cxx, test/testServer.cxx, - test/testSimpleLeak.cxx, test/testSipFrag.cxx, - test/testSipMessage.cxx, test/testSipMessageMemory.cxx, - test/testSipStack1.cxx, test/testSipStackInvite.cxx, - test/testSpeed.cxx, test/testTcpTransport.cxx, - test/testThreadIf.cxx, test/testTimer.cxx, - test/testTlsConnection.cxx, test/testTransactionFSM.cxx, - test/testTypes.cxx, test/testUdp.cxx, test/testUri.cxx, - test/testXMLCursor.cxx, test/testpp.cxx: change from sip2 to - resiprocate - -2003-03-24 14:40 alan - - * doc/static/README: update - -2003-03-24 14:40 alan - - * doc/static/README: added fancy stuff - -2003-03-24 14:35 alan - - * doc/static/README: testing commit list again - -2003-03-24 14:32 alan - - * doc/static/README: test update - -2003-03-22 13:02 jason - - * test/testSipMessage.cxx: [no log message] - -2003-03-22 11:38 jason - - * SipStack.cxx, TimerQueue.cxx, TransactionState.cxx, - Transport.cxx: remove debugs - -2003-03-22 11:33 jason - - * README: [no log message] - -2003-03-17 13:30 davidb - - * Makefile: oops - -2003-03-17 09:54 davidb - - * Contents.cxx, Contents.hxx, LazyParser.cxx, LazyParser.hxx, - ParserCategories.hxx, ParserCategory.cxx, ParserCategory.hxx, - ParserContainer.hxx, os/ParseBuffer.cxx, os/ParseBuffer.hxx, - test/testParseBuffer.cxx, test/testParserCategories.cxx, - test/testSipMessage.cxx: pass (header) context into ParserBuffer - for message on throw - -2003-03-17 09:52 davidb - - * os/Log.cxx: indent - -2003-03-17 09:52 davidb - - * test/testLogger.cxx: test detect log recursion -- assert rather - than deadlock (will deadlock on WIN32) - -2003-03-17 09:51 davidb - - * os/: ThreadIf.cxx, ThreadIf.hxx: interface to get current thread - id (not in WIN32) - -2003-03-17 09:50 davidb - - * os/: Logger.cxx, Logger.hxx: detect log recursion -- assert - rather than deadlock (noop in WIN32) - -2003-03-17 09:49 davidb - - * os/: BaseException.cxx, BaseException.hxx: add interface to - extract message - -2003-03-17 09:48 davidb - - * Preparse.cxx: simplified debug switching - -2003-03-17 09:48 davidb - - * Helper.cxx, Helper.hxx: added makeRegister interface account for - badly formed authentication header - -2003-03-17 09:46 davidb - - * DataParameter.cxx: do not allow unassigned data parameter e.g. - ttl;transport=tcp - -2003-03-14 12:04 alan - - * ParserCategory.cxx: Made param static (better performance) - -2003-03-13 12:17 ryker - - * TcpTransport.cxx: Make select(2) on TCP connect(2) signal safe. - -2003-03-13 11:32 ryker - - * DnsResolver.cxx, DnsResolver.hxx: That won't work either - as you'd have to mutex lock the ares_channel to avoid bad things if - we go multi-threaded (I didn't know we could but hey). Make - mChannel a non-static member again and find a way to get back to it - from the static DnsResolver member functions. I don't like this - too much but my timetable does not give me the option of rewriting - it from scratch. - -2003-03-13 09:51 ryker - - * DnsResolver.cxx, DnsResolver.hxx: Fix for static ares_channel - being initialised/destroyed in the DnsResolver - constructor/destructor. Change mChannel to a static pointer and - alloc/init it in the DnsResolver constructor only once. No new - static initialisers. - -2003-03-12 22:30 fluffy - - * Security.hxx, sipstack.vcproj: updated - -2003-03-12 21:24 fluffy - - * Security.cxx: compile windows - -2003-03-10 14:24 ryker - - * TcpTransport.cxx: Fix select(2) argument. - -2003-03-10 12:47 ryker - - * DataParameter.cxx: If there is no RHS, just return. Hopefully - whoever picks up the parsing next won't fall over. - -2003-03-10 12:45 ryker - - * TcpTransport.cxx: Make the TCP connect(2) non-blocking and select - for some arbitrary timeout, currently 16*T1. This is still crap - because the whole stack could block for this length of time but - it's better than blocking for a TCP timeout which can be up to - 120s. In the latter (current) case, you never get to try another - transport because 120s > SIP timeout. - -2003-03-10 12:44 ryker - - * TransactionState.cxx, TransactionState.hxx: Fixes to accomodate - updates in DnsResolver. - -2003-03-10 12:43 ryker - - * DnsResolver.cxx, DnsResolver.hxx: Make SRV work a little better - in the face of TCP _and_ UDP transports being available and - restructure a bit to make NAPTR a little easier. - -2003-03-10 12:41 ryker - - * TransportSelector.hxx: Add a findTransport() that takes a - transport type directly in addition to the existing version that - takes a tuple. Make the tuple version forward to this new - findTransport() implementation. Also make DnsResolver a friend. - -2003-03-10 12:38 ryker - - * ParserCategory.cxx: Add Alan's fix for encoding the msgr - parameter in a way MSN can live with. - -2003-03-10 11:26 ryker - - * TransportSelector.cxx: Add a findTransport() that takes a - transport type directly in addition to the existing version that - takes a tuple. Make the tuple version forward to this new - findTransport() implementation. Also make DnsResolver a friend. - -2003-03-10 11:20 ryker - - * PlainContents.cxx, PlainContents.hxx: Add a PlainContents::Empty - static member. - -2003-03-10 11:19 ryker - - * Symbols.hxx: NAPTR-related symbols. - -2003-03-10 10:22 ryker - - * Symbols.cxx: NAPTR-related symbols. - -2003-03-10 10:15 ryker - - * os/Timer.cxx: Check if defined(__PPC__) and select the timer - implementation appropriately. This makes the sip2 stack work on - Linux/PPC. - -2003-03-07 14:50 jason - - * DnsResolver.hxx: turn on ares for linux - -2003-03-07 14:50 jason - - * Dialog.cxx, Dialog.hxx, Dialog2.cxx, Dialog2.hxx, DialogSet.cxx, - DialogSet.hxx, Subscription.cxx, Subscription.hxx, TuShim.hxx, - TuUa.hxx, SipStack.hxx, .cvsignore: [no log message] - -2003-03-06 14:52 davidb - - * ApplicationSip.hxx: added note about static referencing - -2003-03-06 14:49 davidb - - * ApplicationSip.cxx, ApplicationSip.hxx, Makefile, SipFrag.cxx, - SipFrag.hxx, test/Makefile, test/testApplicationSip.cxx: - ApplicationSip (application/sip) preceded SipFrag content-type - -2003-03-05 18:17 davidb - - * Helper.cxx, SipMessage.cxx, SipMessage.hxx: refactored - copyRFC2543TransactionId - -2003-03-05 18:15 davidb - - * BranchParameter.cxx, BranchParameter.hxx: simplified, removed - clientdata - -2003-03-05 18:14 davidb - - * test/: testEmbedded.cxx, testParserCategories.cxx, - testSipMessage.cxx: adjusted for new BranchParameter form - -2003-03-05 18:14 davidb - - * test/testXMLCursor.cxx: added "All OK" output - -2003-03-05 18:12 davidb - - * test/testMessageWaiting.cxx: fixed input strings - -2003-03-05 18:12 davidb - - * test/: test1.cxx, testTcpTransport.cxx: fixed - -2003-03-05 18:11 davidb - - * test/TestSupport.hxx: added SipRawMessage - not used yet - -2003-03-05 18:10 davidb - - * test/SipTortureTests.cxx: remove client data reference - -2003-03-05 18:10 davidb - - * SipStack.hxx: export UnknownParameterType - -2003-03-05 18:09 davidb - - * DataParameter.cxx: upped defaulted parameter access to ErrLog - -2003-03-05 18:07 davidb - - * test/testRandomHex.cxx: correct for change in parameterization by - bytes - -2003-03-05 18:07 davidb - - * test/testParseBuffer.cxx: added boundary condition test for - eof/skipN - -2003-03-05 18:06 davidb - - * os/Random.cxx, os/Random.hxx, test/testDataPerformance.cxx: - parametersized by number of bytes rather than number of digits - -2003-03-05 18:05 davidb - - * os/: ParseBuffer.cxx, ParseBuffer.hxx: skipBackN - -2003-03-03 10:08 davidb - - * HeaderHash.cxx: temporary fix to automated hash bug - -2003-03-03 09:21 jason - - * DataParameter.cxx: added a debug - -2003-02-28 15:41 davidb - - * Transport.cxx: exclude the connection from Transport comparison - and hash - -2003-02-28 15:34 fluffy - - * HeaderHash.cxx, HeaderHash.gperf, Makefile, os/fixupGperf: !rm! - added minor fix for gperf auto making still need to make mktmp - portable infixupGperf - -2003-02-28 13:45 davidb - - * Connection.cxx: deal with preparser state where buffer ends on - Header: - -2003-02-28 13:43 davidb - - * test/testPreparse.cxx: added long message test - -2003-02-28 13:40 davidb - - * Transport.cxx, Transport.hxx: simplified data translation - -2003-02-28 13:37 davidb - - * Headers.hxx: added typedef for Auths - -2003-02-27 01:54 fluffy - - * Helper.cxx, Helper.hxx, TuIM.cxx, test/limpc.cxx: !rm! added 405 - response to TuIM, changed User-Agent header - -2003-02-27 01:28 alan - - * test/Makefile: removed bad test driver from Makefile - -2003-02-26 08:38 ryker - - * DnsResolver.cxx: Remove old comment about memory leak which I - believe is now fixed. See how old comments always become out of - date. - -2003-02-26 06:38 ryker - - * TransactionState.cxx: Fix a memory leak WRT DNS messages. Always - delete the messages after use. - -2003-02-26 06:37 ryker - - * DnsResolver.cxx: Fix a crash if no results are found for an - A/AAAA record lookup. Currently someone can put a pathological - name in a SIP URI and crash the stack. - -2003-02-25 08:33 alan - - * Helper.cxx, Helper.hxx: Added make405 - ------------------------------------------------------------------- - --- - -2003-02-25 08:22 jason - - * SipStack.cxx: [no log message] - -2003-02-25 01:11 jason - - * Helper.cxx: [no log message] - -2003-02-24 21:22 jason - - * Preparse.cxx, .cvsignore: [no log message] - -2003-02-24 21:22 jason - - * Helper.cxx: be more careful about checking for existence of - headers before using them - -2003-02-24 20:40 jason - - * test/testSipMessage.cxx: added test case from radvision interop - at sipit - -2003-02-24 20:40 jason - - * test/TestSupport.cxx: added debug - -2003-02-24 09:50 davidb - - * BranchParameter.cxx: use dot to terminate external tid; allows - internal dashes not a great solution, but gets us past radvision - -2003-02-21 08:32 alan - - * test/: Makefile, SipTortureTests.cxx: updates to - SipTortureTest.cxx - -2003-02-20 15:23 jason - - * BranchParameter.cxx, BranchParameter.hxx: changes to support - spirals - -2003-02-20 15:22 jason - - * TcpTransport.cxx, test/testDigestAuthentication.cxx, - test/testParserCategories.cxx, test/testServer.cxx, - test/testSipMessage.cxx, test/testData.cxx: [no log message] - -2003-02-20 12:33 fluffy - - * Makefile: updated - -2003-02-20 12:33 fluffy - - * test/Makefile: [no log message] - -2003-02-17 14:38 fluffy - - * SdpContents.cxx, SdpContents.hxx: included in windows - -2003-02-17 14:14 davidb - - * SdpContents.cxx, SdpContents.hxx: reordered class declarations - for windows - -2003-02-17 10:38 fluffy - - * XMLCursor.cxx, Security.cxx, Security.hxx: update - -2003-02-16 22:18 fluffy - - * os/.cvsignore, os/util.vcproj, .cvsignore, sipstack.vcproj: - update - -2003-02-16 22:17 jason - - * TransactionState.cxx: fix bug passing message to TU that should - only go to wire - -2003-02-16 19:10 fluffy - - * os/util.vcproj, sipstack.vcproj: made a lib - -2003-02-16 18:34 fluffy - - * os/util.vcproj: no message - -2003-02-16 18:34 fluffy - - * SdpContents.cxx, SdpContents.hxx, TuShim.cxx, XMLCursor.cxx: - remove from windows compile - -2003-02-16 18:11 fluffy - - * SSL.cxx, SSL.hxx: no longer used - -2003-02-16 17:50 fluffy - - * os/util.vcproj: no message - -2003-02-16 15:04 fluffy - - * ParserCategories.cxx: fix to compile in windows - -2003-02-13 19:01 fluffy - - * Dialog2.cxx: [no log message] - -2003-02-13 16:31 fluffy - - * Dialog2.cxx: added a few more member functions. - - -rohan - -2003-02-13 16:30 fluffy - - * TuShim.cxx: wrote a few more methods based on existing - declarations. - - -rohan - -2003-02-13 10:34 davidb - - * test/testData.cxx: added prefix tests - -2003-02-13 10:34 davidb - - * test/testUri.cxx: added tel tests - -2003-02-13 10:34 davidb - - * Symbols.cxx: added = to end of fixed user parameters - don't - match postdfoo - -2003-02-12 15:09 jason - - * Dialog.cxx: truly hideous bug in Dialog::clear() was fixed. was - causing a throw every time clear was called - -2003-02-12 13:24 alan - - * test/testParserCategories.cxx: added verbosity to the test driver - -2003-02-12 12:50 alan - - * ParserCategories.cxx, Uri.cxx, test/testParserCategories.cxx, - test/testUri.cxx: Fixed copy ctor in DateCategory. Fixed encode in - Uri. - -2003-02-12 11:19 jason - - * SipStack.hxx: added Dialog.hxx back in. SipStack.hxx is the only - file that external clients of the stack should have to include - -2003-02-11 21:43 fluffy - - * test/testDnsResolver.cxx: need to #include early - otherwise a bunch of stuff doesn't work. -rohan CVS - ------------------------------------------------------------------- - --- - -2003-02-11 15:27 fluffy - - * TuShim.cxx: Fleshed out logic in TuShim::processResponse - -2003-02-11 14:02 alan - - * SdpContents.cxx, SdpContents.hxx: added accessor for Address - -2003-02-11 11:22 alan - - * SipStack.hxx, TuIM.cxx: Moved include to client - -2003-02-11 11:20 jason - - * MessageWaitingContents.cxx, MessageWaitingContents.hxx: fix to - work with 7960 - -2003-02-11 08:49 davidb - - * Symbols.cxx, Symbols.hxx, Uri.cxx, Uri.hxx, os/Data.cxx, - os/Data.hxx, test/testUri.cxx: conversion from tel to sip uri - Uri::fromTel - -2003-02-10 16:09 davidb - - * Symbols.cxx, Symbols.hxx, Uri.cxx, Uri.hxx, os/Data.cxx, - os/Data.hxx, test/testEmbedded.cxx, test/testParserCategories.cxx, - test/testUri.cxx: separate user parameters from user in Uri. - support tel scheme - -2003-02-10 13:52 alan - - * Preparse.cxx: Fixed Preparser Bug on Linux (PPC) platform - -2003-02-10 11:47 davidb - - * Pidf.cxx, Pidf.hxx, Pkcs7Contents.cxx, Pkcs7Contents.hxx, - SdpContents.cxx, SdpContents.hxx, test/testSdp.cxx: made sure rhs - was cleared in all operator= - -2003-02-10 11:46 davidb - - * os/ParseBuffer.cxx, os/ParseBuffer.hxx, test/testParseBuffer.cxx: - added unsignedInteger parser - -2003-02-10 11:45 davidb - - * Uri.cxx: removed try/catch from Uri::Uri(const Data&) - -2003-02-10 09:32 alan - - * FloatParameter.cxx, Helper.cxx, MessageWaitingContents.cxx, - MultipartMixedContents.cxx, ParserCategories.cxx, - RportParameter.cxx, Uri.cxx, XMLCursor.cxx: oops, backing out eof() - removal - -2003-02-10 09:27 alan - - * FloatParameter.cxx, Helper.cxx, MessageWaitingContents.cxx, - MultipartMixedContents.cxx, ParserCategories.cxx, - RportParameter.cxx, Uri.cxx, XMLCursor.cxx: undoing now redundant - eof() checks. - -2003-02-09 00:00 jason - - * test/testParserCategories.cxx: added a test - -2003-02-09 00:00 jason - - * TransactionState.cxx: added an assert - -2003-02-09 00:00 jason - - * SipStack.cxx: debug - -2003-02-08 23:59 jason - - * SipMessage.cxx: add support for updating rfc2543 tid in response - -2003-02-08 23:59 jason - - * ParserCategory.cxx: fix bug in assignment op - -2003-02-08 23:58 jason - - * SdpContents.cxx: [no log message] - -2003-02-07 19:06 jason - - * test/: SipTortureTests.cxx, testSdp.cxx, testSipMessage.cxx: - update for SdpContents interface - -2003-02-07 19:06 jason - - * Connection.cxx, Pkcs7Contents.cxx, SdpContents.hxx, Security.cxx, - SipFrag.cxx, TuIM.cxx, XMLCursor.cxx, os/Log.hxx: force use of - leading << in log macros - -2003-02-07 19:05 jason - - * ParserCategories.cxx, os/ParseBuffer.cxx, os/ParseBuffer.hxx, - test/testParseBuffer.cxx: implicitly check for out-of-bounds - dereferncing in ParseBuffer - -2003-02-07 10:55 alan - - * Contents.cxx, DataParameter.cxx: intermediary updates for eof() - -2003-02-07 10:55 alan - - * test/testParserCategories.cxx: updates to test driver for output - -2003-02-06 19:01 jason - - * ParserCategories.cxx: fixed bug in auth parser - -2003-02-06 18:49 jason - - * os/: Data.cxx, Data.hxx: weird order of initialization bug fix - -2003-02-06 18:48 jason - - * SdpContents.cxx, SdpContents.hxx: various changes to interface - -2003-02-06 13:47 alan - - * test/testSpeed.cxx: undo accidental checkin - -2003-02-06 13:46 alan - - * DnsResolver.cxx, FloatParameter.cxx, Helper.cxx, - MessageWaitingContents.cxx, MultipartMixedContents.cxx, - ParserCategories.cxx, RportParameter.cxx, SdpContents.cxx, - TimerQueue.cxx, Uri.cxx, XMLCursor.cxx, test/testSpeed.cxx: - ParseBuffer Fixes and valgrind comments - -2003-02-06 10:54 ryker - - * DnsResolver.cxx: Unbreak in case the ares resolver is not being - used. - -2003-02-05 21:10 jason - - * Symbols.cxx, Symbols.hxx: [no log message] - -2003-02-05 14:56 jason - - * os/HashMap.hxx: support for hash_set - -2003-02-05 11:56 ryker - - * SipStack.cxx: Initialise variable before use. - -2003-02-05 11:22 ryker - - * TransactionState.cxx: Keep better track of the "current" notion - in our DNS resolution list. - -2003-02-05 10:36 alan - - * os/Log.cxx: Fixed unsafe argv[0] manipulation -- was crashing - when relative paths used to execute - -2003-02-05 09:49 ryker - - * DnsResolver.cxx, DnsResolver.hxx, TransactionState.cxx, - TransactionState.hxx: Add SRV lookup support. This also involved a - change to the TransactionState to count the number of outstanding - name lookups although this could easily be moved to another place. - - Modified Files: DnsResolver.cxx DnsResolver.hxx - TransactionState.cxx TransactionState.hxx - -2003-02-05 08:23 ryker - - * Symbols.cxx, Symbols.hxx: Add symbols for _sip, _sips, _udp, and - _tcp for use with SRV lookups. - -2003-02-03 19:34 fluffy - - * Dialog2.cxx, Dialog2.hxx, DialogSet.cxx, DialogSet.hxx, Makefile, - Registration.cxx, Registration.hxx, SipSession.cxx, SipSession.hxx, - Subscription.cxx, Subscription.hxx, TuShim.cxx, TuShim.hxx, - TuUa.hxx: added new TU Shim Related stuff - -2003-02-03 16:40 jason - - * BranchParameter.cxx: remove debug - -2003-02-03 16:39 jason - - * Dialog.cxx, Dialog.hxx: remove via - -2003-02-03 16:39 jason - - * TransactionMap.cxx, TransactionMap.hxx, TransactionState.cxx: - terminate stateless transaction rename Tmap::remove to Tmap::erase - -2003-02-01 09:27 davidb - - * os/: ParseBuffer.cxx, ParseBuffer.hxx: added skipToOneOf - -2003-02-01 09:18 davidb - - * os/: Subsystem.cxx, Subsystem.hxx: added SDP - -2003-01-31 17:14 jason - - * Contents.cxx, Contents.hxx, LazyParser.hxx, - MessageWaitingContents.cxx, MultipartMixedContents.cxx, - MultipartMixedContents.hxx, ParserCategory.cxx, ParserCategory.hxx, - Pkcs7Contents.cxx, SipStack.cxx, SipStack.hxx, TransactionMap.cxx, - TransactionMap.hxx, os/Fifo.hxx: memory leaks - -2003-01-31 15:41 jason - - * ConnectionMap.hxx, TcpTransport.cxx, TlsTransport.cxx, - TransactionMap.hxx, Transport.cxx, Transport.hxx, - TransportSelector.cxx, UdpTransport.cxx, os/Data.cxx, os/Data.hxx, - os/HashMap.hxx, os/Inserter.hxx, os/Timer.cxx, os/compat.hxx, - test/testCoders.cxx: intel compiler (icc) compatibility stuff - -2003-01-31 12:58 bko - - * DnsResolver.cxx, os/Data.hxx, os/HashMap.hxx, os/Inserter.hxx, - os/Timer.cxx, os/compat.hxx, test/Resolver.cxx, - test/testCoders.cxx: fixes for FreeBSD / gcc 2.9x compiling - -2003-01-31 12:34 davidb - - * os/ParseBuffer.cxx, os/ParseBuffer.hxx, test/testParseBuffer.cxx: - added skipBackToChar() skipBackChar() bof() // - beginning of file to ParseBuffer Note: skipBackChar() is an inverse - of skipChar -- iterator semantics! this means that pb.position() - will be AT the skipped character - -2003-01-31 12:31 davidb - - * HeaderTypes.hxx, Headers.cxx, IntegerParameter.hxx, - SipMessage.cxx, Uri.cxx, test/testHash.cxx, - test/testParserCategories.cxx, test/testSipMessage.cxx, - test/testTypes.cxx: fixed UNKNOWN = -1 as array index - -2003-01-30 18:15 jason - - * test/: SipTortureTests.cxx, testEmbedded.cxx, .cvsignore: [no log - message] - -2003-01-30 18:14 jason - - * TransactionState.cxx: fix bug with ACK received from wire - -2003-01-30 18:12 jason - - * SipStack.cxx, SipStack.hxx: added interface to specify strict - router - -2003-01-30 18:12 jason - - * SdpContents.cxx, SdpContents.hxx: added empty - -2003-01-30 14:14 bko - - * ParserCategories.cxx: compile fix - -2003-01-28 09:41 jason - - * TransactionState.cxx: ack to 200 from wire doesn't need to create - a transaction, just pass to TU - -2003-01-26 16:13 jason - - * ParserCategories.cxx, ParserCategories.hxx: initialize - DateCategory to current date/time - -2003-01-26 12:54 jason - - * os/Data.cxx, os/Data.hxx, test/testData.cxx: added find and - substr - -2003-01-25 15:39 fluffy - - * os/: Socket.cxx, Socket.hxx, compat.hxx: fixed to compile in - windows. - -2003-01-25 10:32 jason - - * .cvsignore, BranchParameter.cxx, BranchParameter.hxx, Makefile, - SipMessage.cxx, SipMessage.hxx, SipStack.cxx, SipStack.hxx, - TransactionState.cxx, TransactionState.hxx, - TransactionTerminated.hxx, TransportSelector.cxx, - TransportSelector.hxx, os/Timer.cxx, os/Timer.hxx: big overhaul of - Transaction stuff - -2003-01-24 21:51 davidb - - * Headers.hxx, SipMessage.hxx: refined header macros - -2003-01-24 19:56 jason - - * os/: Data.cxx, Data.hxx: put string conversion back in - -2003-01-24 19:44 jason - - * os/Inserter.hxx: solaris compat - -2003-01-24 19:41 jason - - * Executive.cxx: temporary fix for latency problem - -2003-01-24 19:41 jason - - * DataParameter.cxx: added comment - -2003-01-24 19:38 jason - - * Connection.cxx, Connection.hxx, ParameterTypes.cxx, - ParserCategories.cxx, ParserCategory.hxx, TcpTransport.cxx, - Transport.cxx, UdpTransport.cxx, Uri.cxx, test/Resolver.cxx: - solaris compat - -2003-01-24 19:35 jason - - * os/Coders.cxx, os/Condition.cxx, os/Data.cxx, os/Data.hxx, - os/Inserter.hxx, os/Log.cxx, os/Mutex.hxx, os/Socket.cxx, - os/Socket.hxx, os/ThreadIf.cxx, os/compat.hxx, test/testCoders.cxx, - test/testData.cxx, test/testDataStream.cxx: solaris compat - -2003-01-24 12:56 davidb - - * UnknownHeaderType.hxx, UnknownParameterType.hxx: explicit - constructors - -2003-01-24 12:54 davidb - - * ParameterTypes.cxx, ParameterTypes.hxx, ParserCategories.cxx, - ParserCategories.hxx, ParserCategory.cxx, ParserCategory.hxx: - macroized parameters - -2003-01-23 21:16 fluffy - - * ParserCategory.cxx: updated to compile on windows - -2003-01-23 21:07 fluffy - - * ParserCategory.cxx, ParserCategory.hxx: updated to compile on - windows - -2003-01-23 21:07 fluffy - - * os/HashMap.hxx: updated to compile on windows - may have broken - something but hope not - -2003-01-23 18:48 derekm - - * HeaderHash.cxx, Headers.cxx, MethodHash.cxx, ParserCategory.cxx, - ParserCategory.hxx: gperf compiles under linux-hack - decullinized--use #ifndef WIN32 - -2003-01-23 18:47 jason - - * os/BaseException.hxx, os/.cvsignore, os/Condition.cxx, - os/Data.cxx, os/Data.hxx, os/HashMap.hxx, os/ParseBuffer.cxx, - test/testData.cxx, test/testLogger.cxx, test/testParseBuffer.cxx, - test/testThreadIf.cxx: solaris compat - -2003-01-23 18:45 jason - - * TimerQueue.cxx: debug - -2003-01-23 18:44 jason - - * .cvsignore, TODO, Transport.cxx: [no log message] - -2003-01-23 18:44 jason - - * Connection.cxx, Connection.hxx, Security.hxx, Preparse.hxx, - TlsTransport.cxx, Transport.hxx, TransactionMap.cxx, - TransactionMap.hxx: solaris compat - -2003-01-23 18:43 jason - - * DnsResolver.cxx: fix bug with doing 2 dns lookups - -2003-01-23 18:43 jason - - * Helper.cxx: fix bug with failure and 100 responses having totag - -2003-01-23 18:41 jason - - * Uri.cxx: stuff for scheme in aor (not by default) - -2003-01-23 18:41 jason - - * XMLCursor.cxx, XMLCursor.hxx: solaris compat - -2003-01-22 22:59 davidb - - * XMLCursor.cxx: added url to grammar comment - -2003-01-22 22:58 davidb - - * UnknownHeaderType.cxx, UnknownParameterType.cxx: remove spaces - around token before checking against hash - -2003-01-22 22:58 davidb - - * HeaderHash.cxx, Headers.hxx, MethodHash.cxx, ParserCategory.hxx, - SipMessage.cxx, SipMessage.hxx: ifdeffed nasty template tricks - -2003-01-22 20:41 fluffy - - * Headers.hxx, MethodHash.cxx, ParserCategory.cxx, - ParserCategory.hxx: fixed to compile in windows - not a good fix - -2003-01-22 16:54 jason - - * os/: Logger.cxx, Logger.hxx: fix the syslog logger - never worked - before - -2003-01-22 15:18 jason - - * Symbols.cxx, Symbols.hxx: added dot - -2003-01-22 09:24 alan - - * MethodHash.hxx, ParameterHash.hxx, test/testHash.cxx: link fixes - for namespace - -2003-01-21 17:09 alan - - * .cvsignore, HeaderHash.cxx, HeaderHash.gperf, HeaderHash.hxx, - Headers.cxx, Makefile, MethodHash.cxx, MethodHash.gperf, - MethodHash.hxx, MethodTypes.cxx, ParameterHash.cxx, - ParameterHash.gperf, ParameterHash.hxx, ParameterTypes.cxx, - headers.gperf, methods.gperf, parameters.gperf, os/fixupGperf: - automatic gperf upgrades - -2003-01-21 16:55 davidb - - * Contents.cxx, Contents.hxx, Headers.cxx, Headers.hxx, Helper.cxx, - IntegerParameter.cxx, Makefile, MessageWaitingContents.cxx, - MultipartMixedContents.cxx, MultipartSignedContents.cxx, - ParserCategory.cxx, ParserCategory.hxx, QuotedDataParameter.cxx, - SipFrag.cxx, SipMessage.cxx, SipMessage.hxx, TransactionState.cxx, - UnknownHeaderType.cxx, UnknownHeaderType.hxx, - UnknownParameterType.cxx, UnknownParameterType.hxx, XMLCursor.cxx, - test/Makefile, test/SipTortureTests.cxx, - test/testParserCategories.cxx, test/testSipMessage.cxx, - test/testSipMessageMemory.cxx, test/testUri.cxx, - os/BaseException.hxx, os/Data.cxx, os/Data.hxx, os/ParseBuffer.cxx, - os/ParseBuffer.hxx, os/Subsystem.cxx, os/Subsystem.hxx, - test/testData.cxx: unknown/known header/parameter collision - detection XMLCursor, test reworked template approach to headers - macros for header/parameter declaration/definition - ParseBuffer::skipChar() throws on eof - -2003-01-21 11:23 davidb - - * XMLCursor.cxx, XMLCursor.hxx, test/testXMLCursor.cxx: [no log - message] - -2003-01-20 18:25 davidb - - * XMLCursor.cxx, XMLCursor.hxx: [no log message] - -2003-01-19 18:40 fluffy - - * Security.cxx, Security.hxx: updated to compile in windows - -2003-01-19 18:40 fluffy - - * os/: BaseException.cxx, BaseException.hxx: made non pur virtual - - needed so can catch all types - -2003-01-18 22:56 fluffy - - * Helper.cxx: no change - -2003-01-18 20:59 fluffy - - * MultipartSignedContents.cxx, MultipartSignedContents.hxx, - Security.cxx: ghanced getStatiType to be static - -2003-01-18 20:45 fluffy - - * Contents.hxx, MessageWaitingContents.cxx, - MessageWaitingContents.hxx, MultipartMixedContents.cxx, - MultipartMixedContents.hxx, Pidf.cxx, Pidf.hxx, Pkcs7Contents.cxx, - Pkcs7Contents.hxx, PlainContents.cxx, PlainContents.hxx, - SdpContents.cxx, SdpContents.hxx, SipFrag.cxx, SipFrag.hxx: changed - getStaticType to be (duh) static instead of virtual - -2003-01-18 19:59 fluffy - - * Headers.cxx, MultipartMixedContents.cxx: fixed to compile - -2003-01-18 19:45 derekm - - * Uri.cxx: (david) small efficiency issue with concatenating up - address of record - -2003-01-18 09:47 davidb - - * BranchParameter.hxx, Contents.cxx, Contents.hxx, Dialog.cxx, - DnsResolver.cxx, HeaderFieldValueList.hxx, HeaderTypes.hxx, - Headers.cxx, Headers.hxx, ParameterTypeEnums.hxx, - ParameterTypes.cxx, ParameterTypes.hxx, ParserCategories.hxx, - ParserCategory.cxx, ParserCategory.hxx, RportParameter.hxx, - Security.cxx, SipMessage.cxx, SipMessage.hxx, Symbols.cxx, - Symbols.hxx, Transport.cxx, gperfNotes.txt, headers.gperf, - parameters.gperf, test/Transceiver.cxx, - test/testParserCategories.cxx, test/testSipMessage.cxx: changes to - support easy removal of typed headers macros to support writing - headers and parameters - -2003-01-17 21:15 fluffy - - * TuIM.cxx: fixed typo - -2003-01-17 21:13 fluffy - - * Pkcs7Contents.cxx, Pkcs7Contents.hxx, Security.cxx, Security.hxx, - TuIM.cxx, UdpTransport.cxx: integrated lates Contents changes from - David - -2003-01-17 21:12 fluffy - - * MultipartMixedContents.cxx: fixed bug with missing CRLF before - last boundary - -2003-01-17 19:12 jason - - * Dialog.cxx, Helper.cxx: always create a to tag for a response, - for Dialog, override this value with the stored one. - -2003-01-17 19:09 jason - - * DataParameter.cxx: added an assert for empty parameter. - Ultimately this should be a throw but we want to see it in the - applications for now. - -2003-01-16 15:56 kdc - - * TransactionState.cxx: added a 3261 guard around transaction id - update code - -2003-01-16 14:49 kdc - - * SipMessage.cxx: fixed creation of to tag - -2003-01-16 09:01 ryker - - * DnsResolver.cxx: Add some questions in the comments of Via - lookups. - -2003-01-16 08:45 ryker - - * DnsResolver.cxx: Stub in some information about how NAPTR+SRV - should work. - -2003-01-15 21:11 jason - - * Helper.cxx: removed bogus comment - -2003-01-15 18:08 alan - - * DnsResolver.cxx, TransportSelector.cxx: Transport Updates for - 2543 compat - -2003-01-15 15:23 derekm - - * test/SipTortureTests.cxx: fixed some tests...test10 is still odd - -2003-01-15 12:54 jason - - * os/: Data.cxx, Data.hxx: added unsigned int to Data constructors - -2003-01-14 18:30 davidb - - * ParserCategory.cxx, ParserCategory.hxx, TODO, - test/testParserCategories.cxx: typeless parameter interface - -2003-01-14 13:00 ryker - - * os/ParseBuffer.cxx: Update a !dlb! to parse floats that look like - just "1" instead of "1.0". - -2003-01-13 18:29 davidb - - * Connection.cxx, Contents.cxx, Contents.hxx, - MessageWaitingContents.cxx, MultipartMixedContents.cxx, - MultipartMixedContents.hxx, ParserCategories.cxx, Pidf.cxx, - Pidf.hxx, Pkcs7Contents.cxx, PlainContents.cxx, SipMessage.cxx, - test/testMultipartMixedContents.cxx, test/testPlainContents.cxx: - multipart actually works - fixed Mime::operator< - separated - parseHeader and parse - modified Pidf parser to use Data overlay - -2003-01-12 23:15 fluffy - - * os/ParseBuffer.cxx: [no log message] - -2003-01-12 23:15 fluffy - - * Contents.cxx, Contents.hxx, Makefile, MultipartMixedContents.cxx, - MultipartSignedContents.cxx, MultipartSignedContents.hxx, - Pkcs7Contents.cxx, PlainContents.cxx, PlainContents.hxx, - Security.cxx, Security.hxx, SipMessage.cxx, TuIM.cxx: All the - Content stuff is really confused - half of it thinks that it is a - mim message, half of it thinks it is the body part of a mime - message. It is all somewhate broken in the current state. - -2003-01-12 16:50 fluffy - - * Security.cxx, TuIM.cxx, test/limpc.cxx: few fix up in header - outputs - -2003-01-12 16:50 fluffy - - * Pkcs7Contents.cxx: fixed bug in and made it encode headers - -2003-01-12 16:49 fluffy - - * Contents.cxx: fixed bug in output of header - -2003-01-12 15:00 fluffy - - * MultipartMixedContents.cxx, MultipartMixedContents.hxx, - Security.cxx, Security.hxx, SipMessage.cxx, TuIM.cxx: fixed ugly - bug in multipart - sign security currently broken - -2003-01-12 13:23 davidb - - * Helper.cxx: allow specification of port and transport in register - request - -2003-01-12 12:21 fluffy - - * test/SipTortureTests.cxx: [no log message] - -2003-01-12 11:59 fluffy - - * test/SipTortureTests.cxx: added dump for contents type - -2003-01-12 11:37 davidb - - * SipStack.hxx: remove default port from addAlias - -2003-01-12 11:34 fluffy - - * Security.cxx: updated headers for s/mime encrypt stuff - -2003-01-12 11:09 fluffy - - * Pkcs7Contents.cxx, Readme-Complinace.txt, Security.cxx, - SipMessage.cxx: updated headers for s/mime encrypt stuff - -2003-01-11 22:55 fluffy - - * TuIM.cxx, TuIM.hxx, test/SipTortureTests.cxx, test/limpc.cxx: - fixed up expires in contact header paramter - -2003-01-11 20:52 fluffy - - * Readme-Complinace.txt, test/Transceiver.cxx, test/limpc.cxx, - test/test1.cxx: updated - -2003-01-11 19:39 fluffy - - * SipStack.cxx, SipStack.hxx, Transport.hxx, TransportSelector.cxx: - toying with IP instead of hostnames - -2003-01-11 15:24 fluffy - - * Readme-Complinace.txt: update - -2003-01-11 15:22 fluffy - - * Embedded.cxx, HeaderFieldValueList.cxx: fix includes - -2003-01-11 14:20 jason - - * SipStack.cxx, SipStack.hxx: include port in alias for a my domain - -2003-01-10 17:54 alan - - * os/Coders.cxx, os/Data.cxx, test/testCoders.cxx: Coder update - -2003-01-10 17:53 alan - - * ParserCategories.cxx, Symbols.cxx, Symbols.hxx: Added STAR - support to contacts - -2003-01-10 10:21 ryker - - * TransactionState.cxx: Don't change mMsgToRetransmit from INVITE - to ACK in the failure case of a client INVITE transaction (e.g. - 300-699). This causes problems later with respect to the special - case transaction ID for ACK. Instead recreate the ACK message for - each 300-699 retransmission. Ugly but works. - -2003-01-10 08:17 davidb - - * os/Data.cxx: added asserts where char* could be 0 - -2003-01-09 18:51 derekm - - * test/: Makefile, testClient.cxx, testServer.cxx: [no log message] - -2003-01-09 17:30 derekm - - * TODO: [no log message] - -2003-01-09 17:30 derekm - - * Dialog.cxx: removed spurious comment - -2003-01-09 17:30 derekm - - * Connection.cxx, ConnectionMap.cxx, ConnectionMap.hxx, - SipStack.cxx, SipStack.hxx, TcpTransport.cxx, Transport.cxx, - Transport.hxx: fixed bugs in Connection & Transport More efficient - lookup of connections in ConnectionMap SipStack::getHostName() is - now static - -2003-01-08 19:08 jason - - * SipStack.hxx: [no log message] - -2003-01-08 12:45 davidb - - * test/Makefile: remove limp - -2003-01-08 12:44 davidb - - * DataParameter.cxx: indent - -2003-01-08 12:44 davidb - - * TODO: [no log message] - -2003-01-08 12:43 davidb - - * Embedded.cxx, HeaderFieldValueList.cxx, ParserCategories.cxx, - ParserContainer.hxx, SipMessage.cxx, Uri.cxx, - test/testEmbedded.cxx: fixed embedded multiple headers - -2003-01-07 18:42 davidb - - * HeaderTypes.hxx, ParameterTypeEnums.hxx, gperfNotes.txt, - parametersA.gperf: notes and comments about gperf use - -2003-01-07 17:54 derekm - - * HeaderTypes.hxx, Headers.cxx, Headers.hxx, - ParameterTypeEnums.hxx, ParameterTypes.cxx, ParameterTypes.hxx, - ParserCategories.hxx, ParserCategory.cxx, ParserCategory.hxx, - SipMessage.cxx, SipMessage.hxx, Symbols.cxx, Symbols.hxx, - headers.gperf, parameters.gperf, test/testParserCategories.cxx, - test/testSipMessage.cxx: added rfc 3329 headers, parameters - -2003-01-07 10:20 jason - - * TuIM.hxx: [no log message] - -2003-01-06 22:28 davidb - - * TODO, Headers.hxx: [no log message] - -2003-01-06 22:27 davidb - - * Embedded.cxx, Embedded.hxx, HeaderFieldValueList.cxx, - HeaderFieldValueList.hxx, Makefile, ParserContainer.hxx, - ParserContainerBase.hxx, SipMessage.cxx, SipMessage.hxx, - Symbols.cxx, Symbols.hxx, Uri.cxx, Uri.hxx, test/Makefile, - test/testEmbedded.cxx: Uri embedded headers - -2003-01-06 19:46 fluffy - - * MultipartMixedContents.cxx, TuIM.cxx, TuIM.hxx: fixed inti - problems - -2003-01-06 19:46 fluffy - - * os/Random.cxx: fixid init problem - -2003-01-05 11:01 davidb - - * os/ParseBuffer.cxx: fixed skipToChars, skipLWS - -2003-01-05 10:59 davidb - - * os/Data.hxx, os/DataStream.cxx, os/DataStream.hxx, - test/limpc.cxx: added static Data::from template - -2003-01-05 10:58 davidb - - * Contents.cxx, Contents.hxx, LazyParser.cxx, - MessageWaitingContents.cxx, MultipartMixedContents.cxx, - MultipartMixedContents.hxx, ParserCategories.cxx, - ParserContainer.hxx, Pidf.cxx, PlainContents.cxx, SipMessage.cxx, - Symbols.cxx, Symbols.hxx, test/testMessageWaiting.cxx, - test/testMultipartMixedContents.cxx, test/testParserCategories.cxx, - test/testPlainContents.cxx: dealt with content headers being either - in SipMessage headers or part of multipart body - -2003-01-05 08:57 davidb - - * ParserCategories.cxx: StringCategory::parse fix - -2003-01-04 19:49 fluffy - - * TuIM.cxx, TuIM.hxx, test/SipTortureTests.cxx, test/limpc.cxx: - updated for outbound proxy stuff - -2003-01-04 17:19 jason - - * Helper.cxx, Helper.hxx, TransactionState.cxx: refactor - getSentPort and fix bug when no sent port in via - -2003-01-04 17:10 fluffy - - * UdpTransport.cxx: added assert - -2003-01-04 15:20 jason - - * Transport.cxx: use source port only if rport is present, - otherwise use sentPort from via - -2003-01-04 15:20 jason - - * TransactionState.cxx: change Tuple::operator< to use the - Connection* if it exists - -2003-01-04 13:35 jason - - * TransactionState.cxx: fixed the retransmit bug cullen found - -2003-01-04 07:59 fluffy - - * TransactionState.cxx: turned evil hack ErrLog to InfoLog - please - - need to fix what cuases this - -2003-01-04 07:55 fluffy - - * test/limpc.cxx: updated - -2003-01-04 07:55 fluffy - - * SipStack.cxx, SipStack.hxx, TuIM.cxx, TuIM.hxx: moved the - setOutboundProxy - -2003-01-03 22:08 fluffy - - * SipStack.cxx, SipStack.hxx: add outbound proxy api - -2003-01-03 20:59 fluffy - - * os/Data.cxx, os/ParseBuffer.cxx, os/Socket.cxx, os/Socket.hxx, - TcpTransport.cxx, TuIM.cxx, TuIM.hxx, UdpTransport.cxx, Uri.cxx: - fix bugs to do with error recovery - -2003-01-02 23:31 fluffy - - * os/Data.cxx, os/Data.hxx, os/compat.hxx, TcpTransport.cxx, - TlsTransport.cxx: windows ports for min/max stuff - -2003-01-02 18:25 fluffy - - * Dialog.cxx, DnsResolver.cxx, Helper.cxx, TransportSelector.cxx, - TuIM.cxx, test/limpc.cxx: few formatting changes - -2003-01-02 15:27 derekm - - * test/SipTortureTests.cxx: unknown scheme test had invalid auth - param - -2003-01-02 15:26 derekm - - * test/limpc.cxx: added template method as stopgap to stream - -2003-01-02 15:25 derekm - - * SipStack.hxx: fixed merge - -2003-01-02 15:25 derekm - - * os/Socket.hxx: spelling - -2003-01-02 15:24 derekm - - * test/: Transceiver.cxx, test1.cxx, test2.cxx, - testDnsResolver.cxx, testLockStep.cxx, testSipStack1.cxx, - testSpeed.cxx, testTcpTransport.cxx: selectMilliseconds calls are - now passed milliseconds - -2003-01-02 15:23 derekm - - * Uri.cxx, Uri.hxx: added getOpaque method to retrieve contents of - absolute URI -- non standard schemes no longer result in an - exception - -2003-01-02 15:22 derekm - - * TcpTransport.cxx, TlsTransport.cxx, Transport.cxx, os/compat.hxx: - added min, max to compat - - used where appropriate - -2003-01-02 13:27 jason - - * test/: SipTortureTests.cxx, raw-tests.txt: added some more - torture tests - -2003-01-02 13:27 jason - - * SipStack.hxx: added some interface comments - -2003-01-02 13:26 jason - - * SipStack.cxx, test/testDnsResolver.cxx, test/torture-test.txt: - [no log message] - -2003-01-01 22:57 fluffy - - * Security.cxx: update - -2003-01-01 21:48 fluffy - - * TuIM.cxx, TuIM.hxx: caugh ugly bug with fail loop - -2003-01-01 19:25 fluffy - - * Security.cxx, TuIM.cxx, TuIM.hxx, test/limpc.cxx: turned an - assertion into an error - -2003-01-01 19:02 fluffy - - * Dialog.cxx, LazyParser.cxx, ParserCategories.cxx, SipStack.cxx: - few assertions - -2003-01-01 19:00 fluffy - - * TransactionState.cxx: cullen checked in hack change - is likely - wrong and shoudl be removed - -2003-01-01 18:59 fluffy - - * Security.cxx, Security.hxx, TuIM.cxx, TuIM.hxx, test/limpc.cxx, - test/testIM.cxx: changed some assertions to pass up error instead - -2002-12-31 20:03 fluffy - - * Security.cxx, TlsTransport.cxx, os/Log.hxx, os/Random.cxx: - windows port - -2002-12-31 18:15 fluffy - - * test/: Makefile, limpc.cxx: [no log message] - -2002-12-31 17:18 fluffy - - * Executive.cxx, Security.cxx, Security.hxx, SipStack.cxx, - TcpTransport.cxx, TlsTransport.cxx, Transport.cxx, Transport.hxx, - TransportSelector.cxx, TransportSelector.hxx, TuIM.cxx, TuIM.hxx, - UdpTransport.cxx, Uri.cxx, test/limpc.cxx, test/testIM.cxx: general - clean up of bits - -2002-12-31 11:58 fluffy - - * DnsResolver.cxx, Executive.cxx, TcpTransport.cxx, TimerQueue.cxx, - TimerQueue.hxx, TlsTransport.cxx, Transport.cxx, Transport.hxx, - UdpTransport.cxx, UdpTransport.hxx, test/limpc.cxx: fixed nast bug - that cause select to always return - -2002-12-31 10:41 fluffy - - * Executive.cxx, Executive.hxx, SipStack.cxx, SipStack.hxx, - Transport.cxx, TuIM.cxx, TuIM.hxx, os/Log.hxx, os/Socket.hxx, - test/Transceiver.cxx, test/limpc.cxx, test/test1.cxx, - test/test2.cxx, test/testDnsResolver.cxx, test/testIM.cxx, - test/testLockStep.cxx, test/testSipStack1.cxx, test/testSpeed.cxx, - test/testTcpTransport.cxx, test/testSipStack1.cxx: changed time - signatures - -2002-12-30 22:10 fluffy - - * TlsTransport.cxx: [no log message] - -2002-12-30 22:05 fluffy - - * test/: .cvsignore, testIM.cxx: [no log message] - -2002-12-30 22:04 fluffy - - * Connection.cxx, Connection.hxx, ConnectionMap.cxx, - ConnectionMap.hxx, Makefile, Security.cxx, TcpTransport.cxx, - TlsTransport.cxx, TransportSelector.cxx, test/Makefile: refactored - some of the socket code out of the connection class - -2002-12-30 18:50 fluffy - - * DnsResolver.cxx, DnsResolver.hxx, os/Socket.cxx, test/Makefile: - added USE_ARES for ARES stuff - -2002-12-29 19:52 fluffy - - * TlsTransport.cxx: windows fix ups - -2002-12-29 19:27 fluffy - - * Connection.cxx, ConnectionMap.cxx, Security.cxx, Security.hxx, - SipStack.cxx, TcpTransport.cxx: windows fixes - -2002-12-23 16:14 jason - - * DnsMessage.cxx, DnsMessage.hxx, DnsResolver.cxx, DnsResolver.hxx, - Executive.cxx, Executive.hxx, Makefile, TransactionState.cxx, - TransactionState.hxx, test/.cvsignore, test/Makefile, - test/testDnsResolver.cxx, Transport.cxx: moved to using ares lib on - linux for async dns no more support for partial results from dns - queries still uses ares_gethostbyname, needs to support the general - dns result - -2002-12-23 16:13 jason - - * TransportSelector.cxx: [no log message] - -2002-12-23 16:13 jason - - * HeaderTypes.hxx: reordered headers according to rfc - -2002-12-23 15:53 jason - - * os/Socket.hxx: make members public for async dns - -2002-12-23 12:49 fluffy - - * os/Log.hxx: mess with ERR definition - -2002-12-23 12:46 fluffy - - * test/limpc.cxx: no - -2002-12-23 10:04 alan - - * doc/Makefile: added rules for old diagrams - -2002-12-22 14:04 fluffy - - * SipStack.cxx: fixed includes for RH compile - -2002-12-22 13:21 fluffy - - * ConnectionMap.cxx, Pidf.cxx, Uri.cxx, Uri.hxx: few windows fixes - -2002-12-22 12:12 davidb - - * ParserCategories.cxx: added encode parameters to Token::encode, - String::encode - -2002-12-22 07:44 fluffy - - * Connection.cxx, SipFrag.cxx, TcpTransport.cxx, TuIM.cxx, - TuIM.hxx, os/Data.hxx, SipStack.cxx, SipStack.hxx: update to - compile in wind woes - -2002-12-21 22:30 fluffy - - * Dialog.cxx, Pidf.cxx, TuIM.cxx: got resubscriptiongs flowing and - added pidf parse - -2002-12-21 19:15 fluffy - - * Makefile, Pidf.cxx, Pidf.hxx, TuIM.cxx, TuIM.hxx: added PIDF mime - type - -2002-12-21 16:20 fluffy - - * Dialog.cxx, Helper.cxx, TuIM.cxx, TuIM.hxx, UdpTransport.cxx, - os/Timer.cxx, test/testIM.cxx: updates for TuIM sub/notify stuff - -2002-12-21 13:28 fluffy - - * Dialog.cxx, Dialog.hxx, Helper.cxx, Helper.hxx, TuIM.cxx, - TuIM.hxx, os/Timer.cxx, os/Timer.hxx, test/Register.cxx, - test/testIM.cxx, test/testSipMessage.cxx, test/testSpeed.cxx, - test/testTlsConnection.cxx: updating dialog and helper stuff - -2002-12-20 16:36 alan - - * Makefile: added makefile opt - -2002-12-20 16:35 alan - - * test/Makefile: include opts - -2002-12-20 16:19 ryker - - * SipMessage.cxx, SipMessage.hxx, SipStack.cxx, SipStack.hxx: Get - rid of the FixedDest part of SipMessage. It would have been nice - if the author had mentioned this during the list discussion. The - mTarget version is almost the same except it takes Uri types - instead of Data. It is thought that this is better as the rest of - the stack is plugged into it and you may need more than just the - hostname, e.g. the scheme to indicate that the target must be - contacted over TLS. - -2002-12-20 14:32 alan - - * os/Makefile, test/testCoders.cxx: Makefile - -2002-12-20 12:02 jason - - * RportParameter.cxx: output value if set - -2002-12-20 11:03 jason - - * DnsResolver.cxx, os/compat.hxx: moved compatibility stuff into - compat.hxx - -2002-12-20 11:02 jason - - * Helper.cxx: [no log message] - -2002-12-20 11:02 jason - - * Connection.cxx, Transport.cxx, Transport.hxx, UdpTransport.cxx: - refactored received= and rport= code - -2002-12-20 09:53 ryker - - * Helper.cxx, Helper.hxx, SipMessage.cxx, SipMessage.hxx, - TransportSelector.cxx: Implement the notion of a forced target to a - SipMessage with accessor functions. In the TransportSelector this - target is used if it exists, otherwise loose routing rules are - applied. The routes/request-uri rotation magic can be done with - Helper::processStrictRoute(). - -2002-12-20 08:22 kdc - - * TcpTransport.cxx, TlsTransport.cxx, UdpTransport.cxx: changed int - to socklen_t to fix gcc3.2 compile errors - -2002-12-19 23:56 fluffy - - * DnsResolver.cxx, TcpTransport.cxx, TlsTransport.cxx, - UdpTransport.cxx, os/Timer.cxx, os/compat.hxx, test/Resolver.cxx, - test/testTlsConnection.cxx, test/testTransactionFSM.cxx, - os/.cvsignore, test/.cvsignore: compile on mac os 10 - -2002-12-19 10:32 ryker - - * Dialog.cxx: Dialog::makeResponse() was choking with an assert if - the request came with a To: tag already. This happens with - Re-INVITE, for example, so only attempt to generate a To: tag if - there isn't already one present. - -2002-12-18 16:49 alan - - * os/HashMap.hxx: fixed extra defined() test - -2002-12-18 09:21 kdc - - * Dialog.cxx, Dialog.hxx: reverted changes to makeBye - -2002-12-17 16:26 jason - - * Connection.cxx, DnsResolver.cxx, Makefile, ParameterTypes.hxx, - ParserCategory.cxx, RportParameter.cxx, RportParameter.hxx, - UdpTransport.cxx, test/Transceiver.cxx, - test/testParserCategories.cxx: refactored rport param to support - both ;rport and ;rport=value - -2002-12-17 13:45 ryker - - * SdpContents.cxx: Fix parsing of bandwith line of SDP. - -2002-12-17 11:54 ryker - - * os/HashMap.hxx: Correct syntax error. - -2002-12-17 10:06 jason - - * UdpTransport.cxx, test/Makefile: [no log message] - -2002-12-17 10:05 jason - - * os/Data.cxx, os/HashMap.hxx, os/Timer.cxx, Security.cxx, - TuIM.cxx, TuIM.hxx, Uri.hxx: added intel compiler stuff - -2002-12-16 17:46 fluffy - - * test/testIM.cxx: few changes - -2002-12-16 14:51 kdc - - * Dialog.cxx, Dialog.hxx: fixed makeBye - -2002-12-16 12:45 fluffy - - * Security.cxx: fixed compile bug on older versions of OPENSSL - -2002-12-16 12:07 jason - - * TlsTransport.cxx, TlsTransport.hxx: compilation issues - -2002-12-16 12:03 jason - - * ConnectionMap.cxx, ConnectionMap.hxx, TcpTransport.cxx, - TcpTransport.hxx: separate Connection from ConnectionMap - -2002-12-16 12:03 jason - - * TransactionState.cxx, TransactionState.hxx: for Server - transaction, always reply to source (from SipMessage) - -2002-12-16 12:02 jason - - * Transport.cxx, Transport.hxx: added Connection* to Tuple - -2002-12-16 12:01 jason - - * TransportSelector.cxx, TransportSelector.hxx: change constness - (temporary change) - -2002-12-16 12:01 jason - - * test/testLockStep.cxx: [no log message] - -2002-12-16 12:01 jason - - * test/SipTortureTests.cxx: added a torture test(2) - -2002-12-16 12:00 jason - - * SipMessage.cxx: fixes to copy constructor - -2002-12-16 12:00 jason - - * DnsResolver.hxx: added NoLookupRequired - -2002-12-16 11:58 jason - - * Connection.cxx, Connection.hxx, Makefile: separated Connection - from ConnectionMap - -2002-12-16 11:37 derekm - - * ParserCategories.cxx, Uri.cxx, test/testUri.cxx: uri::parse now - parses parameters - -2002-12-16 10:27 derekm - - * SipMessage.cxx, SipMessage.hxx: added create timestamp - -2002-12-15 14:46 fluffy - - * test/testIM.cxx: switched back to UDP - -2002-12-15 14:30 fluffy - - * TlsTransport.cxx: update toc compile - does not work - should be - thrown out once TCP is done - -2002-12-15 14:26 fluffy - - * test/: Makefile, testIM.cxx: updated for TLS - -2002-12-15 14:26 fluffy - - * Makefile, TlsTransport.cxx, TlsTransport.hxx, - TransportSelector.cxx: added Tls transport placeholder class - -2002-12-15 14:25 fluffy - - * DnsResolver.cxx: updatted for sips and tls con - -2002-12-15 14:24 fluffy - - * Security.cxx, Security.hxx: [no log message] - -2002-12-15 12:10 fluffy - - * TcpTransport.cxx: removed one debug message - -2002-12-15 12:09 fluffy - - * test/testIM.cxx: TCP version - -2002-12-15 11:45 fluffy - - * test/: testUri.cxx, Makefile: [no log message] - -2002-12-14 21:06 davidb - - * Contents.cxx, Contents.hxx: added headers to Contents -- closer - to recursive contents - -2002-12-14 21:05 davidb - - * os/ParseBuffer.cxx, os/ParseBuffer.hxx, test/testParseBuffer.cxx: - deal with LWS in ParseBuffer, some tests - -2002-12-14 16:04 fluffy - - * TuIM.cxx, TuIM.hxx: updated buddy stuff - -2002-12-14 15:36 fluffy - - * test/testIM.cxx: add press callback - -2002-12-14 15:36 fluffy - - * MultipartMixedContents.cxx: fixed include to compile - -2002-12-14 15:16 fluffy - - * TuIM.cxx, TuIM.hxx: update API - -2002-12-14 15:16 fluffy - - * os/Socket.hxx: fix compiel warnings - -2002-12-14 12:03 davidb - - * Symbols.cxx, Symbols.hxx: parse symbols as Data, others used in - static init - -2002-12-14 12:03 davidb - - * PlainContents.cxx: don't need pb.reset() - -2002-12-14 11:57 davidb - - * Uri.cxx: use efficient ParseBuffer::data - -2002-12-14 11:55 davidb - - * Contents.cxx, Contents.hxx, MultipartMixedContents.cxx, - MultipartMixedContents.hxx, Security.cxx, Symbols.cxx, Symbols.hxx, - os/Data.hxx, os/Random.cxx, test/Makefile, - test/testMultipartMixedContents.cxx, test/testPlainContents.cxx: - second swipe at MultipartMixedContents -- not there yet - -2002-12-14 11:26 fluffy - - * TimerQueue.cxx, UdpTransport.cxx: update for windows - -2002-12-14 11:26 fluffy - - * test/testIM.cxx: update - sort of works in windows other than bug - that reading from stdin is blocking - -2002-12-14 11:10 fluffy - - * test/testIM.cxx: general messing around - -2002-12-14 10:51 jason - - * TimerQueue.cxx, TimerQueue.hxx, test/Makefile, - test/testTimer.cxx: added TimerQueue::msTillNextTimer() - -2002-12-14 10:43 fluffy - - * DnsResolver.cxx, Executive.cxx, TimerQueue.cxx, TimerQueue.hxx, - TransactionState.cxx, TransportSelector.cxx, TuIM.cxx, - UdpTransport.cxx, test/testIM.cxx, test/testParserCategories.cxx, - test/testSpeed.cxx: general messing around - -2002-12-14 10:43 fluffy - - * os/Socket.cxx: fixed windwos blocking bug - -2002-12-14 09:04 fluffy - - * Symbols.cxx, Symbols.hxx: switch symbols back to char* instead of - Data. This is becuase of initailizor order bug. The headers rely on - symbold being initialized before they are ther is no way to enforce - this Synbols needthere initalizeors to run - -2002-12-14 09:03 fluffy - - * TransactionState.cxx, TransportSelector.cxx: catch weird DNS erro - -2002-12-14 09:03 fluffy - - * Preparse.cxx: make work either symbvol type - -2002-12-14 09:02 fluffy - - * Makefile: add HeaderTypes - -2002-12-14 09:02 fluffy - - * HeaderTypes.cxx: remove duplicat junk - -2002-12-14 09:02 fluffy - - * BranchParameter.cxx: make work either type of symbol - -2002-12-13 18:19 derekm - - * ConnectionMap.cxx, Dialog.cxx, Executive.cxx, SipMessage.cxx, - SipMessage.hxx, UdpTransport.cxx, test/TestSupport.cxx: SipMessage - no longer has a SipMessage(bool) constructor -- this caused - problems because a pointer was convertable to a bool..use - SipMessage::FromWire, SipMessage::NotFromWire(the default) instead - - Fixes to dialog. - -2002-12-13 16:53 derekm - - * ConnectionMap.cxx, DnsResolver.cxx, Executive.cxx, - ReliabilityMessage.hxx, TcpTransport.cxx, TransportMessage.hxx, - UdpTransport.cxx, os/Socket.cxx, os/Socket.hxx: more tcp transport - fixes--snapshot of a work in progress changed Executive::process - loop to only call process once on the transports - - sockets are now made non-blocking after connect, so the connects - are blocking--avoids some book keeping - -2002-12-13 10:47 jason - - * Dialog.cxx: [no log message] - -2002-12-12 22:52 fluffy - - * ConnectionMap.cxx: change *1.5 to *3/2 - -2002-12-12 22:47 fluffy - - * test/: SipTortureTests.cxx, testSpeed.cxx: no message - -2002-12-12 21:52 jason - - * ConnectionMap.cxx, TcpTransport.cxx: [no log message] - -2002-12-12 21:51 jason - - * ParserCategories.hxx: added some explicits - -2002-12-12 19:34 derekm - - * ConnectionMap.cxx, TcpTransport.cxx, TransportSelector.cxx: fixed - a couple of bugs added tcp transportSelector - -2002-12-12 19:12 derekm - - * test/testTcpTransport.cxx: [no log message] - -2002-12-12 19:02 derekm - - * ConnectionMap.cxx, ConnectionMap.hxx, Preparse.cxx, - TcpTransport.cxx, TcpTransport.hxx, Transport.cxx, os/Socket.hxx, - test/testPreparse.cxx, test/testTcpTransport.cxx: tcpTransport is - almost complete various tests& bug fixes removed CritLog from - preParser - -2002-12-12 10:01 fluffy - - * doc/: FifoFlow.pdf, FifoFlow.vsd: no message - -2002-12-11 22:44 jason - - * SipStack.hxx, Security.cxx, Security.hxx, - test/testTlsConnection.cxx: [no log message] - -2002-12-11 22:21 fluffy - - * SSL.cxx, SSL.hxx: removed - -2002-12-11 22:15 fluffy - - * ConnectionMap.cxx: fixed a type - -2002-12-11 19:52 derekm - - * os/Data.hxx: Data::size_type is now size_t - -2002-12-11 19:51 derekm - - * ConnectionMap.cxx, ConnectionMap.hxx, SipFrag.cxx, - TcpTransport.cxx, Transport.hxx, UdpTransport.hxx, test/Makefile, - test/TestSupport.cxx, test/testTcpTransport.cxx: wrote - ConnectionMap::Connection. - - Transport no longer has a preparser--UdpConnection has one, each - ConnectionMap::Connection has one - - tests, fixed some include problems that resulted from the above - -2002-12-11 18:33 jason - - * Helper.cxx: added makeCancel helper - -2002-12-11 14:34 kdc - - * Contents.cxx: fixed copy constructor - -2002-12-11 12:48 derekm - - * ParserCategory.cxx: removed : - - cerr << endl; - -2002-12-11 12:20 jason - - * SipMessage.cxx, SipMessage.hxx, TransactionState.cxx, - TransactionState.hxx: implement support for rfc2543 compatibility - for transactionId - used to match the transaction for requests - coming from 2543 sip elements - -2002-12-11 12:18 jason - - * UdpTransport.cxx: minor reorg of debuglog related to EWOULDBLOCK - -2002-12-11 12:15 jason - - * TODO: [no log message] - -2002-12-10 23:17 jason - - * TransactionMap.cxx: support for adding a second entry that maps - to the same pointer - -2002-12-10 23:16 jason - - * ParserCategory.cxx, ParserCategory.hxx: added - commutativeParameterHash for comparing two lists of parameters - -2002-12-10 23:15 jason - - * os/Data.cxx, os/Data.hxx, test/testData.cxx: added exclusive or - operation for data operator^= - -2002-12-10 19:08 fluffy - - * test/testSpeed.cxx: no message - -2002-12-10 10:53 jason - - * os/: Subsystem.cxx, Subsystem.hxx: added some new subsystems for - debugging purposes - -2002-12-10 10:49 fluffy - - * UdpTransport.cxx: fix bug I put in - -2002-12-10 10:36 jason - - * ConnectionMap.cxx, DnsResolver.cxx, SipMessage.cxx, SipStack.hxx, - TcpTransport.cxx, TimerQueue.cxx, TransactionMap.cxx, - TransactionState.cxx, Transport.cxx, TransportSelector.cxx, - UdpTransport.cxx: added some new subsystems for debugging purposes - -2002-12-09 21:11 fluffy - - * BranchParameter.cxx: changed to use a random number for the - branch - -2002-12-09 21:11 fluffy - - * Preparse.cxx, Preparse.hxx: formatting changes - -2002-12-09 21:11 fluffy - - * UdpTransport.cxx: sort out erros - -2002-12-09 21:11 fluffy - - * os/: Log.cxx, Log.hxx, Logger.hxx: fix to work in windows - -2002-12-09 18:28 jason - - * test/testSipMessage.cxx: added test case with copy of a request - and compare request methods - -2002-12-09 18:27 jason - - * test/testParserCategories.cxx: added test with status line reason - phrase - -2002-12-09 18:27 jason - - * Helper.cxx, SipMessage.cxx, SipMessage.hxx: rework how - transaction id is computed for rfc2543 endpoints added an interface - to set the rfc2543 transactionId in the SipMessage - -2002-12-09 18:25 jason - - * UdpTransport.cxx: removed debugs - -2002-12-09 18:24 jason - - * TransactionState.cxx: fixed problem with cancel state machine - debug changes re-indent - -2002-12-09 18:23 jason - - * SipStack.cxx: fix problem adding alias debug changes - -2002-12-09 18:23 jason - - * ParserCategories.cxx: fixed statusline decoder removed some debug - -2002-12-09 16:32 fluffy - - * test/testSdp.cxx: fixed compile bug - -2002-12-09 13:53 fluffy - - * test/testThreadIf.cxx: fixed compile bug - -2002-12-09 11:28 derekm - - * os/Data.cxx, os/Data.hxx, os/MD5Stream.cxx, os/MD5Stream.hxx, - test/testDigestAuthentication.cxx: md5stream is a real stream - - Data no returns lower case hex from hex(), which is necesary for - md5 to work. If upper case hex is needed somewhere we need two - methods. - -2002-12-08 19:13 jason - - * os/Condition.cxx: minor debug changes - -2002-12-08 19:12 jason - - * os/Log.cxx: fix toLevel - -2002-12-08 19:10 jason - - * os/Subsystem.hxx: allow Subsystem to be subclassed - -2002-12-08 19:06 jason - - * Transport.cxx: remove debug output - -2002-12-08 19:04 jason - - * Security.cxx: fix compilation error on gcc 3.2 (const problem) - -2002-12-08 19:04 jason - - * DnsResolver.cxx: comment out debug output - -2002-12-07 01:22 fluffy - - * Pkcs7Contents.cxx, Pkcs7Contents.hxx: addes suppor for signed - type - -2002-12-07 01:21 fluffy - - * Security.cxx, Security.hxx: upgrade to beta version of openssl - -2002-12-06 23:49 fluffy - - * TransactionMap.cxx, TransactionMap.hxx: fixed member data name - -2002-12-06 23:48 fluffy - - * test/testIM.cxx: switched to just encrypt - -2002-12-06 23:47 fluffy - - * Security.cxx, Security.hxx, TuIM.cxx: added stuff to manage other - people public keys - -2002-12-06 23:46 fluffy - - * ParserCategories.cxx, ParserCategory.cxx, PlainContents.cxx: - fixed MIME and paramter parsing - -2002-12-06 23:46 fluffy - - * Uri.cxx, Uri.hxx: added getAorNoPOrt - -2002-12-06 23:43 fluffy - - * os/Data.cxx: reduce mem realloc on esacped stuff - -2002-12-06 19:24 derekm - - * os/Log.cxx, os/Log.hxx, os/Logger.hxx, os/Makefile, - test/testLogger.cxx, test/testThreadIf.cxx: Logger now has - thread-level "service" level settings. Won't work on windows yet. - - some tests for ThreadIf some 'tests' for logging -- not complete - -2002-12-06 17:21 derekm - - * test/: testDigestAuthentication.cxx, testParserCategories.cxx: - [no log message] - -2002-12-06 17:09 derekm - - * ParserCategories.cxx, ParserCategories.hxx: fixed copy - constructor - -2002-12-06 13:47 fluffy - - * test/testDigestAuthentication.cxx: added incldue for auto_ptr - -2002-12-06 12:49 derekm - - * os/ThreadIf.cxx: [no log message] - -2002-12-05 22:19 davidb - - * ParserCategories.cxx: implemented NameAddr(const Uri&) - -2002-12-05 19:51 jason - - * os/ThreadIf.hxx: allow subclasses of ThreadIf to access member - vars - -2002-12-05 19:50 jason - - * SipStack.hxx, .cvsignore: [no log message] - -2002-12-05 19:50 jason - - * Helper.cxx: added an default implementation of makeCancel - -2002-12-05 19:39 derekm - - * SdpContents.cxx, SdpContents.hxx, SipMessage.cxx, SipMessage.hxx, - test/testSdp.cxx, test/testSipMessage.cxx: sdp interface has - changed to allow assembly--still a work/design in progress. - attributes are now multi, so getValue returns a list - - new tests, some fixes to encode. - -2002-12-05 19:35 derekm - - * Helper.cxx, Helper.hxx: changed paramter name from - encodedPassword to password, as its not encoded - -2002-12-05 17:33 derekm - - * os/Makefile, os/ThreadIf.cxx, os/ThreadIf.hxx, - test/testThreadIf.cxx: added - - ThreadIf::waitForShutdown(int ms) const - - which causes the thread to sleep for the specified# of ms, but will - wakeup and return true if shutdown is called. Returns false if the - sleep finished w/out shutdown being called. - - shutdown&join are now called in the destructor. it is now ok to - call join multiple times, nothing happens if there isn't an active - thread. - -2002-12-05 08:51 fluffy - - * IntegerParameter.cxx: fixed windows compile warning - -2002-12-04 21:36 davidb - - * Preparse.cxx, Symbols.cxx, Symbols.hxx, os/ParseBuffer.cxx, - os/ParseBuffer.hxx, test/testParseBuffer.cxx: all Symbols now Data - -- impacted ParseBuffer interface - -2002-12-04 21:35 davidb - - * BranchParameter.cxx, Contents.cxx, Contents.hxx, - MessageWaitingContents.cxx, MultipartMixedContents.cxx, - MultipartMixedContents.hxx, Pkcs7Contents.cxx, PlainContents.cxx, - SdpContents.cxx, Security.hxx, SipFrag.cxx, - test/testPlainContents.cxx, test/testSipMessage.cxx: Contents must - be constructed with the leaf Mime contents type - -2002-12-04 20:38 davidb - - * os/: ParseBuffer.cxx, ParseBuffer.hxx: added skipToChars -- scan - for string - -2002-12-04 20:36 davidb - - * SipMessage.cxx: body => contents - -2002-12-04 20:35 davidb - - * Contents.cxx, Contents.hxx, LazyParser.hxx, Makefile, - MessageWaitingContents.cxx, MessageWaitingContents.hxx, - MultipartMixedContents.cxx, MultipartMixedContents.hxx, - Pkcs7Contents.cxx, Pkcs7Contents.hxx, PlainContents.cxx, - PlainContents.hxx, SdpContents.cxx, SdpContents.hxx, Security.cxx, - SipFrag.cxx, SipFrag.hxx: added multipart/mixed changed to - getStaticType() -- getType() returns Mime plus parameters - -2002-12-04 17:02 derekm - - * os/Random.cxx: removed Logs in static initialization - -2002-12-04 12:46 derekm - - * test/: Makefile, digcalc.hxx, md5.cxx, md5.hxx, - testDigestAuthentication.cxx: digest authentication tests--checks - against rfc 2617 implementation - -2002-12-04 12:44 derekm - - * Helper.cxx, Helper.hxx, Makefile, ParserContainer.hxx, - Symbols.cxx, Symbols.hxx, parameters.gperf, os/Data.cxx, - os/Data.hxx, os/MD5Stream.cxx, os/MD5Stream.hxx, os/Makefile: added - digest authentication helpers, only for md5, qop auth or none - supported changed Data::hex to output lowercase const_iterator on - ParserContainer added MD5Stream -- should be used instead of - concatenating Datas - -2002-12-03 15:55 ryker - - * TransactionState.cxx: Reuse the INVITE DNS query results for - CANCEL in the client transaction case. RFC 3261 says that the - CANCEL MUST be sent to an identical destination address, port, and - transport. - -2002-12-03 12:21 ryker - - * TransactionState.cxx: Correct very misleading debugging - statement. - -2002-12-03 11:44 ryker - - * TransactionState.cxx: - Added a bit of debugging, namely warn - about unhandled msgs to transactions. - Made the CANCEL - transaction work. This involved a fair bit of work to reconcile - the overlapping transaction ids for INVITE and CANCEL. I had to - make sure the non-INVITE routines were called for the CANCEL - version of each transaction. - -2002-12-03 09:10 ryker - - * TransactionState.cxx: In the INVITE client transaction, Timer B - only applies in the Calling state. - -2002-12-03 09:02 ryker - - * SipMessage.cxx: Whoops... back out the last change as Derek did - something equivalent already. - -2002-12-03 08:57 ryker - - * SipMessage.cxx: Always print a Content-Length header at the end - of the headers section. - -2002-12-02 17:05 derekm - - * Dialog.cxx, Headers.cxx, Headers.hxx, SipMessage.cxx, - SipMessage.hxx: auth headers are mostly multi - -2002-12-02 15:43 derekm - - * test/Makefile: commented out testTcpTransport - -2002-12-02 15:43 derekm - - * test/testSipMessage.cxx: added construction test; test - Content-Length encoding - -2002-12-02 15:42 derekm - - * os/: Random.cxx, Random.hxx, Timer.cxx: static initialization; - removed DebugLog in static initializers - -2002-12-02 15:41 derekm - - * os/DataStream.cxx: flush on desctruction - -2002-12-02 15:41 derekm - - * os/Data.cxx: using character version of +=, reduced initial size - in escaped - -2002-12-02 15:35 derekm - - * SipMessage.cxx: encode Content-Length even if the header doesn't - exist - -2002-12-02 15:31 derekm - - * BranchParameter.cxx, BranchParameter.hxx, DataParameter.cxx, - DataParameter.hxx, ExistsParameter.cxx, ExistsParameter.hxx, - FloatParameter.cxx, FloatParameter.hxx, IntegerParameter.cxx, - IntegerParameter.hxx, ParameterTypeEnums.hxx, ParserCategories.cxx, - ParserCategories.hxx, ParserCategory.cxx, QopParameter.cxx, - QopParameter.hxx, QuotedDataParameter.cxx, QuotedDataParameter.hxx, - test/testParserCategories.cxx: re-factored terminating characters - in Parameter parsing added auth parameters - -2002-12-02 11:48 kdc - - * SdpContents.hxx: added const to getSession() fixed Bandwith - spelling error - -2002-12-01 12:33 fluffy - - * Security.hxx, TuIM.cxx, test/testIM.cxx: fix to compile on - windows - -2002-11-30 23:06 fluffy - - * test/testIM.cxx: updated - -2002-11-30 22:40 fluffy - - * Security.cxx, Security.hxx, TuIM.cxx, TuIM.hxx, test/testIM.cxx: - refactored security interface - -2002-11-30 21:18 fluffy - - * MessageWaitingContents.cxx: [no log message] - -2002-11-30 21:07 fluffy - - * Contents.cxx, Contents.hxx, MessageWaitingContents.hxx, - Pkcs7Contents.cxx, Pkcs7Contents.hxx, PlainContents.cxx, - PlainContents.hxx, SdpContents.cxx, SdpContents.hxx, Security.cxx, - Security.hxx, SipFrag.cxx, SipFrag.hxx, Symbols.cxx, Symbols.hxx, - TransactionState.cxx, TuIM.cxx, test/testIM.cxx: many changes for - SMIME stuff - -2002-11-30 21:06 fluffy - - * os/Data.cxx: fixed bug zero len stuff - -2002-11-30 15:04 fluffy - - * Security.cxx, os/Data.cxx: few changes - -2002-11-30 12:57 fluffy - - * Pkcs7Contents.cxx, Security.cxx, Security.hxx, test/testIM.cxx: - updated and removed hard coded cert paths - -2002-11-30 12:56 fluffy - - * Contents.hxx, Message.cxx, Transport.cxx, TransportSelector.cxx, - UdpTransport.cxx: made debug prints be escaped data - -2002-11-30 12:56 fluffy - - * os/: Data.cxx, Data.hxx: addec escaped function and fixed but in - constructor - -2002-11-30 10:22 fluffy - - * BranchParameter.cxx, SipMessage.cxx, Symbols.cxx: changed branch - tag creation to reduce odds of transaction id conflict - -2002-11-29 20:42 fluffy - - * Pkcs7Contents.cxx, Security.cxx: changed to do the binary PKCS7 - format instead of SMIME - -2002-11-29 20:30 fluffy - - * Makefile, Pkcs7Contents.cxx, Pkcs7Contents.hxx, Security.cxx, - Security.hxx, TuIM.cxx, test/testIM.cxx: very basic sign and verify - working - -2002-11-29 20:29 fluffy - - * PlainContents.cxx: fixed extra CRLF bug - -2002-11-29 10:36 fluffy - - * LazyParser.cxx, PreparseInlines.cxx, SdpContents.cxx, - SdpContents.hxx, SipStack.cxx, TuIM.cxx, UdpTransport.cxx, - test/testSpeed.cxx: compile and sort of work in windows - -2002-11-29 10:35 fluffy - - * os/: Condition.cxx, Data.cxx, Random.cxx: compile and work in - windows - -2002-11-29 00:56 fluffy - - * test/: Makefile, testSpeed.cxx: added speed test program - -2002-11-29 00:56 fluffy - - * Dialog.cxx, Dialog.hxx: create from just a response instead of - requiring request too - -2002-11-29 00:55 fluffy - - * Executive.cxx: noted bug - -2002-11-29 00:55 fluffy - - * SipMessage.cxx: made breif more useful - -2002-11-29 00:54 fluffy - - * os/Timer.hxx: added code to get cpuSpeed - -2002-11-29 00:54 fluffy - - * os/.cvsignore, test/.cvsignore: ingnore otehr directories - -2002-11-28 15:29 ryker - - * TransactionState.cxx: Don't delete mCancelStateMachine when a - TransactionState is deleted. mCancelStateMachine is another - TransactionState that holds a new CANCEL transaction FSM. I think - this is bad design and we should create an mCancelStateMachine-like - object free of a host TransactionState. - -2002-11-28 13:01 ryker - - * Makefile: Add new file to compile list. - -2002-11-28 12:48 alan - - * test/testSdp.cxx: testSdp -- added reporting - -2002-11-28 09:12 ryker - - * os/Data.hxx: Make isLessThanNoCase() work. - -2002-11-28 08:51 alan - - * Makefile: Added entry for QopParameter - -2002-11-27 19:49 jason - - * ParserContainer.hxx: added stuff for stl algorithms - -2002-11-27 19:49 jason - - * ParserCategories.cxx, ParserCategories.hxx: added operator< for - Token added accessor to wildcard for NameAddr - -2002-11-27 19:39 derekm - - * DataParameter.hxx, ParameterTypeEnums.hxx, ParameterTypes.cxx, - ParameterTypes.hxx, ParserCategories.cxx, QopParameter.cxx, - QopParameter.hxx, QuotedDataParameter.cxx, QuotedDataParameter.hxx, - Symbols.cxx, Symbols.hxx: working on auth parsercategory not - finished...but all of the tests passed. - -2002-11-27 17:19 jason - - * Helper.cxx, Helper.hxx: added interface for authentication added - makeUri from aor - -2002-11-27 17:19 jason - - * SipStack.cxx, SipStack.hxx: added isMyDomain() method - -2002-11-27 17:19 jason - - * UdpTransport.cxx: added comment that inet_ntoa is not reentrant - -2002-11-27 17:19 jason - - * os/: Data.cxx, Data.hxx: added Data::substr method - -2002-11-27 17:09 alan - - * test/SipTortureTests.cxx: Fixed Some test cases. Improved - Reporting. Checked for completion. - -2002-11-27 17:09 alan - - * test/tassert.h: Added better reporting features. - -2002-11-27 17:08 alan - - * Preparse.cxx: Cleaned up debugging. Made it possible to turn - on/off at runtime. - -2002-11-27 17:07 alan - - * ParserCategories.cxx: Removed exception based expires parser -- - changed to logic test - -2002-11-27 16:09 derekm - - * test/testParserCategories.cxx: [no log message] - -2002-11-27 16:09 derekm - - * BranchParameter.cxx: fixed...didn't terminate paramater parse - correctly - -2002-11-27 12:31 alan - - * test/.cvsignore: removed tassert.h - -2002-11-27 11:42 kdc - - * SipMessage.cxx: fixed up some contents stuff - -2002-11-27 11:38 derekm - - * test/testSipMessage.cxx: [no log message] - -2002-11-27 11:37 derekm - - * test/SipTortureTests.cxx: removed false negative from - SipTortureTests - -2002-11-27 11:37 derekm - - * HeaderTypes.hxx, Headers.cxx, Headers.hxx, Symbols.cxx, - Symbols.hxx, headers.gperf: added more headers to the GPerf(most of - the new ones are mapped to unknown) - - added AllowEvent, Event as real headers - -2002-11-26 14:15 derekm - - * ParserCategories.cxx, ParserCategories.hxx: fixed operator < for - Mime fixed accessors for Mime - -2002-11-26 13:46 alan - - * TuIM.cxx: removed ^M s and added a bunch of ^J s. Darned DOS - people :-P :-) - -2002-11-26 13:37 alan - - * test/: TestSupport.cxx, TestSupport.hxx: initial impound - -2002-11-26 13:37 alan - - * test/testPreparse.cxx: ported to new interface changed diagnostic - calls to use TestSupport - -2002-11-26 13:37 alan - - * test/: testNonInviteClientTx.cxx, testSipFrag.cxx, - testSipMessage.cxx, testSipMessageMemory.cxx, - testTransactionFSM.cxx: ported makeMessage to new location - -2002-11-26 13:37 alan - - * test/: testIM.cxx, testSipStackInvite.cxx, testTcpTransport.cxx: - removed unused include - -2002-11-26 13:37 alan - - * test/test2.cxx: increased loop count - -2002-11-26 13:37 alan - - * test/SipTortureTests.cxx: Fixed typos in messages - -2002-11-26 13:37 alan - - * test/Makefile: Added TestSupport - -2002-11-26 13:37 alan - - * SipFrag.cxx, UdpTransport.cxx: updated preparse interface - -2002-11-26 13:37 alan - - * PreparseInlines.cxx: inline Preparse routines - -2002-11-26 13:37 alan - - * Preparse.hxx: cleanup of straggling private types new interface - for process() new routines - -2002-11-26 13:37 alan - - * Preparse.cxx: moved diagnostic output routines to - test/TestSupport removed complex interface and added functions for - status reporting - -2002-11-26 13:37 alan - - * Makefile: added inline switch for Preparse inline functions - -2002-11-26 13:37 alan - - * Helper.cxx, Helper.hxx: removed makeMessage() -- put in - test/TestSupport - -2002-11-26 12:13 davidb - - * Contents.cxx, Contents.hxx, MessageWaitingContents.cxx, - MessageWaitingContents.hxx, PlainContents.cxx, PlainContents.hxx, - SdpContents.cxx, SdpContents.hxx, SipFrag.cxx, SipFrag.hxx, - SipMessage.cxx, test/testMessageWaiting.cxx, - test/testPlainContents.cxx, test/testSdp.cxx: creating Contents - against HFV and now Mime instance (for parameters) - -2002-11-26 10:13 davidb - - * TuIM.cxx, TuIM.hxx, test/testIM.cxx: used PlainContents as - intended - -2002-11-26 10:05 davidb - - * Contents.cxx, Contents.hxx: access Contents via getContents() -- - allows wrappers like signed, encrypted access Contents via - getContents(cinst Mime&) -- null if not given Mime type - -2002-11-26 10:03 davidb - - * test/: Makefile, testPlainContents.cxx: [no log message] - -2002-11-26 10:02 davidb - - * PlainContents.cxx, PlainContents.hxx: fluffed (de-fluffed?) up - PlainContents - -2002-11-25 21:27 fluffy - - * Makefile, PlainContents.cxx, PlainContents.hxx, SipMessage.cxx, - TuIM.cxx, test/Makefile, test/SipTortureTests.cxx, test/testIM.cxx: - Updated to use new Content class for body stuff for TuIM - -2002-11-25 18:28 davidb - - * test/: testSipFrag.cxx, Makefile: [no log message] - -2002-11-25 18:28 davidb - - * LazyParser.cxx, LazyParser.hxx, Makefile, - MessageWaitingContents.cxx, MessageWaitingContents.hxx, - ParserCategories.cxx, ParserCategories.hxx, ParserCategory.hxx, - ParserContainer.hxx, SdpContents.cxx, SdpContents.hxx, SipFrag.cxx, - SipFrag.hxx, SipMessage.cxx, Uri.cxx, Uri.hxx: changed encode to - encodeParsed in subclasses of lazyParser--lazyParser now has a - non-virtual parse - - added sipFrag - -2002-11-25 14:12 ryker - - * os/Data.hxx: Add isLessThanNoCase(). - -2002-11-25 12:15 davidb - - * test/.cvsignore: [no log message] - -2002-11-25 12:14 davidb - - * test/: testMessageWaiting.cxx, testSdp.cxx, testSipMessage.cxx: - modified for Contents added extension header test - -2002-11-25 12:14 davidb - - * Makefile, test/Makefile: commented out IM stuff -- not quite - ready for not-quite-prime time - -2002-11-25 12:13 davidb - - * Helper.cxx: removed Debug - -2002-11-25 12:12 davidb - - * HeaderFieldValueList.cxx, HeaderFieldValueList.hxx, - ParserContainer.hxx, ParserContainerBase.hxx, SipMessage.cxx: - generalized encode to unify with extension headers - -2002-11-25 11:54 davidb - - * Helper.cxx: [no log message] - -2002-11-25 11:30 davidb - - * .cvsignore: [no log message] - -2002-11-25 11:30 davidb - - * os/: Makefile, ParseBuffer.cxx, ParseBuffer.hxx: added skipChars - which skips a string - -2002-11-25 11:29 davidb - - * os/: DataStream.cxx, DataStream.hxx: prettified - -2002-11-25 11:29 davidb - - * os/: Data.cxx, Data.hxx: removed string related functions no - allocation on empty copy - -2002-11-25 11:29 davidb - - * os/CountStream.cxx, os/CountStream.hxx, test/testCountStream.cxx: - CountStream--used to efficiently determine Content Size - -2002-11-25 11:28 davidb - - * Symbols.cxx, Symbols.hxx: added LPAREN, RPAREN - -2002-11-25 11:27 davidb - - * IntegerParameter.cxx, os/TODO, test/testData.cxx, - test/testParseBuffer.cxx: [no log message] - -2002-11-25 11:27 davidb - - * Dialog.cxx, Helper.cxx: content length is not exposed to - application - -2002-11-25 11:26 davidb - - * Contents.cxx, Contents.hxx, LazyParser.cxx, LazyParser.hxx, - Makefile, MessageWaitingContents.cxx, MessageWaitingContents.hxx, - ParserCategories.cxx, ParserCategories.hxx, ParserCategory.cxx, - ParserCategory.hxx, SdpContents.cxx, SdpContents.hxx, - SipMessage.cxx, SipMessage.hxx, test/Makefile, - test/testMessageWaiting.cxx, test/testSdp.cxx, - test/testSipMessage.cxx: lazy parser as base for ParserCategory and - Contents. added MessageWaitingContents, SdpContents. - -2002-11-24 16:41 fluffy - - * Makefile, Security.cxx, Security.hxx, SipStack.cxx, SipStack.hxx: - added Security stuff - -2002-11-23 23:48 fluffy - - * Helper.cxx, Makefile, SipStack.hxx, TuIM.cxx, TuIM.hxx, - test/Makefile, test/test2.cxx, test/testIM.cxx, test/testIM.hxx, - test/testSipStack1.cxx: added IM stuff and changed Random stuff - -2002-11-23 23:47 fluffy - - * os/Random.cxx: few trivial changes - -2002-11-23 14:06 fluffy - - * Helper.cxx, Makefile, SipStack.cxx, test/Makefile, - test/Transceiver.cxx, test/testTcpTransport.cxx, os/Data.cxx, - os/Data.hxx, os/Makefile, os/RandomHex.cxx, os/RandomHex.hxx, - test/testDataPerformance.cxx, test/testRandomHex.cxx: fixed Random - Number stuff - -2002-11-23 13:59 fluffy - - * os/: Random.cxx, Random.hxx: [no log message] - -2002-11-23 10:55 fluffy - - * SipStack.hxx, test/testDnsResolver.cxx, - test/testTransactionFSM.cxx: Changed some things from public to - private in the SipStack.hxx and fixed issues cuased by this. - -2002-11-22 16:04 alan - - * SipMessage.cxx: Added encoder call to 2543 tid case. (NULs in tid - were causing problems (also makes it printable) - -2002-11-20 13:16 ryker - - * TransactionState.cxx: In the server non-INVITE transaction also - resent the mMsgToRetransmit if we get a message from the wire in - the Completed state. Also, don't assert(0) in the "stale" - transaction if we get a timer message other than the stale timer. - Just print out the message and continue on. - -2002-11-20 10:45 ryker - - * SipMessage.cxx: Check for mBody == 0. - -2002-11-20 10:05 ryker - - * TransactionState.cxx: Make sure a SIP message is a request before - asking if it's an ACK. - -2002-11-20 09:51 ryker - - * SipMessage.cxx, SipMessage.hxx: Add updateContentLength() to - class SipMessage. This sets a Content-Length header in the message - based on the size of its body including 0 if the body hasn't been - touched yet. - -2002-11-20 08:53 ryker - - * SipMessage.cxx, SipMessage.hxx: Add a temporary getBody() method - so people can continue working before a rich body and MIME - infrastructure is in place. - -2002-11-19 15:30 ryker - - * SipMessage.cxx: Only ask for a From tag if we know it exists. - Also ask for the from tag, not a tag on the From URI. - -2002-11-19 14:50 ryker - - * SipMessage.cxx: For an RFC 2543 transaction id, don't factor in - the branch if no branch exists in the message. My Cisco 7960 load, - for example, will send an INVITE without a branch. This fix - prevents the getTransactionId() function from creating a branch in - the message when none should be there. - -2002-11-19 11:05 davidb - - * test/testSipMessage.cxx: [no log message] - -2002-11-19 11:05 davidb - - * ParserContainer.hxx: fixed leak in pop - -2002-11-19 11:04 davidb - - * ParserCategories.cxx: allow parameters after integer in Expires - -2002-11-18 18:44 derekm - - * os/Log.cxx: string constructor is no longer explicit--made - necessary changes - -2002-11-18 18:44 derekm - - * os/: Data.cxx, Data.hxx: more comparison operators. string - constructor is no longer explicit - -2002-11-18 18:43 derekm - - * test/: testParserCategories.cxx, testSipMessage.cxx, - testData.cxx: [no log message] - -2002-11-18 18:42 derekm - - * Uri.hxx: removed unused member mPortSpecified - -2002-11-18 18:42 derekm - - * Uri.cxx: calls checkparsed in getAor - -2002-11-18 18:42 derekm - - * SipStack.cxx: wrapped win32 warning pragma inside an ifdef - -2002-11-18 18:40 derekm - - * IntegerParameter.cxx: No longer is always 3600 when this is an - expires param. - -2002-11-18 14:04 ryker - - * TransactionState.cxx: Check to see that a dynamic_cast succeeded - before indirecting through the resultant pointer. - -2002-11-18 11:02 ryker - - * TransactionState.cxx: Prevent the stack from sending more than - one 100. We do this by moving to a Trying state on receipt of an - INVITE. If the TU sends a 1xx we move to Proceeding. Likewise if - the timer for sending a 100 expires, the stack sends a 100 and - moves to Proceeding. If the timer fires and the state is already - Proceeding (by virtue of a 1xx from the TU already) then we ignore - the timer. This just makes the code match a server INVITE FSM - diagram I have. - -2002-11-18 10:07 ryker - - * TransactionState.cxx: In the INVITE server transaction the Trying - and Proceeding states collapse into one. For 100 messages, - however, we were only testing against the Trying state and not the - Proceeding state too. - -2002-11-15 18:53 derekm - - * os/Data.cxx: long construcor no longer leaks. - -2002-11-15 18:52 derekm - - * Helper.cxx: ACK is now ACK - -2002-11-15 18:52 derekm - - * Dialog.cxx: CANCEL is no longer INVITE - -2002-11-15 15:24 kdc - - * SipMessage.cxx: fixed bogus logic for via branch - -2002-11-15 10:57 alan - - * doc/.cvsignore: Added dot files - -2002-11-14 22:01 fluffy - - * os/Condition.cxx, os/Data.cxx, DnsResolver.cxx, - ParserCategories.cxx, SipStack.cxx, UdpTransport.cxx, Uri.cxx, - test/SipTortureTests.cxx, test/tassert.h: compile under windows - -2002-11-14 20:10 jason - - * Uri.cxx, Uri.hxx: [no log message] - -2002-11-14 20:06 jason - - * Uri.cxx, Uri.hxx: added interface to make uri from Data - -2002-11-14 20:06 jason - - * SipStack.hxx: [no log message] - -2002-11-14 20:05 jason - - * Helper.hxx: added makeCancel - -2002-11-14 20:00 derekm - - * test/testData.cxx: [no log message] - -2002-11-14 19:57 derekm - - * test/test1.cxx: now actually lockstepped -- stable memory usage. - constructs message correctly. - -2002-11-14 19:56 derekm - - * test/: InviteClient.cxx, InviteClient.hxx, InviteServer.cxx, - InviteServer.hxx, Makefile, Register.cxx, Register.hxx, - Registrar.cxx, Registrar.hxx, Transceiver.cxx, Transceiver.hxx, - lg.cxx: a small 'loadgen' test. - -2002-11-14 19:53 derekm - - * UdpTransport.cxx: fixed leak. the buffer that was being allocated - was not deleted when EWOULDBLOCK was the result of read - -2002-11-14 17:40 fluffy - - * test/test1.cxx: fixed includes to compile in linux - -2002-11-14 17:37 fluffy - - * os/Condition.cxx: fixed includes to compile in linux - -2002-11-14 17:22 davidb - - * FAQ: feel free to contribute... - -2002-11-14 17:22 davidb - - * test/SipTortureTests.cxx: added the next test - -2002-11-14 17:20 davidb - - * Headers.hxx, ParserCategories.cxx, ParserCategories.hxx: added - Expires parser category fixed some problems with IntegerCategory - comment - -2002-11-14 15:11 derekm - - * UdpTransport.cxx: reverted cullens change--his code does not work - on linux - -2002-11-14 13:04 derekm - - * HeaderFieldValue.hxx, ParserCategory.cxx: un-'fixed' - ParserCategory constructor. - - In the ParserCategory constructor thats takes an hfv, the - parsercategory is considered parsed if the hfv has no contents. - This requires that the default constructor of the hfv set mField to - zero. - -2002-11-14 12:17 davidb - - * ParserCategories.cxx, Uri.cxx, Uri.hxx: rewrote the NameAddr and - Uri Data parsers again. - -2002-11-14 12:15 derekm - - * os/: Condition.cxx, Condition.hxx: Added timed wait--only for - linux - -2002-11-14 11:49 fluffy - - * os/Mutex.cxx, os/ParseBuffer.cxx, os/ParseBuffer.hxx, - os/Socket.cxx, os/Socket.hxx, SipStack.cxx, TransportSelector.cxx, - test/test2.cxx: few windows fixes - -2002-11-14 10:48 jason - - * Makefile, test/Makefile, test/Resolver.cxx, test/Resolver.hxx, - test/test1.cxx: moved Resolver.?xx into test directory - -2002-11-14 10:22 fluffy - - * TransportSelector.cxx: removed resolver - -2002-11-14 10:13 fluffy - - * Resolver.cxx, Resolver.hxx, SIPSTACK.dsp, SIPSTACK.dsw: no longer - used - -2002-11-14 10:12 fluffy - - * UdpTransport.cxx: compile in windows may have broken received - address tag - -2002-11-14 10:10 fluffy - - * DnsResolver.cxx: compile in windows - -2002-11-14 10:10 fluffy - - * Resolver.cxx, Resolver.hxx: no longer used - -2002-11-14 09:26 jason - - * test/: .cvsignore, Makefile, test1.cxx: [no log message] - -2002-11-13 19:36 davidb - - * HeaderFieldValue.cxx, HeaderFieldValue.hxx, ParserCategories.cxx, - ParserCategories.hxx, ParserCategory.cxx, ParserCategory.hxx, - test/testParserCategories.cxx: simplified constructor of NameAddr - from Data - -2002-11-13 17:50 alan - - * doc/: Makefile, fsm-dot.awk, static/Preparse.pdf, - static/Preparse.png, static/Preparse.ps, static/Preparse.svg: PNG - formatted better now - -2002-11-13 17:21 ryker - - * TransactionState.cxx: Validate that a message is indeed a request - before asking if it's an ACK. - -2002-11-13 17:20 alan - - * TransportSelector.cxx: Added check to ensure that the message is - a request before ACK - -2002-11-13 16:43 ryker - - * UdpTransport.cxx: Fix logic in test of preparse status result. - -2002-11-13 15:54 jason - - * os/compat.hxx: fixes for qnx - -2002-11-13 15:31 jason - - * test/testParserCategories.cxx: [no log message] - -2002-11-13 14:40 ryker - - * TransactionState.cxx: More fixing the ACK pseudotransaction. - This involved getting rid of special ACK processing for the - incoming case and actually dispatching to the right machine for the - outgoing case. Furthermore the processAck() logic has been fixed - to enable retries on transport failure and die on transport - success. Although this will enable a TU to complete the 3-way - handshake in the common case, the ACK pseudotransaction can't - really satisfy RFC 3263 as it should due to problems assessing - success or failure in the transport. - -2002-11-13 14:38 davidb - - * test/testSipMessage.cxx: added test for expires="Sat, 01 Dec 2040 - 16:00:00 GMT" => 3600 - -2002-11-13 14:38 davidb - - * ParserCategories.cxx: removed Alan's hack for other Uri types - -2002-11-13 14:37 davidb - - * IntegerParameter.cxx: backward compatible for expires="Sat, 01 - Dec 2040 16:00:00 GMT" - -2002-11-13 14:16 ryker - - * TransportSelector.cxx: In the TransportSelector send() routine we - also (yes this is lame) need to find out if the message is an ACK - and if so add "ACK" to the transaction id. This relates to the - need to have the same branch parameter in the INVITE and ACK but - have different transaction ids for the purpose of dispatching to - the correct code. - -2002-11-13 13:45 alan - - * ConnectionMap.cxx: Removed unused var - -2002-11-13 12:42 davidb - - * os/: Data.cxx, Data.hxx: added clear() added some asserts - -2002-11-13 12:41 davidb - - * os/Logger.hxx: simplified macros to work everywhere - -2002-11-13 12:41 davidb - - * os/: ParseBuffer.cxx, ParseBuffer.hxx: added copy constructor and - operator= - -2002-11-13 10:05 jason - - * test/: .cvsignore, testSipMessageMemory.cxx, torture-test.txt: - [no log message] - -2002-11-13 09:56 jason - - * ParserCategories.cxx, ParserCategories.hxx, TcpTransport.cxx, - TransactionState.cxx, UdpTransport.cxx, os/Logger.hxx, - os/compat.hxx, test/.cvsignore, test/testCoders.cxx, - test/.cvsignore, test/testParserCategories.cxx: fixed to compile on - qnx/neutrino 6.0 with gcc 2.95 - -2002-11-13 09:07 jason - - * test/: Makefile, testNonInviteClientTx.cxx, testTcpTransport.cxx: - get it to compile again - -2002-11-12 15:33 ryker - - * TransportSelector.cxx: In the case of an ACK request we need to - hack the transaction id passed to the DNS resolver to reflect that - it's an ACK. I'm not too happy with this but it does seem to make - the INVITE client transaction work. I think the ACK - pseudotransaction in TransactionState.cxx will never get cleaned up - now, though. - -2002-11-12 14:03 ryker - - * TransactionState.cxx: Improve the handling of DnsMessage events - in processAck(). - -2002-11-12 09:18 ryker - - * os/Data.cxx: Make this compile again by #including . - This is needed on my DeadRat 7.3 install with gcc 2.96. - -2002-11-12 00:05 alan - - * Preparse.cxx: Turned off DEBUG - -2002-11-11 23:42 alan - - * ConnectionMap.cxx, ConnectionMap.hxx, Helper.cxx, Preparse.cxx, - Preparse.hxx, UdpTransport.cxx, test/SipTortureTests.cxx, - test/testPreparse.cxx: Preparse Fragment Support. - -2002-11-11 22:42 alan - - * .cvsignore, ChangeLog, ParserCategories.cxx, SipMessage.cxx, - Uri.cxx, test/SipTortureTests.cxx, test/tassert.h, - test/testSipStack1.cxx: Updates to support torture tests. - -2002-11-11 22:42 alan - - * ConnectionMap.cxx: Final fragmentation pre-merge - -2002-11-11 22:41 alan - - * Helper.cxx, Preparse.cxx, Preparse.hxx, UdpTransport.cxx, - test/testPreparse.cxx: Pre-merge fragmentation implementation - -2002-11-11 22:35 alan - - * test/.cvsignore: dded misc - -2002-11-11 21:16 jason - - * os/: Data.cxx, Data.hxx: added some explicit constructors for - double, int, char, unsigned long and convertInt and convertFloat - -2002-11-11 21:16 jason - - * os/: Condition.cxx, Condition.hxx: support broadcast in the - Condition - -2002-11-11 21:15 jason - - * os/: Lock.cxx, Lock.hxx, Mutex.hxx, RWMutex.cxx, RWMutex.hxx, - Makefile: extend Locks to support ReadersWriter - -2002-11-11 21:14 jason - - * HeaderFieldValue.cxx, HeaderFieldValue.hxx, ParserCategories.hxx, - ParserCategory.cxx, ParserCategory.hxx: added capability to create - a NameAddr (or other ParserCategories) from an unparsed Data. - -2002-11-11 15:58 ryker - - * test/testTFSM-clientinvite: Flesh out test more. - -2002-11-11 15:32 ryker - - * TransactionState.cxx: - Handle DnsMessage event in the client - invite transaction. - Send a 503 to the TU in case Timer B fires, - killing the same transaction. - -2002-11-11 15:09 jason - - * os/: BaseException.hxx, CircularBuffer.hxx, Coders.hxx, Data.hxx, - Fifo.hxx, Lock.hxx, Lockable.hxx, vmd5.hxx, vthread.hxx: avoid more - vocal1 namespace conflicts - -2002-11-11 14:46 ryker - - * test/: testTFSM-clientinvite, testTFSM-clientnoninvite: Add - testTFSM-clientinvite. - -2002-11-11 14:38 kdc - - * test/Makefile: removed testtransport stuff - -2002-11-11 14:37 kdc - - * Makefile, TestTransport.cxx, TestTransport.hxx, - TransactionState.cxx, Transport.cxx, Transport.hxx, - TransportSelector.cxx, TransportSelector.hxx, - test/testTFSM-clientnoninvite, test/testTransactionFSM.cxx: removed - TestTransport stuff fixed resend fixed timer discarding for deleted - transactions added client noninvite test - -2002-11-11 14:05 jason - - * os/: Condition.hxx, Data.hxx, DataStream.hxx, Fifo.hxx, - HashMap.hxx, Inserter.hxx, Lock.hxx, Lockable.hxx, Log.hxx, - Logger.hxx, Mutex.hxx, ParseBuffer.hxx, RandomHex.hxx, Socket.hxx, - Subsystem.hxx, SysLogBuf.hxx, SysLogStream.hxx, ThreadIf.hxx, - Timer.hxx, vmd5.hxx, vthread.hxx: change #ifndef guards to have - Vocal2 prefix to avoid collisions with Vocal1 files - -2002-11-11 13:46 jason - - * Dialog.hxx, ParseException.hxx, SipMessage.hxx, Transport.cxx, - Transport.hxx, TransportSelector.cxx, os/BaseException.cxx, - os/BaseException.hxx, os/Makefile, os/ParseBuffer.hxx, - os/VException.cxx, os/VException.hxx: rename VException to - BaseException - -2002-11-11 11:06 derekm - - * Transport.cxx: toTransport is now case insensitive. - -2002-11-11 10:39 ryker - - * TransactionState.cxx: Initialise mDnsState in the - TransactionState ctor. This fixes a couple of problems (including - a SEGV) that prevented responses from being sent properly. - -2002-11-11 10:35 ryker - - * test/testTransactionFSM.cxx: Add PASS/FAIL on completion plus - complete port to UDP transport. - -2002-11-11 08:58 ryker - - * test/: testTFSM-remoteinvite.dat, testTFSM-remotenoninvite.dat, - testTFSM-serverinvite, testTFSM-servernoninvite: Make names match - RFC. Also change them to specify UDP. - -2002-11-11 08:57 ryker - - * test/testTransactionFSM.cxx: Use UDP transport. - -2002-11-10 20:56 alan - - * ConnectionMap.cxx, Preparse.cxx, Preparse.hxx, UdpTransport.cxx, - test/testPreparse.cxx: Interim fixups - -2002-11-10 12:44 alan - - * ConnectionMap.cxx, UdpTransport.cxx, Helper.cxx: TEMPO W/A - -2002-11-09 23:08 alan - - * test/testPreparse.cxx: More acid tests - -2002-11-09 23:02 alan - - * doc/static/: Preparse.pdf, Preparse.png, Preparse.ps, - Preparse.svg: Updates for leading blanks in headers. - -2002-11-09 23:01 alan - - * Preparse.cxx: Fixed DATA error in early header continuation. - -2002-11-09 21:59 alan - - * Preparse.cxx, Preparse.hxx, test/testPreparse.cxx: Added fixes - for continuations. - -2002-11-09 21:32 alan - - * doc/static/: Preparse.pdf, Preparse.png, Preparse.ps, - Preparse.svg: Updates to PP - -2002-11-09 20:35 alan - - * doc/static/: Preparse.pdf, Preparse.png, Preparse.ps, - Preparse.svg: Preparser State Updates -- typo repair - -2002-11-09 20:32 alan - - * doc/static/: Preparse.pdf, Preparse.png, Preparse.ps, - Preparse.svg: Preparser State Updates - -2002-11-09 19:45 alan - - * Preparse.cxx, Preparse.hxx, test/testPreparse.cxx: Initial revamp - of fragmentation Integration with remainder of stack still - required. - -2002-11-08 18:47 derekm - - * SipMessage.cxx, SipMessage.hxx: added getSource method, which - returns where this message came from as a Transport::Tuple - -2002-11-08 18:46 derekm - - * Resolver.cxx, Resolver.hxx: New constructor--don't need to make a - URI. - -2002-11-08 18:46 derekm - - * ParserCategories.cxx: Fixed CallId operator== - - Always enodes NameAddr with '<' '>' syntax. - -2002-11-08 18:45 derekm - - * Helper.cxx: Now correctly copies Record-Route into responses. - -2002-11-08 18:44 derekm - - * Dialog.cxx: Fixed CSeq for ACK messages. Added max-forwards to - requests. - -2002-11-08 18:44 derekm - - * ConnectionMap.cxx: source is now set in the message upon receipt - -2002-11-08 17:27 derekm - - * os/Fifo.cxx: [no log message] - -2002-11-08 17:06 ryker - - * test/testTFSM-remotenoninvite.dat: More detailed test. - -2002-11-08 16:17 ryker - - * TransactionState.cxx: Yet more guards on the TestTransport. - -2002-11-08 16:01 ryker - - * test/testTFSM-remotenoninvite.dat: Server Non-Invite test. The - TU passes a provisional response to a REGISTER which the stack has - to pass along. - -2002-11-08 16:00 ryker - - * test/testTransactionFSM.cxx: Print the contents of messages if we - don't expect them. - -2002-11-08 15:58 ryker - - * TransactionState.cxx: Fix guard in the other place too. - -2002-11-08 15:38 ryker - - * TransactionState.cxx: Fix use of USETESTTRANSPORT. - -2002-11-08 15:27 ryker - - * DnsResolver.cxx: Revert change Jason made from v1.7 -> v1.8 which - I think breaks name resolution. - -2002-11-08 15:27 kdc - - * test/testSipStackInvite.cxx: updated test - -2002-11-08 15:00 ryker - - * TransactionState.cxx: Fix comment. - -2002-11-08 14:57 ryker - - * TransactionState.cxx: In the Proceeding/Completed state of the - server INVITE transaction we were passing retransmissions of the - INVITE to the TU and not generating a provisional response for each - retransmission. Both problems fixed. - -2002-11-08 14:33 ryker - - * test/testTFSM-remoteinvite.dat: Test file for the server invite - transaction. - -2002-11-08 14:20 kdc - - * test/testSipStackInvite.cxx: updated to new interfaces - -2002-11-08 14:03 ryker - - * Helper.cxx: Change the Helper::makeResponse to invert the - direction of this message. For example, if the original request - came from the transport, then the constructed response should - appear to have come from the TU. - -2002-11-08 13:58 alan - - * Preparse.cxx: Fixed code. - -2002-11-08 13:55 ryker - - * TransactionState.cxx: More DNS message handling. - -2002-11-08 13:54 ryker - - * test/testTransactionFSM.cxx: More fixes. I hate this code. - -2002-11-08 13:53 alan - - * Preparse.cxx, Preparse.hxx: - Stable fixes (no frag support) until frag completed later today. - -2002-11-08 12:34 ryker - - * test/testTransactionFSM.cxx: Allow the stack to run every 100ms - and change the units of time to ms. - -2002-11-08 12:10 ryker - - * SipMessage.hxx: Add setFromExternal() member function to mirror - setFromTU(). - -2002-11-08 11:49 jason - - * Resolver.hxx, Transport.cxx: new resolver constructor Transport - ptr no longer used for comparsion in Transport::Tuple - -2002-11-08 10:46 ryker - - * Makefile, TestTransport.cxx, TestTransport.hxx, - TransactionState.cxx, Transport.cxx, Transport.hxx: Introduce the - USETESTTRANSPORT guard so we can conditionally compile out the test - transport stuff. - -2002-11-08 10:33 ryker - - * test/Makefile: Compile with -DUSETESTTRANSPORT - -2002-11-08 09:53 jason - - * test/: testCoders.cxx, testDataStream.cxx: [no log message] - -2002-11-08 09:53 jason - - * DnsResolver.cxx, Resolver.cxx, TcpTransport.cxx, - UdpTransport.cxx, os/Coders.cxx, os/Data.cxx, os/Data.hxx: added - Data::size_type and made usage consistent in the code - -2002-11-08 09:45 jason - - * os/Makefile, test/testData.cxx, test/testDataStream.cxx: [no log - message] - -2002-11-08 09:45 jason - - * os/Data.cxx: fix various bugs in Data - -2002-11-08 09:42 jason - - * UdpTransport.cxx: stamp received and rport params on incoming - requests - -2002-11-08 09:41 jason - - * TODO, test/.cvsignore, test/Makefile, - test/testNameAddrParamExclusions.cxx, - test/testSipMessageMemory.cxx: [no log message] - -2002-11-08 09:40 jason - - * Resolver.cxx: handle dotted quad case - -2002-11-08 09:40 jason - - * ParserCategory.cxx: fix bug in assignment - -2002-11-08 09:39 jason - - * ParserCategories.cxx, ParserCategories.hxx: added default - constructor for cseq strictly disallow certain things in cseq - -2002-11-08 09:38 jason - - * Helper.cxx: fix tag (not in uri) shorten callid - -2002-11-08 09:38 jason - - * DnsResolver.cxx: changes to dns resolver - don't need to remove - dups - -2002-11-08 09:37 jason - - * Dialog.cxx: various dialog bugs - found in testing - -2002-11-08 09:30 ryker - - * Transport.cxx: Add in case statements for Kevin's TestReliable - and TestUnreliable stuff. This should be conditionally compiled. - -2002-11-08 09:28 ryker - - * TestTransport.cxx: Identify the test transports by their real - names. A long time ago in a galaxy far, far away there were - dependencies on UDP which is why these transports identified - themselves that way. - -2002-11-08 09:27 ryker - - * test/testTransactionFSM.cxx: Assert if Helper::makeMessage fails. - We want to test the transaction FSM, not the Helper function (this - bit me). - -2002-11-08 09:26 ryker - - * TransactionState.cxx, TransactionState.hxx: Handle messages from - the DnsResolver. - -2002-11-08 08:11 ryker - - * test/testTransactionFSM.cxx: Whoops. Increment iterator. - -2002-11-07 16:10 ryker - - * test/testTransactionFSM.cxx: s/cerr/DebugLog/ - -2002-11-07 15:42 ryker - - * Makefile: Don't build Circular.cxx anymore. - -2002-11-07 15:30 ryker - - * test/Makefile: Add testTransactionFSM.cxx - -2002-11-07 15:30 ryker - - * test/testTransactionFSM.cxx: Update this to match how - TestTransport works now. - -2002-11-07 15:27 ryker - - * Circular.cxx, Circular.hxx, TestTransport.cxx, TestTransport.hxx: - Make the test transports use a fifo internally, not a circular - buffer. - -2002-11-07 15:01 alan - - * test/.cvsignore: Added ti ugnire - -2002-11-07 15:01 alan - - * doc/fsm-dot.awk: Updated to make cleaner diagram - -2002-11-07 13:40 jason - - * BranchParameter.cxx, Dialog.cxx, Symbols.cxx: [no log message] - -2002-11-07 12:26 jason - - * SipMessage.cxx: fix output - -2002-11-07 12:26 jason - - * Resolver.cxx: [no log message] - -2002-11-07 12:26 jason - - * Dialog.cxx: set the contact in dialog - -2002-11-07 10:40 derekm - - * ConnectionMap.cxx: fixed one bug...still largely untested - -2002-11-07 10:39 derekm - - * Dialog.cxx: Pot authentication header logic back in. - -2002-11-07 09:49 ryker - - * test/testTransactionFSM.cxx: Fixup. The main thing wrong with - this is detecting messages from the wire properly. - TestTransport.cxx needs to be fixed and then this can be updated to - match the newer, improved interface there. - -2002-11-06 20:07 fluffy - - * DnsResolver.cxx, Transport.cxx: fixed inet_ntop stuff - -2002-11-06 19:07 jason - - * BranchParameter.cxx, BranchParameter.hxx, Circular.cxx, - ConnectionMap.cxx, ConnectionMap.hxx, DataParameter.cxx, - DataParameter.hxx, Dialog.cxx, Dialog.hxx, DnsMessage.cxx, - DnsMessage.hxx, DnsResolver.cxx, DnsResolver.hxx, Executive.cxx, - Executive.hxx, ExistsParameter.cxx, ExistsParameter.hxx, - FloatParameter.cxx, FloatParameter.hxx, HeaderFieldValue.cxx, - HeaderFieldValue.hxx, HeaderFieldValueList.cxx, - HeaderFieldValueList.hxx, HeaderTypes.cxx, HeaderTypes.hxx, - Headers.cxx, Headers.hxx, Helper.cxx, Helper.hxx, - IntegerParameter.cxx, IntegerParameter.hxx, Makefile, Message.cxx, - Message.hxx, MethodTypes.cxx, Parameter.cxx, Parameter.hxx, - ParameterTypeEnums.hxx, ParameterTypes.cxx, ParameterTypes.hxx, - ParseException.hxx, ParserCategories.cxx, ParserCategories.hxx, - ParserCategory.cxx, ParserCategory.hxx, ParserContainer.hxx, - ParserContainerBase.hxx, Preparse.cxx, Preparse.hxx, - ReliabilityMessage.hxx, Resolver.cxx, Resolver.hxx, - SendingMessage.cxx, SendingMessage.hxx, SipMessage.cxx, - SipMessage.hxx, SipStack.cxx, SipStack.hxx, Symbols.cxx, - TcpTransport.cxx, TcpTransport.hxx, TestTransport.cxx, - TestTransport.hxx, TimerMessage.cxx, TimerMessage.hxx, - TimerQueue.cxx, TimerQueue.hxx, TransactionMap.cxx, - TransactionMap.hxx, TransactionState.cxx, TransactionState.hxx, - Transport.cxx, Transport.hxx, TransportMessage.hxx, - TransportSelector.cxx, TransportSelector.hxx, UdpTransport.cxx, - UdpTransport.hxx, UnknownParameter.cxx, UnknownParameter.hxx, - Uri.cxx, Uri.hxx, test/test1.cxx, test/test2.cxx, - test/testHash.cxx, test/testHeaderFieldValueList.cxx, - test/testNonInviteClientTx.cxx, test/testNonInviteServerTx.cxx, - test/testParserCategories.cxx, test/testPreparse.cxx, - test/testSimpleLeak.cxx, test/testSipMessage.cxx, - test/testSipMessageMemory.cxx, test/testSipStack1.cxx, - test/testSipStackInvite.cxx, test/testTcpTransport.cxx, - test/testTimer.cxx, test/testTransactionFSM.cxx, - test/testTypes.cxx, test/testUdp.cxx, test/testpp.cxx, - os/Coders.cxx, os/Coders.hxx, os/Condition.cxx, os/Data.cxx, - os/Data.hxx, os/DataStream.cxx, os/DataStream.hxx, os/Fifo.cxx, - os/Fifo.hxx, os/Lock.cxx, os/Lock.hxx, os/Lockable.hxx, os/Log.cxx, - os/Log.hxx, os/Logger.cxx, os/Logger.hxx, os/Mutex.cxx, - os/Mutex.hxx, os/ParseBuffer.cxx, os/ParseBuffer.hxx, - os/RandomHex.cxx, os/RandomHex.hxx, os/Socket.cxx, os/Socket.hxx, - os/Subsystem.cxx, os/Subsystem.hxx, os/SysLogStream.hxx, - os/ThreadIf.cxx, os/ThreadIf.hxx, os/Timer.cxx, os/Timer.hxx, - os/VException.cxx, os/VException.hxx, os/vmd5.cxx, os/vmd5.hxx, - test/testCoders.cxx, test/testData.cxx, - test/testDataPerformance.cxx, test/testDataStream.cxx, - test/testParseBuffer.cxx, test/testRandomHex.cxx: moved includes to - sip2/ - -2002-11-06 19:00 derekm - - * Uri.cxx: Uri operator< - -2002-11-06 18:57 derekm - - * Makefile: removed test programs - -2002-11-06 18:52 derekm - - * test/testTcpTransport.cxx: Uri operator< - -2002-11-06 18:51 derekm - - * test/SipTortureTests.cxx, test/testDnsResolver.cxx, - SipTortureTests.cxx, test1.cxx, test2.cxx, testDnsResolver.cxx, - testHash.cxx, testHashCasen.cxx, testHeaderFieldValueList.cxx, - testNonInviteClientTx.cxx, testNonInviteServerTx.cxx, - testParserCategories.cxx, testPreparse.cxx, testSimpleLeak.cxx, - testSipMessage.cxx, testSipMessageMemory.cxx, testSipStack1.cxx, - testSipStackInvite.cxx, testTimer.cxx, testTransactionFSM.cxx, - testTypes.cxx, testUdp.cxx, testpp.cxx: [no log message] - -2002-11-06 18:49 derekm - - * test/: Makefile, testTransactionFSM.cxx: brought over changes - from sipstack directory - -2002-11-06 18:44 derekm - - * ParserCategories.cxx, os/Data.cxx, os/Data.hxx: Data operator> - NameAddr operator< Uri operator< - -2002-11-06 18:08 fluffy - - * DnsResolver.cxx: [no log message] - -2002-11-06 18:02 fluffy - - * os/: Log.cxx, ThreadIf.cxx: windows fixes - -2002-11-06 17:28 fluffy - - * DnsResolver.cxx: may have broken this - compiles in windows - -2002-11-06 17:26 fluffy - - * Helper.cxx: fix to compile in windows - -2002-11-06 17:26 fluffy - - * Resolver.cxx, Resolver.hxx: no longer used - -2002-11-06 17:05 fluffy - - * Uri.cxx: fixed problem that caused bug in windows compiler - -2002-11-06 16:12 veer - - * os/Timer.cxx, os/vmd5.hxx, test/testCoders.cxx: Ported on forte - CC 6Update 1 for sparc - -2002-11-06 16:01 bko - - * Makefile, ParserCategories.cxx, ParserCategories.hxx, Uri.cxx, - testParserCategories.cxx: code for warningcategory. at least one - possible bug remains - -2002-11-06 15:49 ryker - - * Helper.cxx, Helper.hxx: Add optional second parameter to - Helper::makeMessage so that you can make a message that is thought - to have arrived from the wire as well as from a TU. Test stuff - needs this to synthesise messages for the transaction state - machines that appear to have arrived from the wire. - -2002-11-06 15:31 veer - - * ConnectionMap.cxx, DnsResolver.cxx, Preparse.hxx, Resolver.cxx, - TransactionState.hxx, Uri.cxx, os/HashMap.hxx, os/vmd5.hxx: Ported - on forte CC 6Update 1 for sparc - -2002-11-06 15:20 alan - - * Preparse.cxx: Fixed traiiling \n problem - -2002-11-06 15:15 alan - - * test/testPreparse.cxx: Added dereks test case - -2002-11-06 13:58 davidb - - * ParserCategories.cxx, ParserCategories.hxx: added - CallId::operator== - -2002-11-06 13:06 alan - - * doc/static/: Preparse.pdf, Preparse.png, Preparse.ps, - Preparse.svg, README, srv-inv-fsm.pdf, srv-inv-fsm.png, - srv-inv-fsm.ps, srv-inv-fsm.svg, srv-inv-tree.pdf, - srv-inv-tree.png, srv-inv-tree.ps, srv-inv-tree.svg: This is a - snapshot of the documentation. Real documentation should be build - from the source. - -2002-11-06 13:04 ryker - - * testTransactionFSM.cxx: Cleanup and port to the new TestTransport - stuff. - -2002-11-06 12:36 ryker - - * TestTransport.cxx: #include for std::auto_ptr. - -2002-11-06 11:38 derekm - - * test/: Makefile, test1.cxx, test2.cxx, testHash.cxx, - testHashCasen.cxx, testHeaderFieldValueList.cxx, - testNonInviteClientTx.cxx, testNonInviteServerTx.cxx, - testParserCategories.cxx, testPreparse.cxx, testSimpleLeak.cxx, - testSipMessage.cxx, testSipMessageMemory.cxx, testSipStack1.cxx, - testSipStackInvite.cxx, testTcpTransport.cxx, testTimer.cxx, - testTransactionFSM.cxx, testTypes.cxx, testUdp.cxx, testpp.cxx: - moved tests from sipstack directory to test directory - -2002-11-06 10:51 davidb - - * os/CircularBuffer.hxx: stub for CircularBuffer - -2002-11-06 10:23 kdc - - * Makefile: add Circular.cxx - -2002-11-06 10:20 kdc - - * Circular.cxx, Circular.hxx, TestTransport.hxx, circular.hxx: - simplified circular buffer stuff - -2002-11-06 08:19 fluffy - - * Resolver.cxx: fixed to compile in windows - -2002-11-05 22:55 fluffy - - * TcpTransport.cxx: windows compile updates and fiexed nasty bug in - accept - -2002-11-05 22:54 fluffy - - * os/Socket.hxx, os/Timer.cxx, Headers.cxx, SendingMessage.cxx, - TransactionState.cxx, Transport.cxx: windows compile updates - -2002-11-05 22:53 jason - - * Resolver.cxx, Resolver.hxx, test1.cxx: make test1 work again - -2002-11-05 22:15 jason - - * Executive.cxx, Executive.hxx, Preparse.cxx, SipStack.cxx, - SipStack.hxx, TcpTransport.cxx, TcpTransport.hxx, - TestTransport.cxx, TestTransport.hxx, Transport.cxx, Transport.hxx, - TransportSelector.cxx, TransportSelector.hxx, UdpTransport.cxx, - UdpTransport.hxx, test2.cxx, testNonInviteClientTx.cxx, - testSipStack1.cxx: added FdSet, also support for read and write - fdsets embedded in FdSet class - -2002-11-05 22:14 jason - - * os/Socket.hxx: added FdSet - -2002-11-05 21:15 jason - - * ReliabilityMessage.hxx, TransportMessage.hxx, DnsMessage.cxx, - Makefile, TransactionState.cxx, Transport.cxx, - TransportSelector.cxx: [no log message] - -2002-11-05 21:11 fluffy - - * convertStringToInt.cxx, convertStringToInt.cxx: not used - -2002-11-05 21:10 fluffy - - * os/HashMap.hxx, os/ParseBuffer.cxx, os/RandomHex.cxx, - DnsMessage.cxx, SSL.cxx, SendingMessage.cxx, SipStack.cxx, - TransactionState.cxx, Transport.cxx, TransportSelector.cxx, - Uri.cxx, testSipStack1.cxx: fixed to compile in windows - -2002-11-05 19:52 jason - - * testDnsResolver.cxx, testPreparse.cxx: make tests compile - -2002-11-05 19:52 jason - - * UdpTransport.cxx: [no log message] - -2002-11-05 19:51 jason - - * SipMessage.cxx, TransactionState.cxx: added debug to destructor - -2002-11-05 19:50 jason - - * Makefile: remove test that no longer works - -2002-11-05 19:20 jason - - * SipTortureTests.cxx: [no log message] - -2002-11-05 18:59 davidb - - * BranchParameter.cxx, BranchParameter.hxx, ConnectionMap.cxx, - ConnectionMap.hxx, DataParameter.cxx, DataParameter.hxx, - Dialog.cxx, Dialog.hxx, DnsMessage.cxx, DnsMessage.hxx, - DnsResolver.cxx, DnsResolver.hxx, Executive.cxx, Executive.hxx, - ExistsParameter.cxx, ExistsParameter.hxx, FloatParameter.cxx, - FloatParameter.hxx, HeaderFieldValue.cxx, HeaderFieldValue.hxx, - HeaderFieldValueList.cxx, HeaderFieldValueList.hxx, - HeaderTypes.cxx, HeaderTypes.hxx, Headers.cxx, Headers.hxx, - Helper.cxx, Helper.hxx, IntegerParameter.cxx, IntegerParameter.hxx, - Message.cxx, Message.hxx, MethodTypes.cxx, Parameter.cxx, - Parameter.hxx, ParameterTypeEnums.hxx, ParameterTypes.cxx, - ParameterTypes.hxx, ParseException.hxx, ParserCategories.cxx, - ParserCategory.cxx, ParserCategory.hxx, ParserContainer.hxx, - ParserContainerBase.hxx, Preparse.cxx, Preparse.hxx, Resolver.cxx, - Resolver.hxx, SendingMessage.cxx, SendingMessage.hxx, - SipMessage.cxx, SipMessage.hxx, SipStack.cxx, SipStack.hxx, - SipTortureTests.cxx, Symbols.cxx, TcpTransport.cxx, - TcpTransport.hxx, TestTransport.hxx, TimerMessage.cxx, - TimerMessage.hxx, TimerQueue.cxx, TimerQueue.hxx, - TransactionMap.cxx, TransactionMap.hxx, TransactionState.cxx, - TransactionState.hxx, Transport.cxx, Transport.hxx, - TransportSelector.cxx, TransportSelector.hxx, UdpTransport.cxx, - UdpTransport.hxx, UnknownParameter.cxx, UnknownParameter.hxx, - Uri.cxx, Uri.hxx, test1.cxx, test2.cxx, testDnsResolver.cxx, - testHash.cxx, testHeaderFieldValueList.cxx, - testNonInviteServerTx.cxx, testParserCategories.cxx, - testPreparse.cxx, testSimpleLeak.cxx, testSipMessage.cxx, - testSipMessageMemory.cxx, testSipStack1.cxx, - testSipStackInvite.cxx, testTimer.cxx, testTransactionFSM.cxx, - testTypes.cxx, testUdp.cxx, testpp.cxx, os/Coders.cxx, - os/Coders.hxx, os/Condition.cxx, os/Data.cxx, os/Data.hxx, - os/DataStream.cxx, os/DataStream.hxx, os/Fifo.cxx, os/Fifo.hxx, - os/Lock.cxx, os/Lock.hxx, os/Log.cxx, os/Log.hxx, os/Logger.cxx, - os/Logger.hxx, os/Mutex.cxx, os/Mutex.hxx, os/ParseBuffer.cxx, - os/ParseBuffer.hxx, os/RandomHex.cxx, os/RandomHex.hxx, - os/Socket.cxx, os/Subsystem.cxx, os/Subsystem.hxx, - os/SysLogStream.hxx, os/ThreadIf.cxx, os/ThreadIf.hxx, - os/Timer.cxx, os/Timer.hxx, os/VException.cxx, os/VException.hxx, - os/vmd5.cxx, os/vmd5.hxx, test/testCoders.cxx, test/testData.cxx, - test/testDataPerformance.cxx, test/testDataStream.cxx, - test/testParseBuffer.cxx, test/testRandomHex.cxx: #include <> to - #include "" - -2002-11-05 18:42 jason - - * testParserCategories.cxx, testSipMessage.cxx: added some tests - -2002-11-05 18:41 jason - - * test2.cxx: doesn't work - -2002-11-05 18:41 jason - - * Transport.cxx, Transport.hxx, TransportSelector.cxx: added an - output operator for Tuple - -2002-11-05 18:40 jason - - * SipMessage.hxx: removed unused - -2002-11-05 18:39 jason - - * BranchParameter.hxx, Helper.cxx, TestTransport.cxx, - TestTransport.hxx, TransactionState.cxx, testNonInviteClientTx.cxx: - [no log message] - -2002-11-05 18:35 jason - - * DataParameter.cxx, FloatParameter.cxx, IntegerParameter.cxx, - SipTortureTests.cxx: skipping whitespace before and after the "=" - -2002-11-05 18:33 derekm - - * os/RandomHex.cxx: better randomness when openssl not - available--will be replaced by Random.hxx soon - -2002-11-05 18:32 derekm - - * test/testRandomHex.cxx: [no log message] - -2002-11-05 18:32 derekm - - * os/: Data.hxx, Logger.hxx, Makefile: added size_t to data fixed - logger to work on linux again added a random tests to the makefile - -2002-11-05 18:31 derekm - - * ConnectionMap.cxx, ConnectionMap.hxx, Makefile, TcpTransport.cxx, - TcpTransport.hxx, UdpTransport.cxx, UdpTransport.hxx: added tcp - transport class -- compiles, untested. added related logic to - connectionmap - -2002-11-05 16:36 veer - - * os/Logger.hxx: more Forte port - -2002-11-05 16:34 alan - - * os/Coders.cxx, os/Coders.hxx, test/testCoders.cxx, - test/testData.cxx: Added base64 coders (Data change) - -2002-11-05 16:33 alan - - * testPreparse.cxx: Blah - -2002-11-05 16:33 alan - - * TODO: Added uchar - -2002-11-05 16:29 veer - - * os/Logger.hxx: More Forte port - -2002-11-05 16:25 alan - - * Preparse.cxx, testPreparse.cxx: Removed EDGE-iness - -2002-11-05 16:13 jason - - * BranchParameter.cxx, BranchParameter.hxx, DataParameter.cxx: - fixed how branch encodes/decodes - -2002-11-05 16:13 jason - - * testParserCategories.cxx: added tests for branch - -2002-11-05 16:12 jason - - * os/ParseBuffer.cxx: fixed bug in skipN - -2002-11-05 16:12 veer - - * HeaderTypes.hxx: forte don't like enum dec. line should not have - , - -2002-11-05 16:12 ryker - - * testTransactionFSM.cxx: A test driver for the transaction state - machine. This allows you to write a test specification in a data - file which this program munches on and performs a test with. See - the comments at the top of the file for instructions on its use. - This is thought to work or be close to working but has not been - used successfully due to volatility in certain parts of the stack. - -2002-11-05 16:06 veer - - * os/Log.hxx: Port to Forte - -2002-11-05 16:04 veer - - * os/Logger.hxx: more Forte support - -2002-11-05 16:00 veer - - * os/Logger.hxx: add Forte support - -2002-11-05 15:55 jason - - * TransactionState.cxx, TransactionState.hxx: fixed bug in dns - state - -2002-11-05 15:54 jason - - * Symbols.cxx, Symbols.hxx: added vocal2 cookie - -2002-11-05 15:54 jason - - * .cvsignore: [no log message] - -2002-11-05 15:53 jason - - * os/: ParseBuffer.cxx, ParseBuffer.hxx: add assertNotEof() - -2002-11-05 14:47 veer - - * SipMessage.cxx, SipMessage.hxx: Add support for backward - compatible RFC2543 transaction Id - -2002-11-05 14:16 kdc - - * TransportSelector.cxx: changed TestReliable to TestUnreliable in - switch() statement - -2002-11-05 14:14 kdc - - * TestTransport.cxx, TestTransport.hxx, testNonInviteClientTx.cxx: - many changes - -2002-11-05 13:38 jason - - * SipMessage.cxx, SipMessage.hxx, TransactionState.cxx, - TransactionState.hxx, Transport.cxx, Transport.hxx, - TransportSelector.cxx, TransportSelector.hxx, UdpTransport.cxx: - changes for integration of - TransportSelector/DnsResolver/TransactionState - -2002-11-05 13:38 jason - - * SendingMessage.cxx, SendingMessage.hxx: [no log message] - -2002-11-05 13:36 jason - - * DnsResolver.cxx, DnsResolver.hxx, DnsMessage.cxx, DnsMessage.hxx, - ConnectionMap.cxx: change interface slightly. - -2002-11-05 13:34 jason - - * Dialog.cxx, Helper.cxx, Makefile, ParameterTypes.hxx, - ParserCategories.hxx, ParserCategory.cxx, Symbols.cxx, Symbols.hxx: - change way of creating branch - -2002-11-05 13:34 jason - - * BranchParameter.cxx, BranchParameter.hxx: [no log message] - -2002-11-05 13:25 jason - - * os/Socket.hxx: added some sys includes - -2002-11-05 13:25 jason - - * os/: ParseBuffer.cxx, ParseBuffer.hxx: added some stuff for - advancing pointer - -2002-11-05 12:56 bko - - * testParserCategories.cxx: added test for Mime - -2002-11-05 12:55 bko - - * ParserCategory.cxx: skip whitespace around semi colons in - parseParameters() - -2002-11-05 12:54 bko - - * ParserCategories.cxx, ParserCategories.hxx: implemented Mime - ParserCategory - -2002-11-05 12:05 bko - - * ParserCategories.cxx, testParserCategories.cxx: fixes for Date - parsing - -2002-11-05 11:54 bko - - * Makefile: fix for xyz - -2002-11-05 11:43 davidb - - * Makefile, SipTortureTests.cxx, TestTransport.cxx, - testNonInviteClientTx.cxx, testParserCategories.cxx, - testSipMessage.cxx: got tests compiling with modified Preparsers - -2002-11-05 10:26 alan - - * Helper.cxx, Helper.hxx: Helper for makeMessage - -2002-11-04 23:22 kdc - - * circular.hxx: initial checkin of circular buffer - -2002-11-04 23:10 alan - - * Helper.cxx, Helper.hxx, UdpTransport.cxx: makeMessage helper - -2002-11-04 22:50 davidb - - * ParserCategories.cxx, ParserCategories.hxx: added DateCategory - -2002-11-04 22:49 davidb - - * SipMessage.cxx, SipMessage.hxx: added exists for unknown headers - -2002-11-04 22:49 davidb - - * Symbols.cxx, Symbols.hxx: added ZERO - -2002-11-04 22:49 davidb - - * TODO: [no log message] - -2002-11-04 22:45 davidb - - * os/: ParseBuffer.cxx, ParseBuffer.hxx: added assertEof() for - validation - -2002-11-04 22:44 davidb - - * testSipMessage.cxx: simplified auto_ptr use - -2002-11-04 22:17 alan - - * Makefile, Preparse.cxx, Preparse.hxx, Transport.hxx, - UdpTransport.cxx, UdpTransport.hxx, testPreparse.cxx, - testSipStackInvite.cxx: Preparser Updates - -2002-11-04 21:46 kdc - - * testNonInviteClientTx.cxx: [no log message] - -2002-11-04 21:39 kdc - - * TestTransport.cxx, TestTransport.hxx: initial checkin of - TestTransport stub test harness - -2002-11-04 21:38 kdc - - * Transport.cxx, Transport.hxx, TransportSelector.cxx: added - TestReliable and TestUnreliable transports - -2002-11-04 18:56 derekm - - * Uri.cxx, Uri.hxx, testParserCategories.cxx, os/Data.cxx, - os/Data.hxx, test/testData.cxx: Uri comparison works. added - lowercase, uppercase to data updated tests - -2002-11-04 18:07 veer - - * TransactionState.cxx, TransactionState.hxx: isFromwire is - introduced and stale statemachine is in - -2002-11-04 18:07 bko - - * ParserCategories.cxx, ParserCategories.hxx, SipTortureTests.cxx, - dayofweek.gperf, month.gperf: start implementation of date - -2002-11-04 17:23 bko - - * TODO: update with missing parsers - -2002-11-04 17:12 bko - - * ParameterTypes.hxx, ParserCategories.cxx, ParserCategories.hxx, - ParserCategory.cxx, testParserCategories.cxx: make GenericUri - headers work - -2002-11-04 17:07 davidb - - * Makefile: [no log message] - -2002-11-04 17:06 davidb - - * SipTortureTests.cxx: Sip Torture Tests - -2002-11-04 16:36 veer - - * TransactionState.cxx: added some info on state machine - -2002-11-04 15:59 bko - - * ParserCategories.cxx, testParserCategories.cxx: add a lot more - test cases for auth - -2002-11-04 15:52 veer - - * TransactionState.cxx: added some info on state machine - -2002-11-04 15:42 bko - - * DataParameter.cxx, DataParameter.hxx, ParserCategories.cxx, - ParserCategories.hxx, ParserCategory.cxx, ParserCategory.hxx, - UnknownParameter.cxx, UnknownParameter.hxx, - testParserCategories.cxx: fix unknown parameters as well as first - path at auth parameters - -2002-11-04 15:41 bko - - * os/Data.cxx: fix bug in data - -2002-11-04 14:38 derekm - - * DnsMessage.cxx, DnsResolver.cxx, DnsResolver.hxx: fixed memory - leak in DnsResolver. DnsResolver no longer returns duplicate - elements. - -2002-11-04 13:36 bko - - * testParserCategories.cxx: clean up - -2002-11-04 12:53 bko - - * TODO: update the todo file. - -2002-11-04 12:50 alan - - * os/Coders.cxx, os/Coders.hxx, test/testCoders.cxx, os/Makefile: - Initial Base64 implementation. (contrib'd Alan Hawrylyshen) - -2002-11-04 12:36 derekm - - * os/Data.cxx: fixed operator < - -2002-11-04 12:27 bko - - * DataParameter.cxx, ParserCategories.cxx, - testParserCategories.cxx: fix parsing of parameters terminated by - angle brackets - -2002-11-04 11:46 derekm - - * os/Data.cxx: [no log message] - -2002-11-04 11:34 bko - - * Makefile, testSipMessage.cxx, testSipStack1.cxx: fixes for - compile under gcc < 3 - -2002-11-04 11:07 derekm - - * Makefile: [no log message] - -2002-11-04 10:42 bko - - * Transport.cxx, test2.cxx: fixes for gcc < 3 - -2002-11-04 10:36 bko - - * os/Data.cxx: fixes for gcc < 3 - -2002-11-03 22:36 derekm - - * testDnsResolver.cxx: [no log message] - -2002-11-03 22:33 derekm - - * Makefile, Message.hxx, ParameterTypes.cxx, ParameterTypes.hxx, - ParserCategories.cxx, SipStack.cxx, SipStack.hxx, Symbols.cxx, - Symbols.hxx, os/Data.cxx, os/Data.hxx, DnsMessage.cxx, - DnsMessage.hxx, DnsResolver.cxx, DnsResolver.hxx, os/HashMap.hxx: - [no log message] - -2002-11-03 22:30 jason - - * os/: Timer.cxx, Timer.hxx: add toData - -2002-11-03 22:29 jason - - * testNonInviteClientTx.cxx, testNonInviteServerTx.cxx, Makefile, - testParserCategories.cxx, testSipMessage.cxx, - testSipStackInvite.cxx: [no log message] - -2002-11-03 22:28 jason - - * UdpTransport.cxx, UdpTransport.hxx: added a dummy TcpTransport - -2002-11-03 22:28 jason - - * TransportSelector.cxx, TransportSelector.hxx: support retransmit - move stuff into SipMessage - -2002-11-03 22:28 jason - - * Transport.cxx, Transport.hxx: don't pass in Data*, use Data& - instead - -2002-11-03 22:27 jason - - * TransactionState.cxx: numerous bugs in TransactionState fixed - (for non-invite transaction) - -2002-11-03 22:27 jason - - * TransactionMap.cxx: fix problem erasing TransactionState from - Tmap - -2002-11-03 22:26 jason - - * TimerMessage.cxx, TimerQueue.cxx: debug output for timer type - -2002-11-03 22:26 jason - - * SipMessage.cxx, SipMessage.hxx: store Resolver and encoded - message in SipMessage - -2002-11-03 22:25 jason - - * Resolver.hxx: modified interface to allow creating Resolver with - Via - -2002-11-03 22:25 jason - - * ParserCategories.cxx: ignored grammar and accept no trailing - space - -2002-11-03 22:24 jason - - * Helper.cxx: add response reasons - -2002-11-03 22:23 jason - - * SendingMessage.cxx, SendingMessage.hxx: [no log message] - -2002-11-03 22:22 jason - - * os/ParseBuffer.hxx: removed - -2002-11-03 22:22 jason - - * ConnectionMap.cxx, ConnectionMap.hxx, Makefile, TcpTransport.cxx, - TcpTransport.hxx, Transport.cxx, Transport.hxx, UdpTransport.cxx: - ConnectionMap, enriched Tuple - -2002-11-03 19:17 fluffy - - * TcpTransport.cxx: [no log message] - -2002-11-03 18:57 jason - - * ConnectionMap.cxx, ConnectionMap.hxx, TcpTransport.cxx, - TcpTransport.hxx: [no log message] - -2002-11-03 17:58 dabryan - - * Transport.hxx: [no log message] - -2002-11-03 17:42 alan - - * SSL.cxx, SSL.hxx: Initial SSL support files. - ------------------------------------------------------------------- - --- - -2002-11-02 17:01 derekm - - * Transport.hxx: mem leak - -2002-11-02 17:00 derekm - - * os/.cvsignore, .cvsignore, Dialog.cxx, test1.cxx, - testParserCategories.cxx: [no log message] - -2002-11-02 15:57 jason - - * Preparse.cxx: change from string to data - -2002-11-02 15:31 fluffy - - * doc/: client-invite-state.tif, client-invite-tree.tif, - client-noninvite-state.tif, client-noninvite-tree.tif, - server-invite-state.tif, server-invite-tree.tif, - server-noninvite-state.tif, server-noninvite-tree.tif, - stale-state.tif, stale-tree.tif: initial creation - -2002-11-02 11:31 jason - - * os/: Data.cxx, Data.hxx: moved outline - -2002-11-01 18:51 jason - - * Dialog.cxx, Dialog.hxx: many fixes - -2002-11-01 16:06 jason - - * Symbols.cxx: changed scheme to lowercase - -2002-11-01 15:49 jason - - * Dialog.cxx, Dialog.hxx: support for creating responses in dialog - -2002-11-01 15:34 jason - - * SipStack.cxx: force app to create transport - -2002-11-01 15:34 jason - - * SipMessage.cxx: brief output for sipmessage - -2002-11-01 15:34 jason - - * Helper.cxx: remove setting to tag in response creation - -2002-11-01 14:01 jason - - * test/testData.cxx: [no log message] - -2002-11-01 14:01 jason - - * os/: Data.cxx, Data.hxx: dont allocate for empty Data - -2002-11-01 11:16 jason - - * SipMessage.cxx, SipMessage.hxx, test1.cxx, test2.cxx: [no log - message] - -2002-11-01 11:14 jason - - * TransactionState.cxx: fix bug in isResponse - -2002-11-01 11:12 jason - - * Transport.cxx, Transport.hxx, TransportSelector.cxx, - UdpTransport.cxx, UdpTransport.hxx, SipStack.cxx: [no log message] - -2002-10-31 23:10 fluffy - - * os/RandomHex.cxx, os/ThreadIf.hxx, os/compat.hxx, os/vmd5.cxx, - Resolver.cxx, SipStack.cxx, SipStack.hxx, Transport.cxx, - Transport.hxx, TransportSelector.cxx, TransportSelector.hxx, - UdpTransport.cxx, UdpTransport.hxx, Uri.hxx: fixed to compile under - windows - -2002-10-31 18:03 jason - - * os/ParseBuffer.cxx: fixed reset -- which should actually be - called set - -2002-10-31 18:02 jason - - * testParserCategories.cxx: [no log message] - -2002-10-31 18:02 jason - - * Helper.cxx, Helper.hxx: added makeRegister added reason to - makeresponse - -2002-10-31 17:51 jason - - * os/Timer.hxx: added doc for timers - -2002-10-31 17:50 jason - - * TransactionState.cxx, TransportSelector.cxx, test1.cxx, - test2.cxx, testSipMessage.cxx, testSipStack1.cxx, Makefile: [no log - message] - -2002-10-31 17:50 jason - - * SipStack.cxx, SipStack.hxx: addTransport added to interface - -2002-10-31 17:49 jason - - * SipMessage.hxx: make constructor explicit since it was having bad - effects - -2002-10-31 17:49 jason - - * SipMessage.cxx: return transaction id (branch) - -2002-10-31 17:49 jason - - * Helper.cxx, Helper.hxx: change methods to return SipMessage* - instead of objects - -2002-10-31 15:29 jason - - * Helper.cxx, ParserCategories.hxx: added beginnings of a loadgen - -2002-10-31 13:43 jason - - * TransportSelector.cxx: removed spurious !'s - -2002-10-31 13:07 jason - - * TransportSelector.cxx: fixed use of via's when picking - destination for a response - -2002-10-31 12:52 jason - - * os/: Data.cxx, Makefile: optimization in the Data stream inserter - -2002-10-31 12:51 jason - - * test/testDataPerformance.cxx: [no log message] - -2002-10-30 22:15 jason - - * os/Data.hxx: added compat for qnx - -2002-10-30 20:18 fluffy - - * os/RandomHex.cxx: fixed evil bug when not using OPENSSL and got - to compile - -2002-10-30 17:39 jason - - * Makefile, os/Makefile: changed over to use vocal build stuff - -2002-10-30 17:38 jason - - * SipMessage.cxx, SipMessage.hxx, TransportSelector.cxx: removed - Data encode - -2002-10-30 17:30 jason - - * ParserCategories.hxx, Uri.cxx, testSipMessage.cxx: [no log - message] - -2002-10-30 17:18 jason - - * test1.cxx: [no log message] - -2002-10-30 17:13 jason - - * ParserCategories.cxx, ParserCategories.hxx, ParserCategory.cxx, - ParserCategory.hxx, Uri.cxx, Uri.hxx, os/Data.hxx, os/compat.hxx: - added opeartor== to URI - -2002-10-30 17:08 jason - - * os/: RandomHex.cxx, compat.hxx: use srandom instead of srand - -2002-10-30 17:08 jason - - * os/.cvsignore, os/Data.hxx, test/testData.cxx, os/vmd5.hxx: [no - log message] - -2002-10-30 17:08 jason - - * UdpTransport.cxx, test1.cxx, testPreparse.cxx, - testSipMessage.cxx: for qnx - -2002-10-30 17:07 jason - - * os/DataStream.cxx, os/DataStream.hxx, test/testDataStream.cxx: - got rid of intermediate buffer in DataStream - -2002-10-30 17:04 jason - - * Resolver.cxx, SipMessage.cxx, TransportSelector.cxx: for qnx - -2002-10-30 17:04 jason - - * .cvsignore, HeaderTypes.hxx: [no log message] - -2002-10-30 15:48 jason - - * os/Data.cxx, os/Data.hxx, os/DataStream.cxx, os/DataStream.hxx, - os/Makefile, test/testData.cxx, test/testDataStream.cxx: added - DataStream - -2002-10-30 12:38 jason - - * UdpTransport.cxx, test1.cxx: [no log message] - -2002-10-30 12:30 jason - - * os/Data.cxx: fix bug in md5 - -2002-10-30 12:30 jason - - * os/Data.cxx: fixed a leak -- set mMine incorrectly - -2002-10-30 10:49 jason - - * SipStack.hxx, TransactionState.cxx, TransactionState.hxx, - Transport.cxx, Transport.hxx, TransportSelector.cxx, - UdpTransport.cxx, UdpTransport.hxx: [no log message] - -2002-10-30 10:49 jason - - * SipMessage.cxx, SipMessage.hxx: fix encode - -2002-10-30 10:49 jason - - * Resolver.cxx: fix the resolver - -2002-10-30 10:48 jason - - * ParserCategories.cxx, ParserCategories.hxx: fixed copy - constructor - -2002-10-30 10:47 jason - - * Helper.cxx, Helper.hxx: failure ack, simple changes to other - message creation - -2002-10-30 10:46 jason - - * os/Data.cxx: use memmove when overlap is possible - -2002-10-30 10:45 jason - - * test1.cxx, Dialog.cxx: [no log message] - -2002-10-30 10:44 jason - - * os/Data.hxx: fixed guard - -2002-10-29 18:14 jason - - * HostSpecification.cxx, HostSpecification.hxx: changed name to - Resolver - -2002-10-29 18:14 jason - - * Makefile, Resolver.cxx, Resolver.hxx, Transport.cxx, - Transport.hxx, TransportSelector.cxx, TransportSelector.hxx, - UdpTransport.cxx, UdpTransport.hxx: first cut at TransportSelector - -2002-10-29 17:10 jason - - * Executive.cxx, Executive.hxx: [no log message] - -2002-10-29 17:10 jason - - * Transport.cxx, Transport.hxx, TransportSelector.cxx, - TransportSelector.hxx, UdpTransport.cxx, UdpTransport.hxx: added - code to create transports in the TransportSelector - -2002-10-29 17:10 jason - - * HostSpecification.cxx, HostSpecification.hxx: added getHostName() - -2002-10-25 17:28 alan - - * ParserCategory.cxx, ParserCategory.hxx, SipMessage.cxx, - Transport.hxx, TransportSelector.cxx, testSipStackInvite.cxx: Many - updates and fixes to coerce a message to the TU and get the - provisional message out the wire. - -2002-10-25 17:28 alan - - * TransactionState.cxx: It is really never a good idea to return a - reference to an object on the stack. - -2002-10-25 13:32 alan - - * ParserCategory.cxx: Removed accidental logic flip in ctor. - -2002-10-25 12:43 alan - - * ChangeLog, HostSpecification.cxx, ParserCategories.cxx, - ParserCategory.cxx, ParserCategory.hxx, SipMessage.hxx, - SipStack.cxx, TransactionState.cxx, TransactionState.hxx, - UdpTransport.cxx, doc/design-overview.xml, os/Log.hxx, - os/ParseBuffer.cxx, os/ParseBuffer.hxx: General Bug fixes and clean - up. See ChangeLog - -2002-10-22 16:51 alan - - * Preparse.cxx, Transport.cxx, UdpTransport.cxx, os/Subsystem.cxx, - os/Subsystem.hxx: Added changes that fix Preparse Added Subsystem - APP class Fixed Bug in Transport fd_set generation - -2002-10-22 08:57 jason - - * Symbols.cxx, Symbols.hxx, TimerQueue.cxx, Transport.cxx, - Transport.hxx, UdpTransport.cxx, UdpTransport.hxx, - TransportSelector.cxx, testSipStack1.cxx, HostSpecification.cxx, - HostSpecification.hxx, Helper.cxx, Helper.hxx, Makefile: [no log - message] - -2002-10-22 08:56 jason - - * ParserCategories.hxx: initialize via parameters for protocol and - version - -2002-10-22 08:47 jason - - * os/ThreadIf.cxx: [no log message] - -2002-10-22 08:47 jason - - * os/: ParseBuffer.cxx, ParseBuffer.hxx: add a data method that - makes a copy - -2002-10-22 08:47 jason - - * os/Fifo.hxx: cache fifo size - -2002-10-21 15:49 jason - - * os/vmd5.cxx, os/vmd5.hxx, os/Data.cxx, os/Data.hxx, - test/testData.cxx, os/Makefile: steal md5 stuff from vocal - -2002-10-21 15:46 jason - - * Headers.hxx: added typedefs for ParserContainer<{parser - category}> for multi-categories, e.g. Vias - -2002-10-21 13:28 jason - - * SipMessage.cxx, SipMessage.hxx, SipStack.cxx, - TransportSelector.cxx: [no log message] - -2002-10-21 13:28 jason - - * TransactionState.cxx: added debug - -2002-10-19 10:11 jason - - * os/Data.cxx, test/testData.cxx: corrected tests for - Data::operator< - -2002-10-19 09:23 fluffy - - * os/Timer.cxx: updated CPU speed list - -2002-10-19 09:23 fluffy - - * os/Data.cxx: fixed bogus operator < - did not test - -2002-10-15 14:09 alan - - * .cvsignore: Added local test loop - -2002-10-15 14:06 alan - - * SipMessage.cxx, testSimpleLeak.cxx, testSipMessageMemory.cxx: - Added looping to testSipMessageMemory. Added memory debugging. - -2002-10-15 13:50 jason - - * ParserContainer.hxx: added a destructor, oops - -2002-10-15 13:49 fluffy - - * .cvsignore: [no log message] - -2002-10-15 11:03 jason - - * os/Data.cxx, os/Data.hxx, test/testData.cxx: added operator< hash - uses Data::data() rather than Data::c_str() - -2002-10-15 10:35 alan - - * testSipMessage.cxx, Preparse.cxx, Preparse.hxx: Fixed looping - buffer processing - -2002-10-15 08:53 jason - - * os/: Data.cxx, Data.hxx: minor mods for gcc-2.9x - -2002-10-15 08:46 alan - - * os/: Lock.cxx, Lock.hxx, Lockable.hxx, Mutex.cxx, Mutex.hxx: - Moved Licenses to EOF - -2002-10-13 09:20 jason - - * os/Timer.cxx: changed (unsigned long) cast style to compile - -2002-10-13 09:19 jason - - * SipMessage.cxx, os/compat.hxx: use Data.data() rather than - data.c_str() -- data never copies - -2002-10-12 23:02 jason - - * DataParameter.cxx, HeaderFieldValue.cxx, Headers.cxx, - MethodTypes.cxx, MethodTypes.hxx, Parameter.cxx, - ParameterTypes.cxx, ParserCategories.cxx, ParserCategories.hxx, - ParserCategory.cxx, SipMessage.cxx, Uri.cxx, methods.gperf, - testParserCategories.cxx, testSipMessage.cxx, os/Data.cxx, - os/Data.hxx, os/Makefile, os/ParseBuffer.cxx, os/ParseBuffer.hxx, - test/testData.cxx, test/testParseBuffer.cxx: modified - ParserBuffer::data to cause memory sharing in the Data reference - arg - -2002-10-12 20:46 fluffy - - * os/ParseBuffer.cxx, os/Timer.cxx, Transport.cxx: few windows - updates - -2002-10-12 20:37 fluffy - - * os/Data.cxx, os/Mutex.cxx, Headers.hxx, Helper.cxx, - ParameterTypes.hxx, ParserCategory.cxx, ParserCategory.hxx, - TimerQueue.cxx, UdpTransport.cxx, Transport.cxx: few windows - updates - -2002-10-12 19:26 fluffy - - * os/Data.hxx, os/Inserter.hxx, os/Log.cxx, os/Logger.hxx, - os/compat.hxx, Executive.hxx, HeaderTypes.cxx, Headers.hxx, - Transport.hxx, TransportSelector.hxx: few windows updates - -2002-10-08 11:34 jason - - * SipMessage.cxx: notes for Unknown backward compatibility - -2002-10-08 03:14 jason - - * FloatParameter.cxx, HeaderFieldValueList.cxx, Preparse.cxx, - testSipMessage.cxx: member initializers, turn on testSipMessage - -2002-10-08 03:09 jason - - * TimerQueue.cxx, TimerQueue.hxx, testTimer.cxx, os/Timer.cxx, - os/Timer.hxx: added << to Timer fixed TimerQueue bug, tested - -2002-10-07 12:19 jason - - * HeaderTypes.hxx, ParserCategories.cxx, ParserCategory.cxx, - ParserContainer.hxx, SipMessage.cxx, Uri.cxx, Uri.hxx, - testSipMessage.cxx, os/Data.hxx: fixed some leaks, initializers, - Via parser test copying parts across messages - -2002-10-07 08:47 jason - - * testSipMessage.cxx: added more testing - -2002-10-07 08:28 jason - - * HeaderFieldValue.cxx, HeaderFieldValue.hxx, - HeaderFieldValueList.cxx, ParserCategory.cxx, SipMessage.cxx: - remove back pointer from HeaderFieldValue to ParserCategory -- have - HeaderFieldValueList => ParserContainer => ParserCategory => - HeaderFieldValue - -2002-10-07 08:13 jason - - * HeaderFieldValueList.cxx, HeaderFieldValueList.hxx, - HeaderTypes.hxx, ParserCategories.cxx, ParserContainer.hxx, - ParserContainerBase.hxx, SipMessage.cxx, SipMessage.hxx: SipMessage - copy constructor works using HeaderFieldValueList to hold - RequestLine, StatusLine - -2002-10-06 22:39 jason - - * ParserCategories.cxx: [no log message] - -2002-10-06 13:59 jason - - * HeaderFieldValueList.hxx, ParserCategories.hxx, os/Data.cxx, - os/Data.hxx, os/Log.cxx, os/Log.hxx, os/Subsystem.cxx, - os/Subsystem.hxx, os/ThreadIf.cxx: change Data to contain rather - than inherit from string much reduced interface to Data still needs - to get a more efficient implementation - -2002-10-06 12:00 jason - - * testSipMessage.cxx: [no log message] - -2002-10-06 11:45 jason - - * testSipMessage.cxx: added a test case to copy a SipMessage - -2002-10-06 11:36 jason - - * testSipStack1.cxx: added some code to create and send a sip - message - -2002-10-06 11:34 jason - - * Transport.cxx, TransportSelector.cxx, UdpTransport.cxx: add - exception handler - -2002-10-06 11:34 jason - - * ParserCategories.cxx: mods to copy constructor to initialize all - members for NameAddr - -2002-10-06 11:33 jason - - * ParseException.hxx, SipMessage.hxx, Transport.hxx: changed - VException signature - -2002-10-06 11:33 jason - - * Makefile: add openssl back in - -2002-10-06 11:33 jason - - * Helper.cxx, Helper.hxx: add some helpers (remove others) - -2002-10-06 11:32 jason - - * HeaderFieldValue.cxx: remove assert, and replace with InfoLog - -2002-10-06 11:32 jason - - * Dialog.cxx: remove an out of date helper - -2002-10-06 11:31 jason - - * os/: ParseBuffer.hxx, VException.cxx, VException.hxx: change - signature of VException - -2002-10-06 11:31 jason - - * os/RandomHex.cxx: use openssl on non-windows - -2002-10-06 08:39 jason - - * MethodTypes.cxx, MethodTypes.hxx, ParserCategory.hxx, - Symbols.cxx, Symbols.hxx, Uri.cxx, Uri.hxx, testSipMessage.cxx: - ParserCategory created from a fake HeaderFieldValue is parsed fixed - Response method name added DefaultSipScheme fixed Uri::encode - simple tests for creating headers in messages - -2002-10-06 08:07 jason - - * testSipMessage.cxx: added simple header creation test - -2002-10-05 18:11 jason - - * ParserCategories.cxx, ParserCategories.hxx: create lazy Uri in - NameAddr and RequestLine - -2002-10-05 11:11 jason - - * HeaderFieldValue.cxx, HeaderFieldValue.hxx, ParserCategories.cxx, - ParserCategories.hxx, ParserCategory.cxx, ParserContainer.hxx: - parser container uses list added operator= to all parser - categories - -2002-10-04 21:47 fluffy - - * testSipStack1.cxx: fixed license statements - -2002-10-04 21:44 fluffy - - * os/Inserter.hxx, os/Log.cxx, os/Log.hxx, os/Logger.cxx, - os/Logger.hxx, os/ParseBuffer.cxx, os/ParseBuffer.hxx, - os/RandomHex.cxx, os/Socket.cxx, os/Socket.hxx, os/Subsystem.cxx, - os/Subsystem.hxx, os/SysLogBuf.hxx, os/SysLogStream.hxx, - os/Timer.cxx, os/Timer.hxx, os/compat.hxx, - test/testParseBuffer.cxx, DataParameter.cxx, DataParameter.hxx, - Dialog.cxx, Dialog.hxx, Executive.cxx, Executive.hxx, - ExistsParameter.cxx, ExistsParameter.hxx, FloatParameter.cxx, - FloatParameter.hxx, HeaderFieldValue.cxx, HeaderFieldValue.hxx, - HeaderFieldValueList.cxx, HeaderFieldValueList.hxx, - HeaderTypes.cxx, HeaderTypes.hxx, Headers.cxx, Headers.hxx, - Helper.cxx, Helper.hxx, HostSpecification.hxx, - IntegerParameter.cxx, IntegerParameter.hxx, Message.cxx, - Message.hxx, MethodTypes.cxx, MethodTypes.hxx, Parameter.cxx, - Parameter.hxx, ParameterTypeEnums.hxx, ParameterTypes.cxx, - ParameterTypes.hxx, ParseException.hxx, ParserCategories.cxx, - ParserCategories.hxx, ParserCategory.cxx, ParserCategory.hxx, - ParserContainer.hxx, ParserContainerBase.hxx, Preparse.cxx, - Preparse.hxx, SipMessage.cxx, SipMessage.hxx, - SipMessageExplicit.cxx, SipMessageExplicit.hxx, SipStack.cxx, - SipStack.hxx, Symbols.cxx, Symbols.hxx, TimerMessage.cxx, - TimerMessage.hxx, TimerQueue.cxx, TimerQueue.hxx, - TransactionMap.cxx, TransactionMap.hxx, TransactionState.cxx, - TransactionState.hxx, Transport.cxx, Transport.hxx, - TransportSelector.cxx, TransportSelector.hxx, UdpTransport.cxx, - UdpTransport.hxx, UnknownParameter.cxx, UnknownParameter.hxx, - Uri.cxx, Uri.hxx, convertStringToInt.cxx, supported.hxx, - testHash.cxx, testHashCasen.cxx, testHeaderFieldValueList.cxx, - testParserCategories.cxx, testPreparse.cxx, testSipMessage.cxx, - testSipMessageMemory.cxx, testTypes.cxx, testUdp.cxx, testpp.cxx: - fixed license statements - -2002-10-04 21:30 fluffy - - * SipMessage.cxx, TransactionState.cxx, testSipStack1.cxx: [no log - message] - -2002-10-04 19:22 jason - - * .cvsignore, FloatParameter.cxx, HeaderTypes.hxx, Headers.cxx, - Headers.hxx, IntegerParameter.cxx, Makefile, MethodTypes.hxx, - ParserCategories.cxx, ParserCategories.hxx, ParserContainer.hxx, - ParserContainerBase.hxx, SipMessage.cxx, SipMessage.hxx, Uri.cxx, - testSipMessage.cxx, torture.txt, os/ParseBuffer.cxx, - os/ParseBuffer.hxx, test/testParseBuffer.cxx: ParseBuffer parses - integers and strings fixed some parsed encode bugs -- still some - work to do checked in sip torture test as text - -2002-10-04 18:17 jason - - * DataParameter.cxx, DataParameter.hxx, HeaderFieldValue.hxx, - Parameter.hxx, ParserCategories.hxx, ParserCategory.hxx, - SipMessage.cxx: fix warnings - -2002-10-04 18:12 jason - - * os/: Condition.cxx, ParseBuffer.cxx, ParseBuffer.hxx, - RandomHex.cxx: fix warnings - -2002-10-04 13:54 jason - - * Transport.hxx, TransportSelector.hxx, UdpTransport.cxx: compat - (qnx and others) - -2002-10-04 13:53 jason - - * HeaderTypes.cxx, ParameterTypes.cxx, ParserCategory.cxx: compat - -2002-10-04 13:52 jason - - * Executive.hxx: [no log message] - -2002-10-04 13:52 jason - - * os/Logger.hxx: added in compatibility with older versions of gcc - -2002-10-04 13:52 jason - - * os/: Data.hxx, compat.hxx: added in common stuff for - compatibility between o/s - -2002-10-04 13:49 jason - - * os/Log.cxx: [no log message] - -2002-10-04 13:48 jason - - * HeaderFieldValue.cxx, HeaderFieldValue.hxx, - HeaderFieldValueList.cxx, HeaderFieldValueList.hxx, - ParserCategory.cxx, ParserCategory.hxx, ParserContainer.hxx, - SipMessage.cxx, SipMessage.hxx, testSipMessage.cxx, - testSipMessageMemory.cxx: more fixes to header memory management, - wrote a few raw and parsed header moving tests - -2002-10-04 10:58 jason - - * HeaderTypes.hxx, Preparse.cxx, os/Logger.hxx: fixed variadic - macros, again, sigh - -2002-10-04 10:24 jason - - * testSipStack1.cxx: [no log message] - -2002-10-04 09:54 alan - - * ChangeLog, Preparse.cxx: Added pre-parse hooks - -2002-10-04 09:48 alan - - * ChangeLog, ParserCategories.cxx, Preparse.cxx, SipMessage.cxx, - SipMessage.hxx, Symbols.cxx, Symbols.hxx, doc/design-overview.xml: - Added pre-parse hooks and const correctness. Added Symbol pkg to - Preparser - -2002-10-03 22:48 fluffy - - * os/Log.cxx: fixed some ^M things - -2002-10-03 22:35 fluffy - - * Executive.cxx, Executive.hxx, Makefile, SipStack.cxx, - SipStack.hxx, Transport.cxx, Transport.hxx, TransportSelector.cxx, - TransportSelector.hxx, UdpTransport.cxx, UdpTransport.hxx, - testSipStack1.cxx: cleaned up use file descriptors for select - -2002-10-03 19:16 jason - - * HeaderFieldValueList.cxx, HeaderFieldValueList.hxx, - ParserCategory.cxx, ParserCategory.hxx, ParserContainer.hxx, - ParserContainerBase.hxx, SipMessage.cxx, testSipMessage.cxx: - simplified HeaderFieldValueList/ParserContainer - HeaderFieldValue/ParserContainer memory management, cloning, - assigning fixed encode to be as lazy as possible - -2002-10-03 16:39 jason - - * ParameterTypeEnums.hxx, ParameterTypes.cxx, ParameterTypes.hxx, - ParserCategories.cxx, ParserCategory.cxx, ParserCategory.hxx, - SipMessage.cxx, Symbols.cxx, Symbols.hxx, Uri.cxx, - parameters.gperf, testParserCategories.cxx: move uri parameters - from header to uri fixed uri parser bug more tests - -2002-10-03 12:49 jason - - * HeaderFieldValue.hxx, Makefile, ParameterList.cxx, - ParameterList.hxx, ParserCategory.cxx, SipMessage.cxx, - SipMessage.hxx, testParameterList.cxx, testSipMessage.cxx: removed - ParameterList wrote a strawman setStartLine implmented isRequest, - isResponse fixed StartLine and StatusLine retrieval - -2002-10-03 09:40 jason - - * FloatParameter.cxx, FloatParameter.hxx, HeaderTypes.cxx, - HeaderTypes.hxx, ParameterTypes.cxx, ParameterTypes.hxx, - ParserCategory.cxx, ParserCategory.hxx, SipMessage.cxx, - SipMessage.hxx, headers.gperf: unrolled the classes and methods for - in header/parameter type safety - -2002-10-02 22:13 fluffy - - * os/Log.cxx, Parameter.hxx: no message - -2002-10-02 22:05 fluffy - - * os/: Mutex.hxx, ParseBuffer.hxx, Timer.cxx, ParseBuffer.cxx, - ThreadIf.cxx, ThreadIf.hxx: no message - -2002-10-02 20:56 fluffy - - * os/Data.hxx: small chave to compile in windows - -2002-10-02 17:21 jason - - * HeaderFieldValueList.cxx, SipMessage.cxx, testSipMessage.cxx: - fixed some initializers, got testSipMessage going with Preparse - -2002-10-02 16:08 jason - - * HeaderFieldValue.cxx, HeaderFieldValue.hxx, Makefile, - Parameter.cxx, Parameter.hxx, ParseException.hxx, - ParserCategories.cxx, ParserCategories.hxx, ParserCategory.cxx, - ParserCategory.hxx, SipMessage.cxx, SipMessage.hxx, Uri.cxx, - testParserCategories.cxx, os/Data.hxx, os/Makefile, - os/ParseBuffer.cxx, os/ParseBuffer.hxx, os/VException.cxx: - ParameterLists moved to ParserCategory reimplemented ParameterLists - in stl fixed some destructors (leaked) fixed some parsers (missing - some validation), added interface to ParseBuffer added - ParseBuffer::Exception implemented ParseException as VException - implemented isEqualNoCase global function to Data - -2002-10-01 18:43 jason - - * DataParameter.cxx, ExistsParameter.cxx, FloatParameter.cxx, - HeaderFieldValue.cxx, IntegerParameter.cxx, ParserCategories.cxx, - SipMessage.hxx, Symbols.cxx, Symbols.hxx, Uri.cxx, Uri.hxx, - testParserCategories.cxx, testSipMessage.cxx, os/ParseBuffer.cxx, - os/ParseBuffer.hxx: added Uri, NameAddr, RequestLine parsers & - tests. - -2002-10-01 14:42 alan - - * os/RandomHex.cxx: Added stdio.h (needed for sprintf) - -2002-10-01 14:19 jason - - * HeaderFieldValue.cxx, HeaderFieldValue.hxx, - HeaderFieldValueList.hxx, HeaderTypes.cxx, HeaderTypes.hxx, - ParameterList.cxx, ParameterTypes.cxx, ParameterTypes.hxx, - ParserCategories.cxx, ParserCategory.cxx, ParserCategory.hxx, - ParserContainer.hxx, Preparse.cxx, SipMessage.cxx, SipMessage.hxx, - SipStack.hxx, parameters.gperf, testParserCategories.cxx, - os/Data.hxx, os/ParseBuffer.cxx, os/ParseBuffer.hxx, - test/testParseBuffer.cxx: fixed gperf hashes -- please ask before - messing with them added Via parser, encode, and a test parameter - encode - -2002-10-01 07:53 fluffy - - * os/Fifo.hxx, os/Logger.hxx, ParameterTypes.cxx, UdpTransport.cxx: - few windows port updates - -2002-09-30 19:22 jason - - * Makefile: [no log message] - -2002-09-30 19:21 jason - - * DataParameter.cxx, ExistsParameter.cxx, HeaderFieldValue.cxx, - HeaderFieldValue.hxx, IntegerParameter.cxx, IntegerParameter.hxx, - MethodTypes.cxx, ParameterList.cxx, ParameterList.hxx, - ParameterTypes.cxx, ParserCategories.cxx, ParserCategory.cxx, - ParserCategory.hxx, testParameterList.cxx: parser work in progress. - gPerf workaround(gperf didn't build a correct hash) less explicit - data constructor parameter parsing/retrieval via parser(untested) - -2002-09-30 16:19 jason - - * MethodTypes.cxx: added definition of strncasecmp - -2002-09-30 14:47 jason - - * Transport.cxx, Transport.hxx, UdpTransport.cxx: fixed SendData - constructor to take address reference - -2002-09-30 14:46 jason - - * DataParameter.cxx, DataParameter.hxx, ExistsParameter.cxx, - ExistsParameter.hxx, FloatParameter.cxx, FloatParameter.hxx, - HeaderFieldValue.cxx, IntegerParameter.cxx, IntegerParameter.hxx, - ParameterTypeEnums.hxx, ParameterTypes.cxx, ParameterTypes.hxx, - SipMessage.cxx, SipMessage.hxx, Symbols.cxx, Symbols.hxx, - UnknownParameter.cxx, UnknownParameter.hxx: addded decode, used - ParseBuffer - -2002-09-30 14:19 jason - - * os/: ParseBuffer.cxx, ParseBuffer.hxx: ++ confusion - -2002-09-30 13:55 jason - - * os/ThreadIf.cxx: #ifdeffed out WIN32 clause - -2002-09-30 13:53 jason - - * os/Makefile, os/ParseBuffer.cxx, os/ParseBuffer.hxx, - test/testParseBuffer.cxx: in-place non-destructive parsing - -2002-09-30 12:22 jason - - * Dialog.cxx, Dialog.hxx, Helper.cxx, Helper.hxx, - ParserCategory.cxx, ParserCategory.hxx, SipMessage.hxx, Uri.hxx: - replaced Url w/ nameAddr. changed to param(p_foo) from [p_foo] - syntax. For safety w/ pointers and to avoid uri()[p_foo] uglyness. - -2002-09-30 11:53 jason - - * TimerQueue.cxx: fixed process--would only haved processed timers - that are now - -2002-09-30 11:49 jason - - * os/Logger.hxx: recorrected the __VA_ARGS macros - -2002-09-29 16:41 fluffy - - * os/Data.hxx, os/Fifo.cxx, os/Log.cxx, os/Logger.hxx, - os/Mutex.cxx, os/RandomHex.cxx, os/Socket.cxx, os/Socket.hxx, - os/SysLogBuf.hxx, os/ThreadIf.cxx, os/ThreadIf.hxx, - os/VException.cxx, HeaderFieldValue.cxx, HeaderFieldValue.hxx, - HeaderTypes.cxx, HeaderTypes.hxx, MethodTypes.cxx, - ParserCategories.cxx, ParserCategory.hxx, Preparse.cxx, - SipMessage.cxx, SipMessage.hxx, SipStack.cxx, TimerQueue.cxx, - Transport.cxx, Transport.hxx, UdpTransport.cxx, testUdp.cxx: - changes for Win32 - -2002-09-29 10:14 jason - - * os/Mutex.hxx: [no log message] - -2002-09-28 17:47 alan - - * doc/: .cvsignore, Makefile, design-overview.xml, design.css, - htmlcss.xsl: Added XML DocBook design doc (initial) - -2002-09-28 10:30 fluffy - - * os/: Condition.cxx, Condition.hxx, Fifo.hxx: cleaned up Fifo - -2002-09-28 10:01 fluffy - - * os/: ThreadIf.cxx, ThreadIf.hxx: added some win32 stuff - -2002-09-28 09:41 fluffy - - * os/: Condition.cxx, Condition.hxx, Fifo.hxx, Makefile, Mutex.cxx, - Mutex.hxx, RandomHex.cxx, ThreadIf.cxx, ThreadIf.hxx, Fifo.cxx, - Fifo.cc: cleaned up thread and lock abstractions - -2002-09-28 08:22 fluffy - - * DataParameter.cxx: fix include - -2002-09-28 08:22 fluffy - - * convertStringToInt.cxx: fix return - -2002-09-27 23:13 jason - - * SipMessage.cxx, SipMessage.hxx, SipMessageExplicit.cxx: hoisted - some code out of the template methods - -2002-09-27 22:35 jason - - * SipMessage.cxx, SipMessage.hxx, SipMessageExplicit.cxx, - SipMessageExplicit.hxx: #if switched method templating/explicit - method declaration and defining - -2002-09-27 22:02 fluffy - - * SIPSTACK.dsp: no message - -2002-09-27 21:59 fluffy - - * Transport.hxx, UdpTransport.cxx: switched file descriptors to - Socket - -2002-09-27 21:47 fluffy - - * SipStack.cxx, SipStack.hxx, testSipStack1.cxx: added the fd_set - stuff to the interface - -2002-09-27 21:44 fluffy - - * os/: Makefile, Socket.cxx, Socket.hxx: added Socket class that is - a file descriptor in unix and a SOCKET in windows - -2002-09-27 18:38 jason - - * Dialog.cxx, HeaderFieldValue.cxx, HeaderFieldValue.hxx, - HeaderTypes.cxx, HeaderTypes.hxx, Helper.cxx, Helper.hxx, - HostSpecification.hxx, Makefile, MethodTypes.hxx, - ParserCategories.cxx, ParserCategories.hxx, ParserCategory.hxx, - SipMessage.cxx, SipMessage.hxx, Symbols.cxx, Symbols.hxx, Uri.cxx, - Uri.hxx: Uri component NameAddr is back NameAddr and RequestLine - have a Uri - -2002-09-27 11:24 jason - - * .cvsignore: [no log message] - -2002-09-27 10:43 jason - - * os/Inserter.hxx: [no log message] - -2002-09-27 06:52 fluffy - - * os/RandomHex.cxx: removed open ssl rand stuff - -2002-09-27 06:48 fluffy - - * Makefile, os/Makefile: [no log message] - -2002-09-26 20:02 alan - - * .cvsignore: Added html subdir - -2002-09-26 19:49 alan - - * .cvsignore, ChangeLog, HeaderTypes.cxx, HeaderTypes.hxx, - Makefile, Symbols.cxx, headers.gperf, testHash.cxx: See changelog. - Fixed up hash routines so they work. :-) - -2002-09-26 19:00 jason - - * os/: Data.cxx, Data.hxx: [no log message] - -2002-09-26 17:24 jason - - * HeaderTypes.cxx, HeaderTypes.hxx: fixed some header - declaration/definition issues -- still need to make crossed - MultiHeader/Header decls not compile - -2002-09-26 17:00 jason - - * DataParameter.cxx, DataParameter.hxx, HeaderFieldValue.cxx, - HeaderFieldValue.hxx, Parameter.hxx, ParserCategories.cxx, - ParserCategory.cxx, ParserCategory.hxx, Symbols.cxx, Symbols.hxx, - UnknownParameter.hxx: parser stuff - -2002-09-26 15:00 alan - - * .cvsignore, HeaderTypes.cxx, HeaderTypes.hxx, Makefile, - testTypes.cxx: Adding testTypes - -2002-09-26 14:58 jason - - * HeaderFieldValue.cxx, HeaderFieldValue.hxx, Helper.hxx, - ParserCategory.cxx, ParserCategory.hxx, os/VException.cxx, - os/VException.hxx: [no log message] - -2002-09-26 13:57 jason - - * DataParameter.cxx, DataParameter.hxx, FloatParameter.hxx, - HeaderFieldValue.cxx, HeaderFieldValue.hxx, HeaderTypes.cxx, - HeaderTypes.hxx, IntegerParameter.hxx, Parameter.cxx, - Parameter.hxx, ParameterList.cxx, ParameterTypeEnums.hxx, - ParameterTypes.cxx, ParserCategories.cxx, ParserCategory.cxx, - ParserCategory.hxx, UnknownParameter.cxx, UnknownParameter.hxx, - headers.gperf, parameters.gperf: parser stuff - -2002-09-26 12:46 jason - - * Dialog.cxx, Dialog.hxx, HeaderTypes.cxx, HeaderTypes.hxx, - Makefile, ParserCategories.hxx, ParserContainer.hxx, - SipMessage.cxx, SipMessage.hxx, SipStack.cxx, SipStack.hxx, - Symbols.cxx, Symbols.hxx: [no log message] - -2002-09-26 10:45 jason - - * ParserCategories.hxx, ParserCategory.cxx, ParserCategory.hxx: [no - log message] - -2002-09-25 20:56 fluffy - - * doc/ClassDiag.vsd: first cut - -2002-09-25 20:36 jason - - * HeaderFieldValue.cxx, HeaderFieldValue.hxx, ParseException.hxx, - ParserCategories.cxx, ParserCategory.cxx, ParserCategory.hxx: - parser stuff - -2002-09-25 19:03 jason - - * Helper.hxx, ParserCategories.hxx, os/Data.cxx, os/Data.hxx: [no - log message] - -2002-09-25 18:48 jason - - * testHashCasen.cxx: playing around with hashing functions - -2002-09-25 18:12 jason - - * HeaderFieldValue.cxx, HeaderFieldValueList.cxx, - HeaderFieldValueList.hxx, HeaderTypes.cxx, HeaderTypes.hxx, - Message.cxx, Message.hxx, MethodTypes.cxx, MethodTypes.hxx, - ParserCategories.cxx, ParserCategories.hxx, ParserCategory.cxx, - ParserCategory.hxx, ParserContainer.hxx, ParserContainerBase.hxx, - SipMessage.cxx, SipMessage.hxx, SipStack.cxx, Symbols.cxx, - Symbols.hxx, TimerMessage.cxx, TimerMessage.hxx, - TransactionState.cxx: ParserContainerBase no longer a - ParserCategory Added string names to headers, comma tokenizing in - constructor casts => dynamic_cast - -2002-09-25 17:46 jason - - * os/RandomHex.cxx: [no log message] - -2002-09-25 17:34 jason - - * Makefile, os/Makefile: [no log message] - -2002-09-25 17:30 jason - - * Makefile, os/Makefile, os/Subsystem.cxx, os/Subsystem.hxx: [no - log message] - -2002-09-25 15:50 jason - - * os/: .cvsignore, Inserter.hxx, Makefile, RandomHex.cxx, - RandomHex.hxx: [no log message] - -2002-09-25 15:28 jason - - * Singleton.h, Threads.h: [no log message] - -2002-09-25 15:25 jason - - * Condition.cxx, Condition.hxx, Data.cxx, Data.hxx, - DataParameter.hxx, Dialog.cxx, Executive.cxx, Fifo.cc, Fifo.hxx, - FloatSubComponent.cxx, FloatSubComponent.hxx, HeaderTypes.cxx, - HeaderTypes.hxx, HostSpecification.hxx, IntSubComponent.cxx, - IntSubComponent.hxx, Lock.cxx, Lock.hxx, Lockable.hxx, Log.cxx, - Log.hxx, Logger.cxx, Logger.hxx, Makefile, Message.hxx, - MethodTypes.cxx, Mutex.cxx, Mutex.hxx, Parameter.hxx, - ParameterTypeEnums.hxx, ParameterTypes.hxx, ParserCategories.hxx, - ParserCategory.hxx, ParserContainerBase.hxx, Preparse.cxx, - SipMessage.hxx, SipStack.cxx, SipStack.hxx, StringSubComponent.cxx, - StringSubComponent.hxx, SubComponent.cxx, SubComponent.hxx, - SubComponentList.cxx, SubComponentList.hxx, Subsystem.cxx, - Subsystem.hxx, SysLogBuf.hxx, SysLogStream.hxx, ThreadIf.cxx, - ThreadIf.hxx, Timer.cxx, Timer.hxx, TimerMessage.hxx, - TimerQueue.cxx, TimerQueue.hxx, TransactionMap.cxx, - TransactionMap.hxx, TransactionState.cxx, Transport.hxx, - TransportSelector.hxx, UdpTransport.cxx, UnknownSubComponent.cxx, - UnknownSubComponent.hxx, testHeaderFieldValueList.cxx, testMsg.cxx, - testPreparse.cxx, testSipStack1.cxx, testSubComponentList.cxx, - testUdp.cxx, vthread.hxx: moved util classes into ../util - -2002-09-25 15:24 jason - - * os/: Condition.cxx, Condition.hxx, Data.cxx, Data.hxx, Fifo.cc, - Fifo.hxx, Lock.cxx, Lock.hxx, Lockable.hxx, Log.cxx, Log.hxx, - Logger.cxx, Logger.hxx, Makefile, Mutex.cxx, Mutex.hxx, - Subsystem.cxx, Subsystem.hxx, SysLogBuf.hxx, SysLogStream.hxx, - ThreadIf.cxx, ThreadIf.hxx, Timer.cxx, Timer.hxx, vthread.hxx: - moved util classes into here - -2002-09-25 15:08 jason - - * Dialog.cxx, Dialog.hxx, Helper.hxx, ParameterTypeEnums.hxx, - ParameterTypes.hxx, Symbols.cxx, Symbols.hxx: [no log message] - -2002-09-25 15:02 jason - - * HeaderFieldValue.cxx, HeaderFieldValue.hxx, Helper.cxx, Makefile, - ParserCategories.cxx, ParserCategory.cxx, ParserCategory.hxx, - ParserContainer.hxx, SipMessage.cxx: [no log message] - -2002-09-25 13:13 jason - - * ParserCategories.cxx, ParserCategories.hxx, ParserCategory.cxx, - ParserCategory.hxx: << ParserCategory Symbols::DefaultSipVersion - -2002-09-25 13:09 jason - - * Dialog.cxx, Helper.hxx: [no log message] - -2002-09-25 13:05 jason - - * ParserCategories.cxx, ParserCategories.hxx, ParserContainer.hxx, - SipMessage.hxx, Symbols.cxx, Symbols.hxx: RequestLineComponent => - RequestLine StatusLineComponent => StatusLine - -2002-09-25 13:04 jason - - * Helper.hxx: [no log message] - -2002-09-25 13:00 jason - - * Helper.hxx: [no log message] - -2002-09-25 12:50 jason - - * Helper.hxx: [no log message] - -2002-09-25 12:45 jason - - * ParserCategories.cxx, ParserCategories.hxx: collapsed NameAddr, - NameAddrOrAddrSpec, Contact int Url - -2002-09-25 12:40 jason - - * Dialog.cxx, Dialog.hxx, ThreadIf.cxx, ThreadIf.hxx, vthread.hxx, - Makefile: [no log message] - -2002-09-25 12:37 jason - - * ParserCategories.hxx, HeaderTypes.hxx: collapsed NameAddr, - NameAddrOrAddrSpec, Contact int Url - -2002-09-25 12:17 jason - - * HeaderTypes.cxx, HeaderTypes.hxx, TransactionState.cxx: changed - to h_CamelCase convention - -2002-09-25 12:08 jason - - * ExistsParameter.hxx, FloatParameter.hxx, HeaderTypes.cxx, - HeaderTypes.hxx: [no log message] - -2002-09-25 12:03 jason - - * DataParameter.hxx, ExistsParameter.hxx, FloatParameter.hxx, - HeaderFieldValue.hxx, HeaderFieldValueList.cxx, HeaderTypes.cxx, - HeaderTypes.hxx, IntegerParameter.hxx, ParserCategory.hxx, - ParserContainer.hxx, SipMessage.hxx: fix to SipMessage templated - methods - -2002-09-25 11:57 jason - - * SipStack.cxx, SipStack.hxx: changed interface for SipStack::send - -2002-09-25 09:42 jason - - * Dialog.cxx, SipMessage.hxx: [no log message] - -2002-09-25 07:59 jason - - * testParameterList.cxx: [no log message] - -2002-09-25 07:26 alan - - * UdpTransport.cxx, UdpTransport.hxx: Fixed up some compile issues. - Changed type for MaxBufferSize to size_t. Unsigned long was not - appropriate. - -2002-09-24 22:41 jason - - * ExistsParameter.hxx, FloatParameter.hxx, HeaderTypes.cxx, - HeaderTypes.hxx, ParserCategories.hxx, ParserCategory.hxx, - SubComponentList.hxx, TransactionState.cxx: [no log message] - -2002-09-24 22:23 jason - - * Helper.hxx, ParserCategories.hxx: [no log message] - -2002-09-24 21:49 jason - - * Makefile, testSubComponentList.cxx: SubComponent => Parameter - -2002-09-24 21:42 jason - - * DataParameter.cxx, DataParameter.hxx, ExistsParameter.cxx, - ExistsParameter.hxx, FloatParameter.cxx, FloatParameter.hxx, - HeaderFieldValue.cxx, HeaderFieldValue.hxx, HeaderTypes.cxx, - HeaderTypes.hxx, IntegerParameter.cxx, IntegerParameter.hxx, - Makefile, Parameter.cxx, Parameter.hxx, ParameterList.cxx, - ParameterList.hxx, ParameterTypeEnums.hxx, ParameterTypes.cxx, - ParameterTypes.hxx, ParserCategory.hxx, README, SipMessage.cxx, - SipMessage.hxx, SubComponent.hxx, Symbols.cxx, Symbols.hxx, - TransactionState.cxx, UnknownParameter.cxx, UnknownParameter.hxx: - SubComponent => Parameter - -2002-09-24 21:32 fluffy - - * SIPSTACK.dsw: SIPSTACK.dsp - -2002-09-24 21:30 fluffy - - * Condition.cxx, FloatSubComponent.hxx, Log.cxx, Log.hxx, Makefile, - MethodTypes.cxx, Mutex.cxx, Mutex.hxx, ParserCategories.cxx, - ParserCategory.cxx, ParserContainerBase.hxx, SipMessage.hxx, - StringSubComponent.cxx, StringSubComponent.hxx, SysLogBuf.hxx, - Threads.h, Transport.hxx, testHeaderFieldValueList.cxx, - testSipStack1.cxx, vthread.hxx: few changes for win32 - -2002-09-24 21:29 fluffy - - * Data.cxx: [no log message] - -2002-09-24 21:07 jason - - * Helper.hxx, Dialog.cxx, Dialog.hxx, HeaderTypes.hxx, - ParserContainer.hxx, TODO: [no log message] - -2002-09-24 19:16 jason - - * Helper.hxx: [no log message] - -2002-09-24 18:33 jason - - * TransactionState.cxx, UdpTransport.cxx: using get() rather than - [], some interfaces changed in parser categories - -2002-09-24 18:20 jason - - * Dialog.hxx, SipMessage.cxx, SipMessage.hxx, TransactionState.cxx: - [no log message] - -2002-09-24 18:16 jason - - * Helper.hxx: [no log message] - -2002-09-24 18:07 jason - - * HeaderFieldValue.hxx, HeaderFieldValueList.cxx, HeaderTypes.cxx, - ParserCategories.cxx, ParserCategories.hxx, ParserCategory.cxx, - ParserCategory.hxx, ParserContainer.hxx, ParserContainerBase.hxx, - SipMessage.cxx, SipMessage.hxx, TransactionState.cxx: [no log - message] - -2002-09-24 16:08 alan - - * Preparse.cxx, UdpTransport.cxx: Comments / fleshing out error - conditions - -2002-09-23 16:11 jason - - * HeaderTypes.cxx, HeaderTypes.hxx, ParserCategories.hxx: [no log - message] - -2002-09-23 14:34 jason - - * HeaderTypes.hxx: [no log message] - -2002-09-23 10:33 jason - - * HeaderTypes.hxx, Makefile, ParserCategory.cxx, SipMessage.hxx, - TransactionState.cxx, TransactionState.hxx: [no log message] - -2002-09-22 17:37 dabryan - - * TransactionState.cxx: [no log message] - -2002-09-22 17:32 dabryan - - * TransactionState.cxx, TransactionState.hxx: [no log message] - -2002-09-22 17:24 fluffy - - * .cvsignore, Makefile: Removed old graph rules (now in doc subdir) - -2002-09-22 17:21 fluffy - - * dot.awk: Removed DOT stuff from this dir. - -2002-09-22 17:11 fluffy - - * doc/srv-inv-tree.dot: Added CVS header comments - -2002-09-22 17:09 fluffy - - * doc/: Makefile, srv-inv-tree.dot: Initial server INVITE tree - diagram - -2002-09-22 16:14 dabryan - - * TransactionState.cxx, TransactionState.hxx: [no log message] - -2002-09-22 15:56 fluffy - - * TODO: [no log message] - -2002-09-22 15:32 dabryan - - * Timer.cxx, Timer.hxx, TimerMessage.cxx, TimerMessage.hxx, - TimerQueue.cxx, TransactionState.cxx, TransactionState.hxx: [no log - message] - -2002-09-22 15:08 fluffy - - * doc/: .cvsignore, Makefile, fsm-dot.awk: Moved Preparse FSM - diagram into this dir. - -2002-09-22 15:04 fluffy - - * doc/srv-inv-fsm.dot: - Fixed up - -2002-09-22 14:34 fluffy - - * doc/: .cvsignore, Makefile, srv-inv-fsm.dot: - Fixed up - -2002-09-22 14:32 fluffy - - * doc/: Makefile, srv-inv-fsm.dot: Adding FSM Impound - -2002-09-22 11:44 jason - - * HeaderTypes.cxx, HeaderTypes.hxx, ParserCategories.hxx, - ParserCategory.hxx: [no log message] - -2002-09-22 11:26 dabryan - - * SipStack.cxx, testSipStack1.cxx, Executive.cxx: [no log message] - -2002-09-22 11:19 dabryan - - * Executive.cxx, ParserCategories.cxx, SipMessage.cxx, - TransactionState.cxx: [no log message] - -2002-09-22 11:19 fluffy - - * UdpTransport.cxx: Made Single Shot Test Message - -2002-09-22 11:13 fluffy - - * Preparse.cxx, TimerMessage.cxx, UdpTransport.cxx: Added dump ops. - -2002-09-22 11:08 dabryan - - * Makefile, Message.cxx, Message.hxx, SipMessage.cxx, - SipMessage.hxx, TimerMessage.hxx, convertStringToInt.cxx: [no log - message] - -2002-09-22 11:01 dabryan - - * Executive.cxx, Message.hxx, SipMessage.cxx, SipMessage.hxx, - SipStack.cxx, TimerMessage.hxx, TimerQueue.cxx, - TransactionState.cxx, TransactionState.hxx, TransportSelector.cxx, - TransportSelector.hxx, UdpTransport.cxx: [no log message] - -2002-09-22 10:48 fluffy - - * TransactionState.cxx: Added op<< - -2002-09-22 10:41 jason - - * SipMessage.cxx: [no log message] - -2002-09-22 10:41 dabryan - - * .cvsignore, TransactionState.cxx, TransactionState.hxx, - Transport.cxx, Transport.hxx, TransportSelector.cxx, - TransportSelector.hxx, UdpTransport.cxx, testSipStack1.cxx: [no log - message] - -2002-09-22 10:29 jason - - * HeaderFieldValueList.hxx, HeaderTypes.hxx, SipMessage.hxx: [no - log message] - -2002-09-22 10:20 fluffy - - * UdpTransport.cxx: dummy messages - -2002-09-22 10:08 dabryan - - * ParserCategories.cxx: Added bodeis for clone - -2002-09-22 10:02 dabryan - - * ParserCategories.cxx, ParserCategories.hxx: Added destructors - -2002-09-22 10:00 fluffy - - * ParserCategories.cxx, SipMessage.cxx, .cvsignore: [no log - message] - -2002-09-22 09:55 dabryan - - * ParserCategories.hxx: Added a comment. - -2002-09-22 09:53 dabryan - - * ParserCategories.hxx: Added parse method to RequestLine and - StatusLine components, just a dummy assert zero for now. - -2002-09-22 09:11 fluffy - - * Makefile, SipMessage.cxx, TimerMessage.cxx, TimerMessage.hxx: - compiles and links - -2002-09-22 08:00 fluffy - - * Preparse.cxx: [no log message] - -2002-09-22 00:54 jason - - * HeaderTypes.cxx, Makefile, Message.hxx, SipMessage.cxx, - SipMessage.hxx, TransactionState.cxx, TransactionState.hxx, - testSipMessage.cxx: [no log message] - -2002-09-22 00:31 dabryan - - * ParserCategories.cxx, ParserCategories.hxx: Added CSeq and - Integer components to the parser. - -2002-09-22 00:30 fluffy - - * Preparse.cxx: Added COMMA - -2002-09-22 00:25 jason - - * MethodTypes.hxx, ParserCategories.cxx, ParserCategories.hxx: [no - log message] - -2002-09-22 00:22 fluffy - - * Preparse.cxx, Preparse.hxx: FSM State/Edge Complete - -2002-09-22 00:14 fluffy - - * Preparse.cxx: Minor updates for diagnostics. - -2002-09-22 00:03 jason - - * Executive.cxx, Executive.hxx, Makefile, TimerMessage.cxx, - TimerMessage.hxx, TransactionState.cxx, TransportSelector.cxx: [no - log message] - -2002-09-21 23:47 jason - - * Makefile, Message.hxx, MethodTypes.cxx, SipMessage.cxx, - SipMessage.hxx, TimerMessage.hxx, TransactionState.cxx, - TransactionState.hxx, TransportSelector.cxx: [no log message] - -2002-09-21 23:44 fluffy - - * Makefile: Dependancy fixes - -2002-09-21 23:39 fluffy - - * Makefile: Safety checkin - -2002-09-21 23:26 fluffy - - * Makefile: [no log message] - -2002-09-21 22:49 dabryan - - * MethodTypes.cxx, MethodTypes.hxx: [no log message] - -2002-09-21 22:40 dabryan - - * ParserCategories.hxx, SipMessage.hxx: [no log message] - -2002-09-21 22:37 dabryan - - * Makefile, MethodTypes.cxx, MethodTypes.hxx, ParserCategories.cxx, - ParserCategories.hxx, ParserCategory.hxx, SipMessage.hxx, - Symbols.cxx, Symbols.hxx: [no log message] - -2002-09-21 22:30 fluffy - - * Makefile: Moved Transport error - -2002-09-21 22:10 fluffy - - * Makefile, TimerMessage.hxx, TransactionState.cxx, - TransactionState.hxx: [no log message] - -2002-09-21 22:07 fluffy - - * Preparse.cxx: Added Header Transition - -2002-09-21 21:51 jason - - * TransactionState.cxx, TransactionState.hxx: [no log message] - -2002-09-21 21:32 jason - - * SipStack.hxx, TransactionState.cxx: [no log message] - -2002-09-21 21:22 fluffy - - * Preparse.hxx: General Updates - -2002-09-21 21:22 fluffy - - * Preparse.cxx: General Updates. - -2002-09-21 21:20 fluffy - - * UdpTransport.cxx, testUdp.cxx, testSipStack1.cxx: General - Migrations. - -2002-09-21 21:18 dabryan - - * SipMessage.hxx: [no log message] - -2002-09-21 21:15 jason - - * Message.hxx, SipMessage.hxx, Timer.cxx, Timer.hxx, - TimerMessage.hxx, TransactionState.cxx, TransactionState.hxx, - TransportSelector.hxx: [no log message] - -2002-09-21 21:11 fluffy - - * TransactionState.cxx, TransactionState.hxx: [no log message] - -2002-09-21 21:05 dabryan - - * Makefile, MethodTypes.hxx, ParserCategories.cxx, - ParserCategories.hxx, ParserCategory.hxx, ParserContainer.hxx, - SipMessage.hxx, SipMessage.hxx: [no log message] - -2002-09-21 20:55 fluffy - - * Executive.cxx, TransactionState.cxx, TransactionState.hxx: [no - log message] - -2002-09-21 20:26 dabryan - - * HeaderFieldValue.cxx, HeaderFieldValue.hxx, ParserCategories.cxx, - ParserCategories.hxx, ParserCategory.hxx, SipMessage.cxx, - SipMessage.hxx: [no log message] - -2002-09-21 20:06 jason - - * Message.hxx, SipMessage.hxx, SipStack.cxx, SipStack.hxx, - TimerMessage.hxx, TransactionState.cxx, TransactionState.hxx: [no - log message] - -2002-09-21 20:02 fluffy - - * Makefile, TransactionState.hxx: [no log message] - -2002-09-21 19:58 fluffy - - * TransactionState.hxx, TransactionState.hxx: [no log message] - -2002-09-21 19:51 fluffy - - * Preparse.cxx, UdpTransport.cxx: Loggin and test - -2002-09-21 19:38 jason - - * Transport.cxx, UdpTransport.cxx: warnings - -2002-09-21 19:37 jason - - * Logger.cxx, Logger.hxx, Makefile: [no log message] - -2002-09-21 19:31 dabryan - - * HeaderFieldValue.hxx, HeaderFieldValueList.hxx, HeaderTypes.hxx, - Makefile, ParserCategories.hxx, SipMessage.hxx, testSipMessage.cxx: - [no log message] - -2002-09-21 19:28 dabryan - - * Executive.cxx, SipStack.cxx, SipStack.hxx, TransactionState.hxx, - TransportSelector.cxx, TransportSelector.hxx: Changes to get stack - to build - -2002-09-21 18:56 fluffy - - * Singleton.h, testUdp.cxx: [no log message] - -2002-09-21 18:30 fluffy - - * UdpTransport.cxx: Added Preparse hooks - -2002-09-21 18:30 dabryan - - * Data.hxx: fix snafu - -2002-09-21 18:19 fluffy - - * SipMessage.cxx: Removed stub addSource(). - -2002-09-21 18:16 fluffy - - * Data.cxx, SipMessage.cxx, SipMessage.hxx: UDP test integration. - -2002-09-21 18:10 dabryan - - * Executive.cxx, SipStack.cxx, SipStack.hxx: More changes to get - things going for the calls from the top level down to the bottom. - -2002-09-21 18:07 jason - - * TransactionMap.cxx, TransactionMap.hxx, TransactionState.hxx, - Makefile, .cvsignore: [no log message] - -2002-09-21 18:06 dabryan - - * HeaderFieldValue.cxx, HeaderFieldValueList.cxx, - HeaderFieldValueList.hxx, ParserCategory.hxx, SipMessage.cxx, - ParserCategory.hxx: [no log message] - -2002-09-21 18:01 fluffy - - * Makefile, Preparse.cxx, UdpTransport.cxx: Minor changes. - -2002-09-21 17:57 dabryan - - * SipStack.cxx, SipStack.hxx, TransportSelector.cxx, - TransportSelector.hxx, testSipStack1.cxx: Added some more code in - the middle between the stack and the lower level stuff. - -2002-09-21 17:56 dabryan - - * HeaderFieldValue.cxx, HeaderFieldValue.hxx, - HeaderFieldValueList.cxx, HeaderFieldValueList.hxx, SipMessage.cxx, - SipMessage.hxx, Timer.cxx: [no log message] - -2002-09-21 17:34 dabryan - - * HeaderTypes.cxx, HeaderTypes.hxx, Makefile, ParserCategories.hxx, - ParserCategories.cxx, Symbols.cxx: [no log message] - -2002-09-21 17:24 dabryan - - * Makefile: Added logic to build testSipStack1 - -2002-09-21 17:23 jason - - * Makefile, Timer.cxx, Timer.hxx: added timers - -2002-09-21 17:20 dabryan - - * TransactionMap.cxx, TransportSelector.cxx: Added bodies for these - classes, no code yet. - -2002-09-21 17:20 fluffy - - * HeaderFieldValue.cxx: [no log message] - -2002-09-21 17:15 jason - - * Timer.cxx, TimerMessage.hxx, TimerQueue.cxx, TimerQueue.hxx, - Timer.hxx: added timers - -2002-09-21 17:14 fluffy - - * .cvsignore: Added .dot file. - -2002-09-21 17:13 dabryan - - * HeaderTypes.cxx, HeaderTypes.hxx, Logger.hxx, - ParserCategories.hxx, SipMessage.cxx, SipMessage.hxx, - SysLogBuf.hxx, SysLogStream.hxx, Transport.cxx, Transport.hxx: [no - log message] - -2002-09-21 17:02 fluffy - - * .cvsignore: Added cvsignore file. - -2002-09-21 17:02 fluffy - - * HeaderTypes.cxx, SipMessage.cxx, SipMessage.hxx, Transport.hxx, - UdpTransport.cxx: Compiles - -2002-09-21 16:52 fluffy - - * HeaderFieldValue.cxx, HeaderTypes.cxx, HeaderTypes.hxx, - Preparse.cxx, Preparse.hxx, SipMessage.hxx, Threads.h, - UdpTransport.cxx, UdpTransport.hxx, testUdp.cxx: Preparser - integration. - -2002-09-21 16:41 fluffy - - * Makefile: [no log message] - -2002-09-21 16:34 fluffy - - * SipMessage.hxx, Transport.cxx, Transport.hxx, UdpTransport.cxx, - UdpTransport.hxx: [no log message] - -2002-09-21 16:31 dabryan - - * Executive.cxx, Executive.hxx, Fifo.cc, SipStack.cxx, - SipStack.hxx, TransactionMap.hxx, TransportSelector.hxx: Cleaned - up, added more code. - -2002-09-21 16:27 dabryan - - * Message.hxx: [no log message] - -2002-09-21 16:23 fluffy - - * testPreparse.cxx: Added quick (inop) test class - -2002-09-21 16:16 fluffy - - * SipMessage.hxx: Added setSource - -2002-09-21 16:05 dabryan - - * Timer.hxx: Renamed to TimerWheel. - -2002-09-21 16:03 dabryan - - * Message.hxx, SipMessage.cxx, SipMessage.hxx, TimerMessage.hxx, - ParserContainerBase.hxx: [no log message] - -2002-09-21 15:56 fluffy - - * Preparse.cxx, Preparse.hxx: Updates. - -2002-09-21 15:14 dabryan - - * SipMessage.cxx, SipMessage.hxx: [no log message] - -2002-09-21 14:00 dabryan - - * HeaderFieldValueList.cxx, HeaderFieldValueList.hxx, - HeaderTypes.cxx, ParserContainer.hxx, SipMessage.cxx, - SipMessage.hxx: [no log message] - -2002-09-21 13:53 dabryan - - * SipMessage.cxx, SipMessage.hxx, SipStack.cxx, SipStack.hxx: Put - body into the SipStack code, added a fixed destination to the - SipMessage class. - -2002-09-21 13:51 dabryan - - * HeaderTypes.hxx: [no log message] - -2002-09-21 13:30 fluffy - - * TransportSelector.hxx: [no log message] - -2002-09-21 13:19 fluffy - - * Executive.cxx, TransactionState.hxx: [no log message] - -2002-09-21 13:15 dabryan - - * Condition.cxx, Condition.hxx, Data.hxx, Fifo.hxx, - FloatSubComponent.hxx, HeaderFieldValue.cxx, HeaderFieldValue.hxx, - HeaderFieldValueList.cxx, HeaderFieldValueList.hxx, - HeaderTypes.cxx, HeaderTypes.hxx, HostSpecification.hxx, - IntSubComponent.hxx, Lock.cxx, Lock.hxx, Log.cxx, Log.hxx, - Makefile, Mutex.cxx, Mutex.hxx, ParserCategories.hxx, - ParserCategory.hxx, ParserContainer.hxx, Preparse.cxx, - SipMessage.cxx, SipMessage.hxx, StringSubComponent.cxx, - StringSubComponent.hxx, SubComponent.cxx, SubComponent.hxx, - SubComponentList.cxx, SubComponentList.hxx, Subsystem.hxx, - TransactionMap.hxx, Transport.cxx, Transport.hxx, UdpTransport.cxx, - UdpTransport.hxx, UnknownSubComponent.cxx, UnknownSubComponent.hxx, - testHeaderFieldValueList.cxx, testSubComponentList.cxx: [no log - message] - -2002-09-21 13:04 fluffy - - * Makefile, Preparse.cxx, Preparse.hxx: Compilation errors. - -2002-09-21 12:54 fluffy - - * Makefile: Added Preparse tests - -2002-09-21 12:52 jason - - * SipStack.hxx, HeaderFieldValueList.hxx, SubComponentList.hxx: [no - log message] - -2002-09-21 12:51 dabryan - - * Data.hxx, HeaderFieldValue.cxx, HeaderFieldValue.hxx, - HeaderFieldValueList.cxx, HeaderFieldValueList.hxx, - HeaderTypes.cxx, HeaderTypes.hxx, Log.cxx, Log.hxx, - ParserCategories.hxx, ParserCategory.hxx, ParserContainer.hxx, - SipMessage.cxx, SipMessage.hxx, Symbols.hxx, supported.hxx: [no log - message] - -2002-09-21 12:48 fluffy - - * TransactionState.hxx, TransportSelector.hxx, SipStack.hxx, - TransportSelector.hxx: [no log message] - -2002-09-21 12:48 dabryan - - * testHeaderFieldValueList.cxx: Testing code for the - HeaderFieldValueList object. - -2002-09-21 12:46 jason - - * Transport.cxx, Transport.hxx, UdpTransport.cxx, UdpTransport.hxx: - [no log message] - -2002-09-21 12:34 fluffy - - * dot.awk: Utility awk file for making DOT input file from Preparse - FSM - -2002-09-21 12:30 fluffy - - * Preparse.cxx: Added missing const. - -2002-09-21 12:30 fluffy - - * Preparse.cxx, testpp.cxx: Early Preparse. Integration about to - begin. - -2002-09-21 12:29 fluffy - - * Executive.cxx, Executive.hxx, Timer.hxx: [no log message] - -2002-09-21 12:26 dabryan - - * HeaderFieldValue.cxx, HeaderFieldValueList.cxx: Changes to fix - copy bug in header code - -2002-09-21 12:25 jason - - * .cvsignore, Data.hxx, Makefile: [no log message] - -2002-09-21 12:18 jason - - * Log.cxx, Log.hxx, Logger.hxx, Makefile, Subsystem.cxx, - Subsystem.hxx, SysLogBuf.hxx, SysLogStream.hxx, Data.cxx, Data.hxx: - [no log message] - -2002-09-21 12:03 dabryan - - * HeaderFieldValue.cxx, HeaderFieldValueList.cxx, - testHeaderFieldValueList.cxx: Fixes to allow others to compile. - -2002-09-21 11:50 fluffy - - * Preparse.cxx, Preparse.hxx, testpp.cxx: Improvements, still not - functional. - -2002-09-21 11:27 dabryan - - * HeaderFieldValue.cxx, HeaderFieldValue.hxx, - HeaderFieldValueList.cxx, ParserCategory.hxx, SubComponentList.cxx, - SubComponentList.hxx: Changes for header and subcomponent lists. - -2002-09-21 11:26 dabryan - - * testHeaderFieldValueList.cxx: Added test file for - HeaderFieldValueLists - -2002-09-21 11:06 jason - - * Log.cxx, Log.hxx, Logger.hxx, Singleton.h, Subsystem.cxx, - SysLogBuf.hxx, SysLogStream.hxx, Threads.h, testUdp.cxx: [no log - message] - -2002-09-21 10:30 jason - - * Log.cxx, Log.hxx, Logger.hxx, Subsystem.cxx, Subsystem.hxx: [no - log message] - -2002-09-21 10:07 dabryan - - * FloatSubComponent.cxx, FloatSubComponent.hxx, - HeaderFieldValue.cxx, HeaderFieldValue.hxx, - HeaderFieldValueList.cxx, IntSubComponent.cxx, IntSubComponent.hxx, - StringSubComponent.cxx, StringSubComponent.hxx, SubComponent.cxx, - SubComponent.hxx, SubComponentList.cxx, SubComponentList.hxx: [no - log message] - -2002-09-21 09:48 fluffy - - * Executive.hxx, Makefile: [no log message] - -2002-09-21 09:44 fluffy - - * Executive.hxx, TransactionMap.hxx: [no log message] - -2002-09-21 08:32 fluffy - - * .cvsignore: [no log message] - -2002-09-21 08:28 fluffy - - * SipStack.hxx, testSipStack1.cxx, Makefile: [no log message] - -2002-09-20 23:54 fluffy - - * Preparse.cxx, Preparse.hxx, testpp.cxx: Moved Preparse initial - implementaiton - -2002-09-20 23:49 jason - - * HeaderTypes.cxx, HeaderTypes.hxx, HostSpecification.hxx, - ParserCategory.hxx, SipMessage.cxx, SipMessage.hxx, - HeaderFieldValue.cxx, HeaderFieldValue.hxx, Makefile, - ParseException.hxx, ParserContainer.hxx, UnknownSubComponent.hxx: - [no log message] - -2002-09-20 23:21 fluffy - - * .cvsignore: testSubComponentList - -2002-09-20 22:57 jason - - * Condition.cxx, Condition.hxx, Fifo.cc, Fifo.hxx, Lock.cxx, - Lock.hxx, Lockable.hxx, Mutex.cxx, Mutex.hxx, Transport.cxx, - Transport.hxx, UdpTransport.cxx, UdpTransport.hxx, testUdp.cxx, - vthread.hxx: [no log message] - -2002-09-20 22:55 dabryan - - * HeaderFieldValue.cxx, HeaderFieldValue.hxx, ParseException.hxx, - SubComponentList.cxx, SubComponentList.hxx: Added exists, get, a - bit of cleaning, some exceptions - -2002-09-20 22:40 jason - - * FloatSubComponent.cxx, FloatSubComponent.hxx, - IntSubComponent.cxx, IntSubComponent.hxx, ParserContainer.hxx, - UnknownSubComponent.cxx, UnknownSubComponent.hxx: [no log message] - -2002-09-20 22:09 dabryan - - * HeaderFieldValueList.cxx, HeaderFieldValueList.hxx: Moved some - stuff public - -2002-09-20 22:07 jason - - * StringSubComponent.cxx, StringSubComponent.hxx, SubComponent.cxx, - SubComponent.hxx, SubComponentList.cxx, SubComponentList.hxx, - UnknownSubComponent.cxx, UnknownSubComponent.hxx, Makefile: [no log - message] - -2002-09-20 21:23 dabryan - - * HeaderFieldValue.cxx, HeaderFieldValue.hxx, - HeaderFieldValueList.cxx, SubComponentList.cxx: Updates to allow - printing of the underlying data structures. - - Cleaned up the HeaderFieldValue(List) classes to use sub - components. - -2002-09-20 19:48 dabryan - - * HeaderFieldValueList.cxx, HeaderFieldValueList.hxx: Added the - list of headers - -2002-09-20 19:24 jason - - * Parameter.cxx, Parameter.hxx, ParameterList.cxx, - ParameterList.hxx, StringParameter.cxx, StringParameter.hxx, - UnknownParameter.cxx, UnknownParameter.hxx, testParameterList.cxx, - StringSubComponent.cxx, StringSubComponent.hxx, SubComponent.cxx, - SubComponent.hxx, SubComponentList.cxx, SubComponentList.hxx, - UnknownSubComponent.cxx, UnknownSubComponent.hxx, - testSubComponentList.cxx: [no log message] - -2002-09-20 18:13 fluffy - - * Makefile: updated - -2002-09-20 17:57 dabryan - - * HeaderFieldValue.cxx, HeaderFieldValue.hxx: Added code to have - list of Header Field Values to, code to chunk on copy. - -2002-09-20 17:56 jason - - * Makefile, Parameter.cxx, Parameter.hxx, ParameterList.cxx, - ParameterList.hxx, StringParameter.cxx, StringParameter.hxx, - UnknownParameter.cxx, UnknownParameter.hxx, testParameterList.cxx: - [no log message] - -2002-09-20 16:52 jason - - * Parameter.hxx, ParameterList.cxx, ParameterList.hxx, - StringParameter.cxx, StringParameter.hxx, UnknownParameter.cxx, - UnknownParameter.hxx, testParameterList.cxx: [no log message] - -2002-09-20 16:36 jason - - * HeaderFieldValue.cxx, HeaderFieldValue.hxx: [no log message] - -2002-09-20 16:16 fluffy - - * .cvsignore, Makefile, Parameter.cxx, testMsg.cxx: few things - -2002-09-20 15:57 fluffy - - * Makefile: [no log message] - diff --git a/src/libs/resiprocate/resip/stack/Connection.cxx b/src/libs/resiprocate/resip/stack/Connection.cxx index 344fc090..b5b25409 100644 --- a/src/libs/resiprocate/resip/stack/Connection.cxx +++ b/src/libs/resiprocate/resip/stack/Connection.cxx @@ -2,6 +2,7 @@ #include "config.h" #endif +#include "rutil/ResipAssert.h" #include "rutil/Socket.hxx" #include "rutil/Logger.hxx" #include "resip/stack/Connection.hxx" @@ -15,6 +16,10 @@ #include "resip/stack/ssl/Security.hxx" #endif +#ifdef WIN32 +#include +#endif + #ifdef USE_SIGCOMP #include #include @@ -27,15 +32,23 @@ volatile bool Connection::mEnablePostConnectSocketFuncCall = false; #define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT Connection::Connection(Transport* transport,const Tuple& who, Socket socket, - Compression &compression) + Compression &compression, + bool isServer) : ConnectionBase(transport,who,compression), - mRequestPostConnectSocketFuncCall(false), + mFirstWriteAfterConnectedPending(false), mInWritable(false), mFlowTimerEnabled(false), - mPollItemHandle(0) + mPollItemHandle(0), + mIsServer(isServer) { mWho.mFlowKey=(FlowKey)socket; - InfoLog (<< "Connection::Connection: new connection created to who: " << mWho); + InfoLog (<< "Connection::Connection: new connection created to who: " << mWho << ", is server = " << mIsServer); + + if(transport && isWebSocket(transport->transport())) + { + mSendingTransmissionFormat = WebSocketHandshake; + mReceivingTransmissionFormat = WebSocketHandshake; + } if(mWho.mFlowKey && ConnectionBase::transport()) { @@ -71,7 +84,7 @@ Connection::removeFrontOutstandingSend() if (mOutstandingSends.empty()) { - assert(mInWritable); + resip_assert(mInWritable); getConnectionManager().removeFromWritable(this); mInWritable = false; } @@ -82,13 +95,35 @@ Connection::performWrite() { if(transportWrite()) { - assert(mInWritable); - getConnectionManager().removeFromWritable(this); - mInWritable = false; - return 0; // What does this transportWrite() mean? + // If we get here it means: + // a. on a previous invocation, SSL_do_handshake wanted to write + // (SSL_ERROR_WANT_WRITE) + // b. now the handshake is complete or it wants to read + if(mInWritable) + { + getConnectionManager().removeFromWritable(this); + mInWritable = false; + } + else + { + WarningLog(<<"performWrite invoked while not in write set"); + } + return 0; // Q. What does this transportWrite() mean? + // A. It makes the TLS handshake move along after it + // was waiting in the write set. + } + + // If the TLS handshake returned SSL_ERROR_WANT_WRITE again + // then we could get here without really having something to write + // so just return, remaining in the write set. + if(mOutstandingSends.empty()) + { + // FIXME: this needs to be more elaborate with respect + // to TLS handshaking but it doesn't appear we can do that + // without ABI breakage. + return 0; } - assert(!mOutstandingSends.empty()); switch(mOutstandingSends.front()->command) { case SendData::CloseConnection: @@ -118,7 +153,68 @@ Connection::performWrite() mSendingTransmissionFormat = Uncompressed; } } + else if(mSendingTransmissionFormat == WebSocketHandshake) + { + mSendingTransmissionFormat = WebSocketData; + } + else if(mSendingTransmissionFormat == WebSocketData) + { + SendData *dataWs, *oldSd; + const Data& dataRaw = mOutstandingSends.front()->data; + UInt64 dataSize = 1 + 1 + dataRaw.size(); + UInt64 lSize = (UInt64)dataRaw.size(); + UInt8* uBuffer; + if(lSize > 0x7D && lSize <= 0xFFFF) + { + dataSize += 2; + } + else if(lSize > 0xFFFF) + { + dataSize += 8; + } + + oldSd = mOutstandingSends.front(); + dataWs = new SendData(oldSd->destination, + Data(Data::Take, new char[(int)dataSize], (Data::size_type)dataSize), + oldSd->transactionId, + oldSd->sigcompId, + false); + resip_assert(dataWs && dataWs->data.data()); + uBuffer = (UInt8*)dataWs->data.data(); + + uBuffer[0] = 0x82; + if(lSize <= 0x7D) + { + uBuffer[1] = (UInt8)lSize; + uBuffer = &uBuffer[2]; + } + else if(lSize <= 0xFFFF) + { + uBuffer[1] = 0x7E; + uBuffer[2] = (UInt8)((lSize >> 8) & 0xFF); + uBuffer[3] = (UInt8)(lSize & 0xFF); + uBuffer = &uBuffer[4]; + } + else + { + uBuffer[1] = 0x7F; + uBuffer[2] = (UInt8)((lSize >> 56) & 0xFF); + uBuffer[3] = (UInt8)((lSize >> 48) & 0xFF); + uBuffer[4] = (UInt8)((lSize >> 40) & 0xFF); + uBuffer[5] = (UInt8)((lSize >> 32) & 0xFF); + uBuffer[6] = (UInt8)((lSize >> 24) & 0xFF); + uBuffer[7] = (UInt8)((lSize >> 16) & 0xFF); + uBuffer[8] = (UInt8)((lSize >> 8) & 0xFF); + uBuffer[9] = (UInt8)(lSize & 0xFF); + uBuffer = &uBuffer[10]; + } + + memcpy(uBuffer, dataRaw.data(), dataRaw.size()); + mOutstandingSends.front() = dataWs; + dataWs = 0; + delete oldSd; + } #ifdef USE_SIGCOMP // Perform compression here, if appropriate @@ -147,28 +243,38 @@ Connection::performWrite() } #endif - if(mEnablePostConnectSocketFuncCall && mRequestPostConnectSocketFuncCall) + // Note: The first time the socket is available for write, is when the TCP connect call is completed + if (mFirstWriteAfterConnectedPending) { - // Note: The first time the socket is available for write, is when the TCP connect call is completed - mRequestPostConnectSocketFuncCall = false; - mTransport->callSocketFunc(getSocket()); + mFirstWriteAfterConnectedPending = false; // reset + + // Notify all outstanding sends that we are now connected - stops the TCP Connection timer for all transactions + for (std::list::iterator it = mOutstandingSends.begin(); it != mOutstandingSends.end(); it++) + { + mTransport->setTcpConnectState((*it)->transactionId, TcpConnectState::Connected); + } + if (mEnablePostConnectSocketFuncCall) + { + mTransport->callSocketFunc(getSocket()); + } } const Data& data = mOutstandingSends.front()->data; - int nBytes = write(data.data() + mSendPos,int(data.size() - mSendPos)); //DebugLog (<< "Tried to send " << data.size() - mSendPos << " bytes, sent " << nBytes << " bytes"); if (nBytes < 0) { - //fail(data.transactionId); - InfoLog(<< "Write failed on socket: " << this->getSocket() << ", closing connection"); - return -1; + //fail(data.transactionId); + InfoLog(<< "Write failed on socket: " << this->getSocket() << ", closing connection"); + return -1; } else if (nBytes == 0) { - return 0; + // Nothing was written - likely socket buffers are backed up and EWOULDBLOCK was returned + // no need to do calculations in else statement + return 0; } else { @@ -195,8 +301,6 @@ Connection::performWrites(unsigned int max) if(res<0) { - if (mTransport) - mTransport->increaseConnectionsDeleted(); delete this; return false; } @@ -208,7 +312,8 @@ Connection::ensureWritable() { if(!mInWritable) { - assert(!mOutstandingSends.empty()); + //assert(!mOutstandingSends.empty()); // empty during TLS handshake + // therefore must be careful to check mOutstandingSends later getConnectionManager().addToWritable(this); mInWritable = true; } @@ -236,7 +341,7 @@ Connection::read() size_t bytesToRead = resipMin(writePair.second, static_cast(Connection::ChunkSize)); - assert(bytesToRead > 0); + resip_assert(bytesToRead > 0); int bytesRead = read(writePair.first, (int)bytesToRead); if (bytesRead <= 0) @@ -276,12 +381,38 @@ Connection::read() else #endif { - if(!preparseNewBytes(bytesRead)) - { - // Iffy; only way we have right now to indicate that this connection has - // gone away. - bytesRead=-1; - } + if (mReceivingTransmissionFormat == WebSocketHandshake) + { + bool dropConnection = false; + if(wsProcessHandshake(bytesRead, dropConnection)) + { + ensureWritable(); + if(performWrites()) + { + mReceivingTransmissionFormat = WebSocketData; + } + } + else if(dropConnection) + { + bytesRead=-1; + } + } + else + { + if (mReceivingTransmissionFormat == WebSocketData) + { + if(!wsProcessData(bytesRead)) + { + bytesRead=-1; + } + } + else if(!preparseNewBytes(bytesRead)) + { + // Iffy; only way we have right now to indicate that this connection has + // gone away. + bytesRead=-1; + } + } } return bytesRead; } @@ -300,8 +431,6 @@ Connection::performReads(unsigned int max) if ( bytesRead < 0 ) { DebugLog(<< "Closing connection bytesRead=" << bytesRead); - if (mTransport) - mTransport->increaseConnectionsDeleted(); delete this; return false; } @@ -351,6 +480,29 @@ Connection::isGood() return true; } +bool +Connection::checkConnectionTimedout() +{ + int errNum = 0; + int errNumSize = sizeof(errNum); + if(getsockopt(mWho.mFlowKey, SOL_SOCKET, SO_ERROR, (char *)&errNum, (socklen_t *)&errNumSize) == 0) + { + if (errNum == ETIMEDOUT || errNum == EHOSTUNREACH || + errNum == ECONNREFUSED || errNum == ECONNABORTED) + { + InfoLog(<< "Exception on socket " << mWho.mFlowKey << " code: " << errNum << "; closing connection"); + setFailureReason(TransportFailure::ConnectionException, errNum); + delete this; + return true; + } + else if (errNum != 0) + { + WarningLog(<< "checkConnectionTimedout " << mWho.mFlowKey << " code: " << errNum << "; ignoring - should we error out?"); + } + } + return false; +} + bool Connection::isWritable() { @@ -361,7 +513,8 @@ Connection::isWritable() Virtual function of FdPollItemIf, called to process io events **/ void -Connection::processPollEvent(FdPollEventMask mask) { +Connection::processPollEvent(FdPollEventMask mask) +{ /* The original code in ConnectionManager.cxx didn't check * for error events unless no writable event. (e.g., writable * masked error. Why?) @@ -372,8 +525,6 @@ Connection::processPollEvent(FdPollEventMask mask) { int errNum = getSocketError(fd); InfoLog(<< "Exception on socket " << fd << " code: " << errNum << "; closing connection"); setFailureReason(TransportFailure::ConnectionException, errNum); - if (mTransport) - mTransport->increaseConnectionsDeleted(); delete this; return; } @@ -387,8 +538,25 @@ Connection::processPollEvent(FdPollEventMask mask) { } if ( mask & FPEM_Read ) { - performReads(); + if (!performReads()) + { + // Just deleted self + return; + } } + mTransport->flushStateMacFifo(); +} + +bool +Connection::isServer() const +{ + return mIsServer; +} + +void +Connection::invokeAfterSocketCreationFunc() const +{ + mTransport->callSocketFunc(getSocket()); } /* ==================================================================== diff --git a/src/libs/resiprocate/resip/stack/Connection.hxx b/src/libs/resiprocate/resip/stack/Connection.hxx index d8c7fc2c..aa140803 100644 --- a/src/libs/resiprocate/resip/stack/Connection.hxx +++ b/src/libs/resiprocate/resip/stack/Connection.hxx @@ -43,7 +43,7 @@ class Connection : public ConnectionBase, friend EncodeStream& operator<<(EncodeStream& strm, const resip::Connection& c); public: - Connection(Transport* transport,const Tuple& who, Socket socket, Compression &compression); + Connection(Transport* transport,const Tuple& who, Socket socket, Compression &compression, bool isServer); virtual ~Connection(); /*! @@ -58,7 +58,8 @@ class Connection : public ConnectionBase, /// always true -- always add to fdset as read ready virtual bool hasDataToRead(); /// has valid connection - virtual bool isGood(); + virtual bool isGood(); + virtual bool checkConnectionTimedout(); virtual bool isWritable(); virtual bool transportWrite(){return false;} @@ -99,10 +100,10 @@ class Connection : public ConnectionBase, void enableFlowTimer(); bool isFlowTimerEnabled() { return mFlowTimerEnabled; } - bool mRequestPostConnectSocketFuncCall; + bool mFirstWriteAfterConnectedPending; static volatile bool mEnablePostConnectSocketFuncCall; static void setEnablePostConnectSocketFuncCall(bool enabled = true) { mEnablePostConnectSocketFuncCall = enabled; } - + bool isServer()const; protected: /// pure virtual, but need concrete Connection for book-ends of lists virtual int read(char* /* buffer */, const int /* count */) { return 0; } @@ -114,6 +115,8 @@ class Connection : public ConnectionBase, /* callback method of FdPollItemIf */ virtual void processPollEvent(FdPollEventMask mask); + virtual void invokeAfterSocketCreationFunc() const; + private: ConnectionManager& getConnectionManager() const; void removeFrontOutstandingSend(); @@ -127,6 +130,7 @@ class Connection : public ConnectionBase, /// no value semantics Connection(const Connection&); Connection& operator=(const Connection&); + bool mIsServer; }; EncodeStream& diff --git a/src/libs/resiprocate/resip/stack/ConnectionBase.cxx b/src/libs/resiprocate/resip/stack/ConnectionBase.cxx index f6e5f58a..2bb03a51 100644 --- a/src/libs/resiprocate/resip/stack/ConnectionBase.cxx +++ b/src/libs/resiprocate/resip/stack/ConnectionBase.cxx @@ -2,16 +2,30 @@ #include "config.h" #endif +#include + #include "rutil/Logger.hxx" #include "resip/stack/ConnectionBase.hxx" +#include "resip/stack/WsConnectionBase.hxx" #include "resip/stack/SipMessage.hxx" +#include "resip/stack/WsDecorator.hxx" +#include "resip/stack/Cookie.hxx" +#include "resip/stack/WsBaseTransport.hxx" +#include "resip/stack/WsCookieContext.hxx" +#include "resip/stack/WsCookieContextFactory.hxx" +#include "resip/stack/Symbols.hxx" #include "rutil/WinLeakCheck.hxx" +#include "rutil/SharedPtr.hxx" +#include "rutil/Sha1.hxx" #ifdef USE_SSL #include "resip/stack/ssl/Security.hxx" #include "resip/stack/ssl/TlsConnection.hxx" +#include "rutil/ssl/SHA1Stream.hxx" #endif +#include "rutil/MD5Stream.hxx" + #ifdef USE_SIGCOMP #include #include @@ -19,9 +33,6 @@ #include #endif -#include -#include "resip/stack/InternalTransport.hxx" - using namespace resip; #define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT @@ -29,6 +40,12 @@ using namespace resip; char ConnectionBase::connectionStates[ConnectionBase::MAX][32] = { "NewMessage", "ReadingHeaders", "PartialBody" }; +#ifndef RESIP_SIP_MSG_MAX_BYTES +#define RESIP_SIP_MSG_MAX_BYTES 10485760 +#endif + +size_t +ConnectionBase::messageSizeMax = RESIP_SIP_MSG_MAX_BYTES; ConnectionBase::ConnectionBase(Transport* transport, const Tuple& who, Compression &compression) : mSendPos(0), @@ -47,9 +64,9 @@ ConnectionBase::ConnectionBase(Transport* transport, const Tuple& who, Compressi mBuffer(0), mBufferPos(0), mBufferSize(0), + mWsFrameExtractor(messageSizeMax), mLastUsed(Timer::getTimeMs()), - mConnState(NewMessage), - mTransportLogger(NULL) + mConnState(NewMessage) { DebugLog (<< "ConnectionBase::ConnectionBase, who: " << mWho << " " << this); #ifdef USE_SIGCOMP @@ -67,9 +84,10 @@ ConnectionBase::ConnectionBase(Transport* transport, const Tuple& who, Compressi DebugLog (<< "No compression library available: " << this); #endif - // deprecated; stop doing this eventually - mWho.transport=mTransport; - mWho.transportKey=mTransport ? mTransport->getKey() : 0; + if(mTransport) + { + mWho.mTransportKey = mTransport->getKey(); + } } ConnectionBase::~ConnectionBase() @@ -159,8 +177,8 @@ ConnectionBase::preparseNewBytes(int bytesRead) } } - assert(mTransport); - mMessage = new SipMessage(mTransport); + resip_assert(mTransport); + mMessage = new SipMessage(&mTransport->getTuple()); DebugLog(<< "ConnectionBase::process setting source " << mWho); mMessage->setSource(mWho); @@ -195,25 +213,25 @@ ConnectionBase::preparseNewBytes(int bytesRead) mBuffer = 0; delete mMessage; mMessage = 0; - mConnState=NewMessage; + mConnState = NewMessage; return false; } - if (mMsgHeaderScanner.getHeaderCount() > 256) + if (mMsgHeaderScanner.getHeaderCount() > 1024) { WarningLog(<< "Discarding preparse; too many headers"); delete [] mBuffer; mBuffer = 0; delete mMessage; mMessage = 0; - mConnState=NewMessage; + mConnState = NewMessage; return false; } unsigned int numUnprocessedChars = (unsigned int)((mBuffer + chunkLength) - unprocessedCharPtr); - if(numUnprocessedChars > 2048 && + if(numUnprocessedChars > ConnectionBase::ChunkSize && scanChunkResult == MsgHeaderScanner::scrNextChunk) { WarningLog(<< "Discarding preparse; header-field-value (or " @@ -222,7 +240,7 @@ ConnectionBase::preparseNewBytes(int bytesRead) mBuffer = 0; delete mMessage; mMessage = 0; - mConnState=NewMessage; + mConnState = NewMessage; return false; } @@ -325,12 +343,10 @@ ConnectionBase::preparseNewBytes(int bytesRead) return false; } - if(contentLength > 10485760 || contentLength < 0) + if(contentLength > messageSizeMax || contentLength < 0) { - // !bwc! No more than 10M, thanks. We should make this - // configurable. - WarningLog(<<"Absurdly large Content-Length in connection-based " - "transport."); + WarningLog(<<"Content-Length in connection-based " + "transport exceeds maximum " << messageSizeMax); delete mMessage; mMessage = 0; mBuffer = 0; @@ -381,7 +397,7 @@ ConnectionBase::preparseNewBytes(int bytesRead) mBufferSize = size; DebugLog (<< "Extra bytes after message: " << overHang); - DebugLog (<< Data(mBuffer, overHang)); + //DebugLog (<< Data(mBuffer, overHang)); bytesRead = overHang; } @@ -403,10 +419,10 @@ ConnectionBase::preparseNewBytes(int bytesRead) // .bwc. This handles all appropriate checking for whether // this is a response or an ACK. - std::unique_ptr tryLater(transport()->make503(*mMessage, expectedWait/1000)); + std::auto_ptr tryLater(transport()->make503(*mMessage, expectedWait/1000)); if(tryLater.get()) { - transport()->send(std::move(tryLater)); + transport()->send(tryLater); } delete mMessage; // dropping message due to congestion mMessage = 0; @@ -420,8 +436,7 @@ ConnectionBase::preparseNewBytes(int bytesRead) { Transport::stampReceived(mMessage); DebugLog(<< "##Connection: " << *this << " received: " << *mMessage); - assert( mTransport ); - putMessageToTransportLogger(mMessage); + resip_assert( mTransport ); mTransport->pushRxMsgUp(mMessage); mMessage = 0; } @@ -456,11 +471,36 @@ ConnectionBase::preparseNewBytes(int bytesRead) } mBufferPos += bytesRead; - if (mBufferPos == contentLength) + if (mBufferPos >= contentLength) { + int overHang = mBufferPos - (int)contentLength; + char *overHangStart = mBuffer + contentLength; + mMessage->addBuffer(mBuffer); mMessage->setBody(mBuffer, (UInt32)contentLength); - mBuffer=0; + mConnState = NewMessage; + mBuffer = 0; + + if (overHang > 0) + { + // The next message has been partially read. + size_t size = overHang * 3 / 2; + if (size < ConnectionBase::ChunkSize) + { + size = ConnectionBase::ChunkSize; + } + char* newBuffer = MsgHeaderScanner::allocateBuffer((int)size); + memcpy(newBuffer, overHangStart, overHang); + mBuffer = newBuffer; + mBufferPos = 0; + mBufferSize = size; + + DebugLog(<< "Extra bytes after message: " << overHang); + //DebugLog(<< Data(mBuffer, overHang)); + + bytesRead = overHang; + } + // .bwc. basicCheck takes up substantial CPU. Don't bother doing it // if we're overloaded. CongestionManager::RejectionBehavior b=mTransport->getRejectionBehaviorForIncoming(); @@ -478,10 +518,10 @@ ConnectionBase::preparseNewBytes(int bytesRead) // .bwc. This handles all appropriate checking for whether // this is a response or an ACK. - std::unique_ptr tryLater = transport()->make503(*mMessage, expectedWait/1000); + std::auto_ptr tryLater = transport()->make503(*mMessage, expectedWait/1000); if(tryLater.get()) { - transport()->send(std::move(tryLater)); + transport()->send(tryLater); } delete mMessage; // dropping message due to congestion mMessage = 0; @@ -496,16 +536,20 @@ ConnectionBase::preparseNewBytes(int bytesRead) DebugLog(<< "##ConnectionBase: " << *this << " received: " << *mMessage); Transport::stampReceived(mMessage); - assert( mTransport ); - putMessageToTransportLogger(mMessage); + resip_assert( mTransport ); mTransport->pushRxMsgUp(mMessage); mMessage = 0; } - mConnState = NewMessage; + + if (overHang > 0) + { + goto start; + } } else if (mBufferPos == mBufferSize) { - // .bwc. We've filled our buffer; go ahead and make more room. + // .bwc. We've filled our buffer and haven't read contentLength bytes yet; go ahead and make more room. + resip_assert(contentLength >= mBufferSize); size_t newSize = resipMin(mBufferSize*3/2, contentLength); char* newBuffer = 0; try @@ -525,11 +569,336 @@ ConnectionBase::preparseNewBytes(int bytesRead) break; } default: - assert(0); + resip_assert(0); } return true; } +void +ConnectionBase::wsParseCookies(CookieList& cookieList, const SipMessage* message) +{ + Data name; + Data value; + StringCategories::const_iterator it = message->header(h_Cookies).begin(); + for (; it != message->header(h_Cookies).end(); ++it) + { + ParseBuffer pb((*it).value()); + while(!pb.eof()) + { + const char* anchor = pb.skipWhitespace(); + + pb.skipToChar(Symbols::EQUALS[0]); + pb.data(name, anchor); + + anchor = pb.skipChar(Symbols::EQUALS[0]); + if(*(pb.position()) == Symbols::DOUBLE_QUOTE[0]) + { + anchor = pb.skipChar(Symbols::DOUBLE_QUOTE[0]); + pb.skipToChar(Symbols::DOUBLE_QUOTE[0]); + pb.data(value, anchor); + pb.skipChar(Symbols::DOUBLE_QUOTE[0]); + } + else + { + pb.skipToOneOf(Symbols::SEMI_COLON, ParseBuffer::Whitespace); + pb.data(value, anchor); + } + + Cookie cookie(name, value); + cookieList.push_back(cookie); + DebugLog(<< "Cookie: " << cookie); + + if(!pb.eof() && *(pb.position()) == Symbols::SEMI_COLON[0]) + { + pb.skipChar(Symbols::SEMI_COLON[0]); + } + + pb.skipWhitespace(); + } + } +} + +/* + * Returns true if handshake complete, false if more bytes needed + * Sets dropConnection = true if an error occurs + */ +bool +ConnectionBase::wsProcessHandshake(int bytesRead, bool &dropConnection) +{ + mConnState = WebSocket; + dropConnection = false; + + if(mBufferPos + bytesRead > messageSizeMax) + { + WarningLog(<<"Too many bytes received during WS handshake, dropping connection. Max message size = " << messageSizeMax); + dropConnection = true; + return false; + } + + resip_assert(mTransport); + mMessage = new SipMessage(&mTransport->getTuple()); + resip_assert(mMessage); + + mMessage->setSource(mWho); + mMessage->setTlsDomain(mTransport->tlsDomain()); + + if (!scanMsgHeader(bytesRead)) + { + return false; + } + + try + { + WsConnectionBase* wsConnectionBase = dynamic_cast(this); + CookieList cookieList; + if(wsConnectionBase) + { + SharedPtr wsCookieContext((WsCookieContext*)0); + if (mMessage->exists(h_Cookies)) + { + WsBaseTransport* wst = dynamic_cast(mTransport); + resip_assert(wst); + try + { + wsParseCookies(cookieList, mMessage); + wsConnectionBase->setCookies(cookieList); + // Use of resip WsCookieContext capabilities is not mandatory, + // only try to use it if cookieContextFactory is available + if(wst->cookieContextFactory().get()) + { + Uri& requestUri = mMessage->header(h_RequestLine).uri(); + wsCookieContext = wst->cookieContextFactory()->makeCookieContext(cookieList, requestUri); + wsConnectionBase->setWsCookieContext(wsCookieContext); + } + } + catch(ParseException& ex) + { + WarningLog(<<"Failed to parse cookies into WsCookieContext: " << ex); + } + } + SharedPtr wsConnectionValidator = wsConnectionBase->connectionValidator(); + if(wsConnectionValidator && + (!wsCookieContext.get() || !wsConnectionValidator->validateConnection(*wsCookieContext))) + { + ErrLog(<<"WebSocket cookie validation failed, dropping connection"); + // FIXME: should send back a HTTP error code: + // 400 if the cookie was not in the right syntax + // 403 if the cookie was well formed but rejected + // due to expiry or a bad HMAC + delete mMessage; + mMessage = 0; + mBufferPos = 0; + dropConnection = true; + return false; + } + } + + std::auto_ptr wsResponsePtr = makeWsHandshakeResponse(); + + if (wsResponsePtr.get()) + { + DebugLog (<< "WebSocket upgrade accepted, cookie count = " << cookieList.size()); + + mOutstandingSends.push_back(new SendData( + who(), + *wsResponsePtr.get(), + Data::Empty, + Data::Empty, + true)); + } + else + { + ErrLog(<<"Failed to parse WebSocket initialization request"); + delete mMessage; + mMessage = 0; + mBufferPos = 0; + dropConnection = true; + return false; + } + } + catch(resip::ParseException& e) + { + ErrLog(<<"Cannot auth request is missing " << e); + delete mMessage; + mMessage = 0; + mBufferPos = 0; + dropConnection = true; + return false; + } + + delete mMessage; + mMessage=0; + mBufferPos = 0; + + return true; +} + +bool +ConnectionBase::scanMsgHeader(int bytesRead) +{ + mMsgHeaderScanner.prepareForMessage(mMessage); + char *unprocessedCharPtr; + MsgHeaderScanner::ScanChunkResult scanResult = mMsgHeaderScanner.scanChunk(mBuffer, mBufferPos + bytesRead, &unprocessedCharPtr); + if (scanResult != MsgHeaderScanner::scrEnd) + { + if(scanResult != MsgHeaderScanner::scrNextChunk) + { + StackLog(<<"Failed to parse message, more bytes needed"); + StackLog(<< Data(mBuffer, bytesRead)); + } + delete mMessage; + mMessage=0; + mBufferPos += bytesRead; + return false; + } + return true; +} + +std::auto_ptr +ConnectionBase::makeWsHandshakeResponse() +{ + std::auto_ptr responsePtr(0); + if(isUsingSecWebSocketKey()) + { + responsePtr.reset(new Data("HTTP/1.1 101 WebSocket Protocol Handshake\r\n" + "Upgrade: WebSocket\r\n" + "Connection: Upgrade\r\n" + "Sec-WebSocket-Protocol: sip\r\n")); + + // Assuming that OpenSSL implementation of SHA1 is more effient than our internal one +#ifdef USE_SSL + SHA1Stream wsSha1Stream; + wsSha1Stream << (mMessage->const_header(h_SecWebSocketKey).value() + Symbols::WebsocketMagicGUID); + Data wsAcceptKey = wsSha1Stream.getBin(160).base64encode(); +#else + SHA1 sha1; + sha1.update(mMessage->const_header(h_SecWebSocketKey).value().c_str()); + sha1.update(Symbols::WebsocketMagicGUID); + Data wsAcceptKey = sha1.finalBin().base64encode(); +#endif + *responsePtr += "Sec-WebSocket-Accept: " + wsAcceptKey + "\r\n\r\n"; + } + else if(isUsingDeprecatedSecWebSocketKeys()) + { + ErrLog(<<"WS client wants to use depracated protocol version, unsupported"); + } + else + { + ErrLog(<<"No SecWebSocketKey header"); + } + return responsePtr; +} + +bool ConnectionBase::isUsingDeprecatedSecWebSocketKeys() +{ + resip_assert(mMessage); + return mMessage->exists(h_SecWebSocketKey1) && + mMessage->exists(h_SecWebSocketKey2); +} + +bool ConnectionBase::isUsingSecWebSocketKey() +{ + resip_assert(mMessage); + return mMessage->exists(h_SecWebSocketKey); +} + +bool +ConnectionBase::wsProcessData(int bytesRead) +{ + bool dropConnection = false; + // Always consumes the whole buffer: + std::auto_ptr msg = mWsFrameExtractor.processBytes((UInt8*)mBuffer, bytesRead, dropConnection); + + while(msg.get()) + { + // mWsBuffer should now contain a discrete SIP message, let the + // stack go to work on it + + if(msg->size() == 4 && memcmp(msg->data(), "\r\n\r\n", 4) == 0) + { + // sending a keep alive reply now + StackLog(<<"got a SIP ping embedded in WebSocket frame, replying"); + onDoubleCRLF(); + msg = mWsFrameExtractor.processBytes(0, 0, dropConnection); + continue; + } + + resip_assert(mTransport); + mMessage = new SipMessage(&mTransport->getTuple()); + + mMessage->setSource(mWho); + mMessage->setTlsDomain(mTransport->tlsDomain()); + +#ifdef USE_SSL + // Set TlsPeerName if message is from TlsConnection + TlsConnection *tlsConnection = dynamic_cast(this); + if(tlsConnection) + { + std::list peerNameList; + tlsConnection->getPeerNames(peerNameList); + mMessage->setTlsPeerNames(peerNameList); + } +#endif + + WsConnectionBase *wsConnectionBase = dynamic_cast(this); + if (wsConnectionBase) + { + mMessage->setWsCookies(wsConnectionBase->getCookies()); + mMessage->setWsCookieContext(wsConnectionBase->getWsCookieContext()); + } + + Data::size_type msg_len = msg->size(); + // cast permitted, as it is borrowed: + char *sipBuffer = (char *)msg->data(); + mMessage->addBuffer(sipBuffer); + mMsgHeaderScanner.prepareForMessage(mMessage); + char *unprocessedCharPtr; + if (mMsgHeaderScanner.scanChunk(sipBuffer, + msg_len, + &unprocessedCharPtr) != + MsgHeaderScanner::scrEnd) + { + StackLog(<<"Scanner rejecting WebSocket SIP message as unparsable, length = " << msg_len); + StackLog(<< Data(sipBuffer, msg_len)); + delete mMessage; + mMessage=0; + } + + unsigned int used = unprocessedCharPtr - sipBuffer; + if (mMessage && (used < msg_len)) + { + mMessage->setBody(sipBuffer+used, msg_len-used); + } + + if (mMessage && !transport()->basicCheck(*mMessage)) + { + delete mMessage; + mMessage = 0; + } + + if (mMessage) + { + Transport::stampReceived(mMessage); + resip_assert( mTransport ); + mTransport->pushRxMsgUp(mMessage); + mMessage = 0; + } + else + { + // Something wrong... + ErrLog(<< "We don't have a valid SIP message, maybe drop the connection?"); + } + msg = mWsFrameExtractor.processBytes(0, 0, dropConnection); + } + + if(dropConnection) + { + return false; + } + + return true; +} + #ifdef USE_SIGCOMP void ConnectionBase::decompressNewBytes(int bytesRead) @@ -554,6 +923,17 @@ ConnectionBase::decompressNewBytes(int bytesRead) mMessage->setSource(mWho); mMessage->setTlsDomain(mWho.transport->tlsDomain()); +#ifdef USE_SSL + // Set TlsPeerName if message is from TlsConnection + TlsConnection *tlsConnection = dynamic_cast(this); + if(tlsConnection) + { + std::list peerNameList; + tlsConnection->getPeerNames(peerNameList); + mMessage->setTlsPeerNames(peerNameList); + } +#endif + char *sipBuffer = new char[bytesUncompressed]; memmove(sipBuffer, uncompressed, bytesUncompressed); mMessage->addBuffer(sipBuffer); @@ -621,7 +1001,7 @@ ConnectionBase::decompressNewBytes(int bytesRead) mSigcompStack->provideCompartmentId(sc, compId.data(), compId.size()); } } - assert( mTransport ); + resip_assert( mTransport ); mTransport->pushRxMsgUp(mMessage); mMessage = 0; sc = 0; @@ -632,7 +1012,7 @@ ConnectionBase::decompressNewBytes(int bytesRead) sc = 0; } } - delete uncompressed; + delete [] uncompressed; // If there was a decompression failure, let the other side know. osc::SigcompMessage *nack = mSigcompStack->getNack(); @@ -681,21 +1061,23 @@ ConnectionBase::getCurrentWriteBuffer() } char* -ConnectionBase::getWriteBufferForExtraBytes(int extraBytes) +ConnectionBase::getWriteBufferForExtraBytes(int currentPos, int extraBytes) { - if (extraBytes > 0) + if (currentPos > 0 && extraBytes > 0) { - char* buffer = MsgHeaderScanner::allocateBuffer((int)mBufferSize + extraBytes); - memcpy(buffer, mBuffer, mBufferSize); - delete [] mBuffer; - mBuffer = buffer; - buffer += mBufferSize; - mBufferSize += extraBytes; - return buffer; + if ((currentPos + extraBytes) > mBufferSize) + { + mBufferSize = currentPos + extraBytes; + char* buffer = MsgHeaderScanner::allocateBuffer((int)mBufferSize); + memcpy(buffer, mBuffer, currentPos); + delete[] mBuffer; + mBuffer = buffer; + } + return &mBuffer[currentPos]; } else { - assert(0); + resip_assert(0); return mBuffer; } } @@ -711,7 +1093,7 @@ ConnectionBase::setBuffer(char* bytes, int count) Transport* ConnectionBase::transport() const { - assert(this); + resip_assert(this); return mTransport; } @@ -724,22 +1106,6 @@ resip::operator<<(EncodeStream& strm, return strm; } -void -ConnectionBase::setTransportLogger(InternalTransport::TransportLogger* logger) -{ - mTransportLogger = logger; -} - -void -ConnectionBase::putMessageToTransportLogger(SipMessage* msg) -{ - if (mTransportLogger) - { - std::ostringstream s; - s << *msg; - mTransportLogger->onSipMessage(InternalTransport::TransportLogger::Flow_Received, s.str().c_str(), s.str().length(), &msg->getSource().getSockaddr(), sizeof(sockaddr_in)); - } -} /* ==================================================================== * The Vovida Software License, Version 1.0 * diff --git a/src/libs/resiprocate/resip/stack/ConnectionBase.hxx b/src/libs/resiprocate/resip/stack/ConnectionBase.hxx index 427e893d..e843bde9 100644 --- a/src/libs/resiprocate/resip/stack/ConnectionBase.hxx +++ b/src/libs/resiprocate/resip/stack/ConnectionBase.hxx @@ -9,7 +9,8 @@ #include "resip/stack/Transport.hxx" #include "resip/stack/MsgHeaderScanner.hxx" #include "resip/stack/SendData.hxx" -#include "resip/stack/InternalTransport.hxx" +#include "resip/stack/WsFrameExtractor.hxx" +#include "resip/stack/Cookie.hxx" namespace osc { @@ -48,9 +49,11 @@ class ConnectionBase Tuple& who() { return mWho; } const UInt64& whenLastUsed() { return mLastUsed; } void resetLastUsed() { mLastUsed = Timer::getTimeMs(); } - void setTransportLogger(InternalTransport::TransportLogger* logger); - enum { ChunkSize = 2048 }; // !jf! what is the optimal size here? + enum { ChunkSize = 8192 }; // !jf! what is the optimal size here? + // !dp! 8192 seems to be consistent with a multiple of a page size and + // also good for the larger SDP coming in with ICE attributes, + // multiple media streams, etc protected: enum ConnState @@ -59,6 +62,7 @@ class ConnectionBase ReadingHeaders, PartialBody, SigComp, // This indicates that incoming bytes are compressed. + WebSocket, MAX }; @@ -66,15 +70,20 @@ class ConnectionBase { Unknown, Uncompressed, - Compressed + Compressed, + WebSocketHandshake, + WebSocketData, } TransmissionFormat; ConnState getCurrentState() const { return mConnState; } bool preparseNewBytes(int bytesRead); + bool wsProcessHandshake(int bytesRead, bool &dropConnection); + bool wsProcessData(int bytesRead); + void wsParseCookies(CookieList& cookieList, const SipMessage* message); void decompressNewBytes(int bytesRead); std::pair getWriteBuffer(); std::pair getCurrentWriteBuffer(); - char* getWriteBufferForExtraBytes(int extraBytes); + char* getWriteBufferForExtraBytes(int currentPos, int extraBytes); // for avoiding copies in external transports--not used in core resip void setBuffer(char* bytes, int count); @@ -90,11 +99,13 @@ class ConnectionBase ConnectionBase(); ConnectionBase(const Connection&); ConnectionBase& operator=(const Connection&); + bool scanMsgHeader(int bytesRead); + std::auto_ptr makeWsHandshakeResponse(); + bool isUsingSecWebSocketKey(); + bool isUsingDeprecatedSecWebSocketKeys(); protected: virtual void onDoubleCRLF(){} virtual void onSingleCRLF(){} - void putMessageToTransportLogger(SipMessage* msg); - Transport* mTransport; Tuple mWho; TransportFailure::FailureReason mFailureReason; @@ -104,18 +115,24 @@ class ConnectionBase osc::TcpStream *mSigcompFramer; TransmissionFormat mSendingTransmissionFormat; TransmissionFormat mReceivingTransmissionFormat; - InternalTransport::TransportLogger* mTransportLogger; private: SipMessage* mMessage; char* mBuffer; size_t mBufferPos; size_t mBufferSize; + WsFrameExtractor mWsFrameExtractor; static char connectionStates[MAX][32]; UInt64 mLastUsed; ConnState mConnState; MsgHeaderScanner mMsgHeaderScanner; + + static size_t messageSizeMax; + + public: + static void setMessageSizeMax(size_t max) + { messageSizeMax = max; }; }; EncodeStream& diff --git a/src/libs/resiprocate/resip/stack/ConnectionManager.cxx b/src/libs/resiprocate/resip/stack/ConnectionManager.cxx index 3f97da54..0070f2ad 100644 --- a/src/libs/resiprocate/resip/stack/ConnectionManager.cxx +++ b/src/libs/resiprocate/resip/stack/ConnectionManager.cxx @@ -2,6 +2,11 @@ #include "config.h" #endif +#ifndef WIN32 +#include +#include +#endif + #include "resip/stack/ConnectionManager.hxx" #include "resip/stack/InteropHelper.hxx" #include "rutil/Logger.hxx" @@ -15,10 +20,11 @@ using namespace std; #define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT UInt64 ConnectionManager::MinimumGcAge = 1; // in milliseconds +UInt64 ConnectionManager::MinimumGcHeadroom = 0; bool ConnectionManager::EnableAgressiveGc = false; ConnectionManager::ConnectionManager() : - mHead(0,Tuple(),0,Compression::Disabled), + mHead(0,Tuple(),0,Compression::Disabled, false), mWriteHead(ConnectionWriteList::makeList(&mHead)), mReadHead(ConnectionReadList::makeList(&mHead)), mLRUHead(ConnectionLruList::makeList(&mHead)), @@ -31,10 +37,10 @@ ConnectionManager::ConnectionManager() : ConnectionManager::~ConnectionManager() { closeConnections(); - assert(mReadHead->empty()); - assert(mWriteHead->empty()); - assert(mLRUHead->empty()); - assert(mFlowTimerLRUHead->empty()); + resip_assert(mReadHead->empty()); + resip_assert(mWriteHead->empty()); + resip_assert(mLRUHead->empty()); + resip_assert(mFlowTimerLRUHead->empty()); } void @@ -54,7 +60,7 @@ ConnectionManager::findConnection(const Tuple& addr) IdMap::iterator i = mIdMap.find(addr.mFlowKey); if (i != mIdMap.end()) { - if(i->second->who()==addr) + if(i->second->who() == addr) { DebugLog(<<"Found fd " << addr.mFlowKey); return i->second; @@ -84,7 +90,6 @@ ConnectionManager::findConnection(const Tuple& addr) return i->second; } - DebugLog(<<"Could not find a connection for " << addr); return 0; } @@ -122,7 +127,6 @@ ConnectionManager::findConnection(const Tuple& addr) const return i->second; } - DebugLog(<<"Could not find a connection for " << addr); return 0; } @@ -131,7 +135,7 @@ void ConnectionManager::buildFdSet(FdSet& fdset) { // If using PollGrp, caller shouldn't call this - assert( mPollGrp==0 ); + resip_assert( mPollGrp==0 ); for (ConnectionReadList::iterator i = mReadHead->begin(); i != mReadHead->end(); ++i) @@ -170,7 +174,7 @@ ConnectionManager::removeFromWritable(Connection* conn) } else { - assert(!mWriteHead->empty()); + resip_assert(!mWriteHead->empty()); conn->ConnectionWriteList::remove(); } } @@ -178,10 +182,9 @@ ConnectionManager::removeFromWritable(Connection* conn) void ConnectionManager::addConnection(Connection* connection) { - assert(mAddrMap.find(connection->who())==mAddrMap.end()); + resip_assert(mAddrMap.find(connection->who())==mAddrMap.end()); - //DebugLog (<< "ConnectionManager::addConnection() " << connection->mWho.mFlowKey << ":" << connection->mSocket); - + DebugLog (<< "ConnectionManager::addConnection() " << connection->mWho.mFlowKey << ":" << connection->who() << ", totalConnections=" << mIdMap.size()); mAddrMap[connection->who()] = connection; mIdMap[connection->who().mFlowKey] = connection; @@ -205,13 +208,13 @@ ConnectionManager::addConnection(Connection* connection) //DebugLog (<< "count=" << mAddrMap.count(connection->who()) << "who=" << connection->who() << " mAddrMap=" << Inserter(mAddrMap)); //assert(mAddrMap.begin()->first == connection->who()); - assert(mAddrMap.count(connection->who()) == 1); + resip_assert(mAddrMap.count(connection->who()) == 1); } void ConnectionManager::removeConnection(Connection* connection) { - //DebugLog (<< "ConnectionManager::removeConnection()"); + DebugLog (<< "ConnectionManager::removeConnection()"); mIdMap.erase(connection->mWho.mFlowKey); mAddrMap.erase(connection->mWho); @@ -222,7 +225,7 @@ ConnectionManager::removeConnection(Connection* connection) } else { - assert(!mReadHead->empty()); + resip_assert(!mReadHead->empty()); connection->ConnectionReadList::remove(); connection->ConnectionWriteList::remove(); if(connection->isFlowTimerEnabled()) @@ -237,7 +240,7 @@ ConnectionManager::removeConnection(Connection* connection) } // release excessively old connections (free up file descriptors) -void +unsigned int ConnectionManager::gc(UInt64 relThreshold, unsigned int maxToRemove) { UInt64 curTimeMs = Timer::getTimeMs(); @@ -289,6 +292,78 @@ ConnectionManager::gc(UInt64 relThreshold, unsigned int maxToRemove) } } } + + if(MinimumGcHeadroom > 0) + { +#ifdef WIN32 + DebugLog(<<"MinimumGcHeadroom not yet implemented on Windows (requires getrlimit())"); +#else + struct rlimit rlim; + if(getrlimit(RLIMIT_NOFILE, &rlim) != 0) + { + ErrLog(<<"Call to getrlimit() for RLIMIT_NOFILE failed: " << strerror(errno)); + } + else + { + rlim_t& soft_limit = rlim.rlim_cur; + AddrMap::size_type conn_count = mAddrMap.size(); + AddrMap::size_type headroom = soft_limit - conn_count; + DebugLog(<< "GC headroom check: soft_limit = " << soft_limit << ", managed connection count = " << conn_count << ", headroom = " << headroom << ", minimum headroom = " << MinimumGcHeadroom); + if(headroom < MinimumGcHeadroom) + { + WarningLog(<< "actual headroom = " << headroom << ", MinimumGcHeadroom = " << MinimumGcHeadroom << ", garbage collector making extra effort to reclaim file descriptors"); + AddrMap::size_type mustRemove = MinimumGcHeadroom - headroom; + unsigned int remainder = gcWithTarget(mustRemove); + numRemoved += (mustRemove - remainder); + if(remainder > 0) + { + ErrLog(<< "No more stream connections to close, something else must be eating file descriptors, limit too low or MinimumGcHeadroom too high"); + } + } + } +#endif + } + return numRemoved; +} + +unsigned int +ConnectionManager::gcWithTarget(unsigned int target) +{ + ConnectionLruList::iterator i = mLRUHead->begin(); + FlowTimerLruList::iterator i2 = mFlowTimerLRUHead->begin(); + while(target > 0) + { + Connection* discard = 0; + if(i == mLRUHead->end()) + { + if(i2 == mFlowTimerLRUHead->end()) + { + WarningLog(<< "No more stream connections to close, remaining target = " << target); + return target; + } + discard = *i2; + ++i2; + } + else + { + if(i2 == mFlowTimerLRUHead->end() || + (*i)->whenLastUsed() < (*i2)->whenLastUsed()) + { + discard = *i; + ++i; + } + else + { + discard = *i2; + ++i2; + } + } + resip_assert(discard); + WarningLog(<< "recycling LRU connection: " << discard << " " << discard->getSocket()); + delete discard; + target--; + } + return target; } // move to youngest @@ -318,7 +393,7 @@ ConnectionManager::moveToFlowTimerLru(Connection *connection) void ConnectionManager::process(FdSet& fdset) { - assert( mPollGrp==NULL ); // owner shouldn't call this if polling + resip_assert( mPollGrp==NULL ); // owner shouldn't call this if polling // process the write list for (ConnectionWriteList::iterator writeIter = mWriteHead->begin(); @@ -387,6 +462,15 @@ ConnectionManager::setPollGrp(FdPollGrp *grp) mPollGrp = grp; } +void +ConnectionManager::invokeAfterSocketCreationFunc() const +{ + for (AddrMap::const_iterator it = mAddrMap.begin(); it != mAddrMap.end(); it++) + { + it->second->invokeAfterSocketCreationFunc(); + } +} + /* ==================================================================== * The Vovida Software License, Version 1.0 * diff --git a/src/libs/resiprocate/resip/stack/ConnectionManager.hxx b/src/libs/resiprocate/resip/stack/ConnectionManager.hxx index 0815e1e8..c484beae 100644 --- a/src/libs/resiprocate/resip/stack/ConnectionManager.hxx +++ b/src/libs/resiprocate/resip/stack/ConnectionManager.hxx @@ -18,11 +18,18 @@ class FdPollGrp; */ class ConnectionManager { - friend class Connection; + friend class Connection; + public: /** connection must have no inbound traffic for greater than this time (in ms) before it is garbage collected */ static UInt64 MinimumGcAge; + /** If the difference between the number of permitted FDs + (reported by periodic calls to getrlimit()) and the number + of active stream connections falls below this threshold, + the garbage collector will overlook MinimumGcAge and + more aggressively close connections */ + static UInt64 MinimumGcHeadroom; /** Enable Agressive Connection Garbage Collection to have resip perform garbage collection on every new connection. If disabled then garbage collection is only performed if we run out of Fd's */ @@ -40,6 +47,8 @@ class ConnectionManager void buildFdSet(FdSet& fdset); void process(FdSet& fdset); + virtual void invokeAfterSocketCreationFunc() const; + private: void addToWritable(Connection* conn); // add the specified conn to end void removeFromWritable(Connection* conn); // remove the current mWriteMark @@ -53,7 +62,8 @@ class ConnectionManager /// release excessively old connections (free up file descriptors) /// set maxToRemove to 0 for no-max - void gc(UInt64 threshold, unsigned int maxToRemove); + unsigned int gc(UInt64 threshold, unsigned int maxToRemove); + unsigned int gcWithTarget(unsigned int target); /// move to youngest void touch(Connection* connection); diff --git a/src/libs/resiprocate/resip/stack/ConnectionTerminated.hxx b/src/libs/resiprocate/resip/stack/ConnectionTerminated.hxx index 29262c3b..20930a7c 100644 --- a/src/libs/resiprocate/resip/stack/ConnectionTerminated.hxx +++ b/src/libs/resiprocate/resip/stack/ConnectionTerminated.hxx @@ -17,8 +17,8 @@ class ConnectionTerminated : public TransactionMessage mFlow(flow) { } - virtual const Data& getTransactionId() const { assert(0); return Data::Empty; } - virtual bool isClientTransaction() const { assert(0); return false; } + virtual const Data& getTransactionId() const { resip_assert(0); return Data::Empty; } + virtual bool isClientTransaction() const { resip_assert(0); return false; } virtual Message* clone() const { return new ConnectionTerminated(mFlow); } virtual EncodeStream& encode(EncodeStream& strm) const { return encodeBrief(strm); } virtual EncodeStream& encodeBrief(EncodeStream& str) const diff --git a/src/libs/resiprocate/resip/stack/Contents.cxx b/src/libs/resiprocate/resip/stack/Contents.cxx index 9d3069ea..acb56c50 100644 --- a/src/libs/resiprocate/resip/stack/Contents.cxx +++ b/src/libs/resiprocate/resip/stack/Contents.cxx @@ -8,6 +8,7 @@ #include "rutil/ParseBuffer.hxx" #include "rutil/Logger.hxx" #include "resip/stack/OctetContents.hxx" +#include "rutil/MD5Stream.hxx" #include "rutil/WinLeakCheck.hxx" using namespace resip; @@ -223,7 +224,7 @@ Contents::exists(const MIME_Header& type) const return mDescription != 0; } - assert(false); + resip_assert(false); return false; } @@ -272,7 +273,7 @@ Contents::remove(const MIME_Header& type) return; } - assert(false); + resip_assert(false); } const H_ContentType::Type& @@ -563,7 +564,7 @@ Contents::preParseHeaders(ParseBuffer& pb) // add to application headers someday std::cerr << "Unknown MIME Content- header: " << headerName << std::endl; ErrLog(<< "Unknown MIME Content- header: " << headerName); - assert(false); + resip_assert(false); } } } @@ -662,6 +663,22 @@ Contents::addBuffer(char* buf) mBufferList.push_back(buf); } +bool +resip::operator==(const Contents& lhs, const Contents& rhs) +{ + MD5Stream lhsStream; + lhsStream << lhs; + MD5Stream rhsStream; + rhsStream << rhs; + return lhsStream.getHex() == rhsStream.getHex(); +} + +bool +resip::operator!=(const Contents& lhs, const Contents& rhs) +{ + return !operator==(lhs,rhs); +} + /* ==================================================================== * The Vovida Software License, Version 1.0 * diff --git a/src/libs/resiprocate/resip/stack/Contents.hxx b/src/libs/resiprocate/resip/stack/Contents.hxx index 17fb0a66..43f2f8b9 100644 --- a/src/libs/resiprocate/resip/stack/Contents.hxx +++ b/src/libs/resiprocate/resip/stack/Contents.hxx @@ -361,6 +361,9 @@ class Contents : public LazyParser std::vector mBufferList; }; +bool operator==(const Contents& lhs, const Contents& rhs); +bool operator!=(const Contents& lhs, const Contents& rhs); + } #endif diff --git a/src/libs/resiprocate/resip/stack/ContentsFactoryBase.cxx b/src/libs/resiprocate/resip/stack/ContentsFactoryBase.cxx index 1d89b814..60a6176f 100644 --- a/src/libs/resiprocate/resip/stack/ContentsFactoryBase.cxx +++ b/src/libs/resiprocate/resip/stack/ContentsFactoryBase.cxx @@ -1,4 +1,4 @@ -#include +#include "rutil/ResipAssert.h" #include "resip/stack/ContentsFactoryBase.hxx" #include "rutil/WinLeakCheck.hxx" diff --git a/src/libs/resiprocate/resip/stack/Cookie.cxx b/src/libs/resiprocate/resip/stack/Cookie.cxx new file mode 100644 index 00000000..12862483 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Cookie.cxx @@ -0,0 +1,113 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/Cookie.hxx" +#include "resip/stack/StringCategory.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/ParseBuffer.hxx" + +using namespace resip; + +//==================== +// Cookie +//==================== +Cookie::Cookie() : + mName(), + mValue() +{} + +Cookie::Cookie(const Data& name, const Data& value) : + mName(name.urlDecoded()), + mValue(value.urlDecoded()) +{} + +Cookie& +Cookie::operator=(const Cookie& rhs) +{ + if (this != &rhs) + { + mName = rhs.mName; + mValue = rhs.mValue; + } + return *this; +} + +bool +Cookie::operator==(const Cookie& other) const +{ + return name() == other.name() && value() == other.value(); +} + +bool Cookie::operator<(const Cookie& rhs) const +{ + return name() + value() < rhs.name() + rhs.value(); +} + +EncodeStream& +resip::operator<<(EncodeStream& strm, const Cookie& c) +{ + strm << c.name() << Symbols::EQUALS[0] << c.value(); + return strm; +} + +const Data& +Cookie::name() const +{ + return mName; +} + +Data& +Cookie::name() +{ + return mName; +} + +const Data& +Cookie::value() const +{ + return mValue; +} + +Data& +Cookie::value() +{ + return mValue; +} + +/* ==================================================================== + * BSD License + * + * Copyright (c) 2013 Catalin Constantin Usurelu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + */ diff --git a/src/libs/resiprocate/resip/stack/Cookie.hxx b/src/libs/resiprocate/resip/stack/Cookie.hxx new file mode 100644 index 00000000..18718582 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Cookie.hxx @@ -0,0 +1,77 @@ +#if !defined(RESIP_COOKIE_HXX) +#define RESIP_COOKIE_HXX + + +#include "rutil/Data.hxx" + +#include + +namespace resip +{ + +class Cookie +{ + public: + + Cookie(); + Cookie(const Data& name, const Data& value); + + Cookie& operator=(const Cookie&); + bool operator==(const Cookie& other) const; + bool operator<(const Cookie& rhs) const; + friend EncodeStream& operator<<(EncodeStream& strm, const Cookie& c); + + const Data& name() const; + Data& name(); + + const Data& value() const; + Data& value(); + + private: + Data mName; + Data mValue; +}; + +typedef std::vector CookieList; + +} + +#endif + + +/* ==================================================================== + * BSD License + * + * Copyright (c) 2013 Catalin Constantin Usurelu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + */ diff --git a/src/libs/resiprocate/resip/stack/DataParameter.cxx b/src/libs/resiprocate/resip/stack/DataParameter.cxx index ebc855ca..37d57be4 100644 --- a/src/libs/resiprocate/resip/stack/DataParameter.cxx +++ b/src/libs/resiprocate/resip/stack/DataParameter.cxx @@ -2,7 +2,7 @@ #include "config.h" #endif -#include +#include "rutil/ResipAssert.h" #include "resip/stack/DataParameter.hxx" #include "resip/stack/Symbols.hxx" #include "rutil/ParseBuffer.hxx" @@ -90,7 +90,7 @@ DataParameter::encode(EncodeStream& stream) const { ErrLog(<< "Accessing defaulted DataParameter: '" << getName() << "'"); } - assert(!mValue.empty()); // !jf! probably should throw here + resip_assert(!mValue.empty()); // !jf! probably should throw here return stream << getName() << Symbols::EQUALS << mValue; } } diff --git a/src/libs/resiprocate/resip/stack/DateCategory.cxx b/src/libs/resiprocate/resip/stack/DateCategory.cxx index bcab588d..9c9c20d0 100644 --- a/src/libs/resiprocate/resip/stack/DateCategory.cxx +++ b/src/libs/resiprocate/resip/stack/DateCategory.cxx @@ -1,10 +1,11 @@ -#if defined(HAVE_CONFIG_H) -#include "config.h" -#endif +#include "rutil/compat.hxx" +#include +#include #include #include "resip/stack/DateCategory.hxx" + #include "resip/stack/Transport.hxx" #include "rutil/Data.hxx" #include "rutil/DnsUtil.hxx" @@ -16,6 +17,29 @@ using namespace resip; using namespace std; +namespace resip +{ +// Implemented in gen/DayOfWeekHash.cxx +struct days { const char *name; DayOfWeek type; }; +class DayOfWeekHash +{ +private: + static inline unsigned int hash (const char *str, GPERF_SIZE_TYPE len); +public: + static const struct days *in_word_set (const char *str, GPERF_SIZE_TYPE len); +}; + +// Implemented in gen/MonthHash.cxx +struct months { const char *name; Month type; }; +class MonthHash +{ +private: + static inline unsigned int hash (const char *str, GPERF_SIZE_TYPE len); +public: + static const struct months *in_word_set (const char *str, GPERF_SIZE_TYPE len); +}; +} + #define RESIPROCATE_SUBSYSTEM Subsystem::SIP //==================== @@ -166,264 +190,38 @@ DateCategory::setDatetime(time_t datetime) return true; } -/* ANSI-C code produced by gperf version 2.7.2 */ -/* Command-line: gperf -L ANSI-C -t -k '*' dayofweek.gperf */ -/** - @internal -*/ -struct days { char name[32]; DayOfWeek day; }; - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static unsigned int -dayofweek_hash (register const char *str, register unsigned int len) -{ - static unsigned char asso_values[] = - { - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 1, 13, 13, 13, 13, 13, 13, 5, 13, 13, - 13, 13, 13, 2, 0, 13, 13, 7, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 7, 13, 13, - 0, 0, 13, 13, 4, 0, 13, 13, 13, 13, - 0, 0, 13, 13, 0, 13, 0, 0, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13 - }; - register int hval = len; - - switch (hval) - { - default: /*FALLTHRU*/ - case 3: - hval += asso_values[(unsigned char)str[2]]; - /*FALLTHRU*/ - case 2: - hval += asso_values[(unsigned char)str[1]]; - /*FALLTHRU*/ - case 1: - hval += asso_values[(unsigned char)str[0]]; - break; - } - return hval; -} - -#ifdef __GNUC__ -__inline -#endif -struct days * -in_dayofweek_word_set (register const char *str, register unsigned int len) -{ - static const unsigned int MIN_WORD_LENGTH = 3; - static const unsigned int MAX_WORD_LENGTH = 3; - static const int MAX_HASH_VALUE = 12; - - static struct days wordlist[] = - { - {""}, {""}, {""}, - {"Tue", Tue}, - {"Fri", Fri}, - {"Sun", Sun}, - {""}, - {"Thu", Thu}, - {"Mon", Mon}, - {""}, - {"Wed", Wed}, - {""}, - {"Sat", Sat} - }; - - if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) - { - register int key = dayofweek_hash (str, len); - - if (key <= MAX_HASH_VALUE && key >= 0) - { - register const char *s = wordlist[key].name; - - if (*str == *s && !strcmp (str + 1, s + 1)) - return &wordlist[key]; - } - } - return 0; -} - DayOfWeek DateCategory::DayOfWeekFromData(const Data& dow) { - static const unsigned int MIN_WORD_LENGTH = 3; - static const unsigned int MAX_WORD_LENGTH = 3; - static const int MAX_HASH_VALUE = 12; + const char *str = dow.data(); + Data::size_type len = dow.size(); - register const char *str = dow.data(); - register Data::size_type len = dow.size(); - - static struct days wordlist[] = - { - {""}, {""}, {""}, - {"Tue", Tue}, - {"Fri", Fri}, - {"Sun", Sun}, - {""}, - {"Thu", Thu}, - {"Mon", Mon}, - {""}, - {"Wed", Wed}, - {""}, - {"Sat", Sat} - }; - - if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + const struct days* _day = DayOfWeekHash::in_word_set(str, len); + if(_day != 0) { - register int key = dayofweek_hash (str, (unsigned int)len); - - if (key <= MAX_HASH_VALUE && key >= 0) - { - register const char *s = wordlist[key].name; - - if (*str == *s && !strncmp (str+1, s+1, len-1)) - { - return wordlist[key].day; - } - } + return _day->type; } - return Sun; -} - -/* ANSI-C code produced by gperf version 2.7.2 */ -/* Command-line: gperf -L ANSI-C -t -k '*' month.gperf */ -/** - @internal -*/ -struct months { char name[32]; Month type; }; - -/* maximum key range = 31, duplicates = 0 */ - -#ifdef __GNUC__ -__inline -#else -#ifdef __cplusplus -inline -#endif -#endif -static unsigned int -month_hash (register const char *str, register unsigned int len) -{ - static unsigned char asso_values[] = - { - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 15, 34, 34, 8, 34, - 5, 34, 34, 34, 0, 34, 34, 10, 3, 14, - 34, 34, 34, 9, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 10, 0, 0, - 34, 0, 34, 10, 34, 34, 34, 34, 4, 34, - 0, 0, 0, 34, 0, 34, 0, 0, 0, 34, - 34, 10, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34 - }; - register int hval = len; - - switch (hval) + else { - default: /*FALLTHRU*/ - case 3: - hval += asso_values[(unsigned char)str[2]]; - /*FALLTHRU*/ - case 2: - hval += asso_values[(unsigned char)str[1]]; - /*FALLTHRU*/ - case 1: - hval += asso_values[(unsigned char)str[0]]; - break; + return Sun; } - return hval; } Month DateCategory::MonthFromData(const Data& mon) { - static const unsigned int MIN_WORD_LENGTH = 3; - static const unsigned int MAX_WORD_LENGTH = 3; - static const int MAX_HASH_VALUE = 33; + const char *str = mon.data(); + Data::size_type len = mon.size(); - register const char *str = mon.data(); - register Data::size_type len = mon.size(); - - static struct months wordlist[] = - { - {""}, {""}, {""}, - {"Jun", Jun}, - {""}, {""}, - {"Nov", Nov}, - {"Jul", Jul}, - {"Feb", Feb}, - {""}, {""}, - {"Dec", Dec}, - {"Sep", Sep}, - {"Jan", Jan}, - {""}, {""}, {""}, - {"Oct", Oct}, - {"Apr", Apr}, - {""}, {""}, {""}, {""}, - {"Mar", Mar}, - {""}, {""}, {""}, {""}, - {"Aug", Aug}, - {""}, {""}, {""}, {""}, - {"May", May} - }; - - if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + const struct months* _month = MonthHash::in_word_set(str, len); + if(_month != 0) { - register int key = month_hash (str, (unsigned int)len); - - if (key <= MAX_HASH_VALUE && key >= 0) - { - register const char *s = wordlist[key].name; - - if (*str == *s && !strncmp (str + 1, s + 1, mon.size()-1)) - return wordlist[key].type; - } + return _month->type; + } + else + { + return Jan; } - return Jan; } const DayOfWeek& diff --git a/src/libs/resiprocate/resip/stack/DayOfWeekHash.gperf b/src/libs/resiprocate/resip/stack/DayOfWeekHash.gperf new file mode 100644 index 00000000..5b659975 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/DayOfWeekHash.gperf @@ -0,0 +1,19 @@ +%{ +#include +#include +#include "resip/stack/DateCategory.hxx" + +namespace resip +{ +%} +struct days { const char *name; DayOfWeek type; }; +%% +Sun, Sun +Mon, Mon +Tue, Tue +Wed, Wed +Thu, Thu +Fri, Fri +Sat, Sat +%% +} diff --git a/src/libs/resiprocate/resip/stack/DeprecatedDialog.cxx b/src/libs/resiprocate/resip/stack/DeprecatedDialog.cxx index bf27e901..0324c712 100644 --- a/src/libs/resiprocate/resip/stack/DeprecatedDialog.cxx +++ b/src/libs/resiprocate/resip/stack/DeprecatedDialog.cxx @@ -39,18 +39,18 @@ DeprecatedDialog::DeprecatedDialog(const NameAddr& localContact) SipMessage* DeprecatedDialog::makeResponse(const SipMessage& request, int code) { - assert( code >= 100 ); + resip_assert( code >= 100 ); if ( (!mCreated) && (code < 300) && (code > 100) ) { - assert (code > 100); - assert (code < 300); - assert(request.isRequest()); - assert(request.header(h_RequestLine).getMethod() == INVITE || + resip_assert (code > 100); + resip_assert (code < 300); + resip_assert(request.isRequest()); + resip_assert(request.header(h_RequestLine).getMethod() == INVITE || request.header(h_RequestLine).getMethod() == SUBSCRIBE || request.header(h_RequestLine).getMethod() == PUBLISH); - assert (request.header(h_Contacts).size() == 1); + resip_assert (request.header(h_Contacts).size() == 1); SipMessage* response = Helper::makeResponse(request, code, mContact); if (request.exists(h_RecordRoutes)) @@ -72,7 +72,7 @@ DeprecatedDialog::makeResponse(const SipMessage& request, int code) mLocalEmpty = true; mCallId = request.header(h_CallId); response->header(h_To).param(p_tag) = Helper::computeTag(Helper::tagSize); - assert (response->header(h_To).exists(p_tag)); + resip_assert (response->header(h_To).exists(p_tag)); mLocalTag = response->header(h_To).param(p_tag); // from response if (request.header(h_From).exists(p_tag)) // 2543 compat { @@ -225,7 +225,7 @@ DeprecatedDialog::targetRefreshResponse(const SipMessage& response) int DeprecatedDialog::targetRefreshRequest(const SipMessage& request) { - assert (request.header(h_RequestLine).getMethod() != CANCEL); + resip_assert (request.header(h_RequestLine).getMethod() != CANCEL); if (request.header(h_RequestLine).getMethod() != ACK) { unsigned long cseq = request.header(h_CSeq).sequence(); @@ -263,7 +263,7 @@ DeprecatedDialog::targetRefreshRequest(const SipMessage& request) void DeprecatedDialog::updateRequest(SipMessage& request) { - assert (request.isRequest()); + resip_assert (request.isRequest()); if (mCreated) { request.header(h_RequestLine).uri() = mRemoteTarget.uri(); @@ -303,12 +303,12 @@ DeprecatedDialog::updateRequest(SipMessage& request) void DeprecatedDialog::makeResponse(const SipMessage& request, SipMessage& response, int code) { - assert(request.isRequest()); + resip_assert(request.isRequest()); if ( (!mCreated) && (code < 300) && (code > 100) ) { - assert(request.header(h_RequestLine).getMethod() == INVITE || + resip_assert(request.header(h_RequestLine).getMethod() == INVITE || request.header(h_RequestLine).getMethod() == SUBSCRIBE); - assert (request.header(h_Contacts).size() == 1); + resip_assert (request.header(h_Contacts).size() == 1); Helper::makeResponse(response, request, code, mContact); response.header(h_To).param(p_tag) = Helper::computeTag(Helper::tagSize); @@ -331,7 +331,7 @@ DeprecatedDialog::makeResponse(const SipMessage& request, SipMessage& response, mLocalSequence = 0; mLocalEmpty = true; mCallId = request.header(h_CallId); - assert (response.const_header(h_To).exists(p_tag)); + resip_assert (response.const_header(h_To).exists(p_tag)); mLocalTag = response.header(h_To).param(p_tag); // from response if (request.header(h_From).exists(p_tag)) // 2543 compat { @@ -365,13 +365,13 @@ SipMessage* DeprecatedDialog::makeInitialRegister(const NameAddr& registrar, const NameAddr& aor) { SipMessage* msg = Helper::makeRegister( registrar, aor, mContact ); - assert( msg ); + resip_assert( msg ); mRequestUri = msg->const_header(h_RequestLine).uri(); mLocalEmpty = false; mLocalSequence = msg->const_header(h_CSeq).sequence(); mCallId = msg->const_header(h_CallId); - assert(msg->const_header(h_From).exists(p_tag)); + resip_assert(msg->const_header(h_From).exists(p_tag)); mLocalTag = msg->const_header(h_From).param(p_tag); mRemoteUri = msg->const_header(h_To); mLocalUri = msg->const_header(h_From); @@ -387,13 +387,13 @@ SipMessage* DeprecatedDialog::makeInitialSubscribe(const NameAddr& target, const NameAddr& from) { SipMessage* msg = Helper::makeSubscribe( target, from, mContact ); - assert( msg ); + resip_assert( msg ); mRequestUri = msg->const_header(h_RequestLine).uri(); mLocalEmpty = false; mLocalSequence = msg->const_header(h_CSeq).sequence(); mCallId = msg->const_header(h_CallId); - assert(msg->const_header(h_From).exists(p_tag)); + resip_assert(msg->const_header(h_From).exists(p_tag)); mLocalTag = msg->const_header(h_From).param(p_tag); mRemoteUri = msg->const_header(h_To); mLocalUri = msg->const_header(h_From); @@ -406,13 +406,13 @@ SipMessage* DeprecatedDialog::makeInitialPublish(const NameAddr& target, const NameAddr& from) { SipMessage* msg = Helper::makePublish( target, from, mContact ); - assert( msg ); + resip_assert( msg ); mRequestUri = msg->const_header(h_RequestLine).uri(); mLocalEmpty = false; mLocalSequence = msg->const_header(h_CSeq).sequence(); mCallId = msg->const_header(h_CallId); - assert(msg->const_header(h_From).exists(p_tag)); + resip_assert(msg->const_header(h_From).exists(p_tag)); mLocalTag = msg->const_header(h_From).param(p_tag); mRemoteUri = msg->const_header(h_To); mLocalUri = msg->const_header(h_From); @@ -425,13 +425,13 @@ SipMessage* DeprecatedDialog::makeInitialMessage(const NameAddr& target, const NameAddr& from) { SipMessage* msg = Helper::makeMessage( target, from, mContact ); - assert( msg ); + resip_assert( msg ); mRequestUri = msg->const_header(h_RequestLine).uri(); mLocalEmpty = false; mLocalSequence = msg->const_header(h_CSeq).sequence(); mCallId = msg->const_header(h_CallId); - assert(msg->const_header(h_From).exists(p_tag)); + resip_assert(msg->const_header(h_From).exists(p_tag)); mLocalTag = msg->const_header(h_From).param(p_tag); mRemoteUri = msg->const_header(h_To); mLocalUri = msg->const_header(h_From); @@ -444,13 +444,13 @@ SipMessage* DeprecatedDialog::makeInitialInvite(const NameAddr& target, const NameAddr& from) { SipMessage* msg = Helper::makeInvite( target, from, mContact ); - assert( msg ); + resip_assert( msg ); mRequestUri = msg->const_header(h_RequestLine).uri(); mLocalEmpty = false; mLocalSequence = msg->const_header(h_CSeq).sequence(); mCallId = msg->const_header(h_CallId); - assert(msg->const_header(h_From).exists(p_tag)); + resip_assert(msg->const_header(h_From).exists(p_tag)); mLocalTag = msg->const_header(h_From).param(p_tag); mRemoteUri = msg->const_header(h_To); mLocalUri = msg->const_header(h_From); @@ -543,8 +543,8 @@ DeprecatedDialog::makePublish() SipMessage* DeprecatedDialog::makeRequest(resip::MethodTypes method) { - assert(method != ACK); - assert(method != CANCEL); + resip_assert(method != ACK); + resip_assert(method != CANCEL); SipMessage* request = makeRequestInternal(method); incrementCSeq(*request); @@ -584,8 +584,8 @@ DeprecatedDialog::makeAck() SipMessage* DeprecatedDialog::makeCancel(const SipMessage& request) { - assert (request.header(h_Vias).size() >= 1); - assert (request.header(h_RequestLine).getMethod() == INVITE); + resip_assert (request.header(h_Vias).size() >= 1); + resip_assert (request.header(h_RequestLine).getMethod() == INVITE); SipMessage* cancel = new SipMessage; diff --git a/src/libs/resiprocate/resip/stack/DialogInfoContents.cxx b/src/libs/resiprocate/resip/stack/DialogInfoContents.cxx new file mode 100644 index 00000000..c9ed794d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/DialogInfoContents.cxx @@ -0,0 +1,879 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include +#include + +#include "resip/stack/DialogInfoContents.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/XMLCursor.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Inserter.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +const static Data BaseDialogInfoNamespaceUri("urn:ietf:params:xml:ns:dialog-info"); + +const static Data DefaultEncodeIndent(" "); + +bool +DialogInfoContents::init() +{ + static ContentsFactory factory; + (void)factory; + return true; +} + +static const char* DialogInfoStateStrings[] = +{ + "full", + "partial" +}; + +const char* +DialogInfoContents::dialogInfoStateToString(const DialogInfoState& dialogInfoState) +{ + return DialogInfoStateStrings[dialogInfoState]; +} + +DialogInfoContents::DialogInfoState +DialogInfoContents::dialogInfoStateStringToEnum(const Data& dialogInfoStateString) +{ + for (int i = 0; i < MaxDialogInfoState; i++) + { + if (isEqualNoCase(DialogInfoStateStrings[i], dialogInfoStateString)) + { + return (DialogInfoState)i; + } + } + return MaxDialogInfoState; +} + +static const char* DialogStateStrings[] = +{ + "trying", + "proceeding", + "early", + "confirmed", + "terminated" +}; + +const char* +DialogInfoContents::dialogStateToString(const DialogState& dialogState) +{ + return DialogStateStrings[dialogState]; +} + +DialogInfoContents::DialogState +DialogInfoContents::dialogStateStringToEnum(const Data& dialogStateString) +{ + for (int i = 0; i < MaxDialogState; i++) + { + if (isEqualNoCase(DialogStateStrings[i], dialogStateString)) + { + return (DialogState)i; + } + } + return MaxDialogState; +} + +static const char* DialogStateEventStrings[] = +{ + "cancelled", + "rejected", + "replaced", + "local-bye", + "remote-bye", + "error", + "timeout" +}; + +const char* +DialogInfoContents::dialogStateEventToString(const DialogStateEvent& dialogStateEvent) +{ + return DialogStateEventStrings[dialogStateEvent]; +} + +DialogInfoContents::DialogStateEvent +DialogInfoContents::dialogStateEventStringToEnum(const Data& dialogStateEventString) +{ + for (int i = 0; i < MaxOrUnsetDialogStateEvent; i++) + { + if (isEqualNoCase(DialogStateEventStrings[i], dialogStateEventString)) + { + return (DialogStateEvent)i; + } + } + return MaxOrUnsetDialogStateEvent; +} + +static const char* DirectionStrings[] = +{ + "initiator", + "recipient" +}; + +const char* +DialogInfoContents::directionToString(const Direction& direction) +{ + return DirectionStrings[direction]; +} + +DialogInfoContents::Direction +DialogInfoContents::directionStringToEnum(const Data& directionString) +{ + for (int i = 0; i < MaxOrUnsetDirection; i++) + { + if (isEqualNoCase(DirectionStrings[i], directionString)) + { + return (Direction)i; + } + } + return MaxOrUnsetDirection; +} + +const DialogInfoContents DialogInfoContents::Empty; + +DialogInfoContents::DialogInfoContents() + : Contents(getStaticType()), mIndent(DefaultEncodeIndent), mVersion(0), mDialogInfoState(Partial) +{ +} + +DialogInfoContents::DialogInfoContents(const Mime& contentType) + : Contents(getStaticType()), mIndent(DefaultEncodeIndent), mVersion(0), mDialogInfoState(Partial) +{ +} + +DialogInfoContents::DialogInfoContents(const HeaderFieldValue& hfv, const Mime& contentsType) + : Contents(hfv, contentsType), mIndent(DefaultEncodeIndent), mVersion(0), mDialogInfoState(Partial) +{ +} + +DialogInfoContents::~DialogInfoContents() +{ +} + +Contents* +DialogInfoContents::clone() const +{ + return new DialogInfoContents(*this); +} + +const Mime& +DialogInfoContents::getStaticType() +{ + static Mime type("application","dialog-info+xml"); + return type; +} + +EncodeStream& +DialogInfoContents::encodeParsed(EncodeStream& str) const +{ + str << "" << Symbols::CRLF; + str << "" << Symbols::CRLF; + + for (DialogList::const_iterator it = mDialogs.begin(); it != mDialogs.end(); it++) + { + it->encodeParsed(str, mIndent); + } + + str << "" << Symbols::CRLF; + + return str; +} + +bool +DialogInfoContents::Dialog::getDialogElement(const Data& childElementName, Data& elementValue, int instance) const +{ + bool found = false; + elementValue = ""; + std::pair ::const_iterator, std::multimap::const_iterator> filteredList; + filteredList = mExtraDialogElements.equal_range(childElementName); + int matchCount = 0; + for (std::multimap::const_iterator matchListIterator = filteredList.first; matchListIterator != filteredList.second; ++matchListIterator) + { + if(instance == matchCount) + { + elementValue = matchListIterator->second; + found = true; + break; + } + matchCount++; + } + + return(found); +} + +EncodeStream& +DialogInfoContents::Dialog::encodeParsed(EncodeStream& str, const Data& indent) const +{ + // Encode dialog attributes + str << indent << "" << Symbols::CRLF; + + // Encode state element + str << indent << indent << "" << dialogStateToString(mState) << "" << Symbols::CRLF; + + // Encode duration element + if (mHasDuration) + { + str << indent << indent << "" << mDuration << "" << Symbols::CRLF; + } + + // Encode replaces element + if (!mReplacesCallId.empty()) + { + str << indent << indent << "" << Symbols::CRLF; + } + + // Encode referred by element + if (!mReferredBy.uri().host().empty()) + { + str << indent << indent; + encodeNameAddrElement(str, "referred-by", mReferredBy); + str << Symbols::CRLF; + } + + // Encode route set + if (!mRouteSet.empty()) + { + str << indent << indent << "" << Symbols::CRLF; + for (NameAddrs::const_iterator itNA = mRouteSet.begin(); itNA != mRouteSet.end(); itNA++) + { + str << indent << indent << indent << "" << Data::from(itNA->uri()).xmlCharDataEncode() << "" << Symbols::CRLF; + } + str << indent << indent << "" << Symbols::CRLF; + } + + // Encode local participant (if set) + mLocalParticipant.encode(str, "local", indent); + + // Encode remote participant (if set) + mRemoteParticipant.encode(str, "remote", indent); + + // User specific/non-standard Dialog elements + for(std::multimap::const_iterator elementIterator = mExtraDialogElements.begin(); + elementIterator != mExtraDialogElements.end(); + elementIterator++) + { + DebugLog(<< "Dialog child element Name: \"" << elementIterator->first << "\" Value: \"" << elementIterator->second << "\""); + str << indent << indent << '<' << elementIterator->first << '>' + << elementIterator->second.xmlCharDataEncode() + << "first << '>' << Symbols::CRLF; + } + + str << indent << "" << Symbols::CRLF; + + return str; +} + +EncodeStream& +DialogInfoContents::encodeNameAddrElement(EncodeStream& str, const char* elementName, const NameAddr& nameAddr) +{ + str << "<" << elementName; + if (!nameAddr.displayName().empty()) + { + str << " display=\"" << nameAddr.displayName().xmlCharDataEncode() << "\""; + } + str << ">" << Data::from(nameAddr.uri()).xmlCharDataEncode() << ""; + return str; +} + +void +DialogInfoContents::Dialog::Participant::setTarget(const NameAddr& targetWithContactParams) +{ + mTarget = targetWithContactParams.uri(); + Data paramsData; + { // scope so that stream flushs + DataStream dstr(paramsData); + targetWithContactParams.encodeParameters(dstr); + } + // If there are parameters present - parse them + if (!paramsData.empty()) + { + ParseBuffer pb(paramsData); + pb.skipChar(); // Skip first ; that is always present + pb.skipWhitespace(); + + do + { + const char* anchor = pb.position(); + pb.skipToOneOf("=;"); + if (*pb.position() == '=') + { + Data name; + Data value; + pb.data(name, anchor); + pb.skipChar(); + pb.skipWhitespace(); + if (*pb.position() == '"') + { + // Quoted Value + pb.skipChar(); + anchor = pb.position(); + pb.skipToChar('"'); + value = pb.data(anchor); + pb.skipChar(); + pb.skipToChar(';'); + } + else + { + // Unquoted value + anchor = pb.position(); + pb.skipToChar(';'); + value = pb.data(anchor); + } + mTargetParams[name] = value; + } + else // ';' or eof + { + // No equals operator - this is a boolean param + mTargetParams[pb.data(anchor)] = "true"; + pb.skipToChar(';'); + } + if (!pb.eof()) + { + // Skip ; + pb.skipChar(); + } + } while (!pb.eof()); + } +} + +bool +DialogInfoContents::Dialog::Participant::getTargetParam(const Data& name, Data& value) const +{ + TargetParams::const_iterator it = mTargetParams.find(name); + if (it != mTargetParams.end()) + { + value = it->second; + return true; + } + return false; +} + +EncodeStream& +DialogInfoContents::Dialog::Participant::encode(EncodeStream& str, const char* baseElementName, const Data& indent) const +{ + // Only encode if any of the optional sub elements are actually set + if (!mIdentity.uri().host().empty() || !mTarget.host().empty() || !mSessionDescription.empty() || mHasCSeq) + { + str << indent << indent << "<" << baseElementName << ">" << Symbols::CRLF; + if (!mIdentity.uri().host().empty()) + { + str << indent << indent << indent; + encodeNameAddrElement(str, "identity", mIdentity); + str << Symbols::CRLF; + } + if (!mTarget.host().empty()) + { + str << indent << indent << indent << "" << Symbols::CRLF; + } + else + { + str << ">" << Symbols::CRLF; + for (TargetParams::const_iterator itParm = mTargetParams.begin(); itParm != mTargetParams.end(); itParm++) + { + str << indent << indent << indent << indent << "first.xmlCharDataEncode() << "\" pval=\"" << itParm->second.xmlCharDataEncode() << "\"/>" << Symbols::CRLF; + } + str << indent << indent << indent << "" << Symbols::CRLF; + } + } + if (!mSessionDescription.empty()) + { + // SDP is multiline, so whitespace is important - don't format for "pretty" output + str << indent << indent << indent << "" << mSessionDescription.xmlCharDataEncode() << "" << Symbols::CRLF; + } + if (mHasCSeq) + { + str << indent << indent << indent << "" << mCSeq << "" << Symbols::CRLF; + } + str << indent << indent << "" << Symbols::CRLF; + } + return str; +} + +void +DialogInfoContents::parse(ParseBuffer& pb) +{ + XMLCursor xml(pb); + const XMLCursor::AttributeMap& attr = xml.getAttributes(); + XMLCursor::AttributeMap::const_iterator itAttr = attr.begin(); + bool baseDialogInfoNamespaceUriFound = false; + for (; itAttr != attr.end(); itAttr++) + { + if (itAttr->first.prefix("xmlns")) + { + Data prefix; + ParseBuffer pb(itAttr->first); + pb.skipToChar(Symbols::COLON[0]); + if (!pb.eof()) + { + pb.skipChar(); + const char* anchor = pb.position(); + pb.skipToEnd(); + pb.data(prefix, anchor); + prefix += Symbols::COLON; + } + if (isEqualNoCase(itAttr->second, BaseDialogInfoNamespaceUri)) + { + baseDialogInfoNamespaceUriFound = true; + } + } + else if (itAttr->first == "version") + { + mVersion = itAttr->second.convertUnsignedLong(); + } + else if (itAttr->first == "state") + { + mDialogInfoState = dialogInfoStateStringToEnum(itAttr->second); + } + else if (itAttr->first == "entity") + { + mEntity = Uri(itAttr->second.xmlCharDataDecode()); // can throw! + } + else + { + DebugLog(<< "Unknown root attribute: " << itAttr->first << "=" << itAttr->second); + } + } + + if (!baseDialogInfoNamespaceUriFound) + { + WarningLog(<< "Base xmlns from RFC4235 was not found, expected: " << BaseDialogInfoNamespaceUri); + // ?slg? - throw or be tolerant? + } + + if (xml.firstChild()) + { + do + { + if (xml.getTag() == "dialog") + { + parseDialog(xml); + } + else + { + DebugLog(<< "Unknown root element: " << xml.getTag()); + } + } while (xml.nextSibling()); + xml.parent(); + } +} + +void +DialogInfoContents::parseDialog(XMLCursor& xml) +{ + const XMLCursor::AttributeMap& attr = xml.getAttributes(); + XMLCursor::AttributeMap::const_iterator itAttr = attr.begin(); + Dialog dialog; + for (; itAttr != attr.end(); itAttr++) + { + if (itAttr->first == "id") + { + dialog.mId = itAttr->second.xmlCharDataDecode(); + } + else if (itAttr->first == "call-id") + { + dialog.mCallId = itAttr->second.xmlCharDataDecode(); + } + else if (itAttr->first == "local-tag") + { + dialog.mLocalTag = itAttr->second.xmlCharDataDecode(); + } + else if (itAttr->first == "remote-tag") + { + dialog.mRemoteTag = itAttr->second.xmlCharDataDecode(); + } + else if (itAttr->first == "direction") + { + dialog.mDirection = directionStringToEnum(itAttr->second); + } + else + { + DebugLog(<< "Unknown dialog attribute: " << itAttr->first << "=" << itAttr->second); + } + } + + if (dialog.mId.empty()) + { + WarningLog(<< "Dialog Id was not found for dialog element"); + // ?slg? - throw or be tolerant? + } + + // Clear out any remnent parsed dialog child elements + dialog.mExtraDialogElements.clear(); + + if (xml.firstChild()) + { + do + { + if (xml.getTag() == "state") + { + const XMLCursor::AttributeMap& attr = xml.getAttributes(); + for (itAttr = attr.begin(); itAttr != attr.end(); itAttr++) + { + if (itAttr->first == "event") + { + dialog.mStateEvent = dialogStateEventStringToEnum(itAttr->second); + } + else if (itAttr->first == "code") + { + dialog.mStateCode = itAttr->second.convertInt(); + } + else + { + DebugLog(<< "Unknown state attribute: " << itAttr->first << "=" << itAttr->second); + } + } + if (xml.firstChild()) + { + dialog.mState = dialogStateStringToEnum(xml.getValue()); + xml.parent(); + } + } + else if (xml.getTag() == "duration") + { + if (xml.firstChild()) + { + dialog.mDuration = xml.getValue().convertUnsignedLong(); + dialog.mHasDuration = true; + xml.parent(); + } + } + else if (xml.getTag() == "replaces") + { + const XMLCursor::AttributeMap& attr = xml.getAttributes(); + for (itAttr = attr.begin(); itAttr != attr.end(); itAttr++) + { + if (itAttr->first == "call-id") + { + dialog.mReplacesCallId = itAttr->second.xmlCharDataDecode(); + } + else if (itAttr->first == "local-tag") + { + dialog.mReplacesLocalTag = itAttr->second.xmlCharDataDecode(); + } + else if (itAttr->first == "remote-tag") + { + dialog.mReplacesRemoteTag = itAttr->second.xmlCharDataDecode(); + } + else + { + DebugLog(<< "Unknown dialog/replaces attribute: " << itAttr->first << "=" << itAttr->second); + } + } + } + else if (xml.getTag() == "referred-by") + { + parseNameAddrElement(xml, dialog.mReferredBy); + } + else if (xml.getTag() == "route-set") + { + if (xml.firstChild()) + { + do + { + if (xml.getTag() == "hop") + { + NameAddr nameAddr; + if (parseUriValue(xml, nameAddr.uri())) + { + dialog.mRouteSet.push_back(nameAddr); + } + } + else + { + DebugLog(<< "Unknown dialog/route-set element: " << xml.getTag()); + } + } while (xml.nextSibling()); + xml.parent(); + } + } + else if (xml.getTag() == "local") + { + dialog.mLocalParticipant.parse(xml); + } + else if (xml.getTag() == "remote") + { + dialog.mRemoteParticipant.parse(xml); + } + else + { + Data elementName = xml.getTag(); + if (xml.firstChild()) + { + DebugLog(<< "Unknown dialog element: " << elementName << " value: " << xml.getValue().xmlCharDataDecode()); + dialog.addDialogElement(elementName, xml.getValue().xmlCharDataDecode()); + xml.parent(); + } + else + { + DebugLog(<< "Unknown dialog element: " << elementName); + } + } + } while (xml.nextSibling()); + xml.parent(); + } + + //DebugLog(<< "Pushing " << mDialogs.size() << "'th dialog " << dialog.mId << " parsed into DialogInfoCOntents::mDialogs"); + mDialogs.push_back(dialog); +} + +bool +DialogInfoContents::parseUriValue(XMLCursor& xml, Uri& uri) +{ + bool parseGood = false; + if (xml.firstChild()) + { + try + { + uri = Uri(xml.getValue().xmlCharDataDecode()); + parseGood = true; + } + catch (BaseException& ex) // ?slg? - catch here or not - let exception bubble up? or rethrow? + { + DebugLog(<< "Could not parse NameAddr value: " << xml.getValue().xmlCharDataDecode() << ": " << ex); + } + xml.parent(); + } + return parseGood; +} + +bool +DialogInfoContents::parseNameAddrElement(XMLCursor& xml, NameAddr& nameAddr) +{ + const XMLCursor::AttributeMap& attr = xml.getAttributes(); + XMLCursor::AttributeMap::const_iterator itAttr = attr.begin(); + for (; itAttr != attr.end(); itAttr++) + { + if (itAttr->first == "display") + { + nameAddr.displayName() = itAttr->second.xmlCharDataDecode(); + } + else + { + DebugLog(<< "Unknown NameAddr attribute: " << itAttr->first << "=" << itAttr->second); + } + } + return parseUriValue(xml, nameAddr.uri()); +} + +void +DialogInfoContents::Dialog::Participant::parse(XMLCursor& xml) +{ + if (xml.firstChild()) + { + do + { + if (xml.getTag() == "identity") + { + parseNameAddrElement(xml, mIdentity); + } + else if (xml.getTag() == "target") + { + try + { + const XMLCursor::AttributeMap& attr = xml.getAttributes(); + XMLCursor::AttributeMap::const_iterator itAttr = attr.begin(); + for (; itAttr != attr.end(); itAttr++) + { + if (itAttr->first == "uri") + { + mTarget = Uri(itAttr->second.xmlCharDataDecode()); + } + else + { + DebugLog(<< "Unknown dialog/participant/target attribute: " << itAttr->first << "=" << itAttr->second); + } + } + + if (xml.firstChild()) + { + do + { + if (xml.getTag() == "param") + { + parseParam(xml); + } + else + { + DebugLog(<< "Unknown dialog/particpant/target element: " << xml.getTag()); + } + } while (xml.nextSibling()); + xml.parent(); + } + } + catch (BaseException& ex) // ?slg? - catch here or not - let exception bubble up? or rethrow? + { + DebugLog(<< "Could not parse dialog/participatn/target uri value: " << xml.getValue().xmlCharDataDecode() << ": " << ex); + } + } + else if (xml.getTag() == "session-description") + { + const XMLCursor::AttributeMap& attr = xml.getAttributes(); + XMLCursor::AttributeMap::const_iterator itAttr = attr.begin(); + for (; itAttr != attr.end(); itAttr++) + { + if (itAttr->first == "type") + { + mSessionDescriptionType = itAttr->second.xmlCharDataDecode(); + } + else + { + DebugLog(<< "Unknown dialog/participant/session-description attribute: " << itAttr->first << "=" << itAttr->second); + } + } + if (xml.firstChild()) + { + mSessionDescription = xml.getValue().xmlCharDataDecode(); + xml.parent(); + } + } + else if (xml.getTag() == "cseq") + { + if (xml.firstChild()) + { + mCSeq = xml.getValue().convertUnsignedLong(); + mHasCSeq = true; + xml.parent(); + } + } + else + { + DebugLog(<< "Unknown dialog participant element: " << xml.getTag()); + } + } while (xml.nextSibling()); + xml.parent(); + } +} + +void +DialogInfoContents::Dialog::Participant::parseParam(XMLCursor& xml) +{ + const XMLCursor::AttributeMap& attr = xml.getAttributes(); + XMLCursor::AttributeMap::const_iterator itAttr = attr.begin(); + Data name; + Data value; + for (; itAttr != attr.end(); itAttr++) + { + if (itAttr->first == "pname") + { + name = itAttr->second.xmlCharDataDecode(); + } + else if (itAttr->first == "pval") + { + value = itAttr->second.xmlCharDataDecode(); + } + else + { + DebugLog(<< "Unknown dialog/participant/target/param attribute: " << itAttr->first << "=" << itAttr->second); + } + } + if (!name.empty()) + { + mTargetParams[name] = value; + } +} + +void +DialogInfoContents::addDialog(const Dialog& dialog) +{ + checkParsed(); + // Ensure id doesn't already exist + removeDialog(dialog.mId); + mDialogs.push_back(dialog); +} + +bool +DialogInfoContents::removeDialog(const Data& id) +{ + checkParsed(); + for (DialogList::iterator it = mDialogs.begin(); it != mDialogs.end(); it++) + { + if (it->mId == id) + { + mDialogs.erase(it); + return true; + } + } + return false; +} + + +/* ==================================================================== +* +* Copyright (c) 2016 SIP Spectrum, Inc. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* +* 3. Neither the name of the author(s) nor the names of any contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +* +* ==================================================================== +* +*/ +/* +* vi: set shiftwidth=3 expandtab: +*/ diff --git a/src/libs/resiprocate/resip/stack/DialogInfoContents.hxx b/src/libs/resiprocate/resip/stack/DialogInfoContents.hxx new file mode 100644 index 00000000..274e481e --- /dev/null +++ b/src/libs/resiprocate/resip/stack/DialogInfoContents.hxx @@ -0,0 +1,309 @@ +#if !defined(RESIP_DialogInfoContents_HXX) +#define RESIP_DialogInfoContents_HXX + +#include +#include + +#include "resip/stack/Contents.hxx" +#include "rutil/Data.hxx" +#include "rutil/HashMap.hxx" +#include "resip/stack/Uri.hxx" +#include "rutil/HeapInstanceCounter.hxx" + +namespace resip +{ + +class XMLCursor; + +/** + SIP body type for holding DialogInfo contents (MIME content-type application/dialog-info+xml). +*/ +class DialogInfoContents : public Contents +{ +public: + + enum DialogInfoState + { + Full, + Partial, + MaxDialogInfoState + }; + // Warning if you modify the above list, make sure you modify DialogInfoStateStrings in the .cxx file to match + + enum DialogState + { + Trying = 0, + Proceeding, + Early, + Confirmed, + Terminated, + MaxDialogState + }; + // Warning if you modify the above list, make sure you modify DialogStateStrings in the .cxx file to match + + enum DialogStateEvent + { + Cancelled = 0, + Rejected, + Replaced, + LocalBye, + RemoteBye, + Error, + Timeout, + MaxOrUnsetDialogStateEvent + }; + // Warning if you modify the above list, make sure you modify DialogStateEventStrings in the .cxx file to match + + enum Direction + { + Initiator = 0, + Recipient, + MaxOrUnsetDirection + }; + // Warning if you modify the above list, make sure you modify DialogStateEventStrings in the .cxx file to match + + static const DialogInfoContents Empty; + + RESIP_HeapCount(DialogInfoContents); + DialogInfoContents(const Mime& contentType); + DialogInfoContents(); + DialogInfoContents(const HeaderFieldValue& hfv, const Mime& contentType); + virtual ~DialogInfoContents(); + + /** @brief duplicate an DialogInfoContents object + @return pointer to a new DialogInfoContents object + **/ + virtual Contents* clone() const; + static const Mime& getStaticType(); + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + virtual void parse(ParseBuffer& pb); + + // Default is 3 spaces " " + void setEncodeIndent(const Data& indent) { mIndent = indent; } + + // Accesors for data + void setEntity(const Uri& entity) { checkParsed(); mEntity = entity; } + const Uri& getEntity() const { checkParsed(); return mEntity; } + + void setVersion(UInt32 version) { checkParsed(); mVersion = version; } + UInt32 getVersion() const { checkParsed(); return mVersion; } + + void setDialogInfoState(DialogInfoState dialogInfoState) { checkParsed(); mDialogInfoState = dialogInfoState; } + DialogInfoState getDialogInfoState() const { checkParsed(); return mDialogInfoState; } + + // A DialogInfoContents can have multiple Dialog sections in it + class Dialog + { + public: + Dialog() : mDirection(MaxOrUnsetDirection), mState(Trying), mStateEvent(MaxOrUnsetDialogStateEvent), mStateCode(0), mDuration(0), + mHasDuration(false) {} + + // Accesors for data + void setId(const Data& id) { mId = id; } + const Data& getId() const { return mId; } + + void setCallId(const Data& callId) { mCallId = callId; } + const Data& getCallId() const { return mCallId; } + + void setLocalTag(const Data& localTag) { mLocalTag = localTag; } + const Data& getLocalTag() const { return mLocalTag; } + + void setRemoteTag(const Data& remoteTag) { mRemoteTag = remoteTag; } + const Data& getRemoteTag() const { return mRemoteTag; } + + void setDirection(const Direction& direction) { mDirection = direction; } + const Direction& getDirection() const { return mDirection; } + + void setState(const DialogState& state) { mState = state; } + const DialogState& getState() const { return mState; } + + void setStateEvent(const DialogStateEvent& stateEvent) { mStateEvent = stateEvent; } + const DialogStateEvent& getStateEvent() const { return mStateEvent; } + + void setStateCode(const int& stateCode) { mStateCode = stateCode; } + const int& getStateCode() const { return mStateCode; } + + void setDuration(const UInt32& duration) { mDuration = duration; mHasDuration = true; } + void clearDuration() { mDuration = 0; mHasDuration = false; } + bool hasDuration() const { return mHasDuration; } + const UInt32& getDuration() const { return mDuration; } + + void setReplacesInfo(const Data& callId, const Data& localTag, const Data& remoteTag) + { mReplacesCallId = callId; mReplacesLocalTag = localTag; mReplacesRemoteTag = remoteTag; } + const Data& getReplacesCallId() const { return mReplacesCallId; } + const Data& getReplacesLocalTag() const { return mReplacesLocalTag; } + const Data& getReplacesRemoteTag() const { return mReplacesRemoteTag; } + + void setReferredBy(const NameAddr& referredBy) { mReferredBy = referredBy; } + const NameAddr& getReferredBy() const { return mReferredBy; } + + void addRouteToRouteSet(const NameAddr& route) { mRouteSet.push_back(route); } + void setRouteSet(const NameAddrs& routes) { mRouteSet = routes; } + void clearRouteSet() { mRouteSet.clear(); } + const NameAddrs& getRouteSet() const { return mRouteSet; } + + class Participant + { + public: + Participant() : mCSeq(0), mHasCSeq(false) {} + + void setIdentity(const NameAddr& identity) { mIdentity = identity; } + const NameAddr& getIdentity() const { return mIdentity; } + + void setTarget(const Uri& target) { mTarget = target; } + void setTarget(const NameAddr& targetWithContactParams); + const Uri& getTarget() const { return mTarget; } + + typedef std::map TargetParams; + void addTargetParam(const Data& name, const Data& value) { mTargetParams[name] = value; } + void clearTargetParams() { mTargetParams.clear(); } + const TargetParams& getTargetParams() const { return mTargetParams; } + bool getTargetParam(const Data& name, Data& value) const; + + void setSessionDescription(const Data& sessionDescription, const Data& sessionDescriptionType) + { mSessionDescription = sessionDescription; mSessionDescriptionType = sessionDescriptionType; } + const Data& getSessionDescription() const { return mSessionDescription; } + const Data& getSessionDescriptionType() const { return mSessionDescriptionType; } + + void setCSeq(const UInt32& cseq) { mCSeq = cseq; mHasCSeq = true; } + void clearCSeq() { mCSeq = 0; mHasCSeq = false; } + bool hasCSeq() const { return mHasCSeq; } + const UInt32& getCSeq() const { return mCSeq; } + + private: + NameAddr mIdentity; + Uri mTarget; + TargetParams mTargetParams; + Data mSessionDescription; + Data mSessionDescriptionType; + UInt32 mCSeq; + bool mHasCSeq; + + friend class Dialog; + friend class DialogInfoContents; + EncodeStream& encode(EncodeStream& str, const char* baseElementName, const Data& indent) const; + void parse(XMLCursor& xml); + void parseParam(XMLCursor& xml); + }; + + Participant& localParticipant() { return mLocalParticipant; } + const Participant& localParticipant() const { return mLocalParticipant; } + + Participant& remoteParticipant() { return mRemoteParticipant; } + const Participant& remoteParticipant() const { return mRemoteParticipant; } + + // add element name and value to the extra Dialog child elements map + // These are local/non-standard child elements to the Dialog element + void addDialogElement(const Data& childElementName, const Data& elementValue) { mExtraDialogElements.insert( std::pair(childElementName, elementValue));} + + // get the instance'th occurance of the named Dialog child element. + // The first instance is index 0. + bool getDialogElement(const Data& childElementName, Data& elementValue, int instance=0) const; + + private: + Data mId; + Data mCallId; + Data mLocalTag; + Data mRemoteTag; + Direction mDirection; + + DialogState mState; + DialogStateEvent mStateEvent; + int mStateCode; + + UInt32 mDuration; + bool mHasDuration; + + Data mReplacesCallId; + Data mReplacesLocalTag; + Data mReplacesRemoteTag; + + NameAddr mReferredBy; + + NameAddrs mRouteSet; + + Participant mLocalParticipant; + Participant mRemoteParticipant; + + std::multimap mExtraDialogElements; + + friend class DialogInfoContents; + EncodeStream& encodeParsed(EncodeStream& str, const Data& indent) const; + }; + + typedef std::list DialogList; + const DialogList& getDialogs() const { checkParsed(); return mDialogs; } + void addDialog(const Dialog& dialog); + bool removeDialog(const Data& id); + void clearDialogs() { checkParsed(); mDialogs.clear(); } + + static bool init(); + static const char* dialogInfoStateToString(const DialogInfoState& dialogInfoState); + static DialogInfoState dialogInfoStateStringToEnum(const Data& dialogInfoStateString); + static const char* dialogStateToString(const DialogState& dialogState); + static DialogState dialogStateStringToEnum(const Data& dialogStateString); + static const char* dialogStateEventToString(const DialogStateEvent& dialogStateEvent); + static DialogStateEvent dialogStateEventStringToEnum(const Data& dialogStateEventString); + static const char* directionToString(const Direction& direction); + static Direction directionStringToEnum(const Data& directionString); + +private: + + static EncodeStream& encodeNameAddrElement(EncodeStream& str, const char* elementName, const NameAddr& nameAddr); + void parseDialog(XMLCursor& xml); + static bool parseUriValue(XMLCursor& xml, Uri& uri); + static bool parseNameAddrElement(XMLCursor& xml, NameAddr& nameAddr); + + // Base DialogInfoContents data members + Data mIndent; + Uri mEntity; + UInt32 mVersion; + DialogInfoState mDialogInfoState; + + DialogList mDialogs; +}; + +static bool invokeDialogInfoContentsInit = DialogInfoContents::init(); + +} + +#endif + +/* ==================================================================== +* +* Copyright (c) 2016 SIP Spectrum, Inc. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* +* 3. Neither the name of the author(s) nor the names of any contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +* +* ==================================================================== +* +*/ +/* +* vi: set shiftwidth=3 expandtab: +*/ diff --git a/src/libs/resiprocate/resip/stack/Dispatcher.cxx b/src/libs/resiprocate/resip/stack/Dispatcher.cxx new file mode 100644 index 00000000..254fb395 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Dispatcher.cxx @@ -0,0 +1,187 @@ +#include "resip/stack/Dispatcher.hxx" +#include "resip/stack/Message.hxx" +#include "resip/stack/SipStack.hxx" +#include "rutil/WinLeakCheck.hxx" + + +namespace resip +{ + +Dispatcher::Dispatcher(std::auto_ptr prototype, + resip::SipStack* stack, + int workers, + bool startImmediately): + mStack(stack), + mFifo(0,0), + mAcceptingWork(false), + mShutdown(false), + mStarted(false), + mWorkerPrototype(prototype.release()) +{ + for(int i=0; iclone(),mFifo,mStack)); + } + + if(startImmediately) + { + startAll(); + } +} + +Dispatcher::~Dispatcher() +{ + shutdownAll(); + + std::vector::iterator i; + for(i=mWorkerThreads.begin(); i!=mWorkerThreads.end(); ++i) + { + delete *i; + } + + mWorkerThreads.clear(); + + while(!mFifo.empty()) + { + delete mFifo.getNext(); + } + + delete mWorkerPrototype; + +} + +bool +Dispatcher::post(std::auto_ptr& work) +{ + resip::ReadLock r(mMutex); + if(mAcceptingWork) + { + mFifo.add(work.release(), + resip::TimeLimitFifo::InternalElement); + return true; + } + + return false; + + //If we aren't accepting work, the auto ptr is not released. (We don't + // take ownership, and the caller gets to handle the contents of the + // auto_ptr) +} + +size_t +Dispatcher::fifoCountDepth() const +{ + return mFifo.getCountDepth(); +} + +time_t +Dispatcher::fifoTimeDepth() const +{ + return mFifo.getTimeDepth(); +} + +int +Dispatcher::workPoolSize() const +{ + return (int)mWorkerThreads.size(); +} + +void +Dispatcher::stop() +{ + resip::WriteLock w(mMutex); + mAcceptingWork=false; +} + +void +Dispatcher::resume() +{ + resip::WriteLock w(mMutex); + mAcceptingWork = !mShutdown; +} + +void +Dispatcher::shutdownAll() +{ + resip::WriteLock w(mMutex); + if(!mShutdown) + { + mAcceptingWork=false; + mShutdown=true; + + std::vector::iterator i; + for(i=mWorkerThreads.begin(); i!=mWorkerThreads.end(); ++i) + { + (*i)->shutdown(); + (*i)->join(); + } + } +} + +void +Dispatcher::startAll() +{ + resip::WriteLock w(mMutex); + if(!mShutdown && !mStarted) + { + std::vector::iterator i; + for(i=mWorkerThreads.begin(); i!=mWorkerThreads.end(); ++i) + { + (*i)->run(); + } + mStarted=true; + mAcceptingWork=true; + } +} + +} //namespace resip + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * . + * + */ diff --git a/src/libs/resiprocate/resip/stack/Dispatcher.hxx b/src/libs/resiprocate/resip/stack/Dispatcher.hxx new file mode 100644 index 00000000..e57cc769 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Dispatcher.hxx @@ -0,0 +1,183 @@ +#ifndef DISPATCHER_HXX +#define DISPATCHER_HXX 1 + +#include "resip/stack/WorkerThread.hxx" +#include "resip/stack/Worker.hxx" +#include "resip/stack/ApplicationMessage.hxx" +#include "rutil/TimeLimitFifo.hxx" +#include "rutil/RWMutex.hxx" +#include "rutil/Lock.hxx" +#include + +namespace resip +{ + class SipStack; + class ApplicationMessage; + +/** + @class Dispatcher + + @brief A generic thread-bank class. + + This is intended to be a generic thread-bank class that operates under + the paradigm of accepting messages, modifying those messages, and posting + the messages back to the originator through the SipStack. (Since this uses + ApplicationMessages, the message will automatically get back to the correct + TransactionUser; what happens from there is the coder's business.) + + This class gets + generality by using prototyping of a very simple class, Worker. All the + user must do is subclass Worker to do the work needed, and pass an instance + of this class when constructing the Dispatcher. Dispatcher will clone this + Worker as many times as needed to fill the thread bank. + + @note The functions in this class are intended to be thread-safe. +*/ + +class Dispatcher +{ + public: + + /** + @param prototype The prototypical instance of Worker. + + @param stack The stack to post messages to. + + @param workers The number of threads in this bank. + + @param startImmediately Whether to start this thread bank on + construction. + */ + Dispatcher(std::auto_ptr prototype, + resip::SipStack* stack, + int workers=2, + bool startImmediately=true); + + virtual ~Dispatcher(); + + /** + Posts a message to this thread bank. + + @param work The message that conveys the work that needs to be done. + It is understood that any information that needs to be conveyed + back to the originator will be placed in the message by the Workers + in the thread bank. + + @returns true iff this message was successfully posted. (This may not + be the case if this Dispatcher is in the process of shutting down) + */ + virtual bool post(std::auto_ptr& work); + + /** + @returns The number of messages in this Dispatcher's queue + */ + size_t fifoCountDepth() const; + + /** + @returns The time between which the front of the queue was posted and + the back of the queue was posted. + */ + time_t fifoTimeDepth() const; + + /** + @returns The number of workers in this thread bank. + */ + int workPoolSize() const; + + /** + This Dispatcher will stop accepting new + work, but processing will continue normally on the messages already + in the queue. + */ + void stop(); + + /** + Resumes accepting work. + */ + void resume(); + + /** + Shuts down the thread-bank. + */ + void shutdownAll(); + + + /** + Starts the thread bank. + */ + void startAll(); + + resip::SipStack* mStack; + + + protected: + + resip::TimeLimitFifo mFifo; + bool mAcceptingWork; + bool mShutdown; + bool mStarted; + Worker* mWorkerPrototype; + + resip::RWMutex mMutex; + + std::vector mWorkerThreads; + + private: + //No copying! + Dispatcher(const Dispatcher& toCopy); + Dispatcher& operator=(const Dispatcher& toCopy); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * . + * + */ diff --git a/src/libs/resiprocate/resip/stack/DnsInterface.cxx b/src/libs/resiprocate/resip/stack/DnsInterface.cxx index ea62b676..d7372cda 100644 --- a/src/libs/resiprocate/resip/stack/DnsInterface.cxx +++ b/src/libs/resiprocate/resip/stack/DnsInterface.cxx @@ -32,74 +32,137 @@ using namespace resip; #define RESIPROCATE_SUBSYSTEM resip::Subsystem::DNS -DnsInterface::DnsInterface(DnsStub& dnsStub) : +DnsInterface::DnsInterface(DnsStub& dnsStub, bool useDnsVip) : + mUdpOnlyOnNumeric(false), mDnsStub(dnsStub) { - -#ifdef USE_DNS_VIP - mDnsStub.setResultTransform(&mVip); -#endif + if (useDnsVip) + { + mDnsStub.setResultTransform(&mVip); + } } DnsInterface::~DnsInterface() { } +void +DnsInterface::addTransportType(TransportType type, IpVersion version) +{ + Lock lock(mSupportedMutex); + mSupportedTransports[std::make_pair(type, version)]++; + const Data* pNaptrType = getSupportedNaptrType(type); + if(pNaptrType) + { + mSupportedNaptrs[*pNaptrType]++; + } + //logSupportedTransports(); +} + +void +DnsInterface::removeTransportType(TransportType type, IpVersion version) +{ + Lock lock(mSupportedMutex); + TransportMap::iterator itTrans = mSupportedTransports.find(std::make_pair(type, version)); + if(itTrans != mSupportedTransports.end()) + { + // Remove from map if ref count hits zero + if(--itTrans->second == 0) + { + mSupportedTransports.erase(itTrans); + } + } + + const Data* pNaptrType = getSupportedNaptrType(type); + if(pNaptrType) + { + SupportedNaptrMap::iterator itNT = mSupportedNaptrs.find(*pNaptrType); + if(itNT != mSupportedNaptrs.end()) + { + // Remove from map if ref count hits zero + if(--itNT->second == 0) + { + mSupportedNaptrs.erase(itNT); + } + } + } + //logSupportedTransports(); +} + static Data UdpNAPTRType("SIP+D2U"); static Data TcpNAPTRType("SIP+D2T"); static Data TlsNAPTRType("SIPS+D2T"); static Data DtlsNAPTRType("SIPS+D2U"); -void -DnsInterface::addTransportType(TransportType type, IpVersion version) +static Data WsNAPTRType("SIP+D2W"); +static Data WssNAPTRType("SIPS+D2W"); +const Data* +DnsInterface::getSupportedNaptrType(TransportType type) { - mSupportedTransports.push_back(std::make_pair(type, version)); + Data* pNaptrType = 0; switch (type) { - case UDP: - mSupportedNaptrs.insert(UdpNAPTRType); - break; - case TCP: - mSupportedNaptrs.insert(TcpNAPTRType); - break; - case TLS: - mSupportedNaptrs.insert(TlsNAPTRType); - break; - case DTLS: - mSupportedNaptrs.insert(DtlsNAPTRType); - break; - default: - assert(0); - break; + case UDP: + pNaptrType = &UdpNAPTRType; + break; + case TCP: + pNaptrType = &TcpNAPTRType; + break; + case TLS: + pNaptrType = &TlsNAPTRType; + break; + case DTLS: + pNaptrType = &DtlsNAPTRType; + break; + case WS: + pNaptrType = &WsNAPTRType; + break; + case WSS: + pNaptrType = &WssNAPTRType; + break; + default: + resip_assert(0); + break; + } + return pNaptrType; +} + +void +DnsInterface::logSupportedTransports() +{ + TransportMap::iterator itTrans = mSupportedTransports.begin(); + for(; itTrans != mSupportedTransports.end(); itTrans++) + { + InfoLog(<< "logSupportedTransports: mSupportedTransports[" << toData(itTrans->first.first) << "," << (itTrans->first.second == V4 ? "V4" : "V6") << "] = " << itTrans->second); + } + + SupportedNaptrMap::iterator itNT = mSupportedNaptrs.begin(); + for(; itNT != mSupportedNaptrs.end(); itNT++) + { + InfoLog(<< "logSupportedTransports: mSupportedNaptrs[" << itNT->first << "] = " << itNT->second); } } bool DnsInterface::isSupported(const Data& service) { + Lock lock(mSupportedMutex); return mSupportedNaptrs.count(service) != 0; } - bool DnsInterface::isSupported(TransportType t, IpVersion version) { - if (t != UNKNOWN_TRANSPORT) - return std::find(mSupportedTransports.begin(), mSupportedTransports.end(), std::make_pair(t, version)) != mSupportedTransports.end(); - else - { - for (TransportMap::size_type i=0; ifirst == t) + if (i->first.first == t) { return true; } @@ -109,10 +172,10 @@ DnsInterface::isSupportedProtocol(TransportType t) int DnsInterface::supportedProtocols() { + Lock lock(mSupportedMutex); return (int)mSupportedTransports.size(); } - DnsResult* DnsInterface::createDnsResult(DnsHandler* handler) { @@ -123,38 +186,14 @@ DnsInterface::createDnsResult(DnsHandler* handler) void DnsInterface::lookup(DnsResult* res, const Uri& uri) { - res->lookup(uri, mDnsStub.getEnumSuffixes(), - mDnsStub.getEnumDomains()); + res->lookup(uri); } -// DnsResult* -// DnsInterface::lookup(const Via& via, DnsHandler* handler) -// { -// assert(0); - -// //DnsResult* result = new DnsResult(*this); -// return NULL; -// } - //?dcm? -- why is this here? DnsHandler::~DnsHandler() { } -/* moved to DnsStub. -void -DnsInterface::lookupRecords(const Data& target, unsigned short type, DnsRawSink* sink) -{ - mDnsProvider->lookup(target.c_str(), type, this, sink); -} - -void -DnsInterface::handleDnsRaw(ExternalDnsRawResult res) -{ - reinterpret_cast(res.userData)->onDnsRaw(res.errorCode(), res.abuf, res.alen); - mDnsProvider->freeResult(res); -} -*/ // Copyright (c) 2003, Jason Fischl /* ==================================================================== diff --git a/src/libs/resiprocate/resip/stack/DnsInterface.hxx b/src/libs/resiprocate/resip/stack/DnsInterface.hxx index 5713ae23..68e61ecb 100644 --- a/src/libs/resiprocate/resip/stack/DnsInterface.hxx +++ b/src/libs/resiprocate/resip/stack/DnsInterface.hxx @@ -19,7 +19,6 @@ class DnsResultSink; class DnsResult; class Uri; class Via; -//class ExternalDns; class DnsRawSink; class DnsInterface @@ -37,7 +36,7 @@ class DnsInterface // DnsResult be in the same thread that is processing the async results // since there is no locking on the DnsResult // Will throw DnsInterface::Exception if the Dns provider fails to initialize - DnsInterface(DnsStub& dnsStub); + DnsInterface(DnsStub& dnsStub, bool useDnsVip=false); virtual ~DnsInterface(); @@ -45,7 +44,8 @@ class DnsInterface // set the supported set of types that a UAC wishes to use void addTransportType(TransportType type, IpVersion version); - + void removeTransportType(TransportType type, IpVersion version); + // return if the client supports the specified service (e.g. SIP+D2T) bool isSupported(const Data& service); bool isSupported(TransportType t, IpVersion version); @@ -72,28 +72,38 @@ class DnsInterface DnsResult* createDnsResult(DnsHandler* handler=0); void lookup(DnsResult* res, const Uri& uri); - //DnsResult* lookup(const Uri& url, DnsHandler* handler=0); - //DnsResult* lookup(const Via& via, DnsHandler* handler=0); - - //void lookupRecords(const Data& target, unsigned short type, DnsRawSink* sink); - //virtual void handleDnsRaw(ExternalDnsRawResult); TupleMarkManager& getMarkManager(){return mMarkManager;} + bool setUdpOnlyOnNumeric(bool value) + { + mUdpOnlyOnNumeric = value; + return mUdpOnlyOnNumeric; + } + + bool getUdpOnlyOnNumeric() const + { + return mUdpOnlyOnNumeric; + } + protected: + const Data* getSupportedNaptrType(TransportType type); + void logSupportedTransports(); + // When complete or partial results are ready, call DnsHandler::process() // For synchronous DnsInterface, set to 0 friend class DnsResult; - // DnsHandler* mHandler; // .kw. not used anymore? - std::set mSupportedNaptrs; - typedef std::vector > TransportMap; + Mutex mSupportedMutex; // Protects mSupportedNaptrs and mSupportTransports + typedef std::map SupportedNaptrMap; // second is for RefCount + SupportedNaptrMap mSupportedNaptrs; + typedef std::map, unsigned int> TransportMap; // second is for RefCount TransportMap mSupportedTransports; - //std::set mSupportedTransportTypes; + // Whether transport failover should be disabled on URIs with only a numeric + // IP address (only UDP will ever be attempted). + bool mUdpOnlyOnNumeric; - //ExternalDns* mDnsProvider; - - DnsStub& mDnsStub; - RRVip mVip; - TupleMarkManager mMarkManager; + DnsStub& mDnsStub; + RRVip mVip; // Ensure all access is from DnsThread/DnsStub fifo for thread safety + TupleMarkManager mMarkManager; // Ensure all access is from DnsThread/DnsStub fifo for thread safety }; } @@ -150,4 +160,5 @@ class DnsInterface * */ +// vim: softtabstop=3:shiftwidth=3:expandtab diff --git a/src/libs/resiprocate/resip/stack/DnsResult.cxx b/src/libs/resiprocate/resip/stack/DnsResult.cxx index 594a08e2..d9c431c5 100644 --- a/src/libs/resiprocate/resip/stack/DnsResult.cxx +++ b/src/libs/resiprocate/resip/stack/DnsResult.cxx @@ -37,7 +37,6 @@ #include "rutil/dns/DnsNaptrRecord.hxx" #include "resip/stack/DnsResult.hxx" #include "resip/stack/DnsInterface.hxx" -#include "resip/stack/TupleMarkManager.hxx" #include "resip/stack/Tuple.hxx" #include "resip/stack/Uri.hxx" #include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below @@ -60,21 +59,21 @@ EnumResult::~EnumResult() void EnumResult::onDnsResult(const DNSResult& result) { - assert(0); + resip_assert(0); delete this; } void EnumResult::onDnsResult(const DNSResult& result) { - assert(0); + resip_assert(0); delete this; } void EnumResult::onDnsResult(const DNSResult&) { - assert(0); + resip_assert(0); delete this; } @@ -88,13 +87,13 @@ EnumResult::onDnsResult(const DNSResult& result) void EnumResult::onDnsResult(const DNSResult&) { - assert(0); + resip_assert(0); delete this; } DnsResult::DnsResult(DnsInterface& interfaceObj, DnsStub& dns, RRVip& vip, DnsHandler* handler) : mInterface(interfaceObj), - mDns(dns), + mDnsStub(dns), mVip(vip), mHandler(handler), mSRVCount(0), @@ -112,7 +111,7 @@ DnsResult::DnsResult(DnsInterface& interfaceObj, DnsStub& dns, RRVip& vip, DnsHa DnsResult::~DnsResult() { //DebugLog (<< "DnsResult::~DnsResult() " << *this); - assert(mType != Pending); + resip_assert(mType != Pending); } void @@ -121,7 +120,7 @@ DnsResult::transition(Type t) if((t == Pending || t== Available) && (mType== Finished || mType == Destroyed) ) { - assert(0); + resip_assert(0); } mType = t; @@ -130,7 +129,7 @@ DnsResult::transition(Type t) void DnsResult::destroy() { - assert(this); + resip_assert(this); //DebugLog (<< "DnsResult::destroy() " << *this); if (mType == Pending) @@ -149,17 +148,16 @@ DnsResult::blacklistLast(UInt64 expiry) { if(mHaveReturnedResults) { - assert(!mLastReturnedPath.empty()); - assert(mLastReturnedPath.size()<=3); - Item top = mLastReturnedPath.back(); - - mInterface.getMarkManager().mark(mLastResult,expiry,TupleMarkManager::BLACK); - - DebugLog( << "Remove vip " << top.domain << "(" << top.rrType << ")"); - mVip.removeVip(top.domain, top.rrType); + resip_assert(!mLastReturnedPath.empty()); + resip_assert(mLastReturnedPath.size()<=3); + GreyOrBlacklistCommand* command = new GreyOrBlacklistCommand(mVip, mInterface.getMarkManager(), + mLastReturnedPath.back(), + mLastResult, + expiry, + TupleMarkManager::BLACK); + mDnsStub.queueCommand(command); return true; } - return false; } @@ -168,24 +166,32 @@ DnsResult::greylistLast(UInt64 expiry) { if(mHaveReturnedResults) { - assert(!mLastReturnedPath.empty()); - assert(mLastReturnedPath.size()<=3); - Item top = mLastReturnedPath.back(); - - mInterface.getMarkManager().mark(mLastResult,expiry,TupleMarkManager::GREY); - - DebugLog( << "Remove vip " << top.domain << "(" << top.rrType << ")"); - mVip.removeVip(top.domain, top.rrType); + resip_assert(!mLastReturnedPath.empty()); + resip_assert(mLastReturnedPath.size()<=3); + GreyOrBlacklistCommand* command = new GreyOrBlacklistCommand(mVip, mInterface.getMarkManager(), + mLastReturnedPath.back(), + mLastResult, + expiry, + TupleMarkManager::GREY); + mDnsStub.queueCommand(command); return true; } - return false; } +void +DnsResult::GreyOrBlacklistCommand::execute() +{ + mMarkManager.mark(mResult, mExpiry, mMarkType); + + DebugLog( << "Remove vip " << mPathTop.domain << "(" << mPathTop.rrType << ")"); + mVip.removeVip(mPathTop.domain, mPathTop.rrType); +} + DnsResult::Type DnsResult::available() { - assert(mType != Destroyed); + resip_assert(mType != Destroyed); if (mType == Available) { if (!mResults.empty()) @@ -207,8 +213,8 @@ DnsResult::available() Tuple DnsResult::next() { - assert(available()==Available); - assert(mCurrentPath.size()<=3); + resip_assert(available()==Available); + resip_assert(mCurrentPath.size()<=3); mLastResult=mResults.front(); mResults.pop_front(); @@ -233,9 +239,16 @@ DnsResult::next() void DnsResult::whitelistLast() +{ + WhitelistCommand* command = new WhitelistCommand(mVip, mLastReturnedPath); + mDnsStub.queueCommand(command); +} + +void +DnsResult::WhitelistCommand::execute() { std::vector::iterator i; - for (i=mLastReturnedPath.begin(); i!=mLastReturnedPath.end(); ++i) + for (i=mPath.begin(); i!=mPath.end(); ++i) { DebugLog( << "Whitelisting " << i->domain << "(" << i->rrType << "): " << i->value); mVip.vip(i->domain, i->rrType, i->value); @@ -243,27 +256,38 @@ DnsResult::whitelistLast() } void -DnsResult::lookup(const Uri& uri, const std::vector &enumSuffixes, - const std::map &enumDomains) +DnsResult::lookup(const Uri& uri) { DebugLog (<< "DnsResult::lookup " << uri); - //int type = this->mType; - if (!enumSuffixes.empty() && uri.isEnumSearchable() && - enumDomains.find(uri.host()) != enumDomains.end()) + + // Dispatch lookup request to DnsThread + LookupCommand *command = new LookupCommand(*this, uri); + mDnsStub.queueCommand(command); +} + +void +DnsResult::lookupInternalWithEnum(const Uri& uri) +{ + if ( mType == Destroyed ) + { + destroy(); + return; + } + if (!mDnsStub.getEnumSuffixes().empty() && + uri.isEnumSearchable() && + mDnsStub.getEnumDomains().find(uri.host()) != mDnsStub.getEnumDomains().end()) { mInputUri = uri; int order = 0; - std::vector enums = uri.getEnumLookups(enumSuffixes); - assert(enums.size() >= 1); + std::vector enums = uri.getEnumLookups(mDnsStub.getEnumSuffixes()); + resip_assert(enums.size() >= 1); if (!enums.empty()) { mDoingEnum = enums.size(); - for(std::vector::iterator it = enums.begin(); - it != enums.end(); it++) + for(std::vector::iterator it = enums.begin(); it != enums.end(); it++) { InfoLog (<< "Doing ENUM lookup on " << *it); - mDns.lookup(*it, Protocol::Enum, - new EnumResult(*this, order++)); + mDnsStub.lookup(*it, Protocol::Enum, new EnumResult(*this, order++)); } return; } @@ -279,6 +303,11 @@ DnsResult::lookupInternal(const Uri& uri) //assert(uri.scheme() == Symbols::Sips || uri.scheme() == Symbols::Sip); mSips = (uri.scheme() == Symbols::Sips); mTarget = (!mSips && uri.exists(p_maddr)) ? uri.param(p_maddr) : uri.host(); + // remove brackets around ipv6 address if present + if (mTarget.size() >= 2 && mTarget[0] == '[' && mTarget[mTarget.size()-1] == ']') + { + mTarget = mTarget.substr(1,mTarget.size()-2); + } mSrvKey = Symbols::UNDERSCORE + uri.scheme().substr(0, uri.scheme().size()) + Symbols::DOT; bool isNumeric = DnsUtil::isIpAddress(mTarget); @@ -290,7 +319,13 @@ DnsResult::lookupInternal(const Uri& uri) if (isNumeric) // IP address specified { mPort = getDefaultPort(mTransport, uri.port()); - Tuple tuple(mTarget, mPort, mTransport, mTarget); + // If the target Uri has a netns specified, we need to copy it into the Tuple + // We need to distinguish between the Uri not having an netns set and the + // the default/global netns "" (emtpy string). + Tuple tuple(mTarget, mPort, mTransport, mTarget, uri.netNs()); +#ifdef USE_NETNS + DebugLog(<< "DnsResult netns: " << uri.netNs()); +#endif // ?bwc? If this is greylisted, what can we do? This is the only result if(!(mInterface.getMarkManager().getMarkType(tuple)==TupleMarkManager::BLACK)) @@ -321,11 +356,12 @@ DnsResult::lookupInternal(const Uri& uri) mTransport = DTLS; if (!mInterface.isSupportedProtocol(mTransport)) { + DebugLog(<<"transport " << toData(mTransport) << " not supported"); transition(Finished); if (mHandler) mHandler->handle(this); return; } - if(!mDns.supportedType(T_SRV)) + if(!mDnsStub.supportedType(T_SRV)) { mPort = getDefaultPort(mTransport, uri.port()); lookupHost(mTarget); // for current target and port @@ -333,7 +369,7 @@ DnsResult::lookupInternal(const Uri& uri) else { mSRVCount++; - mDns.lookup("_sips._udp." + mTarget, Protocol::Sip, this); + mDnsStub.lookup("_sips._udp." + mTarget, Protocol::Sip, this); StackLog (<< "Doing SRV lookup of _sips._udp." << mTarget); } } @@ -343,11 +379,12 @@ DnsResult::lookupInternal(const Uri& uri) mHaveChosenTransport=true; if (!mInterface.isSupportedProtocol(mTransport)) { + DebugLog(<<"transport " << toData(mTransport) << " not supported"); transition(Finished); if (mHandler) mHandler->handle(this); return; } - if(!mDns.supportedType(T_SRV)) + if(!mDnsStub.supportedType(T_SRV)) { mPort = getDefaultPort(mTransport, uri.port()); lookupHost(mTarget); // for current target and port @@ -355,7 +392,7 @@ DnsResult::lookupInternal(const Uri& uri) else { mSRVCount++; - mDns.lookup("_sips._tcp." + mTarget, Protocol::Sip, this); + mDnsStub.lookup("_sips._tcp." + mTarget, Protocol::Sip, this); StackLog (<< "Doing SRV lookup of _sips._tcp." << mTarget); } } @@ -364,12 +401,13 @@ DnsResult::lookupInternal(const Uri& uri) { if (!mInterface.isSupportedProtocol(mTransport)) { + DebugLog(<<"transport " << toData(mTransport) << " not supported"); transition(Finished); if (mHandler) mHandler->handle(this); return; } - if(!mDns.supportedType(T_SRV)) + if(!mDnsStub.supportedType(T_SRV)) { mPort = getDefaultPort(mTransport, uri.port()); lookupHost(mTarget); // for current target and port @@ -380,17 +418,17 @@ DnsResult::lookupInternal(const Uri& uri) { case TLS: //deprecated, mean TLS over TCP mSRVCount++; - mDns.lookup("_sips._tcp." + mTarget, Protocol::Sip, this); + mDnsStub.lookup("_sips._tcp." + mTarget, Protocol::Sip, this); StackLog (<< "Doing SRV lookup of _sips._tcp." << mTarget); break; case DTLS: //deprecated, mean TLS over TCP mSRVCount++; - mDns.lookup("_sip._dtls." + mTarget, Protocol::Sip, this); + mDnsStub.lookup("_sip._dtls." + mTarget, Protocol::Sip, this); StackLog (<< "Doing SRV lookup of _sip._dtls." << mTarget); break; case TCP: mSRVCount++; - mDns.lookup("_sip._tcp." + mTarget, Protocol::Sip, this); + mDnsStub.lookup("_sip._tcp." + mTarget, Protocol::Sip, this); StackLog (<< "Doing SRV lookup of _sip._tcp." << mTarget); break; case SCTP: @@ -398,7 +436,7 @@ DnsResult::lookupInternal(const Uri& uri) case UDP: default: //fall through to UDP for unimplemented & unknown mSRVCount++; - mDns.lookup("_sip._udp." + mTarget, Protocol::Sip, this); + mDnsStub.lookup("_sip._udp." + mTarget, Protocol::Sip, this); StackLog (<< "Doing SRV lookup of _sip._udp." << mTarget); } } @@ -407,7 +445,7 @@ DnsResult::lookupInternal(const Uri& uri) else // transport parameter is not specified { // if hostname is numeric, a port is specified, or NAPTR queries are not support by the DNS layer - skip NAPTR lookup - if (isNumeric || uri.port() != 0 || !mDns.supportedType(T_NAPTR)) + if (isNumeric || uri.port() != 0 || !mDnsStub.supportedType(T_NAPTR)) { TupleMarkManager::MarkType mark=TupleMarkManager::BLACK; Tuple tuple; @@ -427,6 +465,7 @@ DnsResult::lookupInternal(const Uri& uri) } else { + bool udpSupported = false;; if(mark!=TupleMarkManager::OK && (mInterface.isSupported(UDP, V4) || mInterface.isSupported(UDP, V6))) { @@ -434,24 +473,59 @@ DnsResult::lookupInternal(const Uri& uri) mPort = getDefaultPort(mTransport,uri.port()); tuple=Tuple(mTarget,mPort,mTransport,mTarget); mark=mInterface.getMarkManager().getMarkType(tuple); + udpSupported = true; } - if(mark!=TupleMarkManager::OK && (mInterface.isSupported(TCP, V4) || - mInterface.isSupported(TCP, V6))) + if (!mInterface.getUdpOnlyOnNumeric()) { - mTransport=TCP; - mPort = getDefaultPort(mTransport,uri.port()); - tuple=Tuple(mTarget,mPort,mTransport,mTarget); - mark=mInterface.getMarkManager().getMarkType(tuple); - } - - if(mark!=TupleMarkManager::OK && (mInterface.isSupported(TLS, V4) || - mInterface.isSupported(TLS, V6))) - { - mTransport=TLS; - mPort = getDefaultPort(mTransport,uri.port()); - tuple=Tuple(mTarget,mPort,mTransport,mTarget); - mark=mInterface.getMarkManager().getMarkType(tuple); + bool allMarksNotOK = mark != TupleMarkManager::OK; + bool tcpSupported = false; + if(mark!=TupleMarkManager::OK && (mInterface.isSupported(TCP, V4) || + mInterface.isSupported(TCP, V6))) + { + mTransport=TCP; + mPort = getDefaultPort(mTransport,uri.port()); + // Need to get netns from Uri if set and set it in + // the Tuple for this IP address case + tuple=Tuple(mTarget, mPort, mTransport, mTarget, uri.netNs()); +#ifdef USE_NETNS + DebugLog(<< "DnsResult netns: " << uri.netNs()); +#endif + mark=mInterface.getMarkManager().getMarkType(tuple); + allMarksNotOK = mark != TupleMarkManager::OK; + tcpSupported = true; + } + + if(mark!=TupleMarkManager::OK && (mInterface.isSupported(TLS, V4) || + mInterface.isSupported(TLS, V6))) + { + mTransport=TLS; + mPort = getDefaultPort(mTransport,uri.port()); + tuple=Tuple(mTarget,mPort,mTransport,mTarget); + mark=mInterface.getMarkManager().getMarkType(tuple); + allMarksNotOK = mark != TupleMarkManager::OK; + } + + // If all transports are grey or blacklisted, then just fallback to UDP, assuming it is available + // or TCP if it is available. We don't want to end up continually trying TCP or TLS because all + // transports for this IP Address are greylisted. + if (allMarksNotOK) + { + if (udpSupported && mTransport != UDP) + { + mTransport = UDP; + mPort = getDefaultPort(mTransport, uri.port()); + tuple = Tuple(mTarget, mPort, mTransport, mTarget); + mark = mInterface.getMarkManager().getMarkType(tuple); + } + else if (tcpSupported && mTransport != TCP) + { + mTransport = TCP; + mPort = getDefaultPort(mTransport, uri.port()); + tuple = Tuple(mTarget, mPort, mTransport, mTarget, uri.netNs()); + mark = mInterface.getMarkManager().getMarkType(tuple); + } + } } } @@ -465,7 +539,7 @@ DnsResult::lookupInternal(const Uri& uri) else { // .bwc. Numeric result is blacklisted. Oh well. - assert(mResults.empty()); + resip_assert(mResults.empty()); transition(Available); DebugLog(<< "Numeric result, but this result is currently blacklisted: " << tuple); } @@ -505,14 +579,14 @@ DnsResult::lookupInternal(const Uri& uri) else { // !bwc! Debatable. - assert(0); + resip_assert(0); if (mHandler) mHandler->handle(this); } } } else // do NAPTR { - mDns.lookup(mTarget, Protocol::Sip, this); // for current target + mDnsStub.lookup(mTarget, Protocol::Sip, this); // for current target } } } @@ -524,21 +598,21 @@ void DnsResult::lookupHost(const Data& target) #ifdef USE_IPV6 DebugLog(<< "Doing host (AAAA) lookup: " << target); mPassHostFromAAAAtoA = target; - mDns.lookup(target, Protocol::Sip, this); + mDnsStub.lookup(target, Protocol::Sip, this); #else - assert(0); - mDns.lookup(target, Protocol::Sip, this); + resip_assert(0); + mDnsStub.lookup(target, Protocol::Sip, this); #endif } else if (mInterface.isSupported(mTransport, V4)) { - mDns.lookup(target, Protocol::Sip, this); + mDnsStub.lookup(target, Protocol::Sip, this); } else { CritLog(<<"Cannot lookup target="<handle(this); } // don't call primeResults since we need to wait for the response to @@ -638,8 +716,8 @@ DnsResult::SRV DnsResult::retrieveSRV() { // !ah! if mTransport is known -- should we ignore those that don't match?! - assert(!mSRVResults.empty()); - assert(mSRVCount==0); + resip_assert(!mSRVResults.empty()); + resip_assert(mSRVCount==0); const SRV& srv = *mSRVResults.begin(); int priority = srv.priority; @@ -660,7 +738,7 @@ DnsResult::retrieveSRV() // All SRVs must match. transport=mTransport; - assert(mSRVResults.begin()->transport==transport); + resip_assert(mSRVResults.begin()->transport==transport); } if (mCumulativeWeight == 0) @@ -670,7 +748,7 @@ DnsResult::retrieveSRV() && i->priority == priority && i->transport == transport; i++) { - assert(i->weight>=0); + resip_assert(i->weight>=0); mCumulativeWeight += i->weight; } } @@ -707,7 +785,7 @@ DnsResult::retrieveSRV() { InfoLog (<< "SRV Results problem selected=" << selected << " cum=" << mCumulativeWeight); } - assert(i != mSRVResults.end()); + resip_assert(i != mSRVResults.end()); SRV next = *i; mCumulativeWeight -= next.weight; mSRVResults.erase(i); @@ -974,7 +1052,7 @@ void DnsResult::onDnsResult(const DNSResult& result) return; } StackLog (<< "DnsResult::onDnsResult() " << result.status); - assert(mInterface.isSupported(mTransport, V6)); + resip_assert(mInterface.isSupported(mTransport, V6)); // This function assumes that the AAAA query that caused this callback // is the _only_ outstanding DNS query that might result in a @@ -1005,25 +1083,23 @@ void DnsResult::onDnsResult(const DNSResult& result) default: ;// .bwc. Do nothing. } - } - } else { StackLog (<< "Failed async AAAA query: " << result.msg); } // funnel through to host processing - mDns.lookup(mPassHostFromAAAAtoA, Protocol::Sip, this); + mDnsStub.lookup(mPassHostFromAAAAtoA, Protocol::Sip, this); #else - assert(0); + resip_assert(0); #endif } void DnsResult::onDnsResult(const DNSResult& result) { StackLog (<< "Received SRV result for: " << mTarget); - assert(mSRVCount>=0); + resip_assert(mSRVCount>=0); mSRVCount--; StackLog (<< "DnsResult::onDnsResult() " << mSRVCount << " status=" << result.status); @@ -1046,14 +1122,6 @@ void DnsResult::onDnsResult(const DNSResult& result) srv.weight = (*it).weight(); srv.port = (*it).port(); srv.target = (*it).target(); - - // Workaround for dns server bug - domain name can be doubled via dot - Data p1 = srv.target.substr(0, srv.target.size()/2), p2 = srv.target.substr(srv.target.size()/2 + 1); - if (p1 == p2) - { - StackLog (<< "Workaround for SRV result : " << srv.target << " rewrites to " << p1); - srv.target = p1; - } // fillin srv.naptrpref - if found in NAPTR map, then SRV query was driven from a NAPTR lookup std::map::iterator itNaptr = mTopOrderedNAPTRs.find(srv.key); if(itNaptr != mTopOrderedNAPTRs.end()) @@ -1134,19 +1202,6 @@ void DnsResult::onDnsResult(const DNSResult& result) mTransport = TCP; mHaveChosenTransport=true; } - else - if (mInterface.isSupported(UDP, V6)) - { - mTransport = UDP; - mHaveChosenTransport = true; - } - else - if (mInterface.isSupported(TCP, V6)) - { - mTransport = TCP; - mHaveChosenTransport = true; - } - /* Yes, there is the possibility that at this point mTransport is still UNKNOWN_TRANSPORT, but this is likely to fail just as well as defaulting to UDP when there isn't an interface that @@ -1189,7 +1244,7 @@ void DnsResult::onEnumResult(const DNSResult& result, int order) { Lock l(mEnumDestinationsMutex); - assert(mDoingEnum > 0); + resip_assert(mDoingEnum > 0); mDoingEnum--; @@ -1319,7 +1374,7 @@ DnsResult::onNaptrResult(const DNSResult& result) StackLog (<< "NAPTR record is supported and matches highes priority order. doing SRV query: " << (*it)); mTopOrderedNAPTRs[(*it).replacement] = (*it); mSRVCount++; - mDns.lookup((*it).replacement, Protocol::Sip, this); + mDnsStub.lookup((*it).replacement, Protocol::Sip, this); } } } @@ -1349,32 +1404,32 @@ DnsResult::onNaptrResult(const DNSResult& result) } mSRVCount++; - mDns.lookup("_sips._tcp." + mTarget, Protocol::Sip, this); + mDnsStub.lookup("_sips._tcp." + mTarget, Protocol::Sip, this); StackLog (<< "Doing SRV lookup of _sips._tcp." << mTarget); } else { if (mInterface.isSupportedProtocol(TLS)) { - mDns.lookup("_sips._tcp." + mTarget, Protocol::Sip, this); + mDnsStub.lookup("_sips._tcp." + mTarget, Protocol::Sip, this); ++mSRVCount; StackLog (<< "Doing SRV lookup of _sips._tcp." << mTarget); } if (mInterface.isSupportedProtocol(DTLS)) { - mDns.lookup("_sips._udp." + mTarget, Protocol::Sip, this); + mDnsStub.lookup("_sips._udp." + mTarget, Protocol::Sip, this); ++mSRVCount; StackLog (<< "Doing SRV lookup of _sips._udp." << mTarget); } if (mInterface.isSupportedProtocol(TCP)) { - mDns.lookup("_sip._tcp." + mTarget, Protocol::Sip, this); + mDnsStub.lookup("_sip._tcp." + mTarget, Protocol::Sip, this); ++mSRVCount; StackLog (<< "Doing SRV lookup of _sip._tcp." << mTarget); } if (mInterface.isSupportedProtocol(UDP)) { - mDns.lookup("_sip._udp." + mTarget, Protocol::Sip, this); + mDnsStub.lookup("_sip._udp." + mTarget, Protocol::Sip, this); ++mSRVCount; StackLog (<< "Doing SRV lookup of _sip._udp." << mTarget); } @@ -1398,7 +1453,6 @@ DnsResult::onDnsResult(const DNSResult& result) } onNaptrResult(result); - } void DnsResult::onDnsResult(const DNSResult& result) @@ -1496,3 +1550,5 @@ resip::operator<<(EncodeStream& strm, const resip::DnsResult::SRV& srv) * . * */ + +// vim: softtabstop=3:shiftwidth=3:expandtab diff --git a/src/libs/resiprocate/resip/stack/DnsResult.hxx b/src/libs/resiprocate/resip/stack/DnsResult.hxx index 3315efdf..fc1d4a48 100644 --- a/src/libs/resiprocate/resip/stack/DnsResult.hxx +++ b/src/libs/resiprocate/resip/stack/DnsResult.hxx @@ -16,6 +16,7 @@ #include "resip/stack/Tuple.hxx" #include "resip/stack/Transport.hxx" #include "resip/stack/Uri.hxx" +#include "resip/stack/TupleMarkManager.hxx" #include "rutil/Condition.hxx" #include "rutil/HeapInstanceCounter.hxx" #include "rutil/dns/RRVip.hxx" @@ -32,12 +33,12 @@ namespace resip class DnsInterface; class DnsAAAARecord; class DnsHandler; +class WhiteListLastCommand; class EnumResultSink { public: - virtual void onEnumResult(const DNSResult& result, - int order) = 0; + virtual void onEnumResult(const DNSResult& result, int order) = 0; }; class EnumResult : public DnsResultSink @@ -48,11 +49,7 @@ class EnumResult : public DnsResultSink // DnsResultSink void onDnsResult(const DNSResult&); - -//#ifdef USE_IPV6 void onDnsResult(const DNSResult&); -//#endif - void onDnsResult(const DNSResult&); void onDnsResult(const DNSResult&); void onDnsResult(const DNSResult&); @@ -84,23 +81,18 @@ class DnsResult : public DnsResultSink, public EnumResultSink typedef std::vector DataVector; - /*! Starts a lookup. Has the rules for determining the transport from a uri as per rfc3263 and then does a NAPTR lookup or an A - lookup depending on the uri. + lookup depending on the uri. Also does ENUM lookups if + domain matches a configured enum domain. This call is threadsafe. @param uri The uri to resolve. - @param enumSuffixes If the uri is enum searchable, this is the list of - enum suffixes (for example "e164.arpa") that will be used in - the attempt to resolve this uri. - @param enumDomains The ENUM possibility is only considered if - the URI domain part is one of these domains */ - void lookup(const Uri& uri, const std::vector &enumSuffixes, - const std::map &enumDomains); + void lookup(const Uri& uri); /*! - Blacklist the last returned result until the specified time (ms) + Blacklist the last returned result until the specified time (ms). + This call is threadsafe. @param expiry The absolute expiry, in ms, of this blacklist. @return true iff the last result could be blacklisted @@ -112,6 +104,7 @@ class DnsResult : public DnsResultSink, public EnumResultSink Greylist the last returned result until the specified time (ms) Greylisting a tuple effectively de-prioritizes it, so it will not be tried if there are any non-grey or blacklisted tuples left to try. + This call is threadsafe. @param expiry The absolute expiry, in ms, of this blacklist. @return true iff the last result could be greylisted @@ -122,6 +115,7 @@ class DnsResult : public DnsResultSink, public EnumResultSink /*! Tries to load the next tuple. If Available is returned, the tuple may be accessed using current(). + Safe to call after DnsHandler::handle callback has been called. @return Available if there is a result ready, Pending if it needs to follow an SRV (more results might come in later), or Finished @@ -132,6 +126,7 @@ class DnsResult : public DnsResultSink, public EnumResultSink /*! Return the next tuple available for this query. + Safe to call after DnsHandler::handle callback has been called. @return The next Tuple available for this query. @note ALWAYS call available() and verify the return is Available @@ -148,6 +143,7 @@ class DnsResult : public DnsResultSink, public EnumResultSink match, even if the order/preference changes in the DNS, and this A/AAAA record will be favored above all others that match, even if new ones are added.) + This call is threadsafe. @note It can be argued that using this is harmful, since the load- leveling capabilities of DNS are ignored from here on. @@ -157,6 +153,7 @@ class DnsResult : public DnsResultSink, public EnumResultSink void whitelistLast(); // return the target of associated query + // Safe to call after DnsHandler::handle callback has been called. Data target() const { return mTarget; } unsigned int getSRVResultsSize() const {return (unsigned int)mSRVResults.size();} @@ -200,6 +197,28 @@ class DnsResult : public DnsResultSink, public EnumResultSink }; private: + + /* + The following command is used to ensure that all DnsInterface mRRVip and + mTupleMarkManager, and enum setting accesses are done from the DnsThread. + This gets the initial call * lookupInternalWithEnum to occur on the + DnsThread (using the DnsStub command fifo). + */ + class LookupCommand : public DnsStub::Command + { + public: + LookupCommand(DnsResult& dnsResult, const Uri& uri) : mDnsResult(dnsResult), mUri(uri) {} + virtual ~LookupCommand() {} + virtual void execute() + { + mDnsResult.lookupInternalWithEnum(mUri); + } + private: + DnsResult& mDnsResult; + Uri mUri; + }; + friend class LookupCommand; + void lookupInternalWithEnum(const Uri& uri); void lookupInternal(const Uri& uri); // Given a transport and port from uri, return the default port to use @@ -220,7 +239,7 @@ class DnsResult : public DnsResultSink, public EnumResultSink private: DnsInterface& mInterface; - DnsStub& mDns; + DnsStub& mDnsStub; RRVip& mVip; DnsHandler* mHandler; int mSRVCount; @@ -283,18 +302,13 @@ class DnsResult : public DnsResultSink, public EnumResultSink // DnsResultSink void onDnsResult(const DNSResult&); - -//#ifdef USE_IPV6 void onDnsResult(const DNSResult&); -//#endif - void onDnsResult(const DNSResult&); void onDnsResult(const DNSResult&); void onDnsResult(const DNSResult&); void onEnumResult(const DNSResult& result, int order); void onNaptrResult(const DNSResult& result); - typedef struct { @@ -319,12 +333,41 @@ class DnsResult : public DnsResultSink, public EnumResultSink This exists solely to allow mLastReturnedPath to be defined. */ std::vector mCurrentPath; - bool mHaveReturnedResults; - void clearCurrPath(); - Tuple mLastResult; + + /* + The following two commands are to ensure that all DnsInterface mVip + and mTupleMarkManager calls are done from the DnsThread (using the + DnsStub command fifo). + */ + class WhitelistCommand : public DnsStub::Command + { + public: + WhitelistCommand(RRVip& vip, std::vector& path) : mVip(vip), mPath(path) {} + virtual ~WhitelistCommand() {} + virtual void execute(); + private: + RRVip& mVip; + std::vector mPath; + }; + + class GreyOrBlacklistCommand : public DnsStub::Command + { + public: + GreyOrBlacklistCommand(RRVip& vip, TupleMarkManager& markManager, Item& pathTop, Tuple& result, UInt64 expiry, TupleMarkManager::MarkType markType) : + mVip(vip), mMarkManager(markManager), mPathTop(pathTop), mResult(result), mExpiry(expiry), mMarkType(markType) {} + virtual ~GreyOrBlacklistCommand() {} + virtual void execute(); + private: + RRVip& mVip; + TupleMarkManager& mMarkManager; + Item mPathTop; + Tuple mResult; + UInt64 mExpiry; + TupleMarkManager::MarkType mMarkType; + }; }; EncodeStream& operator<<(EncodeStream& strm, const DnsResult&); @@ -334,6 +377,7 @@ EncodeStream& operator<<(EncodeStream& strm, const DnsResult::NAPTR&); } #endif + // Copyright (c) 2003, Jason Fischl /* ==================================================================== * The Vovida Software License, Version 1.0 diff --git a/src/libs/resiprocate/resip/stack/DomainMatcher.hxx b/src/libs/resiprocate/resip/stack/DomainMatcher.hxx new file mode 100644 index 00000000..b5e3fa75 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/DomainMatcher.hxx @@ -0,0 +1,101 @@ +#if !defined(RESIP_DOMAINMATCHER_HXX) +#define RESIP_DOMAINMATCHER_HXX + +#include "resip/stack/Contents.hxx" +#include "rutil/Data.hxx" +#include "rutil/HashMap.hxx" +#include "rutil/ParseBuffer.hxx" + +namespace resip +{ + +class DomainMatcher +{ + + public: + + /** + @brief Returns true iff domain matches one of the domains that this + TransactionUser is responsible for. (added with addDomain). + @param domain The domain name to check. + @return True iff this TransactionUser is responsible for domain. + @note The comparison performed is case-sensitive; make sure you + lower-case everything you put in here. + */ + virtual bool isMyDomain(const Data& domain) const = 0; + + /** + @brief Adds a domain to the set of domains that this TransactionUser is + responsible for. + @note The comparison performed is case-sensitive; make sure you + lower-case everything you put in here. + @todo Make this case-insensitive. + @warning This method is NOT thread-safe. mDomainList is accessed from both the + thread that queues to the TU (iff a DomainIsMe MessageFilterRule is used) + and from within the TU itself. The only way calling this is safe, is if you + can ensure both of these threads are not calling isMyDomain when you call + this method. For example an application that does NOT use a DomainIsMe + MessageFilterRule and that posts the addDomain call to the TU processing + thread for execution there, will be thread safe. This API is also safe to call + before any of the processing threads have been started. + */ + virtual void addDomain(const Data& domain) = 0; + + /** + @brief Removes a domain from the set of domains that this TransactionUser is + responsible for. + @note This API will lowercase the domain when searching for the domain to + remove + @warning This method is NOT thread-safe. mDomainList is accessed from both the + thread that queues to the TU (iff a DomainIsMe MessageFilterRule is used) + and from within the TU itself. The only way calling this is safe, is if you + can ensure both of these threads are not calling isMyDomain when you call + this method. For example an application that does NOT use a DomainIsMe + MessageFilterRule and that posts the removeDomain call to the TU processing + thread (ie: DUMThread) for execution there, will be thread safe. + */ + virtual void removeDomain(const Data& domain) = 0; + +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright 2017 Daniel Pocock http://danielpocock.com All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/resip/stack/DtmfPayloadContents.cxx b/src/libs/resiprocate/resip/stack/DtmfPayloadContents.cxx new file mode 100644 index 00000000..48853367 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/DtmfPayloadContents.cxx @@ -0,0 +1,241 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/DtmfPayloadContents.hxx" +#include "resip/stack/Helper.hxx" +#include "rutil/ParseBuffer.hxx" +#include "rutil/DataStream.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/Logger.hxx" +#include "rutil/WinLeakCheck.hxx" +#include "resip/stack/SdpContents.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::SDP + +using namespace resip; +using namespace std; + +//const DtmfPayloadContents DtmfPayloadContents::Empty; + +bool +DtmfPayloadContents::init() +{ + static ContentsFactory factory; + (void)factory; + return true; +} + +DtmfPayloadContents::DtmfPayloadContents() : Contents(getStaticType()) +{ +} + +DtmfPayloadContents::DtmfPayloadContents(const HeaderFieldValue& hfv, const Mime& contentTypes) + : Contents(hfv, contentTypes) +{ +} + +DtmfPayloadContents::~DtmfPayloadContents() +{ +} + +DtmfPayloadContents& +DtmfPayloadContents::operator=(const DtmfPayloadContents& rhs) +{ + if (this != &rhs) + { + Contents::operator=(rhs); + mDtmfPayload = rhs.mDtmfPayload; + } + return *this; +} + +Contents* +DtmfPayloadContents::clone() const +{ + return new DtmfPayloadContents(*this); +} + +void +DtmfPayloadContents::parse(ParseBuffer& pb) +{ + mDtmfPayload.parse(pb); +} + +EncodeStream& +DtmfPayloadContents::encodeParsed(EncodeStream& s) const +{ + mDtmfPayload.encode(s); + return s; +} + +const Mime& +DtmfPayloadContents::getStaticType() +{ + static Mime type("application", "dtmf-relay"); + return type; +} + +DtmfPayloadContents::DtmfPayload::DtmfPayload(char button, int duration) + : mButton(button), + mDuration(duration) +{} + +DtmfPayloadContents::DtmfPayload::DtmfPayload(const DtmfPayload& rhs) +{ + *this = rhs; +} + +DtmfPayloadContents::DtmfPayload& +DtmfPayloadContents::DtmfPayload::operator=(const DtmfPayload& rhs) +{ + if (this != &rhs) + { + mButton = rhs.mButton; + mDuration = rhs.mDuration; + } + return *this; +} + +bool +DtmfPayloadContents::DtmfPayload::isValidButton(const char c) +{ + static const char* permittedChars = "ABCD*#"; + if(isdigit(c)) + { + return true; + } + if(strchr(permittedChars, c) != NULL) + { + return true; + } + WarningLog(<<"Not a valid DTMF button: " << c); + return false; +} + +void +DtmfPayloadContents::DtmfPayload::parse(ParseBuffer& pb) +{ + const char* anchor = pb.skipWhitespace(); + Data val; + pb.skipToChars(Symbols::EQUALS); + pb.data(val, anchor); + if(!isEqualNoCase(val, "Signal")) + { + ErrLog(<<"first key must be Signal, found: " << val); + throw ParseException("first key must be Signal", pb.getContext(), __FILE__, __LINE__); + } + pb.skipChar(); + anchor = pb.skipWhitespace(); + pb.skipToOneOf(Symbols::CRLF); + pb.data(val, anchor); + if(val.size() != 1) + { + ErrLog(<<"signal string [" << val << "], size = " << val.size()); + throw ParseException("Exactly one button character expected in SIP INFO", pb.getContext(), __FILE__, __LINE__); + } + const char& _button = val[0]; + if(!isValidButton(_button)) + { + throw ParseException("Invalid DTMF button character found", pb.getContext(), __FILE__, __LINE__); + } + StackLog(<< "Button=" << _button); + + skipEol(pb); + anchor = pb.skipWhitespace(); + pb.skipToChars(Symbols::EQUALS); + pb.data(val, anchor); + if(!isEqualNoCase(val, "Duration")) + { + ErrLog(<<"second key must be Duration, found: " << val); + throw ParseException("second key must be Duration", pb.getContext(), __FILE__, __LINE__); + } + pb.skipChar(); + pb.skipWhitespace(); + int _duration = pb.integer(); + + StackLog(<< "Duration = " << _duration); + if(_duration < 20 || _duration > 5000) + { + ErrLog(<<"Invalid duration: " << _duration); + throw ParseException("Invalid duration", pb.getContext(), __FILE__, __LINE__); + } + + mButton = _button; + mDuration = _duration; +} + +unsigned short +DtmfPayloadContents::DtmfPayload::getEventCode() const +{ + resip_assert(mButton); + unsigned short eventCode; + if(isdigit(mButton)) + { + eventCode = mButton - '0'; + } + else if(mButton == '*') + { + eventCode = 10; + } + else if(mButton == '#') + { + eventCode = 11; + } + else if(mButton >= 'A' && mButton <= 'D') + { + eventCode = 12 + mButton - 'A'; + } + else + { + resip_assert(0); // unexpected button, should have been caught by the parser + } + + return eventCode; +} + +EncodeStream& +DtmfPayloadContents::DtmfPayload::encode(EncodeStream& s) const +{ + s << "Signal=" << mButton << Symbols::CRLF; + s << "Duration=" << mDuration << Symbols::CRLF; + return s; +} + +/* ==================================================================== + * + * Copyright 2014 Daniel Pocock http://danielpocock.com All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/resip/stack/DtmfPayloadContents.hxx b/src/libs/resiprocate/resip/stack/DtmfPayloadContents.hxx new file mode 100644 index 00000000..c92cf498 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/DtmfPayloadContents.hxx @@ -0,0 +1,137 @@ +#if !defined(RESIP_DTMFPAYLOADCONTENTS_HXX) +#define RESIP_DTMFPAYLOADCONTENTS_HXX + +#include "resip/stack/Contents.hxx" +#include "rutil/Data.hxx" +#include "rutil/HashMap.hxx" +#include "rutil/ParseBuffer.hxx" + +namespace resip +{ + +/* Provides a way to handle the application/dtmf-relay + content-type from SIP INFO messages. + Attempts to adhere to the IETF draft + draft-kaplan-dispatch-info-dtmf-package-00 +*/ + +class DtmfPayloadContents : public Contents +{ + + public: + + class DtmfPayload + { + public: + DtmfPayload(char button, int duration); + + DtmfPayload() : mButton(0), mDuration(0) {} + DtmfPayload(const DtmfPayload& rhs); + DtmfPayload& operator=(const DtmfPayload& rhs); + + void parse(ParseBuffer& pb); + EncodeStream& encode(EncodeStream&) const; + + /** @brief obtain representation of the button as a character + * + * @return the ASCII symbol for the button pressed + **/ + char getButton() const { return mButton; } + + /** @brief obtain representation of the button as event code + * + * RFC 4733 provides a list of integer event codes for DTMF + * symbols. + * + * @return the event code corresponding to the button pressed + **/ + unsigned short getEventCode() const; + + /** @brief obtain duration in milliseconds + * + * @return the number of milliseconds the button was pressed + **/ + int getDuration() const { return mDuration; } + + private: + char mButton; // ASCII representation of the DTMF button + int mDuration; // milliseconds + + static bool isValidButton(const char c); + + friend class DtmfPayloadContents; + }; + + DtmfPayloadContents(); + DtmfPayloadContents(const HeaderFieldValue& hfv, const Mime& contentTypes); + virtual ~DtmfPayloadContents(); + + DtmfPayloadContents& operator=(const DtmfPayloadContents& rhs); + + /** @brief duplicate an DtmfPayloadContents object + * + * @return pointer to a new DtmfPayloadContents object + **/ + virtual Contents* clone() const; + + /** @brief get the parsed payload + * + * @return parsed payload object + **/ + DtmfPayload& dtmfPayload() {checkParsed(); return mDtmfPayload;} + const DtmfPayload& dtmfPayload() const {checkParsed(); return mDtmfPayload;} + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + virtual void parse(ParseBuffer& pb); + static const Mime& getStaticType() ; + + static bool init(); + + private: + DtmfPayloadContents(const Data& data, const Mime& contentTypes); + DtmfPayload mDtmfPayload; +}; + +static bool invokeDtmfPayloadContentsInit = DtmfPayloadContents::init(); + +} + + +#endif + +/* ==================================================================== + * + * Copyright 2014 Daniel Pocock http://danielpocock.com All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/resip/stack/Embedded.cxx b/src/libs/resiprocate/resip/stack/Embedded.cxx index c810164c..bdf30513 100644 --- a/src/libs/resiprocate/resip/stack/Embedded.cxx +++ b/src/libs/resiprocate/resip/stack/Embedded.cxx @@ -3,7 +3,7 @@ #endif -#include +#include "rutil/ResipAssert.h" #include "resip/stack/Embedded.hxx" #include "rutil/Data.hxx" diff --git a/src/libs/resiprocate/resip/stack/EnableFlowTimer.hxx b/src/libs/resiprocate/resip/stack/EnableFlowTimer.hxx index 185d4aeb..ccd4c9ff 100644 --- a/src/libs/resiprocate/resip/stack/EnableFlowTimer.hxx +++ b/src/libs/resiprocate/resip/stack/EnableFlowTimer.hxx @@ -1,94 +1,94 @@ -#ifndef EnableFlowTimer_Include_Guard -#define EnableFlowTimer_Include_Guard - -#include "resip/stack/TransactionMessage.hxx" -#include "resip/stack/Tuple.hxx" - -namespace resip -{ -class EnableFlowTimer : public TransactionMessage -{ - public: - explicit EnableFlowTimer(const resip::Tuple& flow) : - mFlow(flow) - {} - virtual ~EnableFlowTimer(){} - - virtual const Data& getTransactionId() const {return Data::Empty;} - const Tuple& getFlow() const { return mFlow; } - - virtual bool isClientTransaction() const {return true;} - virtual EncodeStream& encode(EncodeStream& strm) const - { - return strm << "EnableFlowTimer: " << mFlow; - } - virtual EncodeStream& encodeBrief(EncodeStream& strm) const - { - return strm << "EnableFlowTimer: " << mFlow; - } - - virtual Message* clone() const - { - return new EnableFlowTimer(*this); - } - - protected: - const resip::Tuple mFlow; - -}; // class EnableFlowTimer - -} // namespace resip - -#endif // include guard - -/* ==================================================================== - * The Vovida Software License, Version 1.0 - * - * Copyright (c) 2004 Vovida Networks, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The names "VOCAL", "Vovida Open Communication Application Library", - * and "Vovida Open Communication Application Library (VOCAL)" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact vocal@vovida.org. - * - * 4. Products derived from this software may not be called "VOCAL", nor - * may "VOCAL" appear in their name, without prior written - * permission of Vovida Networks, Inc. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND - * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA - * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES - * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ==================================================================== - * - * This software consists of voluntary contributions made by Vovida - * Networks, Inc. and many individuals on behalf of Vovida Networks, - * Inc. For more information on Vovida Networks, Inc., please see - * . - * - * vi: set shiftwidth=3 expandtab: - */ - +#ifndef EnableFlowTimer_Include_Guard +#define EnableFlowTimer_Include_Guard + +#include "resip/stack/TransactionMessage.hxx" +#include "resip/stack/Tuple.hxx" + +namespace resip +{ +class EnableFlowTimer : public TransactionMessage +{ + public: + explicit EnableFlowTimer(const resip::Tuple& flow) : + mFlow(flow) + {} + virtual ~EnableFlowTimer(){} + + virtual const Data& getTransactionId() const {return Data::Empty;} + const Tuple& getFlow() const { return mFlow; } + + virtual bool isClientTransaction() const {return true;} + virtual EncodeStream& encode(EncodeStream& strm) const + { + return strm << "EnableFlowTimer: " << mFlow; + } + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "EnableFlowTimer: " << mFlow; + } + + virtual Message* clone() const + { + return new EnableFlowTimer(*this); + } + + protected: + const resip::Tuple mFlow; + +}; // class EnableFlowTimer + +} // namespace resip + +#endif // include guard + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2004 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * . + * + * vi: set shiftwidth=3 expandtab: + */ + diff --git a/src/libs/resiprocate/resip/stack/EventStackThread.cxx b/src/libs/resiprocate/resip/stack/EventStackThread.cxx index 142a97dc..141d8ae6 100644 --- a/src/libs/resiprocate/resip/stack/EventStackThread.cxx +++ b/src/libs/resiprocate/resip/stack/EventStackThread.cxx @@ -148,12 +148,14 @@ EventStackSimpleMgr::createStack(SipStackOptions& options) } void -EventStackSimpleMgr::release() { +EventStackSimpleMgr::release() +{ if ( mThread ) { delete mThread; mThread = NULL; } - if ( mStack ) { + if ( mStack ) + { // we only delete the stack if we created, not if externally created delete mStack; mStack = NULL; } diff --git a/src/libs/resiprocate/resip/stack/EventStackThread.hxx b/src/libs/resiprocate/resip/stack/EventStackThread.hxx index be107b3c..1af07d4a 100644 --- a/src/libs/resiprocate/resip/stack/EventStackThread.hxx +++ b/src/libs/resiprocate/resip/stack/EventStackThread.hxx @@ -129,7 +129,7 @@ class EventStackSimpleMgr * Thread accessor. * Use this to invoke addStack(), run(), shutdown(), join(), etc. */ - EventStackThread& getThread() { assert(mThread); return *mThread; } + EventStackThread& getThread() { resip_assert(mThread); return *mThread; } /* * Call to release all owned resources early. Stack must be diff --git a/src/libs/resiprocate/resip/stack/ExistsOrDataParameter.cxx b/src/libs/resiprocate/resip/stack/ExistsOrDataParameter.cxx index a567d754..2d7a6eea 100644 --- a/src/libs/resiprocate/resip/stack/ExistsOrDataParameter.cxx +++ b/src/libs/resiprocate/resip/stack/ExistsOrDataParameter.cxx @@ -2,7 +2,7 @@ #include "config.h" #endif -#include +#include "rutil/ResipAssert.h" #include "rutil/ParseException.hxx" #include "resip/stack/ExistsOrDataParameter.hxx" #include "resip/stack/Symbols.hxx" @@ -39,7 +39,7 @@ ExistsOrDataParameter::decode(ParameterTypes::Type type, const std::bitset<256>& terminators, PoolBase* pool) { - pb.skipWhitespace(); + //pb.skipWhitespace(); // whitespace may be a terminator - don't skip it if (pb.eof() || terminators[*pb.position()]) { return new (pool) ExistsOrDataParameter(type); diff --git a/src/libs/resiprocate/resip/stack/ExtendedDomainMatcher.cxx b/src/libs/resiprocate/resip/stack/ExtendedDomainMatcher.cxx new file mode 100644 index 00000000..29383e16 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ExtendedDomainMatcher.cxx @@ -0,0 +1,100 @@ +#include "rutil/Data.hxx" +#include "resip/stack/ExtendedDomainMatcher.hxx" + +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::SIP + +using namespace resip; + +ExtendedDomainMatcher::ExtendedDomainMatcher() : + mDomainSuffixList() +{ +} + +ExtendedDomainMatcher::~ExtendedDomainMatcher() +{ +} + +bool +ExtendedDomainMatcher::isMyDomain(const Data& domain) const +{ + if(BasicDomainMatcher::isMyDomain(domain)) + { + return true; + } + + // Domain search should be case insensitive - search in lowercase only + Data _domain(domain); + _domain.lowercase(); + + if(mDomainSuffixList.empty()) + { + return false; + } + + static const Data dot("."); + Data::size_type i = 0; + for(i = _domain.find(dot, i); i < _domain.size() && i != Data::npos; i++) + { + Data _search = _domain.substr(i); + if(mDomainSuffixList.count(_search) > 0) + { + return true; + } + } + return false; +} + +void +ExtendedDomainMatcher::addDomainSuffix(const Data& domainSuffix) +{ + // Domain search should be case insensitive - store in lowercase only + mDomainSuffixList.insert(Data(domainSuffix).lowercase()); +} + +void +ExtendedDomainMatcher::removeDomainSuffix(const Data& domainSuffix) +{ + DomainSuffixList::iterator it = mDomainSuffixList.find(Data(domainSuffix).lowercase()); + if (it != mDomainSuffixList.end()) + { + mDomainSuffixList.erase(it); + } +} + +/* ==================================================================== + * + * Copyright 2017 Daniel Pocock http://danielpocock.com All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/resip/stack/ExtendedDomainMatcher.hxx b/src/libs/resiprocate/resip/stack/ExtendedDomainMatcher.hxx new file mode 100644 index 00000000..26a4cd11 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ExtendedDomainMatcher.hxx @@ -0,0 +1,70 @@ +#if !defined(RESIP_EXTENDEDDOMAINMATCHER_HXX) +#define RESIP_EXTENDEDDOMAINMATCHER_HXX + +#include "resip/stack/BasicDomainMatcher.hxx" +#include "rutil/Data.hxx" +#include "rutil/HashMap.hxx" +#include "rutil/ParseBuffer.hxx" + +namespace resip +{ + +class ExtendedDomainMatcher : public BasicDomainMatcher +{ + + public: + + ExtendedDomainMatcher(); + virtual ~ExtendedDomainMatcher(); + virtual bool isMyDomain(const Data& domain) const; + virtual void addDomainSuffix(const Data& domainSuffix); + virtual void removeDomainSuffix(const Data& domainSuffix); + + private: + + typedef std::set DomainSuffixList; + DomainSuffixList mDomainSuffixList; +}; + +} + + +#endif + +/* ==================================================================== + * + * Copyright 2017 Daniel Pocock http://danielpocock.com All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/resip/stack/ExtensionHeader.cxx b/src/libs/resiprocate/resip/stack/ExtensionHeader.cxx index ce5571c8..62a3b8cb 100644 --- a/src/libs/resiprocate/resip/stack/ExtensionHeader.cxx +++ b/src/libs/resiprocate/resip/stack/ExtensionHeader.cxx @@ -6,7 +6,7 @@ #include "HeaderTypes.hxx" #include "rutil/Logger.hxx" -#include +#include "rutil/ResipAssert.h" #include "rutil/ParseBuffer.hxx" #define RESIPROCATE_SUBSYSTEM Subsystem::SIP @@ -16,13 +16,15 @@ using namespace resip; ExtensionHeader::ExtensionHeader(const char* name) : mName(name) { - assert(name); + resip_assert(name); if (mName.empty()) { - assert(false); + resip_assert(false); throw Exception("Empty extension header",__FILE__,__LINE__); } - assert(Headers::getType(mName.data(), (int)mName.size()) == Headers::UNKNOWN); + if (Headers::getType(mName.data(), (int)mName.size()) != Headers::UNKNOWN) { + throw Exception("Extension header name is not unknown",__FILE__,__LINE__); + } } ExtensionHeader::ExtensionHeader(const Data& name) @@ -30,10 +32,12 @@ ExtensionHeader::ExtensionHeader(const Data& name) { if (mName.empty()) { - assert(false); + resip_assert(false); throw Exception("Empty extension header",__FILE__,__LINE__); } - assert(Headers::getType(mName.data(), (int)mName.size()) == Headers::UNKNOWN); + if (Headers::getType(mName.data(), (int)mName.size()) != Headers::UNKNOWN) { + throw Exception("Extension header name is not unknown",__FILE__,__LINE__); + } } const Data& diff --git a/src/libs/resiprocate/resip/stack/ExtensionParameter.cxx b/src/libs/resiprocate/resip/stack/ExtensionParameter.cxx index 4a91b9c7..a4b10820 100644 --- a/src/libs/resiprocate/resip/stack/ExtensionParameter.cxx +++ b/src/libs/resiprocate/resip/stack/ExtensionParameter.cxx @@ -5,7 +5,7 @@ #include "ExtensionParameter.hxx" #include "ParameterTypeEnums.hxx" -#include +#include "rutil/ResipAssert.h" #include using namespace resip; @@ -13,7 +13,11 @@ using namespace resip; ExtensionParameter::ExtensionParameter(const Data& name) : mName(name) { - assert(!mName.empty()); + if (mName.empty()) + { + resip_assert(false); + throw Exception("Empty extension parameter",__FILE__,__LINE__); + } } const Data& @@ -22,6 +26,16 @@ ExtensionParameter::getName() const return mName; } +ExtensionParameter::Exception::Exception(const Data& msg, const Data& file, const int line) + : BaseException(msg, file, line) +{} + +const char* +ExtensionParameter::Exception::name() const +{ + return "ExtensionParameter::Exception"; +} + /* ==================================================================== * The Vovida Software License, Version 1.0 * diff --git a/src/libs/resiprocate/resip/stack/ExtensionParameter.hxx b/src/libs/resiprocate/resip/stack/ExtensionParameter.hxx index 7bd83568..aea5489f 100644 --- a/src/libs/resiprocate/resip/stack/ExtensionParameter.hxx +++ b/src/libs/resiprocate/resip/stack/ExtensionParameter.hxx @@ -1,8 +1,7 @@ #ifndef RESIP_ExtensionParameter_hxx #define RESIP_ExtensionParameter_hxx -#include "rutil/Data.hxx" - +#include "rutil/BaseException.hxx" namespace resip { @@ -13,6 +12,13 @@ class ExtensionParameter const Data& getName() const; + class Exception : public BaseException + { + public: + Exception(const Data& msg, const Data& file, const int line); + const char* name() const; + }; + private: const Data mName; }; diff --git a/src/libs/resiprocate/resip/stack/GenericPidfContents.cxx b/src/libs/resiprocate/resip/stack/GenericPidfContents.cxx new file mode 100644 index 00000000..2ec8a14c --- /dev/null +++ b/src/libs/resiprocate/resip/stack/GenericPidfContents.cxx @@ -0,0 +1,890 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include +#include + +#include "resip/stack/GenericPidfContents.hxx" +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Symbols.hxx" +#include "rutil/XMLCursor.hxx" +#include "rutil/Logger.hxx" +#include "rutil/Inserter.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +const static Data BasePidfNamespaceUri("urn:ietf:params:xml:ns:pidf"); + +bool +GenericPidfContents::init() +{ + static ContentsFactory factory; + (void)factory; + return true; +} + +const GenericPidfContents GenericPidfContents::Empty; + +GenericPidfContents::GenericPidfContents() + : Contents(getStaticType()), mSimplePresenceExtracted(false) +{ +} + +GenericPidfContents::GenericPidfContents(const Mime& contentType) + : Contents(getStaticType()), mSimplePresenceExtracted(false) +{ +} + +GenericPidfContents::GenericPidfContents(const HeaderFieldValue& hfv, const Mime& contentsType) + : Contents(hfv, contentsType), mSimplePresenceExtracted(false) +{ +} + +GenericPidfContents& +GenericPidfContents::operator=(const GenericPidfContents& rhs) +{ + if (this != &rhs) + { + Contents::operator=(rhs); + + // clear any data then merge in new stuff + reset(); + mergeNoCheckParse(rhs); + } + return *this; +} + +GenericPidfContents::GenericPidfContents(const GenericPidfContents& rhs) + : Contents(rhs), mSimplePresenceExtracted(false) +{ + // merge in new stuff + mergeNoCheckParse(rhs); +} + +GenericPidfContents::~GenericPidfContents() +{ + reset(); +} + +void +GenericPidfContents::reset() +{ + // Cleanup Node Memory recursively + cleanupNodeMemory(mRootNodes); + + // Clear namespace map + mNamespaces.clear(); + + mRootPidfNamespacePrefix.clear(); + mEntity.host().clear(); + mEntity.user().clear(); + + clearSimplePresenceInfo(); +} + +void GenericPidfContents::clearSimplePresenceInfo() +{ + SimplePresenceInfoList::iterator itSPList = mSimplePresenceInfoList.begin(); + for (; itSPList != mSimplePresenceInfoList.end(); itSPList++) + { + delete *itSPList; + } + mSimplePresenceInfoList.clear(); + mSimplePresenceExtracted = false; +} + +void +GenericPidfContents::cleanupNodeMemory(NodeList& nodeList) +{ + // Cleanup Node Memory recursively + NodeList::iterator itNode = nodeList.begin(); + for (; itNode != nodeList.end(); itNode++) + { + cleanupNodeMemory((*itNode)->mChildren); + delete *itNode; + } + nodeList.clear(); +} + +Contents* +GenericPidfContents::clone() const +{ + return new GenericPidfContents(*this); +} + +const Mime& +GenericPidfContents::getStaticType() +{ + static Mime type("application","pidf+xml"); + return type; +} + +EncodeStream& +GenericPidfContents::encodeParsed(EncodeStream& str) const +{ + str << "" << Symbols::CRLF; + str << "<" << mRootPidfNamespacePrefix << "presence "; + NamespaceMap::const_iterator itNs = mNamespaces.begin(); + bool first = true; + for (; itNs != mNamespaces.end(); itNs++) + { + if (first) + { + first = false; + str << "xmlns"; + } + else + { + str << " xmlns"; + } + if (!itNs->second.empty()) // Check if prefix is not-empty + { + str << ":" << itNs->second.substr(0, itNs->second.size() - 1); // remove trailing ":" + } + str << "=\"" << itNs->first << "\"" << Symbols::CRLF; + } + str << " entity=\"" << mEntity << "\">" << Symbols::CRLF; + NodeList::const_iterator itNode = mRootNodes.begin(); + Data indent(" "); + for (; itNode != mRootNodes.end(); itNode++) + { + (*itNode)->encode(str, indent); + } + str << "" << Symbols::CRLF; + + return str; +} + +void +GenericPidfContents::parse(ParseBuffer& pb) +{ + mSimplePresenceExtracted = false; + + XMLCursor xml(pb); + const XMLCursor::AttributeMap& attr = xml.getAttributes(); + XMLCursor::AttributeMap::const_iterator itAttr = attr.begin(); + for (; itAttr != attr.end(); itAttr++) + { + if (itAttr->first.prefix("xmlns")) + { + Data prefix; + ParseBuffer pb(itAttr->first); + pb.skipToChar(Symbols::COLON[0]); + if (!pb.eof()) + { + pb.skipChar(); + const char* anchor = pb.position(); + pb.skipToEnd(); + pb.data(prefix, anchor); + prefix += Symbols::COLON; + } + if (isEqualNoCase(itAttr->second, BasePidfNamespaceUri)) + { + mRootPidfNamespacePrefix = prefix; + } + + mNamespaces[itAttr->second] = prefix; + } + else if (itAttr->first == "entity") + { + mEntity = Uri(itAttr->second); // can throw! + } + else + { + DebugLog(<< "Unknown root attribute: " << itAttr->first << "=" << itAttr->second); + } + } + + // Ensure root presence node is present + if (xml.getTag() == mRootPidfNamespacePrefix + Symbols::Presence) + { + if (xml.firstChild()) + { + do + { + parseChildren(xml, mRootNodes); + } while (xml.nextSibling()); + xml.parent(); + } + } + else + { + // TODO Throw? + DebugLog(<< "Aborting parse, root presence node missing: " << mRootPidfNamespacePrefix + Symbols::Presence); + } +} + +void +GenericPidfContents::parseChildren(XMLCursor& xml, NodeList& nodeList) +{ + Node* node = new Node(); + node->mAttributes = xml.getAttributes(); // !slg! yuck - yes we are copying memory for attributes + node->mValue.duplicate(xml.getValue()); // use Data::duplicate to avoid copying memory + ParseBuffer pb(xml.getTag()); + const char* anchor = pb.position(); + pb.skipToChar(Symbols::COLON[0]); + if (!pb.eof()) + { + pb.skipChar(); + pb.data(node->mNamespacePrefix, anchor); + anchor = pb.position(); + pb.skipToEnd(); + pb.data(node->mTag, anchor); + } + else + { + // No namespace prefix + node->mTag.duplicate(xml.getTag()); // use Data::duplicate to avoid copying memory + } + + if (node->mValue.empty() && xml.firstChild()) + { + do + { + if (!xml.getValue().empty()) + { + node->mValue.duplicate(xml.getValue()); // use Data::duplicate to avoid copying memory + } + else + { + parseChildren(xml, node->mChildren); + } + } while (xml.nextSibling()); + xml.parent(); + } + nodeList.push_back(node); +} + +EncodeStream& +GenericPidfContents::Node::encodeAttributes(EncodeStream& str) const +{ + AttributeMap::const_iterator itAttrib = mAttributes.begin(); + for (; itAttrib != mAttributes.end(); itAttrib++) + { + str << " " << itAttrib->first << "=\"" << itAttrib->second << "\""; + } + return str; +} + +EncodeStream& +GenericPidfContents::Node::encode(EncodeStream& str, Data indent) const +{ + if (!mTag.empty()) + { + if (mChildren.size() == 0) + { + if (mValue.empty()) + { + str << indent << "<" << mNamespacePrefix << mTag; + encodeAttributes(str); + str << "/>" << Symbols::CRLF; + } + else + { + str << indent << "<" << mNamespacePrefix << mTag; + encodeAttributes(str); + str << ">" << mValue << "" << Symbols::CRLF; + } + } + // The following else collapses simple single nodes (no attributes or values) to one line: ie: + // + else if (mChildren.size() == 1 && mAttributes.empty() && + mChildren.front()->mValue.empty() && mChildren.front()->mAttributes.empty() && mChildren.front()->mChildren.size() == 0) + { + str << indent << "<" << mNamespacePrefix << mTag << "><" << mChildren.front()->mNamespacePrefix; + str << mChildren.front()->mTag << "/>" << Symbols::CRLF; + } + else + { + str << indent << "<" << mNamespacePrefix << mTag; + encodeAttributes(str); + str << ">" << Symbols::CRLF; + NodeList::const_iterator itNode = mChildren.begin(); + for (; itNode != mChildren.end(); itNode++) + { + (*itNode)->encode(str, indent + " "); + } + str << indent << "" << Symbols::CRLF; + } + } + return str; +} + +void +GenericPidfContents::Node::copy(const Node& rhs, HashMap* namespacePrefixCorrections) +{ + if (namespacePrefixCorrections) + { + // Check if namespace should be corrected + HashMap::iterator itNsCorr = namespacePrefixCorrections->find(rhs.mNamespacePrefix); + if (itNsCorr != namespacePrefixCorrections->end()) + { + mNamespacePrefix = itNsCorr->second; + } + else + { + mNamespacePrefix = rhs.mNamespacePrefix; + } + } + else + { + mNamespacePrefix = rhs.mNamespacePrefix; + } + mTag = rhs.mTag; + mAttributes = rhs.mAttributes; + mValue = rhs.mValue; + NodeList::const_iterator itNode = rhs.mChildren.begin(); + for (; itNode != rhs.mChildren.end(); itNode++) + { + Node* node = new Node(); + node->copy(*(*itNode), namespacePrefixCorrections); + mChildren.push_back(node); + } +} + +bool +GenericPidfContents::merge(const GenericPidfContents& other) +{ + // Ensure both sides are parsed if not already + checkParsed(); + other.checkParsed(); + return mergeNoCheckParse(other); +} + +void +GenericPidfContents::setRootNodes(const NodeList& nodeList) +{ + mRootNodes.clear(); + mRootNodes = nodeList; +} + +const Data& +GenericPidfContents::getSubNodeValue(Node* node, const Data& tag) +{ + NodeList::iterator it = node->mChildren.begin(); + for (; it != node->mChildren.end(); it++) + { + if ((*it)->mTag == tag) + { + return (*it)->mValue; + } + } + return Data::Empty; +} + +bool +GenericPidfContents::mergeNoCheckParse(const GenericPidfContents& other) +{ + mSimplePresenceExtracted = false; + + // Validate entity user and host - we allow mismatched schemes + if (mEntity.host().empty()) + { + mEntity = other.mEntity; + } + else if(mEntity.user() != other.mEntity.user() || + mEntity.host() != other.mEntity.host()) + { + DebugLog(<< "Merge failed, entities do not match: " << mEntity << ", other=" << other.mEntity); + return false; + } + + HashMap namespacePrefixCorrections; // other/old prefix name, new/dest prefix name + + // Copy over namespaces - looking for mismatched prefixes + bool checkNamespaceMismatches = mNamespaces.size() > 0; + NamespaceMap::const_iterator itOtherNs = other.mNamespaces.begin(); + for(; itOtherNs != other.mNamespaces.end(); itOtherNs++) + { + // Check if namespace is already in list and if so - verify prefix will match + bool found = false; + if (checkNamespaceMismatches) + { + NamespaceMap::iterator itNs = mNamespaces.find(itOtherNs->first); + if (itNs != mNamespaces.end()) + { + if (itNs->second != itOtherNs->second) + { + // Prefix used for same namespace does not match + namespacePrefixCorrections[itOtherNs->second] = itNs->second; + } + found = true; + } + } + if(!found) + { + mNamespaces[itOtherNs->first] = itOtherNs->second; // Copy over + } + } + // If we didn't check for namespace mismatches then we didn't have any namespaces + // to start with, which means we didn't have a root namespace - set it now + if (!checkNamespaceMismatches) + { + mRootPidfNamespacePrefix = other.mRootPidfNamespacePrefix; + } + + // Merge root presence nodes + bool checkMatches = mRootNodes.size() > 0; + NodeList::const_iterator itOtherNode = other.mRootNodes.begin(); + for(; itOtherNode != other.mRootNodes.end(); itOtherNode++) + { + // If there is an ID attribute then see if tag/id combo lives already in local list + bool matchFound = false; + if (checkMatches) + { + Node::AttributeMap::iterator itOtherAttrib = (*itOtherNode)->mAttributes.find("id"); + if (itOtherAttrib != (*itOtherNode)->mAttributes.end()) + { + NodeList::iterator itNode = mRootNodes.begin(); + for (; itNode != mRootNodes.end(); itNode++) + { + if ((*itNode)->mTag == (*itOtherNode)->mTag) + { + // Node found - check for id match + Node::AttributeMap::iterator itAttrib = (*itNode)->mAttributes.find("id"); + if (itAttrib != (*itNode)->mAttributes.end()) + { + if (itOtherAttrib->second == itAttrib->second) // Check if Id's match + { + // compare timestamps + const Data& ts1 = getSubNodeValue((*itNode), "timestamp"); + const Data& ts2 = getSubNodeValue((*itOtherNode), "timestamp"); + // Note: to compare timestamps we use a string compare and rely on properties from RFC3339 (section 5.1) with + // the assumption that same id items will generate timestamps in the same timezone and timezone format + if (ts1.empty() || ts2.empty() || ts2 >= ts1) + { + cleanupNodeMemory((*itNode)->mChildren); + (*itNode)->copy(*(*itOtherNode), &namespacePrefixCorrections); + } + matchFound = true; + break; + } + } + } + } + } + } + if (!matchFound) + { + Node* node = new Node(); + node->copy(*(*itOtherNode), namespacePrefixCorrections.size() > 0 ? &namespacePrefixCorrections : 0); + mRootNodes.push_back(node); + } + } + return true; +} + +void +GenericPidfContents::setEntity(const Uri& entity) +{ + checkParsed(); + mEntity = entity; +} + +const Uri& +GenericPidfContents::getEntity() const +{ + checkParsed(); + return mEntity; +} + +void +GenericPidfContents::addNamespace(const Data& uri, const Data& prefix) +{ + checkParsed(); + Data adjustedPrefix(prefix); + // Add colon to end if missing if prefix was provided + if (!prefix.empty() && !prefix.postfix(Symbols::COLON)) + { + adjustedPrefix += Symbols::COLON; + } + if (isEqualNoCase(uri, BasePidfNamespaceUri)) + { + mRootPidfNamespacePrefix = adjustedPrefix; + } + mNamespaces[uri] = adjustedPrefix; +} + +void +GenericPidfContents::setSimplePresenceTupleNode(const Data& id, + bool online, + const Data& timestamp, + const Data& note, + const Data& contact, + const Data& contactPriority) +{ + // Make sure we have extract any existing simple presence info + extractSimplePresenceInfo(); + + if (mNamespaces.empty()) + { + // Add default namespace + addNamespace(BasePidfNamespaceUri, Data::Empty); // no custom prefix + } + + // See if node exists and if so delete it - otherwise add new + bool foundExisting = false; + NodeList::iterator it = mRootNodes.begin(); + for(; it != mRootNodes.end(); it++) + { + if((*it)->mTag == "tuple") + { + Node::AttributeMap::iterator itAttrib = (*it)->mAttributes.find("id"); + if(itAttrib != (*it)->mAttributes.end()) + { + if(itAttrib->second == id) + { + foundExisting = true; + break; + } + } + } + } + + Node* tupleNode; + if(foundExisting) + { + // Remove all children and add back, below + cleanupNodeMemory((*it)->mChildren); + tupleNode = (*it); + } + else + { + tupleNode = new Node(); + tupleNode->mNamespacePrefix = mRootPidfNamespacePrefix; + tupleNode->mTag = "tuple"; + tupleNode->mAttributes["id"] = id; + } + + // Add Status Node with Basic subnode + Node* statusNode = new Node(); + statusNode->mNamespacePrefix = mRootPidfNamespacePrefix; + statusNode->mTag = "status"; + Node* basicNode = new Node(); + basicNode->mNamespacePrefix = mRootPidfNamespacePrefix; + basicNode->mTag = "basic"; + basicNode->mValue = online ? "open" : "closed"; + statusNode->mChildren.push_back(basicNode); + tupleNode->mChildren.push_back(statusNode); + + // Add Contact node if required + if (!contact.empty()) + { + Node* contactNode = new Node(); + contactNode->mNamespacePrefix = mRootPidfNamespacePrefix; + contactNode->mTag = "contact"; + contactNode->mValue = contact; + if (!contactPriority.empty()) + { + contactNode->mAttributes["priority"] = contactPriority; + } + tupleNode->mChildren.push_back(contactNode); + } + + // Add Note node if required + if (!note.empty()) + { + Node* noteNode = new Node(); + noteNode->mNamespacePrefix = mRootPidfNamespacePrefix; + noteNode->mTag = "note"; + noteNode->mValue = note; + tupleNode->mChildren.push_back(noteNode); + } + + // Add Timestamp node if required + if (!timestamp.empty()) + { + Node* timestampNode = new Node(); + timestampNode->mNamespacePrefix = mRootPidfNamespacePrefix; + timestampNode->mTag = "timestamp"; + timestampNode->mValue = timestamp; + tupleNode->mChildren.push_back(timestampNode); + } + + if (!foundExisting) + { + mRootNodes.push_back(tupleNode); + } + + // store info in list - if TupleId exists already then update it, otherwise add new + foundExisting = false; // reuse flag from above + SimplePresenceInfoList::iterator itSPList = mSimplePresenceInfoList.begin(); + for (; itSPList != mSimplePresenceInfoList.end(); itSPList++) + { + if ((*itSPList)->mTupleId == id) + { + (*itSPList)->mOnline = online; + (*itSPList)->mTimestamp = timestamp; + (*itSPList)->mNote = note; + (*itSPList)->mContact = contact; + (*itSPList)->mContactPriority = contactPriority; + foundExisting = true; + } + } + if (!foundExisting) + { + SimplePresenceInfo* info = new SimplePresenceInfo; + info->mTupleId = id; + info->mOnline = online; + info->mTimestamp = timestamp; + info->mNote = note; + info->mContact = contact; + info->mContactPriority = contactPriority; + mSimplePresenceInfoList.push_back(info); + } + mSimplePresenceExtracted = true; +} + +const Data& +GenericPidfContents::getSimplePresenceTupleId() +{ + checkParsed(); + extractSimplePresenceInfo(); + if (mSimplePresenceInfoList.empty()) + { + return Data::Empty; + } + else + { + return mSimplePresenceInfoList.front()->mTupleId; + } +} + +const bool +GenericPidfContents::getSimplePresenceOnline() +{ + checkParsed(); + extractSimplePresenceInfo(); + if (mSimplePresenceInfoList.empty()) + { + return false; + } + else + { + return mSimplePresenceInfoList.front()->mOnline; + } +} + +const Data& +GenericPidfContents::getSimplePresenceTimestamp() +{ + checkParsed(); + extractSimplePresenceInfo(); + if (mSimplePresenceInfoList.empty()) + { + return Data::Empty; + } + else + { + return mSimplePresenceInfoList.front()->mTimestamp; + } +} + +const Data& +GenericPidfContents::getSimplePresenceNote() +{ + checkParsed(); + extractSimplePresenceInfo(); + if (mSimplePresenceInfoList.empty()) + { + return Data::Empty; + } + else + { + return mSimplePresenceInfoList.front()->mNote; + } +} + +const Data& +GenericPidfContents::getSimplePresenceContact() +{ + checkParsed(); + extractSimplePresenceInfo(); + if (mSimplePresenceInfoList.empty()) + { + return Data::Empty; + } + else + { + return mSimplePresenceInfoList.front()->mContact; + } +} + +const Data& +GenericPidfContents::getSimplePresenceContactPriority() +{ + checkParsed(); + extractSimplePresenceInfo(); + if (mSimplePresenceInfoList.empty()) + { + return Data::Empty; + } + else + { + return mSimplePresenceInfoList.front()->mContactPriority; + } +} + +void +GenericPidfContents::extractSimplePresenceInfo() +{ + if (!mSimplePresenceExtracted) + { + clearSimplePresenceInfo(); + + // Iterate through root nodes and find first tuple + NodeList::const_iterator itNode = mRootNodes.begin(); + for (; itNode != mRootNodes.end(); itNode++) + { + if ((*itNode)->mTag == "tuple") + { + Node::AttributeMap::iterator itAttrib = (*itNode)->mAttributes.find("id"); + if (itAttrib != (*itNode)->mAttributes.end()) + { + SimplePresenceInfo* info = new SimplePresenceInfo; + info->mTupleId = itAttrib->second; + // iterate through children looking for nodes we want + NodeList::const_iterator itTupleChild = (*itNode)->mChildren.begin(); + for (; itTupleChild != (*itNode)->mChildren.end(); itTupleChild++) + { + if ((*itTupleChild)->mTag == "status") + { + // iterate through children looking for basic node + NodeList::const_iterator itStatusChild = (*itTupleChild)->mChildren.begin(); + for (; itStatusChild != (*itTupleChild)->mChildren.end(); itStatusChild++) + { + if ((*itStatusChild)->mTag == "basic") + { + info->mOnline = (*itStatusChild)->mValue == "open"; + break; + } + } + } + else if (info->mContact.empty() && (*itTupleChild)->mTag == "contact") + { + info->mContact = (*itTupleChild)->mValue; + Node::AttributeMap::iterator itAttrib = (*itTupleChild)->mAttributes.find("priority"); + if (itAttrib != (*itTupleChild)->mAttributes.end()) + { + info->mContactPriority = itAttrib->second; + } + } + else if (info->mNote.empty() && (*itTupleChild)->mTag == "note") + { + info->mNote = (*itTupleChild)->mValue; + } + else if (info->mTimestamp.empty() && (*itTupleChild)->mTag == "timestamp") + { + info->mTimestamp = (*itTupleChild)->mValue; + } + } + // Just push on the back, we could consider checking if the TupleId already exists before + // adding, but we are assuming unique tupleid entries in the document for now. + mSimplePresenceInfoList.push_back(info); + } + } + } + mSimplePresenceExtracted = true; + } +} + +Data +GenericPidfContents::generateNowTimestampData() +{ + time_t now; + time(&now); + return generateTimestampData(now); +} + +static void pad2(const int x, DataStream& str) +{ + if (x < 10) + { + str << Symbols::ZERO[0]; + } + str << x; +} + +Data +GenericPidfContents::generateTimestampData(time_t datetime) +{ + struct tm gmt; +#if defined(WIN32) || defined(__sun) + struct tm *gmtp = gmtime(&datetime); + if (gmtp == 0) + { + int e = getErrno(); + DebugLog(<< "Failed to convert to gmt: " << strerror(e)); + return Data::Empty; + } + memcpy(&gmt, gmtp, sizeof(gmt)); +#else + if (gmtime_r(&datetime, &gmt) == 0) + { + int e = getErrno(); + DebugLog(<< "Failed to convert to gmt: " << strerror(e)); + return Data::Empty; + } +#endif + + Data timestamp; + { + DataStream ds(timestamp); + ds << gmt.tm_year + 1900 << "-"; + pad2(gmt.tm_mon + 1, ds); + ds << "-"; + pad2(gmt.tm_mday, ds); + ds << "T"; + pad2(gmt.tm_hour, ds); + ds << ":"; + pad2(gmt.tm_min, ds); + ds << ":"; + pad2(gmt.tm_sec, ds); + ds << "Z"; + } + return timestamp; +} + +/* ==================================================================== +* +* Copyright (c) 2015 SIP Spectrum, Inc. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* +* 3. Neither the name of the author(s) nor the names of any contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +* +* ==================================================================== +* +*/ +/* +* vi: set shiftwidth=3 expandtab: +*/ diff --git a/src/libs/resiprocate/resip/stack/GenericPidfContents.hxx b/src/libs/resiprocate/resip/stack/GenericPidfContents.hxx new file mode 100644 index 00000000..0b3e1f03 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/GenericPidfContents.hxx @@ -0,0 +1,181 @@ +#if !defined(RESIP_GENERICPIDFCONTENTS_HXX) +#define RESIP_GENERICPIDFCONTENTS_HXX + +#include +#include + +#include "resip/stack/Contents.hxx" +#include "rutil/Data.hxx" +#include "rutil/HashMap.hxx" +#include "resip/stack/Uri.hxx" +#include "rutil/HeapInstanceCounter.hxx" +#include "resip/stack/QValue.hxx" + +namespace resip +{ + +class XMLCursor; + +/** + SIP body type for holding PIDF contents (MIME content-type application/pidf+xml). + This version is used to be able to extract and manipulate all Pidf contents and + contained extensions (ie: rpid, data-model, cipid, etc.) in a generic manner. +*/ +class GenericPidfContents : public Contents +{ +public: + + static const GenericPidfContents Empty; + + RESIP_HeapCount(GenericPidfContents); + GenericPidfContents(const Mime& contentType); + GenericPidfContents(); + GenericPidfContents(const HeaderFieldValue& hfv, const Mime& contentType); + GenericPidfContents(const GenericPidfContents& rhs); + virtual ~GenericPidfContents(); + virtual GenericPidfContents& operator=(const GenericPidfContents& rhs); + + /** @brief duplicate an GenericPidfContents object + @return pointer to a new GenericPidfContents object + **/ + virtual Contents* clone() const; + static const Mime& getStaticType(); + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + virtual void parse(ParseBuffer& pb); + + void setEntity(const Uri& entity); + const Uri& getEntity() const; + + void addNamespace(const Data& uri, const Data& prefix); + typedef HashMap NamespaceMap; // first is Uri, second is prefix (which includes a trailing ":") + const NamespaceMap& getNamespaces() const { checkParsed(); return mNamespaces; } + // Note: you set the RootPidfNamesapces prefix by adding the generic Pidf + // namespace urn:ietf:params:xml:ns:pidf via addNamespace + const Data& getRootPidfNamespacePrefix() const { checkParsed(); return mRootPidfNamespacePrefix; } + + class Node; + typedef std::list NodeList; + class Node + { + public: + Data mNamespacePrefix; + Data mTag; + typedef HashMap AttributeMap; + AttributeMap mAttributes; + Data mValue; + NodeList mChildren; + + void copy(const Node& rhs, HashMap* namespacePrefixCorrections); + + EncodeStream& encodeAttributes(EncodeStream& str) const; + EncodeStream& encode(EncodeStream& str, Data indent) const; + }; + const NodeList& getRootNodes() const { checkParsed(); return mRootNodes; } + void setRootNodes(const NodeList& nodeList); + + // Helpers for users of this class + static const Data& getSubNodeValue(Node* node, const Data& tag); + static Data generateNowTimestampData(); + static Data generateTimestampData(time_t datetime); + + // You should be adding the namespace first manually if you want a custom prefix + void setSimplePresenceTupleNode(const Data& id, + bool online, + const Data& timestamp = Data::Empty, + const Data& note = Data::Empty, + const Data& contact = Data::Empty, + const Data& contactPriority = Data::Empty); + + // Use these methods to get simple presence info from a document that only contains one Tuple. + // If multiple tuples are in this document, then these API's will only return data from the first + // Tuple in the document. If you require access to the simple presence of all tuples, then use the + // getSimplePresenceList API below. + const Data& getSimplePresenceTupleId(); + const bool getSimplePresenceOnline(); + const Data& getSimplePresenceTimestamp(); + const Data& getSimplePresenceNote(); + const Data& getSimplePresenceContact(); + const Data& getSimplePresenceContactPriority(); + + class SimplePresenceInfo + { + public: + SimplePresenceInfo() : mOnline(false) {} + Data mTupleId; + bool mOnline; + Data mTimestamp; + Data mNote; + Data mContact; + Data mContactPriority; + }; + typedef std::list SimplePresenceInfoList; // Use pointers to avoid copying when adding + const SimplePresenceInfoList& getSimplePresenceList() { checkParsed(); extractSimplePresenceInfo(); return mSimplePresenceInfoList; } + + static bool init(); + + // combine pidfs + bool merge(const GenericPidfContents& other); + +private: + + NamespaceMap mNamespaces; + Data mRootPidfNamespacePrefix; // includes trailing ":" + Uri mEntity; + + // Simple Presence Info + SimplePresenceInfoList mSimplePresenceInfoList; + bool mSimplePresenceExtracted; + + NodeList mRootNodes; + void parseChildren(XMLCursor& xml, NodeList& nodeList); + void cleanupNodeMemory(NodeList& nodeList); + void reset(); + bool mergeNoCheckParse(const GenericPidfContents& other); + void extractSimplePresenceInfo(); + void clearSimplePresenceInfo(); +}; + +static bool invokeGenericPidfContentsInit = GenericPidfContents::init(); + +} + +#endif + +/* ==================================================================== +* +* Copyright (c) 2015 SIP Spectrum, Inc. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* +* 3. Neither the name of the author(s) nor the names of any contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +* +* ==================================================================== +* +*/ +/* +* vi: set shiftwidth=3 expandtab: +*/ diff --git a/src/libs/resiprocate/resip/stack/HEPSipMessageLoggingHandler.cxx b/src/libs/resiprocate/resip/stack/HEPSipMessageLoggingHandler.cxx new file mode 100644 index 00000000..ef1bb6f5 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/HEPSipMessageLoggingHandler.cxx @@ -0,0 +1,93 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include + +#include "resip/stack/HEPSipMessageLoggingHandler.hxx" +#include "rutil/hep/ResipHep.hxx" +#include "rutil/DataStream.hxx" +#include "rutil/Logger.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +HEPSipMessageLoggingHandler::HEPSipMessageLoggingHandler(SharedPtr agent) + : mHepAgent(agent) +{ + if(!agent.get()) + { + ErrLog(<<"agent must not be NULL"); + throw std::runtime_error("agent must not be NULL"); + } +} + +HEPSipMessageLoggingHandler::~HEPSipMessageLoggingHandler() +{ +} + +void +HEPSipMessageLoggingHandler::outboundMessage(const Tuple &source, const Tuple &destination, const SipMessage &msg) +{ + sendToHOMER(source, destination, msg); +} + +void +HEPSipMessageLoggingHandler::outboundRetransmit(const Tuple &source, const Tuple &destination, const SendData &data) +{ + // FIXME - implement for SendData +} + +void +HEPSipMessageLoggingHandler::inboundMessage(const Tuple& source, const Tuple& destination, const SipMessage &msg) +{ + sendToHOMER(source, destination, msg); +} + +void +HEPSipMessageLoggingHandler::sendToHOMER(const Tuple& source, const Tuple& destination, const SipMessage &msg) +{ + mHepAgent->sendToHOMER(source.getType(), + source.toGenericIPAddress(), destination.toGenericIPAddress(), + HepAgent::SIP, msg, + msg.exists(h_CallId) ? msg.header(h_CallId).value() : Data::Empty); +} + +/* ==================================================================== + * + * Copyright 2016 Daniel Pocock http://danielpocock.com All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ diff --git a/src/libs/resiprocate/resip/stack/HEPSipMessageLoggingHandler.hxx b/src/libs/resiprocate/resip/stack/HEPSipMessageLoggingHandler.hxx new file mode 100644 index 00000000..b295afd3 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/HEPSipMessageLoggingHandler.hxx @@ -0,0 +1,69 @@ +#if !defined(RESIP_HEPSIPMESSAGELOGGINGHANDLER_HXX) +#define RESIP_HEPSIPMESSAGELOGGINGHANDLER_HXX + +#include "resip/stack/SipMessage.hxx" +#include "resip/stack/Transport.hxx" +#include "resip/stack/Tuple.hxx" +#include "rutil/Data.hxx" +#include "rutil/Socket.hxx" +#include "rutil/hep/HepAgent.hxx" + +namespace resip +{ + +class HEPSipMessageLoggingHandler : public Transport::SipMessageLoggingHandler +{ + public: + HEPSipMessageLoggingHandler(SharedPtr agent); + virtual ~HEPSipMessageLoggingHandler(); + virtual void outboundMessage(const Tuple &source, const Tuple &destination, const SipMessage &msg); + virtual void outboundRetransmit(const Tuple &source, const Tuple &destination, const SendData &data); + virtual void inboundMessage(const Tuple& source, const Tuple& destination, const SipMessage &msg); + protected: + virtual void sendToHOMER(const Tuple& source, const Tuple& destination, const SipMessage &msg); + private: + SharedPtr mHepAgent; +}; + + +} + +#endif + + +/* ==================================================================== + * + * Copyright 2016 Daniel Pocock http://danielpocock.com All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ diff --git a/src/libs/resiprocate/resip/stack/HeaderFieldValue.cxx b/src/libs/resiprocate/resip/stack/HeaderFieldValue.cxx index e12f31fb..69a37ea2 100644 --- a/src/libs/resiprocate/resip/stack/HeaderFieldValue.cxx +++ b/src/libs/resiprocate/resip/stack/HeaderFieldValue.cxx @@ -105,6 +105,18 @@ HeaderFieldValue::HeaderFieldValue(const HeaderFieldValue& hfv, NoOwnershipEnum // ?bwc? assert(!hfv.mMine); ? } +HeaderFieldValue& +HeaderFieldValue::swap(HeaderFieldValue& orig) +{ + if (this != &orig) + { + std::swap(mField, orig.mField); + std::swap(mFieldLength, orig.mFieldLength); + std::swap(mMine, orig.mMine); + } + return *this; +} + HeaderFieldValue::~HeaderFieldValue() { if (mMine) diff --git a/src/libs/resiprocate/resip/stack/HeaderFieldValue.hxx b/src/libs/resiprocate/resip/stack/HeaderFieldValue.hxx index 393e3330..6b2efad7 100644 --- a/src/libs/resiprocate/resip/stack/HeaderFieldValue.hxx +++ b/src/libs/resiprocate/resip/stack/HeaderFieldValue.hxx @@ -43,6 +43,7 @@ class HeaderFieldValue HeaderFieldValue(const HeaderFieldValue& hfv, NoOwnershipEnum); HeaderFieldValue& operator=(const HeaderFieldValue&); HeaderFieldValue& copyWithPadding(const HeaderFieldValue& rhs); + HeaderFieldValue& swap(HeaderFieldValue& orig); ~HeaderFieldValue(); diff --git a/src/libs/resiprocate/resip/stack/HeaderFieldValueList.cxx b/src/libs/resiprocate/resip/stack/HeaderFieldValueList.cxx index 0dd9190a..db00d3ab 100644 --- a/src/libs/resiprocate/resip/stack/HeaderFieldValueList.cxx +++ b/src/libs/resiprocate/resip/stack/HeaderFieldValueList.cxx @@ -3,7 +3,7 @@ #endif -#include +#include "rutil/ResipAssert.h" #include "resip/stack/HeaderFieldValue.hxx" #include "resip/stack/HeaderFieldValueList.hxx" @@ -139,7 +139,7 @@ HeaderFieldValueList::encode(const Data& headerName, EncodeStream& str) const EncodeStream& HeaderFieldValueList::encodeEmbedded(const Data& headerName, EncodeStream& str) const { - assert(!headerName.empty()); + resip_assert(!headerName.empty()); if (getParserContainer() != 0) { diff --git a/src/libs/resiprocate/resip/stack/HeaderHash.gperf b/src/libs/resiprocate/resip/stack/HeaderHash.gperf index b8c72eb5..4bb04586 100644 --- a/src/libs/resiprocate/resip/stack/HeaderHash.gperf +++ b/src/libs/resiprocate/resip/stack/HeaderHash.gperf @@ -55,6 +55,13 @@ in-reply-to, Headers::InReplyTo min-expires, Headers::MinExpires mime-version, Headers::MIMEVersion organization, Headers::Organization +sec-websocket-key, Headers::SecWebSocketKey +sec-websocket-key1, Headers::SecWebSocketKey1 +sec-websocket-key2, Headers::SecWebSocketKey2 +sec-websocket-accept, Headers::SecWebSocketAccept +cookie, Headers::Cookie +origin, Headers::Origin +host, Headers::Host priority, Headers::Priority proxy-authenticate, Headers::ProxyAuthenticate proxy-authorization, Headers::ProxyAuthorization @@ -110,5 +117,10 @@ min-se, Headers::MinSE refer-sub, Headers::ReferSub remote-party-id, Headers::RemotePartyId history-info, Headers::HistoryInfo +p-access-network-info, Headers::PAccessNetworkInfo +p-charging-vector, Headers::PChargingVector +p-charging-function-addresses, Headers::PChargingFunctionAddresses +p-visited-network-id, Headers::PVisitedNetworkID +user-to-user, Headers::UserToUser %% } diff --git a/src/libs/resiprocate/resip/stack/HeaderHash.hxx b/src/libs/resiprocate/resip/stack/HeaderHash.hxx index 90c10d56..ee112dcb 100644 --- a/src/libs/resiprocate/resip/stack/HeaderHash.hxx +++ b/src/libs/resiprocate/resip/stack/HeaderHash.hxx @@ -1,17 +1,20 @@ #if !defined(RESIP_HEADERHASH_HXX) #define RESIP_HEADERHASH_HXX + +#include "rutil/compat.hxx" + namespace resip { -struct headers { char *name; Headers::Type type; }; +struct headers { const char *name; Headers::Type type; }; /* maximum key range = 494, duplicates = 0 */ class HeaderHash { private: - static inline unsigned int hash (const char *str, unsigned int len); + static inline unsigned int hash (const char *str, GPERF_SIZE_TYPE len); public: - static const struct headers *in_word_set (const char *str, unsigned int len); + static const struct headers *in_word_set (const char *str, GPERF_SIZE_TYPE len); }; // NOTE the cxx file for this class is AUTO GENERATED. DO NOT EDIT IT. // This file should match it. BUT THIS FILE IS MANUALLY GENERATED. diff --git a/src/libs/resiprocate/resip/stack/HeaderTypes.hxx b/src/libs/resiprocate/resip/stack/HeaderTypes.hxx index dcda54eb..cdffa9dd 100644 --- a/src/libs/resiprocate/resip/stack/HeaderTypes.hxx +++ b/src/libs/resiprocate/resip/stack/HeaderTypes.hxx @@ -82,6 +82,13 @@ class Headers defineHeader(MinExpires, "Min-Expires", UInt32Category, "RFC 3261"), defineHeader(MIMEVersion, "MIME-Version", Token, "RFC 3261"), defineHeader(Organization, "Organization", StringCategory, "RFC 3261"), + defineHeader(SecWebSocketKey, "Sec-WebSocket-Key", StringCategory, "RFC 6455"), + defineHeader(SecWebSocketKey1, "Sec-WebSocket-Key1", StringCategory, "draft-hixie- thewebsocketprotocol-76"), + defineHeader(SecWebSocketKey2, "Sec-WebSocket-Key2", StringCategory, "draft-hixie- thewebsocketprotocol-76"), + defineHeader(Origin, "Origin", StringCategory, "draft-hixie- thewebsocketprotocol-76"), + defineHeader(Host, "Host", StringCategory, "draft-hixie- thewebsocketprotocol-76"), + defineHeader(SecWebSocketAccept, "Sec-WebSocket-Accept", StringCategory, "RFC 6455"), + defineMultiHeader(Cookie, "Cookie", StringCategory, "RFC 6265"), defineHeader(Priority, "Priority", Token, "RFC 3261"), defineMultiHeader(ProxyAuthorization, "Proxy-Authorization", Auth, "RFC 3261"), defineHeader(ReplyTo, "Reply-To", NameAddr, "RFC 3261"), @@ -129,6 +136,13 @@ class Headers defineMultiHeader(RemotePartyId, "Remote-Party-ID", NameAddr, "draft-ietf-sip-privacy-04"), // ?bwc? Not in 3323, should we keep? defineMultiHeader(HistoryInfo, "History-Info", NameAddr, "RFC 4244"), + defineMultiHeader(PAccessNetworkInfo, "P-Access-Network-Info", Token, "RFC 7315"), // section 5.4. + defineHeader(PChargingVector, "P-Charging-Vector", Token, "RFC 3455"), + defineHeader(PChargingFunctionAddresses, "P-Charging-Function-Addresses", Token, "RFC 3455"), + defineMultiHeader(PVisitedNetworkID, "P-Visited-Network-ID", TokenOrQuotedStringCategory, "RFC 3455"), + + defineMultiHeader(UserToUser, "User-to-User", TokenOrQuotedStringCategory, "draft-ietf-cuss-sip-uui-17"), + defineMultiHeader(RESIP_DO_NOT_USE, "ShouldNotSeeThis", StringCategory, "N/A"), MAX_HEADERS, NONE diff --git a/src/libs/resiprocate/resip/stack/Headers.cxx b/src/libs/resiprocate/resip/stack/Headers.cxx index 9568f935..1cc21a60 100644 --- a/src/libs/resiprocate/resip/stack/Headers.cxx +++ b/src/libs/resiprocate/resip/stack/Headers.cxx @@ -39,7 +39,14 @@ Headers::isCommaEncoding(Type type) const Data& Headers::getHeaderName(int type) { - return HeaderNames[type+1]; + if(type < MAX_HEADERS) + { + return HeaderNames[type+1]; + } + else + { + return Data::Empty; + } } bool @@ -165,6 +172,10 @@ defineHeader(ReferSub, "Refer-Sub", Token, "RFC 4488"); defineHeader(AnswerMode, "Answer-Mode", Token, "draft-ietf-answermode-01"); defineHeader(PrivAnswerMode, "Priv-Answer-Mode", Token, "draft-ietf-answermode-01"); +defineMultiHeader(PAccessNetworkInfo, "P-Access-Network-Info", Token, "RFC 7315"); // section 5.4. +defineHeader(PChargingVector, "P-Charging-Vector", Token, "RFC 3455"); +defineHeader(PChargingFunctionAddresses, "P-Charging-Function-Addresses", Token, "RFC 3455"); + //==================== // Mime //==================== @@ -221,6 +232,13 @@ defineMultiHeader(HistoryInfo, "History-Info", NameAddr, "RFC 4244"); typedef ParserContainer StringCategories; defineHeader(Organization, "Organization", StringCategory, "RFC 3261"); +defineHeader(SecWebSocketKey, "Sec-WebSocket-Key", StringCategory, "RFC 6455"); +defineHeader(SecWebSocketKey1, "Sec-WebSocket-Key1", StringCategory, "draft-hixie- thewebsocketprotocol-76"); +defineHeader(SecWebSocketKey2, "Sec-WebSocket-Key2", StringCategory, "draft-hixie- thewebsocketprotocol-76"); +defineHeader(Origin, "Origin", StringCategory, "draft-hixie- thewebsocketprotocol-76"); +defineHeader(Host, "Host", StringCategory, "draft-hixie- thewebsocketprotocol-76"); +defineHeader(SecWebSocketAccept, "Sec-WebSocket-Accept", StringCategory, "RFC 6455"); +defineMultiHeader(Cookie, "Cookie", StringCategory, "RFC 6265"); defineHeader(Server, "Server", StringCategory, "RFC 3261"); defineHeader(Subject, "Subject", StringCategory, "RFC 3261"); defineHeader(UserAgent, "User-Agent", StringCategory, "RFC 3261"); @@ -287,6 +305,12 @@ defineHeader(RAck, "RAck", RAckCategory, "RFC 3262"); defineMultiHeader(Via, "Via", Via, "RFC 3261"); +//============================ +// TokenOrQuotedStringCategory +//============================ +defineMultiHeader(PVisitedNetworkID, "P-Visited-Network-ID", TokenOrQuotedStringCategory, "RFC 3455"); +defineMultiHeader(UserToUser, "User-to-User", TokenOrQuotedStringCategory, "draft-ietf-cuss-sip-uui-17"); + //Enforces string encoding of extension headers Headers::Type H_RESIP_DO_NOT_USEs::getTypeNum() const {return Headers::RESIP_DO_NOT_USE;} diff --git a/src/libs/resiprocate/resip/stack/Headers.hxx b/src/libs/resiprocate/resip/stack/Headers.hxx index 227cbae5..60f55848 100644 --- a/src/libs/resiprocate/resip/stack/Headers.hxx +++ b/src/libs/resiprocate/resip/stack/Headers.hxx @@ -156,6 +156,10 @@ defineHeader(ReferSub, "Refer-Sub", Token, "RFC 4488"); defineHeader(AnswerMode, "Answer-Mode", Token, "draft-ietf-answermode-01"); defineHeader(PrivAnswerMode, "Priv-Answer-Mode", Token, "draft-ietf-answermode-01"); +defineMultiHeader(PAccessNetworkInfo, "P-Access-Network-Info", Token, "RFC 7315"); // section 5.4. +defineHeader(PChargingVector, "P-Charging-Vector", Token, "RFC 3455"); +defineHeader(PChargingFunctionAddresses, "P-Charging-Function-Addresses", Token, "RFC 3455"); + //==================== // Mime //==================== @@ -211,6 +215,13 @@ typedef ParserContainer StringCategories; defineHeader(ContentTransferEncoding, "Content-Transfer-Encoding", StringCategory, "RFC ?"); defineHeader(Organization, "Organization", StringCategory, "RFC 3261"); +defineHeader(SecWebSocketKey, "Sec-WebSocket-Key", StringCategory, "RFC 6455"); +defineHeader(SecWebSocketKey1, "Sec-WebSocket-Key1", StringCategory, "draft-hixie- thewebsocketprotocol-76"); +defineHeader(SecWebSocketKey2, "Sec-WebSocket-Key2", StringCategory, "draft-hixie- thewebsocketprotocol-76"); +defineHeader(Origin, "Origin", StringCategory, "draft-hixie- thewebsocketprotocol-76"); +defineHeader(Host, "Host", StringCategory, "draft-hixie- thewebsocketprotocol-76"); +defineHeader(SecWebSocketAccept, "Sec-WebSocket-Accept", StringCategory, "RFC 6455"); +defineMultiHeader(Cookie, "Cookie", StringCategory, "RFC 6265"); defineHeader(Server, "Server", StringCategory, "RFC 3261"); defineHeader(Subject, "Subject", StringCategory, "RFC 3261"); defineHeader(UserAgent, "User-Agent", StringCategory, "RFC 3261"); @@ -291,6 +302,12 @@ defineMultiHeader(Via, "Via", Via, "RFC 3261"); //==================== defineHeader(RAck, "RAck", RAckCategory, "RFC 3262"); +//============================ +// TokenOrQuotedStringCategory +//============================ +defineMultiHeader(PVisitedNetworkID, "P-Visited-Network-ID", TokenOrQuotedStringCategory, "RFC 3455"); +defineMultiHeader(UserToUser, "User-to-User", TokenOrQuotedStringCategory, "draft-ietf-cuss-sip-uui-17"); + //==================== // special first line accessors //==================== diff --git a/src/libs/resiprocate/resip/stack/Helper.cxx b/src/libs/resiprocate/resip/stack/Helper.cxx index 6919705b..3daf2977 100644 --- a/src/libs/resiprocate/resip/stack/Helper.cxx +++ b/src/libs/resiprocate/resip/stack/Helper.cxx @@ -21,6 +21,7 @@ #include "rutil/DnsUtil.hxx" #include "rutil/compat.hxx" #include "rutil/ParseBuffer.hxx" +#include "rutil/TransportType.hxx" #include "resip/stack/SipMessage.hxx" #include "resip/stack/Pkcs7Contents.hxx" #include "resip/stack/MultipartSignedContents.hxx" @@ -116,7 +117,7 @@ unsigned int Helper::hex2integer(const char* _s) SipMessage* Helper::makeRequest(const NameAddr& target, const NameAddr& from, const NameAddr& contact, MethodTypes method) { - std::unique_ptr request(new SipMessage); + std::auto_ptr request(new SipMessage); RequestLine rLine(method); rLine.uri() = target.uri(); request->header(h_To) = target; @@ -153,7 +154,7 @@ Helper::makeRegister(const NameAddr& to, const NameAddr& from) SipMessage* Helper::makeRegister(const NameAddr& to, const NameAddr& from, const NameAddr& contact) { - std::unique_ptr request(new SipMessage); + std::auto_ptr request(new SipMessage); RequestLine rLine(REGISTER); rLine.uri().scheme() = to.uri().scheme(); @@ -172,7 +173,7 @@ Helper::makeRegister(const NameAddr& to, const NameAddr& from, const NameAddr& c request->header(h_From) = from; request->header(h_From).param(p_tag) = Helper::computeTag(Helper::tagSize); request->header(h_CallId).value() = Helper::computeCallId(); - assert(!request->exists(h_Contacts) || request->header(h_Contacts).empty()); + resip_assert(!request->exists(h_Contacts) || request->header(h_Contacts).empty()); request->header(h_Contacts).push_back( contact ); Via via; @@ -192,7 +193,7 @@ Helper::makeRegister(const NameAddr& to,const Data& transport) SipMessage* Helper::makeRegister(const NameAddr& to, const Data& transport, const NameAddr& contact) { - std::unique_ptr request(new SipMessage); + std::auto_ptr request(new SipMessage); RequestLine rLine(REGISTER); rLine.uri().scheme() = to.uri().scheme(); @@ -211,7 +212,7 @@ Helper::makeRegister(const NameAddr& to, const Data& transport, const NameAddr& request->header(h_From) = to; request->header(h_From).param(p_tag) = Helper::computeTag(Helper::tagSize); request->header(h_CallId).value() = Helper::computeCallId(); - assert(!request->exists(h_Contacts) || request->header(h_Contacts).empty()); + resip_assert(!request->exists(h_Contacts) || request->header(h_Contacts).empty()); request->header(h_Contacts).push_back( contact ); Via via; @@ -231,7 +232,7 @@ Helper::makePublish(const NameAddr& target, const NameAddr& from) SipMessage* Helper::makePublish(const NameAddr& target, const NameAddr& from, const NameAddr& contact) { - std::unique_ptr request(new SipMessage); + std::auto_ptr request(new SipMessage); RequestLine rLine(PUBLISH); rLine.uri() = target.uri(); @@ -243,7 +244,7 @@ Helper::makePublish(const NameAddr& target, const NameAddr& from, const NameAddr request->header(h_From) = from; request->header(h_From).param(p_tag) = Helper::computeTag(Helper::tagSize); request->header(h_CallId).value() = Helper::computeCallId(); - assert(!request->exists(h_Contacts) || request->header(h_Contacts).empty()); + resip_assert(!request->exists(h_Contacts) || request->header(h_Contacts).empty()); request->header(h_Contacts).push_back( contact ); Via via; request->header(h_Vias).push_back(via); @@ -261,7 +262,7 @@ Helper::makeMessage(const NameAddr& target, const NameAddr& from) SipMessage* Helper::makeMessage(const NameAddr& target, const NameAddr& from, const NameAddr& contact) { - std::unique_ptr request(new SipMessage); + std::auto_ptr request(new SipMessage); RequestLine rLine(MESSAGE); rLine.uri() = target.uri(); @@ -273,7 +274,7 @@ Helper::makeMessage(const NameAddr& target, const NameAddr& from, const NameAddr request->header(h_From) = from; request->header(h_From).param(p_tag) = Helper::computeTag(Helper::tagSize); request->header(h_CallId).value() = Helper::computeCallId(); - assert(!request->exists(h_Contacts) || request->header(h_Contacts).empty()); + resip_assert(!request->exists(h_Contacts) || request->header(h_Contacts).empty()); request->header(h_Contacts).push_back( contact ); Via via; request->header(h_Vias).push_back(via); @@ -292,7 +293,7 @@ Helper::makeSubscribe(const NameAddr& target, const NameAddr& from) SipMessage* Helper::makeSubscribe(const NameAddr& target, const NameAddr& from, const NameAddr& contact) { - std::unique_ptr request(new SipMessage); + std::auto_ptr request(new SipMessage); RequestLine rLine(SUBSCRIBE); rLine.uri() = target.uri(); @@ -304,7 +305,7 @@ Helper::makeSubscribe(const NameAddr& target, const NameAddr& from, const NameAd request->header(h_From) = from; request->header(h_From).param(p_tag) = Helper::computeTag(Helper::tagSize); request->header(h_CallId).value() = Helper::computeCallId(); - assert(!request->exists(h_Contacts) || request->header(h_Contacts).empty()); + resip_assert(!request->exists(h_Contacts) || request->header(h_Contacts).empty()); request->header(h_Contacts).push_front( contact ); Via via; request->header(h_Vias).push_front(via); @@ -315,7 +316,7 @@ Helper::makeSubscribe(const NameAddr& target, const NameAddr& from, const NameAd int Helper::jitterValue(int input, int lowerPercentage, int upperPercentage, int minimum) { - assert(upperPercentage >= lowerPercentage); + resip_assert(upperPercentage >= lowerPercentage); if (input < minimum) { return input; @@ -430,6 +431,8 @@ Helper::makeResponse(SipMessage& response, } else { + // This makes a response to an internally generated request look like it's + // external even though it isn't response.setFromExternal(); } @@ -453,7 +456,7 @@ Helper::makeResponse(const SipMessage& request, { // .bwc. Exception safety. Catch/rethrow is dicey because we can't rethrow // resip::BaseException, since it is abstract. - std::unique_ptr response(new SipMessage); + std::auto_ptr response(new SipMessage); makeResponse(*response, request, responseCode, reason, hostname, warning); @@ -475,7 +478,7 @@ Helper::makeResponse(const SipMessage& request, { // .bwc. Exception safety. Catch/rethrow is dicey because we can't rethrow // resip::BaseException, since it is abstract. - std::unique_ptr response(new SipMessage); + std::auto_ptr response(new SipMessage); makeResponse(*response, request, responseCode, reason, hostname, warning); return response.release(); @@ -572,9 +575,9 @@ Helper::getResponseCodeReason(int responseCode, Data& reason) SipMessage* Helper::makeCancel(const SipMessage& request) { - assert(request.isRequest()); - assert(request.header(h_RequestLine).getMethod() == INVITE); - std::unique_ptr cancel(new SipMessage); + resip_assert(request.isRequest()); + resip_assert(request.header(h_RequestLine).getMethod() == INVITE); + std::auto_ptr cancel(new SipMessage); RequestLine rLine(CANCEL, request.header(h_RequestLine).getSipVersion()); rLine.uri() = request.header(h_RequestLine).uri(); @@ -608,10 +611,10 @@ Helper::makeCancel(const SipMessage& request) SipMessage* Helper::makeFailureAck(const SipMessage& request, const SipMessage& response) { - assert (request.header(h_Vias).size() >= 1); - assert (request.header(h_RequestLine).getMethod() == INVITE); + resip_assert (request.header(h_Vias).size() >= 1); + resip_assert (request.header(h_RequestLine).getMethod() == INVITE); - std::unique_ptr ack(new SipMessage); + std::auto_ptr ack(new SipMessage); RequestLine rLine(ACK, request.header(h_RequestLine).getSipVersion()); rLine.uri() = request.header(h_RequestLine).uri(); @@ -644,15 +647,10 @@ Helper::computeUniqueBranch() return result; } - -// It is overwritten by Dmytro; because doing getLocalHostName() during initialization is not best idea. -static Data localhostname = "localhost"; -//DnsUtil::getLocalHostName(); - Data Helper::computeCallId() { - Data hostAndSalt(localhostname + Random::getRandomHex(16)); + Data hostAndSalt(DnsUtil::getLocalHostName() + Random::getRandomHex(16)); #ifndef USE_SSL // .bwc. None of this is neccessary if we're using openssl #if defined(__linux__) || defined(__APPLE__) pid_t pid = getpid(); @@ -708,7 +706,12 @@ Helper::makeResponseMD5WithA1(const Data& a1, const Data& qop, const Data& cnonce, const Data& cnonceCount, const Contents* entityBody) { +#ifdef RESIP_DIGEST_LOGGING + Data _a2; + DataStream a2(_a2); +#else MD5Stream a2; +#endif a2 << method << Symbols::COLON << digestUri; @@ -720,14 +723,25 @@ Helper::makeResponseMD5WithA1(const Data& a1, MD5Stream eStream; eStream << *entityBody; a2 << Symbols::COLON << eStream.getHex(); +#ifdef RESIP_DIGEST_LOGGING + StackLog(<<"auth-int, body length = " << eStream.bytesTaken()); +#endif } else { a2 << Symbols::COLON << noBody; +#ifdef RESIP_DIGEST_LOGGING + StackLog(<<"auth-int, no body"); +#endif } } +#ifdef RESIP_DIGEST_LOGGING + Data _r; + DataStream r(_r); +#else MD5Stream r; +#endif r << a1 << Symbols::COLON << nonce @@ -742,9 +756,22 @@ Helper::makeResponseMD5WithA1(const Data& a1, << qop << Symbols::COLON; } +#ifdef RESIP_DIGEST_LOGGING + a2.flush(); + StackLog(<<"A2 = " << _a2); + MD5Stream a2md5; + a2md5 << _a2; + r << a2md5.getHex(); + r.flush(); + StackLog(<<"response to be hashed (HA1:nonce:HA2) = " << _r); + MD5Stream rmd5; + rmd5 << _r; + return rmd5.getHex(); +#else r << a2.getHex(); return r.getHex(); +#endif } //RFC 2617 3.2.2.1 @@ -1032,8 +1059,8 @@ Helper::authenticateRequest(const SipMessage& request, i->param(p_nonce), i->param(p_qop), i->param(p_cnonce), - i->param(p_nc)), - request.getContents()) + i->param(p_nc), + request.getContents())) { return Authenticated; } @@ -1245,7 +1272,7 @@ Helper::make405(const SipMessage& request, int last = 0; // ENUMS must be contiguous in order for this to work. - assert( i - last <= 1); + resip_assert( i - last <= 1); Token t; t.value() = getMethodName(static_cast(i)); resp->header(h_Allows).push_back(t); @@ -1366,9 +1393,9 @@ Helper::makeChallengeResponseAuth(const SipMessage& request, { auth.scheme() = Symbols::Digest; auth.param(p_username) = username; - assert(challenge.exists(p_realm)); + resip_assert(challenge.exists(p_realm)); auth.param(p_realm) = challenge.param(p_realm); - assert(challenge.exists(p_nonce)); + resip_assert(challenge.exists(p_nonce)); auth.param(p_nonce) = challenge.param(p_nonce); Data digestUri; { @@ -1396,7 +1423,7 @@ Helper::makeChallengeResponseAuth(const SipMessage& request, } else { - assert(challenge.exists(p_realm)); + resip_assert(challenge.exists(p_realm)); auth.param(p_response) = Helper::makeResponseMD5(username, password, challenge.param(p_realm), @@ -1498,9 +1525,9 @@ Helper::makeChallengeResponseAuthWithA1(const SipMessage& request, { auth.scheme() = Symbols::Digest; auth.param(p_username) = username; - assert(challenge.exists(p_realm)); + resip_assert(challenge.exists(p_realm)); auth.param(p_realm) = challenge.param(p_realm); - assert(challenge.exists(p_nonce)); + resip_assert(challenge.exists(p_nonce)); auth.param(p_nonce) = challenge.param(p_nonce); Data digestUri; { @@ -1526,7 +1553,7 @@ Helper::makeChallengeResponseAuthWithA1(const SipMessage& request, } else { - assert(challenge.exists(p_realm)); + resip_assert(challenge.exists(p_realm)); auth.param(p_response) = Helper::makeResponseMD5WithA1(passwordHashA1, getMethodName(request.header(h_RequestLine).getMethod()), digestUri, @@ -1574,8 +1601,8 @@ Helper::addAuthorization(SipMessage& request, { Data nonceCountString = Data::Empty; - assert(challenge.isResponse()); - assert(challenge.header(h_StatusLine).responseCode() == 401 || + resip_assert(challenge.isResponse()); + resip_assert(challenge.header(h_StatusLine).responseCode() == 401 || challenge.header(h_StatusLine).responseCode() == 407); if (challenge.exists(h_ProxyAuthenticates)) @@ -1604,8 +1631,8 @@ Helper::addAuthorization(SipMessage& request, Uri Helper::makeUri(const Data& aor, const Data& scheme) { - assert(!aor.prefix("sip:")); - assert(!aor.prefix("sips:")); + resip_assert(!aor.prefix("sip:")); + resip_assert(!aor.prefix("sips:")); Data tmp(aor.size() + scheme.size() + 1, Data::Preallocate); tmp += scheme; @@ -1628,7 +1655,7 @@ Helper::processStrictRoute(SipMessage& request) request.header(h_Routes).push_back(NameAddr(request.const_header(h_RequestLine).uri())); request.header(h_RequestLine).uri() = request.const_header(h_Routes).front().uri(); request.header(h_Routes).pop_front(); // !jf! - assert(!request.hasForceTarget()); + resip_assert(!request.hasForceTarget()); request.setForceTarget(request.const_header(h_RequestLine).uri()); } } @@ -1636,7 +1663,7 @@ Helper::processStrictRoute(SipMessage& request) void Helper::massageRoute(const SipMessage& request, NameAddr& rt) { - assert(request.isRequest()); + resip_assert(request.isRequest()); // .bwc. Let's not record-route with a tel uri or something, shall we? // If the topmost route header is malformed, we can get along without. if (!request.empty(h_Routes) && @@ -1658,10 +1685,11 @@ Helper::massageRoute(const SipMessage& request, NameAddr& rt) int Helper::getPortForReply(SipMessage& request) { - assert(request.isRequest()); + resip_assert(request.isRequest()); int port = 0; - if(request.const_header(h_Vias).front().transport() == Symbols::TCP || - request.const_header(h_Vias).front().transport() == Symbols::TLS) + TransportType transportType = toTransportType( + request.const_header(h_Vias).front().transport()); + if(isReliable(transportType)) { // 18.2.2 - bullet 1 and 2 port = request.getSource().getPort(); @@ -1685,8 +1713,8 @@ Helper::getPortForReply(SipMessage& request) // If we haven't got a valid port yet, then use the default if (port <= 0 || port > 65535) { - if(request.const_header(h_Vias).front().transport() == Symbols::TLS || - request.const_header(h_Vias).front().transport() == Symbols::DTLS) + if(transportType == TLS || + transportType == DTLS) { port = Symbols::DefaultSipsPort; } @@ -1765,7 +1793,7 @@ Helper::validateMessage(const SipMessage& message,resip::Data* reason) } } -#if defined(USE_SSL) +#if defined(USE_SSL) && !defined(OPENSSL_NO_BF) #include static const Data sep("[]"); @@ -1800,7 +1828,7 @@ Helper::gruuUserPart(const Data& instanceId, sep.size() + 1 + aor.size() ) % 8)) % 8)); - unique_ptr out(new unsigned char[token.size()]); + auto_ptr out(new unsigned char[token.size()]); BF_cbc_encrypt((const unsigned char*)token.data(), out.get(), (long)token.size(), @@ -1840,7 +1868,7 @@ Helper::fromGruuUserPart(const Data& gruuUserPart, const Data decoded = gruu.base64decode(); - unique_ptr out(new unsigned char[gruuUserPart.size()+1]); + auto_ptr out(new unsigned char[gruuUserPart.size()+1]); BF_cbc_encrypt((const unsigned char*)decoded.data(), out.get(), (long)decoded.size(), @@ -1860,21 +1888,21 @@ Helper::fromGruuUserPart(const Data& gruuUserPart, } #endif Helper::ContentsSecAttrs::ContentsSecAttrs() - : mContents(nullptr), - mAttributes(nullptr) + : mContents(0), + mAttributes(0) {} -Helper::ContentsSecAttrs::ContentsSecAttrs(std::unique_ptr contents, - std::unique_ptr attributes) - : mContents(std::move(contents)), - mAttributes(std::move(attributes)) +Helper::ContentsSecAttrs::ContentsSecAttrs(std::auto_ptr contents, + std::auto_ptr attributes) + : mContents(contents), + mAttributes(attributes) {} // !!bwc!! Yikes! Destructive copy c'tor! Are we _sure_ this is the // intended behavior? Helper::ContentsSecAttrs::ContentsSecAttrs(const ContentsSecAttrs& rhs) - : mContents(std::move(rhs.mContents)), - mAttributes(std::move(rhs.mAttributes)) + : mContents(rhs.mContents), + mAttributes(rhs.mAttributes) {} Helper::ContentsSecAttrs& @@ -1884,8 +1912,8 @@ Helper::ContentsSecAttrs::operator=(const ContentsSecAttrs& rhs) { // !!bwc!! Yikes! Destructive assignment operator! Are we _sure_ this is // the intended behavior? - mContents = std::move(rhs.mContents); - mAttributes = std::move(rhs.mAttributes); + mContents = rhs.mContents; + mAttributes = rhs.mAttributes; } return *this; } @@ -1990,18 +2018,25 @@ Helper::extractFromPkcs7(const SipMessage& message, b = extractFromPkcs7Recurse(b, toAor, fromAor, attr, security); } } - std::unique_ptr c(b); - std::unique_ptr a(attr); - return ContentsSecAttrs(std::move(c), std::move(a)); + std::auto_ptr c(b); + std::auto_ptr a(attr); + return ContentsSecAttrs(c, a); } Helper::FailureMessageEffect -Helper::determineFailureMessageEffect(const SipMessage& response) +Helper::determineFailureMessageEffect(const SipMessage& response, + const std::set* additionalTransactionTerminatingResponses) { - assert(response.isResponse()); + resip_assert(response.isResponse()); int code = response.header(h_StatusLine).statusCode(); - assert(code >= 400); + resip_assert(code >= 400); + if (additionalTransactionTerminatingResponses && + (additionalTransactionTerminatingResponses->end() != additionalTransactionTerminatingResponses->find(code))) + { + return Helper::TransactionTermination; + } + switch(code) { case 404: @@ -2161,8 +2196,8 @@ SdpContents* getSdpRecurse(Contents* tree) return 0; } -static std::unique_ptr emptysdp; -unique_ptr Helper::getSdp(Contents* tree) +static std::auto_ptr emptysdp; +auto_ptr Helper::getSdp(Contents* tree) { if (tree) { @@ -2171,19 +2206,19 @@ unique_ptr Helper::getSdp(Contents* tree) if (sdp) { DebugLog(<< "Got sdp" << endl); - return unique_ptr(static_cast(sdp->clone())); + return auto_ptr(static_cast(sdp->clone())); } } //DebugLog(<< "No sdp" << endl); - return std::unique_ptr(); + return emptysdp; } bool Helper::isClientBehindNAT(const SipMessage& request, bool privateToPublicOnly) { - assert(request.isRequest()); - assert(!request.header(h_Vias).empty()); + resip_assert(request.isRequest()); + resip_assert(!request.header(h_Vias).empty()); // If received parameter is on top Via, then the source of the message doesn't match // the address provided in the via. Assume this is because the sender is behind a NAT. @@ -2193,14 +2228,28 @@ Helper::isClientBehindNAT(const SipMessage& request, bool privateToPublicOnly) { if(privateToPublicOnly) { - if(Tuple(request.header(h_Vias).front().sentHost(), 0, UNKNOWN_TRANSPORT).isPrivateAddress() && - !Tuple(request.header(h_Vias).front().param(p_received), 0, UNKNOWN_TRANSPORT).isPrivateAddress()) + // Ensure the via host is an IP address (note: web-rtc uses hostnames here instead) + if(DnsUtil::isIpV4Address(request.header(h_Vias).front().sentHost()) +#ifdef USE_IPV6 + || DnsUtil::isIpV6Address(request.header(h_Vias).front().sentHost()) +#endif + ) { - return true; + if(Tuple(request.header(h_Vias).front().sentHost(), 0, UNKNOWN_TRANSPORT).isPrivateAddress() && + !Tuple(request.header(h_Vias).front().param(p_received), 0, UNKNOWN_TRANSPORT).isPrivateAddress()) + { + return true; + } + else + { + return false; + } } else { - return false; + // In this case the via host is likely a hostname (possible with web-rtc) and we will assume the + // client is behind a NAT, even though we don't know for sure + return !Tuple(request.header(h_Vias).front().param(p_received), 0, UNKNOWN_TRANSPORT).isPrivateAddress(); } } return true; @@ -2208,12 +2257,11 @@ Helper::isClientBehindNAT(const SipMessage& request, bool privateToPublicOnly) return false; } - Tuple Helper::getClientPublicAddress(const SipMessage& request) { - assert(request.isRequest()); - assert(!request.header(h_Vias).empty()); + resip_assert(request.isRequest()); + resip_assert(!request.header(h_Vias).empty()); // Iterate through Via's starting at the bottom (closest to the client). Return the first // public address found from received parameter if present, or Via host. @@ -2234,12 +2282,19 @@ Helper::getClientPublicAddress(const SipMessage& request) } // Check IP from Via sentHost - Tuple address(it->sentHost(), 0, UNKNOWN_TRANSPORT); - if(!address.isPrivateAddress()) + if(DnsUtil::isIpV4Address(it->sentHost()) // Ensure the via host is an IP address (note: web-rtc uses hostnames here instead) +#ifdef USE_IPV6 + || DnsUtil::isIpV6Address(it->sentHost()) +#endif + ) { - address.setPort(it->exists(p_rport) ? it->param(p_rport).port() : it->sentPort()); - address.setType(Tuple::toTransport(it->transport())); - return address; + Tuple address(it->sentHost(), 0, UNKNOWN_TRANSPORT); + if(!address.isPrivateAddress()) + { + address.setPort(it->exists(p_rport) ? it->param(p_rport).port() : it->sentPort()); + address.setType(Tuple::toTransport(it->transport())); + return address; + } } if(it == request.header(h_Vias).begin()) break; diff --git a/src/libs/resiprocate/resip/stack/Helper.hxx b/src/libs/resiprocate/resip/stack/Helper.hxx index 0a297ccc..99bd9975 100644 --- a/src/libs/resiprocate/resip/stack/Helper.hxx +++ b/src/libs/resiprocate/resip/stack/Helper.hxx @@ -526,12 +526,12 @@ class Helper struct ContentsSecAttrs { ContentsSecAttrs(); - ContentsSecAttrs(std::unique_ptr contents, - std::unique_ptr attributes); + ContentsSecAttrs(std::auto_ptr contents, + std::auto_ptr attributes); ContentsSecAttrs(const ContentsSecAttrs& rhs); ContentsSecAttrs& operator=(const ContentsSecAttrs& rhs); - mutable std::unique_ptr mContents; - mutable std::unique_ptr mAttributes; + mutable std::auto_ptr mContents; + mutable std::auto_ptr mAttributes; }; static ContentsSecAttrs extractFromPkcs7(const SipMessage& message, Security& security); @@ -540,11 +540,12 @@ class Helper enum FailureMessageEffect{ DialogTermination, TransactionTermination, UsageTermination, RetryAfter, OptionalRetryAfter, ApplicationDependant }; - static FailureMessageEffect determineFailureMessageEffect(const SipMessage& response); + static FailureMessageEffect determineFailureMessageEffect(const SipMessage& response, + const std::set* additionalTransactionTerminatingResponses = NULL); // Just simply walk the contents tree and return the first SdpContents in // the tree. - static std::unique_ptr getSdp(Contents* tree); + static std::auto_ptr getSdp(Contents* tree); /** Looks at SIP headers and message source for a mismatch to make an assumption that the sender is behind a NAT device. diff --git a/src/libs/resiprocate/resip/stack/InternalTransport.cxx b/src/libs/resiprocate/resip/stack/InternalTransport.cxx index f65a6af7..fcea74ec 100644 --- a/src/libs/resiprocate/resip/stack/InternalTransport.cxx +++ b/src/libs/resiprocate/resip/stack/InternalTransport.cxx @@ -27,23 +27,27 @@ InternalTransport::InternalTransport(Fifo& rxFifo, const Data& interfaceObj, AfterSocketCreationFuncPtr socketFunc, Compression &compression, - unsigned transportFlags) : + unsigned transportFlags, + const Data& netNs) : Transport(rxFifo, portNum, version, interfaceObj, Data::Empty, - socketFunc, compression, transportFlags), + socketFunc, compression, transportFlags, netNs), mFd(INVALID_SOCKET), mInterruptorHandle(0), mTxFifoOutBuffer(mTxFifo), mPollGrp(NULL), - mPollItemHandle(NULL), - mTransportLogger(NULL) + mPollItemHandle(NULL) {} InternalTransport::~InternalTransport() { - if (mPollItemHandle && mPollGrp) + if (mPollItemHandle) + { mPollGrp->delPollItem(mPollItemHandle); - if (mInterruptorHandle && mPollGrp) + } + if (mInterruptorHandle) + { mPollGrp->delPollItem(mInterruptorHandle); + } if (mFd != INVALID_SOCKET) { @@ -55,6 +59,7 @@ InternalTransport::~InternalTransport() { WarningLog(<< "TX Fifo non-empty in ~InternalTransport! Has " << mTxFifo.size() << " messages."); } + setCongestionManager(0); // Clear out congestion manager } bool @@ -86,7 +91,7 @@ InternalTransport::socket(TransportType type, IpVersion ipVer) break; default: InfoLog (<< "Try to create an unsupported socket type: " << Tuple::toData(type)); - assert(0); + resip_assert(0); throw Transport::Exception("Unsupported transport", __FILE__,__LINE__); } @@ -97,6 +102,22 @@ InternalTransport::socket(TransportType type, IpVersion ipVer) throw Transport::Exception("Can't create TcpBaseTransport", __FILE__,__LINE__); } +#ifdef USE_IPV6 +#ifdef __linux__ + int on = 1; + if (ipVer == V6) + { + if ( ::setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) ) + { + int e = getErrno(); + InfoLog (<< "Couldn't set sockoptions IPV6_V6ONLY: " << strerror(e)); + error(e); + throw Exception("Failed setsockopt", __FILE__,__LINE__); + } + } +#endif +#endif + DebugLog (<< "Creating fd=" << fd << (ipVer == V4 ? " V4/" : " V6/") << (type == UDP ? "UDP" : "TCP")); return fd; @@ -105,7 +126,12 @@ InternalTransport::socket(TransportType type, IpVersion ipVer) void InternalTransport::bind() { - DebugLog (<< "Binding to " << Tuple::inet_ntop(mTuple)); +#ifdef USE_NETNS + DebugLog (<< "Binding to " << Tuple::inet_ntop(mTuple) + << " in netns=\"" <. - * - */ +#if !defined(RESIP_KEEPALIVEPONG_HXX) +#define RESIP_KEEPALIVEPONG_HXX + +#include "rutil/HeapInstanceCounter.hxx" +#include "resip/stack/TransactionMessage.hxx" +#include "resip/stack/Tuple.hxx" + +namespace resip +{ + +class KeepAlivePong : public TransactionMessage +{ + public: + RESIP_HeapCount(KeepAlivePong); + + KeepAlivePong(const Tuple& flow) : + mFlow(flow) + { + } + virtual const Data& getTransactionId() const { resip_assert(0); return Data::Empty; } + virtual bool isClientTransaction() const { resip_assert(0); return false; } + virtual Message* clone() const { return new KeepAlivePong(mFlow); } + virtual EncodeStream& encode(EncodeStream& strm) const { return encodeBrief(strm); } + virtual EncodeStream& encodeBrief(EncodeStream& str) const + { + return str << "KeepAlivePong " << mFlow; + } + + FlowKey getFlowKey() const + { + return mFlow.mFlowKey; + } + + const Tuple& getFlow() const + { + return mFlow; + } + + private: + const Tuple mFlow; +}; + +} + +#endif +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * . + * + */ diff --git a/src/libs/resiprocate/resip/stack/LazyParser.cxx b/src/libs/resiprocate/resip/stack/LazyParser.cxx index 42f7ae51..a8bc4050 100644 --- a/src/libs/resiprocate/resip/stack/LazyParser.cxx +++ b/src/libs/resiprocate/resip/stack/LazyParser.cxx @@ -3,7 +3,7 @@ #endif -#include +#include "rutil/ResipAssert.h" #include "resip/stack/Headers.hxx" #include "resip/stack/HeaderFieldValue.hxx" @@ -55,7 +55,7 @@ LazyParser::~LazyParser() LazyParser& LazyParser::operator=(const LazyParser& rhs) { - assert( &rhs != 0 ); + resip_assert( &rhs != 0 ); if (this != &rhs) { diff --git a/src/libs/resiprocate/resip/stack/Makefile b/src/libs/resiprocate/resip/stack/Makefile deleted file mode 100644 index 24b44672..00000000 --- a/src/libs/resiprocate/resip/stack/Makefile +++ /dev/null @@ -1,157 +0,0 @@ -############################################################################# -# Makefile for building: resiprocate -# Generated by qmake (2.01a) (Qt 4.7.4) on: ?? 19. ??? 14:08:04 2011 -# Project: resiprocate.pro -# Template: lib -# Command: d:\tools\qtsdk\desktop\qt\4.7.4\msvc2008\bin\qmake.exe -spec d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\win32-msvc2008 -o Makefile resiprocate.pro -############################################################################# - -first: debug -install: debug-install -uninstall: debug-uninstall -MAKEFILE = Makefile -QMAKE = d:\tools\qtsdk\desktop\qt\4.7.4\msvc2008\bin\qmake.exe -DEL_FILE = del -CHK_DIR_EXISTS= if not exist -MKDIR = mkdir -COPY = copy /y -COPY_FILE = $(COPY) -COPY_DIR = xcopy /s /q /y /i -INSTALL_FILE = $(COPY_FILE) -INSTALL_PROGRAM = $(COPY_FILE) -INSTALL_DIR = $(COPY_DIR) -DEL_FILE = del -SYMLINK = -DEL_DIR = rmdir -MOVE = move -CHK_DIR_EXISTS= if not exist -MKDIR = mkdir -SUBTARGETS = \ - debug \ - release - -debug: $(MAKEFILE).Debug FORCE - $(MAKE) -f $(MAKEFILE).Debug -debug-make_default: $(MAKEFILE).Debug FORCE - $(MAKE) -f $(MAKEFILE).Debug -debug-make_first: $(MAKEFILE).Debug FORCE - $(MAKE) -f $(MAKEFILE).Debug first -debug-all: $(MAKEFILE).Debug FORCE - $(MAKE) -f $(MAKEFILE).Debug all -debug-clean: $(MAKEFILE).Debug FORCE - $(MAKE) -f $(MAKEFILE).Debug clean -debug-distclean: $(MAKEFILE).Debug FORCE - $(MAKE) -f $(MAKEFILE).Debug distclean -debug-install: $(MAKEFILE).Debug FORCE - $(MAKE) -f $(MAKEFILE).Debug install -debug-uninstall: $(MAKEFILE).Debug FORCE - $(MAKE) -f $(MAKEFILE).Debug uninstall -release: $(MAKEFILE).Release FORCE - $(MAKE) -f $(MAKEFILE).Release -release-make_default: $(MAKEFILE).Release FORCE - $(MAKE) -f $(MAKEFILE).Release -release-make_first: $(MAKEFILE).Release FORCE - $(MAKE) -f $(MAKEFILE).Release first -release-all: $(MAKEFILE).Release FORCE - $(MAKE) -f $(MAKEFILE).Release all -release-clean: $(MAKEFILE).Release FORCE - $(MAKE) -f $(MAKEFILE).Release clean -release-distclean: $(MAKEFILE).Release FORCE - $(MAKE) -f $(MAKEFILE).Release distclean -release-install: $(MAKEFILE).Release FORCE - $(MAKE) -f $(MAKEFILE).Release install -release-uninstall: $(MAKEFILE).Release FORCE - $(MAKE) -f $(MAKEFILE).Release uninstall - -Makefile: resiprocate.pro d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\win32-msvc2008\qmake.conf d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\qconfig.pri \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\modules\qt_webkit_version.pri \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt_functions.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt_config.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\exclusive_builds.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\default_pre.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\default_pre.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\debug.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\debug_and_release.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\default_post.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\default_post.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\staticlib.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\static.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\rtti.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\exceptions.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\stl.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\embed_manifest_exe.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\embed_manifest_dll.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\warn_on.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\thread.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\moc.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\windows.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\resources.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\uic.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\yacc.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\lex.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\incredibuild_xge.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\include_source_dir.prf - $(QMAKE) -spec d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\win32-msvc2008 -o Makefile resiprocate.pro -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\qconfig.pri: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\modules\qt_webkit_version.pri: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt_functions.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt_config.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\exclusive_builds.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\default_pre.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\default_pre.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\debug.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\debug_and_release.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\default_post.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\default_post.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\staticlib.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\static.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\rtti.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\exceptions.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\stl.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\embed_manifest_exe.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\embed_manifest_dll.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\warn_on.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\thread.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\moc.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\windows.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\resources.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\uic.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\yacc.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\lex.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\incredibuild_xge.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\include_source_dir.prf: -qmake: qmake_all FORCE - @$(QMAKE) -spec d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\win32-msvc2008 -o Makefile resiprocate.pro - -qmake_all: FORCE - -make_default: debug-make_default release-make_default FORCE -make_first: debug-make_first release-make_first FORCE -all: debug-all release-all FORCE -clean: debug-clean release-clean FORCE - -$(DEL_FILE) ..\..\..\..\Libs\compiled\win\resiprocate.ilk - -$(DEL_FILE) vc*.pdb - -$(DEL_FILE) vc*.idb -distclean: debug-distclean release-distclean FORCE - -$(DEL_FILE) Makefile - -$(DEL_FILE) ..\..\..\..\Libs\compiled\win\resiprocate.pdb - -check: first - -debug-mocclean: $(MAKEFILE).Debug - $(MAKE) -f $(MAKEFILE).Debug mocclean -release-mocclean: $(MAKEFILE).Release - $(MAKE) -f $(MAKEFILE).Release mocclean -mocclean: debug-mocclean release-mocclean - -debug-mocables: $(MAKEFILE).Debug - $(MAKE) -f $(MAKEFILE).Debug mocables -release-mocables: $(MAKEFILE).Release - $(MAKE) -f $(MAKEFILE).Release mocables -mocables: debug-mocables release-mocables -FORCE: - -$(MAKEFILE).Debug: Makefile -$(MAKEFILE).Release: Makefile diff --git a/src/libs/resiprocate/resip/stack/Makefile.am b/src/libs/resiprocate/resip/stack/Makefile.am new file mode 100644 index 00000000..4ab15197 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Makefile.am @@ -0,0 +1,457 @@ +# $Id$ + +EXTRA_DIST = DayOfWeekHash.gperf +EXTRA_DIST += Doxyfile +EXTRA_DIST += FAQ +EXTRA_DIST += gperfNotes.txt +EXTRA_DIST += gperf_w32.bat +EXTRA_DIST += groups.doc +EXTRA_DIST += HeaderHash.gperf +EXTRA_DIST += mainpage.doc +EXTRA_DIST += MethodHash.gperf +EXTRA_DIST += MonthHash.gperf +EXTRA_DIST += ParameterHash.gperf +EXTRA_DIST += parametersA.gperf +EXTRA_DIST += Readme-Compliance.txt +EXTRA_DIST += *.vcxproj *.vcxproj.filters +EXTRA_DIST += ssl/WinSecurity.cxx + +SUBDIRS = . test + +AM_CXXFLAGS = -I $(top_srcdir) + +# +# make chokes on the filenames under doc/ because some of them have spaces +# in them. The content needs to be reviewed and renamed appropriately +# before it can be distributed by `make dist' +# +#SUBDIRS += doc + +#AM_CXXFLAGS = -I../../contrib/ares -DUSE_ARES + +BUILT_SOURCES = \ + gen/DayOfWeekHash.cxx \ + gen/HeaderHash.cxx \ + gen/MethodHash.cxx \ + gen/MonthHash.cxx \ + gen/ParameterHash.cxx + +lib_LTLIBRARIES = libresip.la + +libresip_la_LIBADD = ../../rutil/librutil.la +libresip_la_LIBADD += @LIBSSL_LIBADD@ +libresip_la_LIBADD += @LIBSTL_LIBADD@ +libresip_la_LDFLAGS = @LIBTOOL_VERSION_RELEASE@ -export-dynamic + +libresip_la_SOURCES = \ + Auth.cxx \ + CSeqCategory.cxx \ + CallId.cxx \ + Cookie.cxx \ + DateCategory.cxx \ + gen/DayOfWeekHash.cxx \ + DtmfPayloadContents.cxx \ + ExpiresCategory.cxx \ + GenericUri.cxx \ + IntegerCategory.cxx \ + InteropHelper.cxx \ + UInt32Category.cxx \ + Mime.cxx \ + NameAddr.cxx \ + ParserCategories.cxx \ + RequestLine.cxx \ + StatusLine.cxx \ + StringCategory.cxx \ + Token.cxx \ + TokenOrQuotedStringCategory.cxx \ + Via.cxx \ + WarningCategory.cxx \ + \ + Aor.cxx \ + ApiCheck.cxx \ + ApplicationSip.cxx \ + BasicDomainMatcher.cxx \ + BasicNonceHelper.cxx \ + BranchParameter.cxx \ + Connection.cxx \ + ConnectionBase.cxx \ + ConnectionManager.cxx \ + Contents.cxx \ + ContentsFactoryBase.cxx \ + CpimContents.cxx \ + DataParameter.cxx \ + DeprecatedDialog.cxx \ + DialogInfoContents.cxx \ + Dispatcher.cxx \ + DnsInterface.cxx \ + DnsResult.cxx \ + DtlsMessage.cxx \ + Embedded.cxx \ + ExtendedDomainMatcher.cxx \ + ExtensionParameter.cxx \ + ExtensionHeader.cxx \ + ExistsOrDataParameter.cxx \ + ExistsParameter.cxx \ + ExternalBodyContents.cxx \ + QValue.cxx \ + QValueParameter.cxx \ + GenericContents.cxx \ + GenericPidfContents.cxx \ + HEPSipMessageLoggingHandler.cxx \ + HeaderFieldValue.cxx \ + HeaderFieldValueList.cxx \ + gen/HeaderHash.cxx \ + HeaderTypes.cxx \ + Headers.cxx \ + Helper.cxx \ + IntegerParameter.cxx \ + UInt32Parameter.cxx \ + InternalTransport.cxx \ + LazyParser.cxx \ + Message.cxx \ + MessageWaitingContents.cxx \ + gen/MethodHash.cxx \ + MethodTypes.cxx \ + gen/MonthHash.cxx \ + MsgHeaderScanner.cxx \ + MultipartAlternativeContents.cxx \ + MultipartMixedContents.cxx \ + MultipartRelatedContents.cxx \ + MultipartSignedContents.cxx \ + NonceHelper.cxx \ + OctetContents.cxx \ + Parameter.cxx \ + gen/ParameterHash.cxx \ + ParameterTypes.cxx \ + ParserCategory.cxx \ + ParserContainerBase.cxx \ + Pidf.cxx \ + Pkcs7Contents.cxx \ + Pkcs8Contents.cxx \ + PlainContents.cxx \ + PrivacyCategory.cxx \ + QuotedDataParameter.cxx \ + RAckCategory.cxx \ + Rlmi.cxx \ + RportParameter.cxx \ + SERNonceHelper.cxx \ + SdpContents.cxx \ + SecurityAttributes.cxx \ + Compression.cxx \ + SipConfigParse.cxx \ + SipFrag.cxx \ + SipMessage.cxx \ + SipStack.cxx \ + StackThread.cxx \ + InterruptableStackThread.cxx \ + EventStackThread.cxx \ + StatisticsHandler.cxx \ + StatisticsManager.cxx \ + StatisticsMessage.cxx \ + Symbols.cxx \ + TcpBaseTransport.cxx \ + TcpConnection.cxx \ + TcpConnectState.cxx \ + TcpTransport.cxx \ + TimeAccumulate.cxx \ + TimerMessage.cxx \ + TimerQueue.cxx \ + Tuple.cxx \ + TupleMarkManager.cxx \ + TransactionController.cxx \ + MessageFilterRule.cxx \ + TransactionUser.cxx \ + TransactionUserMessage.cxx \ + TransactionMap.cxx \ + TransactionState.cxx \ + Transport.cxx \ + TransportThread.cxx \ + TransportFailure.cxx \ + TransportSelector.cxx \ + TuIM.cxx \ + TuSelector.cxx \ + UdpTransport.cxx \ + UnknownParameter.cxx \ + Uri.cxx \ + X509Contents.cxx \ + KeepAliveMessage.cxx \ + StatelessHandler.cxx \ + InvalidContents.cxx \ + WorkerThread.cxx \ + WsBaseTransport.cxx \ + WsFrameExtractor.cxx \ + WsTransport.cxx \ + WsConnection.cxx \ + WsConnectionBase.cxx \ + WsCookieContext.cxx \ + WsDecorator.cxx + +if USE_SSL +libresip_la_SOURCES += \ + ssl/DtlsTransport.cxx \ + ssl/Security.cxx \ + ssl/TlsBaseTransport.cxx \ + ssl/TlsConnection.cxx \ + ssl/TlsTransport.cxx \ + ssl/WssTransport.cxx \ + ssl/WssConnection.cxx +endif + +SUFFIXES = .gperf .cxx +GPERFOPTS = -C -D -E -L C++ -t --key-positions='*' --compare-strncmp +#GPERFVER="GNU gperf 2.7.2" + +# rule for case sensitive sorts of hash +gen/MethodHash.cxx: MethodHash.gperf + mkdir -p $(abs_srcdir)/gen + gperf $(GPERFOPTS) -Z MethodHash $< > $@ + +# note: the Date header field is case sensitive (RFC 3261 s20.17) +gen/DayOfWeekHash.cxx: DayOfWeekHash.gperf + mkdir -p $(abs_srcdir)/gen + gperf $(GPERFOPTS) -Z DayOfWeekHash $< > $@ +gen/MonthHash.cxx: MonthHash.gperf + mkdir -p $(abs_srcdir)/gen + gperf $(GPERFOPTS) -Z MonthHash $< > $@ + +# rule for insensitive clods +#${SRC}: ${@:%.cxx=%.gperf} -- more portable? +gen/%.cxx: %.gperf + mkdir -p $(abs_srcdir)/gen + gperf $(GPERFOPTS) --ignore-case -Z $* $< > $@ + + +resipincludedir = $(includedir)/resip/stack +nobase_resipinclude_HEADERS = AbandonServerTransaction.hxx \ + AddTransport.hxx \ + Aor.hxx \ + ApiCheck.hxx \ + ApiCheckList.hxx \ + ApplicationMessage.hxx \ + ApplicationSip.hxx \ + Auth.hxx \ + BasicDomainMatcher.hxx \ + BasicNonceHelper.hxx \ + BranchParameter.hxx \ + CallId.hxx \ + Cookie.hxx \ + CancelableTimerQueue.hxx \ + CancelClientInviteTransaction.hxx \ + Compression.hxx \ + ConnectionBase.hxx \ + Connection.hxx \ + ConnectionManager.hxx \ + ConnectionTerminated.hxx \ + ContentsFactoryBase.hxx \ + ContentsFactory.hxx \ + Contents.hxx \ + CpimContents.hxx \ + CSeqCategory.hxx \ + DataParameter.hxx \ + DateCategory.hxx \ + DeprecatedDialog.hxx \ + DialogInfoContents.hxx \ + Dispatcher.hxx \ + DomainMatcher.hxx \ + DnsInterface.hxx \ + DnsResult.hxx \ + DnsResultMessage.hxx \ + DtlsMessage.hxx \ + DtmfPayloadContents.hxx \ + Embedded.hxx \ + EnableFlowTimer.hxx \ + EventStackThread.hxx \ + ExistsOrDataParameter.hxx \ + ExistsParameter.hxx \ + ExpiresCategory.hxx \ + ExtendedDomainMatcher.hxx \ + ExtensionHeader.hxx \ + ExtensionParameter.hxx \ + ExternalBodyContents.hxx \ + FloatParameter.hxx \ + GenericContents.hxx \ + GenericPidfContents.hxx \ + GenericUri.hxx \ + HEPSipMessageLoggingHandler.hxx \ + HeaderFieldValue.hxx \ + HeaderFieldValueList.hxx \ + HeaderHash.hxx \ + Headers.hxx \ + HeaderTypes.hxx \ + Helper.hxx \ + IntegerCategory.hxx \ + IntegerParameter.hxx \ + InternalTransport.hxx \ + InteropHelper.hxx \ + InterruptableStackThread.hxx \ + InvalidContents.hxx \ + InvokeAfterSocketCreationFunc.hxx \ + KeepAliveMessage.hxx \ + KeepAlivePong.hxx \ + LazyParser.hxx \ + MarkListener.hxx \ + MessageDecorator.hxx \ + MessageFilterRule.hxx \ + Message.hxx \ + MessageWaitingContents.hxx \ + MethodHash.hxx \ + MethodTypes.hxx \ + Mime.hxx \ + MsgHeaderScanner.hxx \ + MultipartAlternativeContents.hxx \ + MultipartMixedContents.hxx \ + MultipartRelatedContents.hxx \ + MultipartSignedContents.hxx \ + NameAddr.hxx \ + NonceHelper.hxx \ + OctetContents.hxx \ + ParameterHash.hxx \ + Parameter.hxx \ + ParameterTypeEnums.hxx \ + ParameterTypes.hxx \ + ParserCategories.hxx \ + ParserCategory.hxx \ + ParserContainerBase.hxx \ + ParserContainer.hxx \ + Pidf.hxx \ + Pkcs7Contents.hxx \ + Pkcs8Contents.hxx \ + PlainContents.hxx \ + PollStatistics.hxx \ + PrivacyCategory.hxx \ + QuotedDataParameter.hxx \ + QValue.hxx \ + QValueParameter.hxx \ + RAckCategory.hxx \ + RemoveTransport.hxx \ + RequestLine.hxx \ + Rlmi.hxx \ + RportParameter.hxx \ + SdpContents.hxx \ + SecurityAttributes.hxx \ + SecurityTypes.hxx \ + SendData.hxx \ + SERNonceHelper.hxx \ + ShutdownMessage.hxx \ + SipConfigParse.hxx \ + SipFrag.hxx \ + SipMessage.hxx \ + SipStack.hxx \ + ssl/DtlsTransport.hxx \ + ssl/MacSecurity.hxx \ + ssl/Security.hxx \ + ssl/TlsBaseTransport.hxx \ + ssl/TlsConnection.hxx \ + ssl/TlsTransport.hxx \ + ssl/WinSecurity.hxx \ + ssl/WssTransport.hxx \ + ssl/WssConnection.hxx \ + StackThread.hxx \ + StartLine.hxx \ + StatelessHandler.hxx \ + StatisticsHandler.hxx \ + StatisticsManager.hxx \ + StatisticsMessage.hxx \ + StatusLine.hxx \ + StringCategory.hxx \ + Symbols.hxx \ + TcpBaseTransport.hxx \ + TcpConnection.hxx \ + TcpConnectState.hxx \ + TcpTransport.hxx \ + TerminateFlow.hxx \ + TimeAccumulate.hxx \ + TimerMessage.hxx \ + TimerQueue.hxx \ + Token.hxx \ + TokenOrQuotedStringCategory.hxx \ + TransactionController.hxx \ + TransactionControllerThread.hxx \ + TransactionMap.hxx \ + TransactionMessage.hxx \ + TransportSelectorThread.hxx \ + TransactionState.hxx \ + TransactionTerminated.hxx \ + TransactionUser.hxx \ + TransactionUserMessage.hxx \ + TransportFailure.hxx \ + Transport.hxx \ + TransportSelector.hxx \ + TransportThread.hxx \ + TuIM.hxx \ + Tuple.hxx \ + TupleMarkManager.hxx \ + TuSelector.hxx \ + UdpTransport.hxx \ + UInt32Category.hxx \ + UInt32Parameter.hxx \ + UnknownHeaderType.hxx \ + UnknownParameter.hxx \ + UnknownParameterType.hxx \ + Uri.hxx \ + ValueFifo.hxx \ + Via.hxx \ + WarningCategory.hxx \ + Worker.hxx \ + WorkerThread.hxx \ + WsBaseTransport.hxx \ + WsDecorator.hxx \ + WsFrameExtractor.hxx \ + WsTransport.hxx \ + WsConnection.hxx \ + WsConnectionBase.hxx \ + WsConnectionValidator.hxx \ + WsCookieContext.hxx \ + WsCookieContextFactory.hxx \ + X509Contents.hxx \ + ZeroOutStatistics.hxx + +############################################################################## +# +# The Vovida Software License, Version 1.0 +# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The names "VOCAL", "Vovida Open Communication Application Library", +# and "Vovida Open Communication Application Library (VOCAL)" must +# not be used to endorse or promote products derived from this +# software without prior written permission. For written +# permission, please contact vocal@vovida.org. +# +# 4. Products derived from this software may not be called "VOCAL", nor +# may "VOCAL" appear in their name, without prior written +# permission of Vovida Networks, Inc. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. +# +# ==================================================================== +# +# This software consists of voluntary contributions made by Vovida +# Networks, Inc. and many individuals on behalf of Vovida Networks, +# Inc. For more information on Vovida Networks, Inc., please see +# . +# +############################################################################## diff --git a/src/libs/resiprocate/resip/stack/Makefile.in b/src/libs/resiprocate/resip/stack/Makefile.in new file mode 100644 index 00000000..c6afe942 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Makefile.in @@ -0,0 +1,1856 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# $Id$ + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@USE_SSL_TRUE@am__append_1 = \ +@USE_SSL_TRUE@ ssl/DtlsTransport.cxx \ +@USE_SSL_TRUE@ ssl/Security.cxx \ +@USE_SSL_TRUE@ ssl/TlsBaseTransport.cxx \ +@USE_SSL_TRUE@ ssl/TlsConnection.cxx \ +@USE_SSL_TRUE@ ssl/TlsTransport.cxx \ +@USE_SSL_TRUE@ ssl/WssTransport.cxx \ +@USE_SSL_TRUE@ ssl/WssConnection.cxx + +subdir = resip/stack +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_have_epoll.m4 \ + $(top_srcdir)/m4/gprefver.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(nobase_resipinclude_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(resipincludedir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libresip_la_DEPENDENCIES = ../../rutil/librutil.la +am__libresip_la_SOURCES_DIST = Auth.cxx CSeqCategory.cxx CallId.cxx \ + Cookie.cxx DateCategory.cxx gen/DayOfWeekHash.cxx \ + DtmfPayloadContents.cxx ExpiresCategory.cxx GenericUri.cxx \ + IntegerCategory.cxx InteropHelper.cxx UInt32Category.cxx \ + Mime.cxx NameAddr.cxx ParserCategories.cxx RequestLine.cxx \ + StatusLine.cxx StringCategory.cxx Token.cxx \ + TokenOrQuotedStringCategory.cxx Via.cxx WarningCategory.cxx \ + Aor.cxx ApiCheck.cxx ApplicationSip.cxx BasicDomainMatcher.cxx \ + BasicNonceHelper.cxx BranchParameter.cxx Connection.cxx \ + ConnectionBase.cxx ConnectionManager.cxx Contents.cxx \ + ContentsFactoryBase.cxx CpimContents.cxx DataParameter.cxx \ + DeprecatedDialog.cxx DialogInfoContents.cxx Dispatcher.cxx \ + DnsInterface.cxx DnsResult.cxx DtlsMessage.cxx Embedded.cxx \ + ExtendedDomainMatcher.cxx ExtensionParameter.cxx \ + ExtensionHeader.cxx ExistsOrDataParameter.cxx \ + ExistsParameter.cxx ExternalBodyContents.cxx QValue.cxx \ + QValueParameter.cxx GenericContents.cxx \ + GenericPidfContents.cxx HEPSipMessageLoggingHandler.cxx \ + HeaderFieldValue.cxx HeaderFieldValueList.cxx \ + gen/HeaderHash.cxx HeaderTypes.cxx Headers.cxx Helper.cxx \ + IntegerParameter.cxx UInt32Parameter.cxx InternalTransport.cxx \ + LazyParser.cxx Message.cxx MessageWaitingContents.cxx \ + gen/MethodHash.cxx MethodTypes.cxx gen/MonthHash.cxx \ + MsgHeaderScanner.cxx MultipartAlternativeContents.cxx \ + MultipartMixedContents.cxx MultipartRelatedContents.cxx \ + MultipartSignedContents.cxx NonceHelper.cxx OctetContents.cxx \ + Parameter.cxx gen/ParameterHash.cxx ParameterTypes.cxx \ + ParserCategory.cxx ParserContainerBase.cxx Pidf.cxx \ + Pkcs7Contents.cxx Pkcs8Contents.cxx PlainContents.cxx \ + PrivacyCategory.cxx QuotedDataParameter.cxx RAckCategory.cxx \ + Rlmi.cxx RportParameter.cxx SERNonceHelper.cxx SdpContents.cxx \ + SecurityAttributes.cxx Compression.cxx SipConfigParse.cxx \ + SipFrag.cxx SipMessage.cxx SipStack.cxx StackThread.cxx \ + InterruptableStackThread.cxx EventStackThread.cxx \ + StatisticsHandler.cxx StatisticsManager.cxx \ + StatisticsMessage.cxx Symbols.cxx TcpBaseTransport.cxx \ + TcpConnection.cxx TcpConnectState.cxx TcpTransport.cxx \ + TimeAccumulate.cxx TimerMessage.cxx TimerQueue.cxx Tuple.cxx \ + TupleMarkManager.cxx TransactionController.cxx \ + MessageFilterRule.cxx TransactionUser.cxx \ + TransactionUserMessage.cxx TransactionMap.cxx \ + TransactionState.cxx Transport.cxx TransportThread.cxx \ + TransportFailure.cxx TransportSelector.cxx TuIM.cxx \ + TuSelector.cxx UdpTransport.cxx UnknownParameter.cxx Uri.cxx \ + X509Contents.cxx KeepAliveMessage.cxx StatelessHandler.cxx \ + InvalidContents.cxx WorkerThread.cxx WsBaseTransport.cxx \ + WsFrameExtractor.cxx WsTransport.cxx WsConnection.cxx \ + WsConnectionBase.cxx WsCookieContext.cxx WsDecorator.cxx \ + ssl/DtlsTransport.cxx ssl/Security.cxx \ + ssl/TlsBaseTransport.cxx ssl/TlsConnection.cxx \ + ssl/TlsTransport.cxx ssl/WssTransport.cxx \ + ssl/WssConnection.cxx +am__dirstamp = $(am__leading_dot)dirstamp +@USE_SSL_TRUE@am__objects_1 = ssl/DtlsTransport.lo ssl/Security.lo \ +@USE_SSL_TRUE@ ssl/TlsBaseTransport.lo ssl/TlsConnection.lo \ +@USE_SSL_TRUE@ ssl/TlsTransport.lo ssl/WssTransport.lo \ +@USE_SSL_TRUE@ ssl/WssConnection.lo +am_libresip_la_OBJECTS = Auth.lo CSeqCategory.lo CallId.lo Cookie.lo \ + DateCategory.lo gen/DayOfWeekHash.lo DtmfPayloadContents.lo \ + ExpiresCategory.lo GenericUri.lo IntegerCategory.lo \ + InteropHelper.lo UInt32Category.lo Mime.lo NameAddr.lo \ + ParserCategories.lo RequestLine.lo StatusLine.lo \ + StringCategory.lo Token.lo TokenOrQuotedStringCategory.lo \ + Via.lo WarningCategory.lo Aor.lo ApiCheck.lo ApplicationSip.lo \ + BasicDomainMatcher.lo BasicNonceHelper.lo BranchParameter.lo \ + Connection.lo ConnectionBase.lo ConnectionManager.lo \ + Contents.lo ContentsFactoryBase.lo CpimContents.lo \ + DataParameter.lo DeprecatedDialog.lo DialogInfoContents.lo \ + Dispatcher.lo DnsInterface.lo DnsResult.lo DtlsMessage.lo \ + Embedded.lo ExtendedDomainMatcher.lo ExtensionParameter.lo \ + ExtensionHeader.lo ExistsOrDataParameter.lo ExistsParameter.lo \ + ExternalBodyContents.lo QValue.lo QValueParameter.lo \ + GenericContents.lo GenericPidfContents.lo \ + HEPSipMessageLoggingHandler.lo HeaderFieldValue.lo \ + HeaderFieldValueList.lo gen/HeaderHash.lo HeaderTypes.lo \ + Headers.lo Helper.lo IntegerParameter.lo UInt32Parameter.lo \ + InternalTransport.lo LazyParser.lo Message.lo \ + MessageWaitingContents.lo gen/MethodHash.lo MethodTypes.lo \ + gen/MonthHash.lo MsgHeaderScanner.lo \ + MultipartAlternativeContents.lo MultipartMixedContents.lo \ + MultipartRelatedContents.lo MultipartSignedContents.lo \ + NonceHelper.lo OctetContents.lo Parameter.lo \ + gen/ParameterHash.lo ParameterTypes.lo ParserCategory.lo \ + ParserContainerBase.lo Pidf.lo Pkcs7Contents.lo \ + Pkcs8Contents.lo PlainContents.lo PrivacyCategory.lo \ + QuotedDataParameter.lo RAckCategory.lo Rlmi.lo \ + RportParameter.lo SERNonceHelper.lo SdpContents.lo \ + SecurityAttributes.lo Compression.lo SipConfigParse.lo \ + SipFrag.lo SipMessage.lo SipStack.lo StackThread.lo \ + InterruptableStackThread.lo EventStackThread.lo \ + StatisticsHandler.lo StatisticsManager.lo StatisticsMessage.lo \ + Symbols.lo TcpBaseTransport.lo TcpConnection.lo \ + TcpConnectState.lo TcpTransport.lo TimeAccumulate.lo \ + TimerMessage.lo TimerQueue.lo Tuple.lo TupleMarkManager.lo \ + TransactionController.lo MessageFilterRule.lo \ + TransactionUser.lo TransactionUserMessage.lo TransactionMap.lo \ + TransactionState.lo Transport.lo TransportThread.lo \ + TransportFailure.lo TransportSelector.lo TuIM.lo TuSelector.lo \ + UdpTransport.lo UnknownParameter.lo Uri.lo X509Contents.lo \ + KeepAliveMessage.lo StatelessHandler.lo InvalidContents.lo \ + WorkerThread.lo WsBaseTransport.lo WsFrameExtractor.lo \ + WsTransport.lo WsConnection.lo WsConnectionBase.lo \ + WsCookieContext.lo WsDecorator.lo $(am__objects_1) +libresip_la_OBJECTS = $(am_libresip_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libresip_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(libresip_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/Aor.Plo ./$(DEPDIR)/ApiCheck.Plo \ + ./$(DEPDIR)/ApplicationSip.Plo ./$(DEPDIR)/Auth.Plo \ + ./$(DEPDIR)/BasicDomainMatcher.Plo \ + ./$(DEPDIR)/BasicNonceHelper.Plo \ + ./$(DEPDIR)/BranchParameter.Plo ./$(DEPDIR)/CSeqCategory.Plo \ + ./$(DEPDIR)/CallId.Plo ./$(DEPDIR)/Compression.Plo \ + ./$(DEPDIR)/Connection.Plo ./$(DEPDIR)/ConnectionBase.Plo \ + ./$(DEPDIR)/ConnectionManager.Plo ./$(DEPDIR)/Contents.Plo \ + ./$(DEPDIR)/ContentsFactoryBase.Plo ./$(DEPDIR)/Cookie.Plo \ + ./$(DEPDIR)/CpimContents.Plo ./$(DEPDIR)/DataParameter.Plo \ + ./$(DEPDIR)/DateCategory.Plo ./$(DEPDIR)/DeprecatedDialog.Plo \ + ./$(DEPDIR)/DialogInfoContents.Plo ./$(DEPDIR)/Dispatcher.Plo \ + ./$(DEPDIR)/DnsInterface.Plo ./$(DEPDIR)/DnsResult.Plo \ + ./$(DEPDIR)/DtlsMessage.Plo \ + ./$(DEPDIR)/DtmfPayloadContents.Plo ./$(DEPDIR)/Embedded.Plo \ + ./$(DEPDIR)/EventStackThread.Plo \ + ./$(DEPDIR)/ExistsOrDataParameter.Plo \ + ./$(DEPDIR)/ExistsParameter.Plo \ + ./$(DEPDIR)/ExpiresCategory.Plo \ + ./$(DEPDIR)/ExtendedDomainMatcher.Plo \ + ./$(DEPDIR)/ExtensionHeader.Plo \ + ./$(DEPDIR)/ExtensionParameter.Plo \ + ./$(DEPDIR)/ExternalBodyContents.Plo \ + ./$(DEPDIR)/GenericContents.Plo \ + ./$(DEPDIR)/GenericPidfContents.Plo ./$(DEPDIR)/GenericUri.Plo \ + ./$(DEPDIR)/HEPSipMessageLoggingHandler.Plo \ + ./$(DEPDIR)/HeaderFieldValue.Plo \ + ./$(DEPDIR)/HeaderFieldValueList.Plo \ + ./$(DEPDIR)/HeaderTypes.Plo ./$(DEPDIR)/Headers.Plo \ + ./$(DEPDIR)/Helper.Plo ./$(DEPDIR)/IntegerCategory.Plo \ + ./$(DEPDIR)/IntegerParameter.Plo \ + ./$(DEPDIR)/InternalTransport.Plo \ + ./$(DEPDIR)/InteropHelper.Plo \ + ./$(DEPDIR)/InterruptableStackThread.Plo \ + ./$(DEPDIR)/InvalidContents.Plo \ + ./$(DEPDIR)/KeepAliveMessage.Plo ./$(DEPDIR)/LazyParser.Plo \ + ./$(DEPDIR)/Message.Plo ./$(DEPDIR)/MessageFilterRule.Plo \ + ./$(DEPDIR)/MessageWaitingContents.Plo \ + ./$(DEPDIR)/MethodTypes.Plo ./$(DEPDIR)/Mime.Plo \ + ./$(DEPDIR)/MsgHeaderScanner.Plo \ + ./$(DEPDIR)/MultipartAlternativeContents.Plo \ + ./$(DEPDIR)/MultipartMixedContents.Plo \ + ./$(DEPDIR)/MultipartRelatedContents.Plo \ + ./$(DEPDIR)/MultipartSignedContents.Plo \ + ./$(DEPDIR)/NameAddr.Plo ./$(DEPDIR)/NonceHelper.Plo \ + ./$(DEPDIR)/OctetContents.Plo ./$(DEPDIR)/Parameter.Plo \ + ./$(DEPDIR)/ParameterTypes.Plo \ + ./$(DEPDIR)/ParserCategories.Plo \ + ./$(DEPDIR)/ParserCategory.Plo \ + ./$(DEPDIR)/ParserContainerBase.Plo ./$(DEPDIR)/Pidf.Plo \ + ./$(DEPDIR)/Pkcs7Contents.Plo ./$(DEPDIR)/Pkcs8Contents.Plo \ + ./$(DEPDIR)/PlainContents.Plo ./$(DEPDIR)/PrivacyCategory.Plo \ + ./$(DEPDIR)/QValue.Plo ./$(DEPDIR)/QValueParameter.Plo \ + ./$(DEPDIR)/QuotedDataParameter.Plo \ + ./$(DEPDIR)/RAckCategory.Plo ./$(DEPDIR)/RequestLine.Plo \ + ./$(DEPDIR)/Rlmi.Plo ./$(DEPDIR)/RportParameter.Plo \ + ./$(DEPDIR)/SERNonceHelper.Plo ./$(DEPDIR)/SdpContents.Plo \ + ./$(DEPDIR)/SecurityAttributes.Plo \ + ./$(DEPDIR)/SipConfigParse.Plo ./$(DEPDIR)/SipFrag.Plo \ + ./$(DEPDIR)/SipMessage.Plo ./$(DEPDIR)/SipStack.Plo \ + ./$(DEPDIR)/StackThread.Plo ./$(DEPDIR)/StatelessHandler.Plo \ + ./$(DEPDIR)/StatisticsHandler.Plo \ + ./$(DEPDIR)/StatisticsManager.Plo \ + ./$(DEPDIR)/StatisticsMessage.Plo ./$(DEPDIR)/StatusLine.Plo \ + ./$(DEPDIR)/StringCategory.Plo ./$(DEPDIR)/Symbols.Plo \ + ./$(DEPDIR)/TcpBaseTransport.Plo \ + ./$(DEPDIR)/TcpConnectState.Plo ./$(DEPDIR)/TcpConnection.Plo \ + ./$(DEPDIR)/TcpTransport.Plo ./$(DEPDIR)/TimeAccumulate.Plo \ + ./$(DEPDIR)/TimerMessage.Plo ./$(DEPDIR)/TimerQueue.Plo \ + ./$(DEPDIR)/Token.Plo \ + ./$(DEPDIR)/TokenOrQuotedStringCategory.Plo \ + ./$(DEPDIR)/TransactionController.Plo \ + ./$(DEPDIR)/TransactionMap.Plo \ + ./$(DEPDIR)/TransactionState.Plo \ + ./$(DEPDIR)/TransactionUser.Plo \ + ./$(DEPDIR)/TransactionUserMessage.Plo \ + ./$(DEPDIR)/Transport.Plo ./$(DEPDIR)/TransportFailure.Plo \ + ./$(DEPDIR)/TransportSelector.Plo \ + ./$(DEPDIR)/TransportThread.Plo ./$(DEPDIR)/TuIM.Plo \ + ./$(DEPDIR)/TuSelector.Plo ./$(DEPDIR)/Tuple.Plo \ + ./$(DEPDIR)/TupleMarkManager.Plo \ + ./$(DEPDIR)/UInt32Category.Plo ./$(DEPDIR)/UInt32Parameter.Plo \ + ./$(DEPDIR)/UdpTransport.Plo ./$(DEPDIR)/UnknownParameter.Plo \ + ./$(DEPDIR)/Uri.Plo ./$(DEPDIR)/Via.Plo \ + ./$(DEPDIR)/WarningCategory.Plo ./$(DEPDIR)/WorkerThread.Plo \ + ./$(DEPDIR)/WsBaseTransport.Plo ./$(DEPDIR)/WsConnection.Plo \ + ./$(DEPDIR)/WsConnectionBase.Plo \ + ./$(DEPDIR)/WsCookieContext.Plo ./$(DEPDIR)/WsDecorator.Plo \ + ./$(DEPDIR)/WsFrameExtractor.Plo ./$(DEPDIR)/WsTransport.Plo \ + ./$(DEPDIR)/X509Contents.Plo gen/$(DEPDIR)/DayOfWeekHash.Plo \ + gen/$(DEPDIR)/HeaderHash.Plo gen/$(DEPDIR)/MethodHash.Plo \ + gen/$(DEPDIR)/MonthHash.Plo gen/$(DEPDIR)/ParameterHash.Plo \ + ssl/$(DEPDIR)/DtlsTransport.Plo ssl/$(DEPDIR)/Security.Plo \ + ssl/$(DEPDIR)/TlsBaseTransport.Plo \ + ssl/$(DEPDIR)/TlsConnection.Plo ssl/$(DEPDIR)/TlsTransport.Plo \ + ssl/$(DEPDIR)/WssConnection.Plo ssl/$(DEPDIR)/WssTransport.Plo +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +SOURCES = $(libresip_la_SOURCES) +DIST_SOURCES = $(am__libresip_la_SOURCES_DIST) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(nobase_resipinclude_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp README TODO +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DEPS_PYTHON_CFLAGS = @DEPS_PYTHON_CFLAGS@ +DEPS_PYTHON_LIBS = @DEPS_PYTHON_LIBS@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GPERF = @GPERF@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBARES_LIBADD = @LIBARES_LIBADD@ +LIBGEOIP_LIBADD = @LIBGEOIP_LIBADD@ +LIBLOG_LIBADD = @LIBLOG_LIBADD@ +LIBMYSQL_LIBADD = @LIBMYSQL_LIBADD@ +LIBNETSNMP_LDADD = @LIBNETSNMP_LDADD@ +LIBOBJS = @LIBOBJS@ +LIBPOPT_LIBADD = @LIBPOPT_LIBADD@ +LIBPOSTGRESQL_LIBADD = @LIBPOSTGRESQL_LIBADD@ +LIBPTHREAD_LIBADD = @LIBPTHREAD_LIBADD@ +LIBRADIUS_LIBADD = @LIBRADIUS_LIBADD@ +LIBS = @LIBS@ +LIBSSL_LIBADD = @LIBSSL_LIBADD@ +LIBSTL_LIBADD = @LIBSTL_LIBADD@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_VERSION_RELEASE = @LIBTOOL_VERSION_RELEASE@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PYCXX_SRCDIR = @PYCXX_SRCDIR@ +QT5_CFLAGS = @QT5_CFLAGS@ +QT5_LIBS = @QT5_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SO_RELEASE = @SO_RELEASE@ +STRIP = @STRIP@ +TP_QT5_CFLAGS = @TP_QT5_CFLAGS@ +TP_QT5_LIBS = @TP_QT5_LIBS@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +reproplugindir = @reproplugindir@ +returnpkglibdir = @returnpkglibdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = DayOfWeekHash.gperf Doxyfile FAQ gperfNotes.txt \ + gperf_w32.bat groups.doc HeaderHash.gperf mainpage.doc \ + MethodHash.gperf MonthHash.gperf ParameterHash.gperf \ + parametersA.gperf Readme-Compliance.txt *.vcxproj \ + *.vcxproj.filters ssl/WinSecurity.cxx +SUBDIRS = . test +AM_CXXFLAGS = -I $(top_srcdir) + +# +# make chokes on the filenames under doc/ because some of them have spaces +# in them. The content needs to be reviewed and renamed appropriately +# before it can be distributed by `make dist' +# +#SUBDIRS += doc + +#AM_CXXFLAGS = -I../../contrib/ares -DUSE_ARES +BUILT_SOURCES = \ + gen/DayOfWeekHash.cxx \ + gen/HeaderHash.cxx \ + gen/MethodHash.cxx \ + gen/MonthHash.cxx \ + gen/ParameterHash.cxx + +lib_LTLIBRARIES = libresip.la +libresip_la_LIBADD = ../../rutil/librutil.la @LIBSSL_LIBADD@ \ + @LIBSTL_LIBADD@ $(am__empty) +libresip_la_LDFLAGS = @LIBTOOL_VERSION_RELEASE@ -export-dynamic +libresip_la_SOURCES = Auth.cxx CSeqCategory.cxx CallId.cxx Cookie.cxx \ + DateCategory.cxx gen/DayOfWeekHash.cxx DtmfPayloadContents.cxx \ + ExpiresCategory.cxx GenericUri.cxx IntegerCategory.cxx \ + InteropHelper.cxx UInt32Category.cxx Mime.cxx NameAddr.cxx \ + ParserCategories.cxx RequestLine.cxx StatusLine.cxx \ + StringCategory.cxx Token.cxx TokenOrQuotedStringCategory.cxx \ + Via.cxx WarningCategory.cxx Aor.cxx ApiCheck.cxx \ + ApplicationSip.cxx BasicDomainMatcher.cxx BasicNonceHelper.cxx \ + BranchParameter.cxx Connection.cxx ConnectionBase.cxx \ + ConnectionManager.cxx Contents.cxx ContentsFactoryBase.cxx \ + CpimContents.cxx DataParameter.cxx DeprecatedDialog.cxx \ + DialogInfoContents.cxx Dispatcher.cxx DnsInterface.cxx \ + DnsResult.cxx DtlsMessage.cxx Embedded.cxx \ + ExtendedDomainMatcher.cxx ExtensionParameter.cxx \ + ExtensionHeader.cxx ExistsOrDataParameter.cxx \ + ExistsParameter.cxx ExternalBodyContents.cxx QValue.cxx \ + QValueParameter.cxx GenericContents.cxx \ + GenericPidfContents.cxx HEPSipMessageLoggingHandler.cxx \ + HeaderFieldValue.cxx HeaderFieldValueList.cxx \ + gen/HeaderHash.cxx HeaderTypes.cxx Headers.cxx Helper.cxx \ + IntegerParameter.cxx UInt32Parameter.cxx InternalTransport.cxx \ + LazyParser.cxx Message.cxx MessageWaitingContents.cxx \ + gen/MethodHash.cxx MethodTypes.cxx gen/MonthHash.cxx \ + MsgHeaderScanner.cxx MultipartAlternativeContents.cxx \ + MultipartMixedContents.cxx MultipartRelatedContents.cxx \ + MultipartSignedContents.cxx NonceHelper.cxx OctetContents.cxx \ + Parameter.cxx gen/ParameterHash.cxx ParameterTypes.cxx \ + ParserCategory.cxx ParserContainerBase.cxx Pidf.cxx \ + Pkcs7Contents.cxx Pkcs8Contents.cxx PlainContents.cxx \ + PrivacyCategory.cxx QuotedDataParameter.cxx RAckCategory.cxx \ + Rlmi.cxx RportParameter.cxx SERNonceHelper.cxx SdpContents.cxx \ + SecurityAttributes.cxx Compression.cxx SipConfigParse.cxx \ + SipFrag.cxx SipMessage.cxx SipStack.cxx StackThread.cxx \ + InterruptableStackThread.cxx EventStackThread.cxx \ + StatisticsHandler.cxx StatisticsManager.cxx \ + StatisticsMessage.cxx Symbols.cxx TcpBaseTransport.cxx \ + TcpConnection.cxx TcpConnectState.cxx TcpTransport.cxx \ + TimeAccumulate.cxx TimerMessage.cxx TimerQueue.cxx Tuple.cxx \ + TupleMarkManager.cxx TransactionController.cxx \ + MessageFilterRule.cxx TransactionUser.cxx \ + TransactionUserMessage.cxx TransactionMap.cxx \ + TransactionState.cxx Transport.cxx TransportThread.cxx \ + TransportFailure.cxx TransportSelector.cxx TuIM.cxx \ + TuSelector.cxx UdpTransport.cxx UnknownParameter.cxx Uri.cxx \ + X509Contents.cxx KeepAliveMessage.cxx StatelessHandler.cxx \ + InvalidContents.cxx WorkerThread.cxx WsBaseTransport.cxx \ + WsFrameExtractor.cxx WsTransport.cxx WsConnection.cxx \ + WsConnectionBase.cxx WsCookieContext.cxx WsDecorator.cxx \ + $(am__append_1) +SUFFIXES = .gperf .cxx +GPERFOPTS = -C -D -E -L C++ -t --key-positions='*' --compare-strncmp +resipincludedir = $(includedir)/resip/stack +nobase_resipinclude_HEADERS = AbandonServerTransaction.hxx \ + AddTransport.hxx \ + Aor.hxx \ + ApiCheck.hxx \ + ApiCheckList.hxx \ + ApplicationMessage.hxx \ + ApplicationSip.hxx \ + Auth.hxx \ + BasicDomainMatcher.hxx \ + BasicNonceHelper.hxx \ + BranchParameter.hxx \ + CallId.hxx \ + Cookie.hxx \ + CancelableTimerQueue.hxx \ + CancelClientInviteTransaction.hxx \ + Compression.hxx \ + ConnectionBase.hxx \ + Connection.hxx \ + ConnectionManager.hxx \ + ConnectionTerminated.hxx \ + ContentsFactoryBase.hxx \ + ContentsFactory.hxx \ + Contents.hxx \ + CpimContents.hxx \ + CSeqCategory.hxx \ + DataParameter.hxx \ + DateCategory.hxx \ + DeprecatedDialog.hxx \ + DialogInfoContents.hxx \ + Dispatcher.hxx \ + DomainMatcher.hxx \ + DnsInterface.hxx \ + DnsResult.hxx \ + DnsResultMessage.hxx \ + DtlsMessage.hxx \ + DtmfPayloadContents.hxx \ + Embedded.hxx \ + EnableFlowTimer.hxx \ + EventStackThread.hxx \ + ExistsOrDataParameter.hxx \ + ExistsParameter.hxx \ + ExpiresCategory.hxx \ + ExtendedDomainMatcher.hxx \ + ExtensionHeader.hxx \ + ExtensionParameter.hxx \ + ExternalBodyContents.hxx \ + FloatParameter.hxx \ + GenericContents.hxx \ + GenericPidfContents.hxx \ + GenericUri.hxx \ + HEPSipMessageLoggingHandler.hxx \ + HeaderFieldValue.hxx \ + HeaderFieldValueList.hxx \ + HeaderHash.hxx \ + Headers.hxx \ + HeaderTypes.hxx \ + Helper.hxx \ + IntegerCategory.hxx \ + IntegerParameter.hxx \ + InternalTransport.hxx \ + InteropHelper.hxx \ + InterruptableStackThread.hxx \ + InvalidContents.hxx \ + InvokeAfterSocketCreationFunc.hxx \ + KeepAliveMessage.hxx \ + KeepAlivePong.hxx \ + LazyParser.hxx \ + MarkListener.hxx \ + MessageDecorator.hxx \ + MessageFilterRule.hxx \ + Message.hxx \ + MessageWaitingContents.hxx \ + MethodHash.hxx \ + MethodTypes.hxx \ + Mime.hxx \ + MsgHeaderScanner.hxx \ + MultipartAlternativeContents.hxx \ + MultipartMixedContents.hxx \ + MultipartRelatedContents.hxx \ + MultipartSignedContents.hxx \ + NameAddr.hxx \ + NonceHelper.hxx \ + OctetContents.hxx \ + ParameterHash.hxx \ + Parameter.hxx \ + ParameterTypeEnums.hxx \ + ParameterTypes.hxx \ + ParserCategories.hxx \ + ParserCategory.hxx \ + ParserContainerBase.hxx \ + ParserContainer.hxx \ + Pidf.hxx \ + Pkcs7Contents.hxx \ + Pkcs8Contents.hxx \ + PlainContents.hxx \ + PollStatistics.hxx \ + PrivacyCategory.hxx \ + QuotedDataParameter.hxx \ + QValue.hxx \ + QValueParameter.hxx \ + RAckCategory.hxx \ + RemoveTransport.hxx \ + RequestLine.hxx \ + Rlmi.hxx \ + RportParameter.hxx \ + SdpContents.hxx \ + SecurityAttributes.hxx \ + SecurityTypes.hxx \ + SendData.hxx \ + SERNonceHelper.hxx \ + ShutdownMessage.hxx \ + SipConfigParse.hxx \ + SipFrag.hxx \ + SipMessage.hxx \ + SipStack.hxx \ + ssl/DtlsTransport.hxx \ + ssl/MacSecurity.hxx \ + ssl/Security.hxx \ + ssl/TlsBaseTransport.hxx \ + ssl/TlsConnection.hxx \ + ssl/TlsTransport.hxx \ + ssl/WinSecurity.hxx \ + ssl/WssTransport.hxx \ + ssl/WssConnection.hxx \ + StackThread.hxx \ + StartLine.hxx \ + StatelessHandler.hxx \ + StatisticsHandler.hxx \ + StatisticsManager.hxx \ + StatisticsMessage.hxx \ + StatusLine.hxx \ + StringCategory.hxx \ + Symbols.hxx \ + TcpBaseTransport.hxx \ + TcpConnection.hxx \ + TcpConnectState.hxx \ + TcpTransport.hxx \ + TerminateFlow.hxx \ + TimeAccumulate.hxx \ + TimerMessage.hxx \ + TimerQueue.hxx \ + Token.hxx \ + TokenOrQuotedStringCategory.hxx \ + TransactionController.hxx \ + TransactionControllerThread.hxx \ + TransactionMap.hxx \ + TransactionMessage.hxx \ + TransportSelectorThread.hxx \ + TransactionState.hxx \ + TransactionTerminated.hxx \ + TransactionUser.hxx \ + TransactionUserMessage.hxx \ + TransportFailure.hxx \ + Transport.hxx \ + TransportSelector.hxx \ + TransportThread.hxx \ + TuIM.hxx \ + Tuple.hxx \ + TupleMarkManager.hxx \ + TuSelector.hxx \ + UdpTransport.hxx \ + UInt32Category.hxx \ + UInt32Parameter.hxx \ + UnknownHeaderType.hxx \ + UnknownParameter.hxx \ + UnknownParameterType.hxx \ + Uri.hxx \ + ValueFifo.hxx \ + Via.hxx \ + WarningCategory.hxx \ + Worker.hxx \ + WorkerThread.hxx \ + WsBaseTransport.hxx \ + WsDecorator.hxx \ + WsFrameExtractor.hxx \ + WsTransport.hxx \ + WsConnection.hxx \ + WsConnectionBase.hxx \ + WsConnectionValidator.hxx \ + WsCookieContext.hxx \ + WsCookieContextFactory.hxx \ + X509Contents.hxx \ + ZeroOutStatistics.hxx + +all: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .gperf .cxx .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign resip/stack/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign resip/stack/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } +gen/$(am__dirstamp): + @$(MKDIR_P) gen + @: > gen/$(am__dirstamp) +gen/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) gen/$(DEPDIR) + @: > gen/$(DEPDIR)/$(am__dirstamp) +gen/DayOfWeekHash.lo: gen/$(am__dirstamp) \ + gen/$(DEPDIR)/$(am__dirstamp) +gen/HeaderHash.lo: gen/$(am__dirstamp) gen/$(DEPDIR)/$(am__dirstamp) +gen/MethodHash.lo: gen/$(am__dirstamp) gen/$(DEPDIR)/$(am__dirstamp) +gen/MonthHash.lo: gen/$(am__dirstamp) gen/$(DEPDIR)/$(am__dirstamp) +gen/ParameterHash.lo: gen/$(am__dirstamp) \ + gen/$(DEPDIR)/$(am__dirstamp) +ssl/$(am__dirstamp): + @$(MKDIR_P) ssl + @: > ssl/$(am__dirstamp) +ssl/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) ssl/$(DEPDIR) + @: > ssl/$(DEPDIR)/$(am__dirstamp) +ssl/DtlsTransport.lo: ssl/$(am__dirstamp) \ + ssl/$(DEPDIR)/$(am__dirstamp) +ssl/Security.lo: ssl/$(am__dirstamp) ssl/$(DEPDIR)/$(am__dirstamp) +ssl/TlsBaseTransport.lo: ssl/$(am__dirstamp) \ + ssl/$(DEPDIR)/$(am__dirstamp) +ssl/TlsConnection.lo: ssl/$(am__dirstamp) \ + ssl/$(DEPDIR)/$(am__dirstamp) +ssl/TlsTransport.lo: ssl/$(am__dirstamp) ssl/$(DEPDIR)/$(am__dirstamp) +ssl/WssTransport.lo: ssl/$(am__dirstamp) ssl/$(DEPDIR)/$(am__dirstamp) +ssl/WssConnection.lo: ssl/$(am__dirstamp) \ + ssl/$(DEPDIR)/$(am__dirstamp) + +libresip.la: $(libresip_la_OBJECTS) $(libresip_la_DEPENDENCIES) $(EXTRA_libresip_la_DEPENDENCIES) + $(AM_V_CXXLD)$(libresip_la_LINK) -rpath $(libdir) $(libresip_la_OBJECTS) $(libresip_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f gen/*.$(OBJEXT) + -rm -f gen/*.lo + -rm -f ssl/*.$(OBJEXT) + -rm -f ssl/*.lo + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Aor.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ApiCheck.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ApplicationSip.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Auth.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BasicDomainMatcher.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BasicNonceHelper.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BranchParameter.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CSeqCategory.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CallId.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Compression.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Connection.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ConnectionBase.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ConnectionManager.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Contents.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ContentsFactoryBase.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Cookie.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CpimContents.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DataParameter.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DateCategory.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DeprecatedDialog.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DialogInfoContents.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Dispatcher.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DnsInterface.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DnsResult.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DtlsMessage.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DtmfPayloadContents.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Embedded.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/EventStackThread.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ExistsOrDataParameter.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ExistsParameter.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ExpiresCategory.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ExtendedDomainMatcher.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ExtensionHeader.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ExtensionParameter.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ExternalBodyContents.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GenericContents.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GenericPidfContents.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GenericUri.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HEPSipMessageLoggingHandler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HeaderFieldValue.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HeaderFieldValueList.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HeaderTypes.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Headers.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Helper.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IntegerCategory.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IntegerParameter.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InternalTransport.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InteropHelper.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InterruptableStackThread.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InvalidContents.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/KeepAliveMessage.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LazyParser.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Message.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MessageFilterRule.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MessageWaitingContents.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MethodTypes.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Mime.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MsgHeaderScanner.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MultipartAlternativeContents.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MultipartMixedContents.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MultipartRelatedContents.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MultipartSignedContents.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NameAddr.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NonceHelper.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/OctetContents.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Parameter.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ParameterTypes.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ParserCategories.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ParserCategory.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ParserContainerBase.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Pidf.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Pkcs7Contents.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Pkcs8Contents.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PlainContents.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PrivacyCategory.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/QValue.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/QValueParameter.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/QuotedDataParameter.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RAckCategory.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestLine.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Rlmi.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RportParameter.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SERNonceHelper.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SdpContents.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SecurityAttributes.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SipConfigParse.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SipFrag.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SipMessage.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SipStack.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StackThread.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StatelessHandler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StatisticsHandler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StatisticsManager.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StatisticsMessage.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StatusLine.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StringCategory.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Symbols.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TcpBaseTransport.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TcpConnectState.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TcpConnection.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TcpTransport.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimeAccumulate.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimerMessage.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TimerQueue.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Token.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TokenOrQuotedStringCategory.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TransactionController.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TransactionMap.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TransactionState.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TransactionUser.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TransactionUserMessage.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Transport.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TransportFailure.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TransportSelector.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TransportThread.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TuIM.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TuSelector.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Tuple.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TupleMarkManager.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UInt32Category.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UInt32Parameter.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UdpTransport.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/UnknownParameter.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Uri.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Via.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/WarningCategory.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/WorkerThread.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/WsBaseTransport.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/WsConnection.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/WsConnectionBase.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/WsCookieContext.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/WsDecorator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/WsFrameExtractor.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/WsTransport.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/X509Contents.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@gen/$(DEPDIR)/DayOfWeekHash.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@gen/$(DEPDIR)/HeaderHash.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@gen/$(DEPDIR)/MethodHash.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@gen/$(DEPDIR)/MonthHash.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@gen/$(DEPDIR)/ParameterHash.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@ssl/$(DEPDIR)/DtlsTransport.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@ssl/$(DEPDIR)/Security.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@ssl/$(DEPDIR)/TlsBaseTransport.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@ssl/$(DEPDIR)/TlsConnection.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@ssl/$(DEPDIR)/TlsTransport.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@ssl/$(DEPDIR)/WssConnection.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@ssl/$(DEPDIR)/WssTransport.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.cxx.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cxx.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cxx.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf gen/.libs gen/_libs + -rm -rf ssl/.libs ssl/_libs +install-nobase_resipincludeHEADERS: $(nobase_resipinclude_HEADERS) + @$(NORMAL_INSTALL) + @list='$(nobase_resipinclude_HEADERS)'; test -n "$(resipincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(resipincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(resipincludedir)" || exit 1; \ + fi; \ + $(am__nobase_list) | while read dir files; do \ + xfiles=; for file in $$files; do \ + if test -f "$$file"; then xfiles="$$xfiles $$file"; \ + else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ + test -z "$$xfiles" || { \ + test "x$$dir" = x. || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(resipincludedir)/$$dir'"; \ + $(MKDIR_P) "$(DESTDIR)$(resipincludedir)/$$dir"; }; \ + echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(resipincludedir)/$$dir'"; \ + $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(resipincludedir)/$$dir" || exit $$?; }; \ + done + +uninstall-nobase_resipincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nobase_resipinclude_HEADERS)'; test -n "$(resipincludedir)" || list=; \ + $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ + dir='$(DESTDIR)$(resipincludedir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) check-recursive +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(resipincludedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f gen/$(DEPDIR)/$(am__dirstamp) + -rm -f gen/$(am__dirstamp) + -rm -f ssl/$(DEPDIR)/$(am__dirstamp) + -rm -f ssl/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES) +clean: clean-recursive + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-recursive + -rm -f ./$(DEPDIR)/Aor.Plo + -rm -f ./$(DEPDIR)/ApiCheck.Plo + -rm -f ./$(DEPDIR)/ApplicationSip.Plo + -rm -f ./$(DEPDIR)/Auth.Plo + -rm -f ./$(DEPDIR)/BasicDomainMatcher.Plo + -rm -f ./$(DEPDIR)/BasicNonceHelper.Plo + -rm -f ./$(DEPDIR)/BranchParameter.Plo + -rm -f ./$(DEPDIR)/CSeqCategory.Plo + -rm -f ./$(DEPDIR)/CallId.Plo + -rm -f ./$(DEPDIR)/Compression.Plo + -rm -f ./$(DEPDIR)/Connection.Plo + -rm -f ./$(DEPDIR)/ConnectionBase.Plo + -rm -f ./$(DEPDIR)/ConnectionManager.Plo + -rm -f ./$(DEPDIR)/Contents.Plo + -rm -f ./$(DEPDIR)/ContentsFactoryBase.Plo + -rm -f ./$(DEPDIR)/Cookie.Plo + -rm -f ./$(DEPDIR)/CpimContents.Plo + -rm -f ./$(DEPDIR)/DataParameter.Plo + -rm -f ./$(DEPDIR)/DateCategory.Plo + -rm -f ./$(DEPDIR)/DeprecatedDialog.Plo + -rm -f ./$(DEPDIR)/DialogInfoContents.Plo + -rm -f ./$(DEPDIR)/Dispatcher.Plo + -rm -f ./$(DEPDIR)/DnsInterface.Plo + -rm -f ./$(DEPDIR)/DnsResult.Plo + -rm -f ./$(DEPDIR)/DtlsMessage.Plo + -rm -f ./$(DEPDIR)/DtmfPayloadContents.Plo + -rm -f ./$(DEPDIR)/Embedded.Plo + -rm -f ./$(DEPDIR)/EventStackThread.Plo + -rm -f ./$(DEPDIR)/ExistsOrDataParameter.Plo + -rm -f ./$(DEPDIR)/ExistsParameter.Plo + -rm -f ./$(DEPDIR)/ExpiresCategory.Plo + -rm -f ./$(DEPDIR)/ExtendedDomainMatcher.Plo + -rm -f ./$(DEPDIR)/ExtensionHeader.Plo + -rm -f ./$(DEPDIR)/ExtensionParameter.Plo + -rm -f ./$(DEPDIR)/ExternalBodyContents.Plo + -rm -f ./$(DEPDIR)/GenericContents.Plo + -rm -f ./$(DEPDIR)/GenericPidfContents.Plo + -rm -f ./$(DEPDIR)/GenericUri.Plo + -rm -f ./$(DEPDIR)/HEPSipMessageLoggingHandler.Plo + -rm -f ./$(DEPDIR)/HeaderFieldValue.Plo + -rm -f ./$(DEPDIR)/HeaderFieldValueList.Plo + -rm -f ./$(DEPDIR)/HeaderTypes.Plo + -rm -f ./$(DEPDIR)/Headers.Plo + -rm -f ./$(DEPDIR)/Helper.Plo + -rm -f ./$(DEPDIR)/IntegerCategory.Plo + -rm -f ./$(DEPDIR)/IntegerParameter.Plo + -rm -f ./$(DEPDIR)/InternalTransport.Plo + -rm -f ./$(DEPDIR)/InteropHelper.Plo + -rm -f ./$(DEPDIR)/InterruptableStackThread.Plo + -rm -f ./$(DEPDIR)/InvalidContents.Plo + -rm -f ./$(DEPDIR)/KeepAliveMessage.Plo + -rm -f ./$(DEPDIR)/LazyParser.Plo + -rm -f ./$(DEPDIR)/Message.Plo + -rm -f ./$(DEPDIR)/MessageFilterRule.Plo + -rm -f ./$(DEPDIR)/MessageWaitingContents.Plo + -rm -f ./$(DEPDIR)/MethodTypes.Plo + -rm -f ./$(DEPDIR)/Mime.Plo + -rm -f ./$(DEPDIR)/MsgHeaderScanner.Plo + -rm -f ./$(DEPDIR)/MultipartAlternativeContents.Plo + -rm -f ./$(DEPDIR)/MultipartMixedContents.Plo + -rm -f ./$(DEPDIR)/MultipartRelatedContents.Plo + -rm -f ./$(DEPDIR)/MultipartSignedContents.Plo + -rm -f ./$(DEPDIR)/NameAddr.Plo + -rm -f ./$(DEPDIR)/NonceHelper.Plo + -rm -f ./$(DEPDIR)/OctetContents.Plo + -rm -f ./$(DEPDIR)/Parameter.Plo + -rm -f ./$(DEPDIR)/ParameterTypes.Plo + -rm -f ./$(DEPDIR)/ParserCategories.Plo + -rm -f ./$(DEPDIR)/ParserCategory.Plo + -rm -f ./$(DEPDIR)/ParserContainerBase.Plo + -rm -f ./$(DEPDIR)/Pidf.Plo + -rm -f ./$(DEPDIR)/Pkcs7Contents.Plo + -rm -f ./$(DEPDIR)/Pkcs8Contents.Plo + -rm -f ./$(DEPDIR)/PlainContents.Plo + -rm -f ./$(DEPDIR)/PrivacyCategory.Plo + -rm -f ./$(DEPDIR)/QValue.Plo + -rm -f ./$(DEPDIR)/QValueParameter.Plo + -rm -f ./$(DEPDIR)/QuotedDataParameter.Plo + -rm -f ./$(DEPDIR)/RAckCategory.Plo + -rm -f ./$(DEPDIR)/RequestLine.Plo + -rm -f ./$(DEPDIR)/Rlmi.Plo + -rm -f ./$(DEPDIR)/RportParameter.Plo + -rm -f ./$(DEPDIR)/SERNonceHelper.Plo + -rm -f ./$(DEPDIR)/SdpContents.Plo + -rm -f ./$(DEPDIR)/SecurityAttributes.Plo + -rm -f ./$(DEPDIR)/SipConfigParse.Plo + -rm -f ./$(DEPDIR)/SipFrag.Plo + -rm -f ./$(DEPDIR)/SipMessage.Plo + -rm -f ./$(DEPDIR)/SipStack.Plo + -rm -f ./$(DEPDIR)/StackThread.Plo + -rm -f ./$(DEPDIR)/StatelessHandler.Plo + -rm -f ./$(DEPDIR)/StatisticsHandler.Plo + -rm -f ./$(DEPDIR)/StatisticsManager.Plo + -rm -f ./$(DEPDIR)/StatisticsMessage.Plo + -rm -f ./$(DEPDIR)/StatusLine.Plo + -rm -f ./$(DEPDIR)/StringCategory.Plo + -rm -f ./$(DEPDIR)/Symbols.Plo + -rm -f ./$(DEPDIR)/TcpBaseTransport.Plo + -rm -f ./$(DEPDIR)/TcpConnectState.Plo + -rm -f ./$(DEPDIR)/TcpConnection.Plo + -rm -f ./$(DEPDIR)/TcpTransport.Plo + -rm -f ./$(DEPDIR)/TimeAccumulate.Plo + -rm -f ./$(DEPDIR)/TimerMessage.Plo + -rm -f ./$(DEPDIR)/TimerQueue.Plo + -rm -f ./$(DEPDIR)/Token.Plo + -rm -f ./$(DEPDIR)/TokenOrQuotedStringCategory.Plo + -rm -f ./$(DEPDIR)/TransactionController.Plo + -rm -f ./$(DEPDIR)/TransactionMap.Plo + -rm -f ./$(DEPDIR)/TransactionState.Plo + -rm -f ./$(DEPDIR)/TransactionUser.Plo + -rm -f ./$(DEPDIR)/TransactionUserMessage.Plo + -rm -f ./$(DEPDIR)/Transport.Plo + -rm -f ./$(DEPDIR)/TransportFailure.Plo + -rm -f ./$(DEPDIR)/TransportSelector.Plo + -rm -f ./$(DEPDIR)/TransportThread.Plo + -rm -f ./$(DEPDIR)/TuIM.Plo + -rm -f ./$(DEPDIR)/TuSelector.Plo + -rm -f ./$(DEPDIR)/Tuple.Plo + -rm -f ./$(DEPDIR)/TupleMarkManager.Plo + -rm -f ./$(DEPDIR)/UInt32Category.Plo + -rm -f ./$(DEPDIR)/UInt32Parameter.Plo + -rm -f ./$(DEPDIR)/UdpTransport.Plo + -rm -f ./$(DEPDIR)/UnknownParameter.Plo + -rm -f ./$(DEPDIR)/Uri.Plo + -rm -f ./$(DEPDIR)/Via.Plo + -rm -f ./$(DEPDIR)/WarningCategory.Plo + -rm -f ./$(DEPDIR)/WorkerThread.Plo + -rm -f ./$(DEPDIR)/WsBaseTransport.Plo + -rm -f ./$(DEPDIR)/WsConnection.Plo + -rm -f ./$(DEPDIR)/WsConnectionBase.Plo + -rm -f ./$(DEPDIR)/WsCookieContext.Plo + -rm -f ./$(DEPDIR)/WsDecorator.Plo + -rm -f ./$(DEPDIR)/WsFrameExtractor.Plo + -rm -f ./$(DEPDIR)/WsTransport.Plo + -rm -f ./$(DEPDIR)/X509Contents.Plo + -rm -f gen/$(DEPDIR)/DayOfWeekHash.Plo + -rm -f gen/$(DEPDIR)/HeaderHash.Plo + -rm -f gen/$(DEPDIR)/MethodHash.Plo + -rm -f gen/$(DEPDIR)/MonthHash.Plo + -rm -f gen/$(DEPDIR)/ParameterHash.Plo + -rm -f ssl/$(DEPDIR)/DtlsTransport.Plo + -rm -f ssl/$(DEPDIR)/Security.Plo + -rm -f ssl/$(DEPDIR)/TlsBaseTransport.Plo + -rm -f ssl/$(DEPDIR)/TlsConnection.Plo + -rm -f ssl/$(DEPDIR)/TlsTransport.Plo + -rm -f ssl/$(DEPDIR)/WssConnection.Plo + -rm -f ssl/$(DEPDIR)/WssTransport.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-nobase_resipincludeHEADERS + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f ./$(DEPDIR)/Aor.Plo + -rm -f ./$(DEPDIR)/ApiCheck.Plo + -rm -f ./$(DEPDIR)/ApplicationSip.Plo + -rm -f ./$(DEPDIR)/Auth.Plo + -rm -f ./$(DEPDIR)/BasicDomainMatcher.Plo + -rm -f ./$(DEPDIR)/BasicNonceHelper.Plo + -rm -f ./$(DEPDIR)/BranchParameter.Plo + -rm -f ./$(DEPDIR)/CSeqCategory.Plo + -rm -f ./$(DEPDIR)/CallId.Plo + -rm -f ./$(DEPDIR)/Compression.Plo + -rm -f ./$(DEPDIR)/Connection.Plo + -rm -f ./$(DEPDIR)/ConnectionBase.Plo + -rm -f ./$(DEPDIR)/ConnectionManager.Plo + -rm -f ./$(DEPDIR)/Contents.Plo + -rm -f ./$(DEPDIR)/ContentsFactoryBase.Plo + -rm -f ./$(DEPDIR)/Cookie.Plo + -rm -f ./$(DEPDIR)/CpimContents.Plo + -rm -f ./$(DEPDIR)/DataParameter.Plo + -rm -f ./$(DEPDIR)/DateCategory.Plo + -rm -f ./$(DEPDIR)/DeprecatedDialog.Plo + -rm -f ./$(DEPDIR)/DialogInfoContents.Plo + -rm -f ./$(DEPDIR)/Dispatcher.Plo + -rm -f ./$(DEPDIR)/DnsInterface.Plo + -rm -f ./$(DEPDIR)/DnsResult.Plo + -rm -f ./$(DEPDIR)/DtlsMessage.Plo + -rm -f ./$(DEPDIR)/DtmfPayloadContents.Plo + -rm -f ./$(DEPDIR)/Embedded.Plo + -rm -f ./$(DEPDIR)/EventStackThread.Plo + -rm -f ./$(DEPDIR)/ExistsOrDataParameter.Plo + -rm -f ./$(DEPDIR)/ExistsParameter.Plo + -rm -f ./$(DEPDIR)/ExpiresCategory.Plo + -rm -f ./$(DEPDIR)/ExtendedDomainMatcher.Plo + -rm -f ./$(DEPDIR)/ExtensionHeader.Plo + -rm -f ./$(DEPDIR)/ExtensionParameter.Plo + -rm -f ./$(DEPDIR)/ExternalBodyContents.Plo + -rm -f ./$(DEPDIR)/GenericContents.Plo + -rm -f ./$(DEPDIR)/GenericPidfContents.Plo + -rm -f ./$(DEPDIR)/GenericUri.Plo + -rm -f ./$(DEPDIR)/HEPSipMessageLoggingHandler.Plo + -rm -f ./$(DEPDIR)/HeaderFieldValue.Plo + -rm -f ./$(DEPDIR)/HeaderFieldValueList.Plo + -rm -f ./$(DEPDIR)/HeaderTypes.Plo + -rm -f ./$(DEPDIR)/Headers.Plo + -rm -f ./$(DEPDIR)/Helper.Plo + -rm -f ./$(DEPDIR)/IntegerCategory.Plo + -rm -f ./$(DEPDIR)/IntegerParameter.Plo + -rm -f ./$(DEPDIR)/InternalTransport.Plo + -rm -f ./$(DEPDIR)/InteropHelper.Plo + -rm -f ./$(DEPDIR)/InterruptableStackThread.Plo + -rm -f ./$(DEPDIR)/InvalidContents.Plo + -rm -f ./$(DEPDIR)/KeepAliveMessage.Plo + -rm -f ./$(DEPDIR)/LazyParser.Plo + -rm -f ./$(DEPDIR)/Message.Plo + -rm -f ./$(DEPDIR)/MessageFilterRule.Plo + -rm -f ./$(DEPDIR)/MessageWaitingContents.Plo + -rm -f ./$(DEPDIR)/MethodTypes.Plo + -rm -f ./$(DEPDIR)/Mime.Plo + -rm -f ./$(DEPDIR)/MsgHeaderScanner.Plo + -rm -f ./$(DEPDIR)/MultipartAlternativeContents.Plo + -rm -f ./$(DEPDIR)/MultipartMixedContents.Plo + -rm -f ./$(DEPDIR)/MultipartRelatedContents.Plo + -rm -f ./$(DEPDIR)/MultipartSignedContents.Plo + -rm -f ./$(DEPDIR)/NameAddr.Plo + -rm -f ./$(DEPDIR)/NonceHelper.Plo + -rm -f ./$(DEPDIR)/OctetContents.Plo + -rm -f ./$(DEPDIR)/Parameter.Plo + -rm -f ./$(DEPDIR)/ParameterTypes.Plo + -rm -f ./$(DEPDIR)/ParserCategories.Plo + -rm -f ./$(DEPDIR)/ParserCategory.Plo + -rm -f ./$(DEPDIR)/ParserContainerBase.Plo + -rm -f ./$(DEPDIR)/Pidf.Plo + -rm -f ./$(DEPDIR)/Pkcs7Contents.Plo + -rm -f ./$(DEPDIR)/Pkcs8Contents.Plo + -rm -f ./$(DEPDIR)/PlainContents.Plo + -rm -f ./$(DEPDIR)/PrivacyCategory.Plo + -rm -f ./$(DEPDIR)/QValue.Plo + -rm -f ./$(DEPDIR)/QValueParameter.Plo + -rm -f ./$(DEPDIR)/QuotedDataParameter.Plo + -rm -f ./$(DEPDIR)/RAckCategory.Plo + -rm -f ./$(DEPDIR)/RequestLine.Plo + -rm -f ./$(DEPDIR)/Rlmi.Plo + -rm -f ./$(DEPDIR)/RportParameter.Plo + -rm -f ./$(DEPDIR)/SERNonceHelper.Plo + -rm -f ./$(DEPDIR)/SdpContents.Plo + -rm -f ./$(DEPDIR)/SecurityAttributes.Plo + -rm -f ./$(DEPDIR)/SipConfigParse.Plo + -rm -f ./$(DEPDIR)/SipFrag.Plo + -rm -f ./$(DEPDIR)/SipMessage.Plo + -rm -f ./$(DEPDIR)/SipStack.Plo + -rm -f ./$(DEPDIR)/StackThread.Plo + -rm -f ./$(DEPDIR)/StatelessHandler.Plo + -rm -f ./$(DEPDIR)/StatisticsHandler.Plo + -rm -f ./$(DEPDIR)/StatisticsManager.Plo + -rm -f ./$(DEPDIR)/StatisticsMessage.Plo + -rm -f ./$(DEPDIR)/StatusLine.Plo + -rm -f ./$(DEPDIR)/StringCategory.Plo + -rm -f ./$(DEPDIR)/Symbols.Plo + -rm -f ./$(DEPDIR)/TcpBaseTransport.Plo + -rm -f ./$(DEPDIR)/TcpConnectState.Plo + -rm -f ./$(DEPDIR)/TcpConnection.Plo + -rm -f ./$(DEPDIR)/TcpTransport.Plo + -rm -f ./$(DEPDIR)/TimeAccumulate.Plo + -rm -f ./$(DEPDIR)/TimerMessage.Plo + -rm -f ./$(DEPDIR)/TimerQueue.Plo + -rm -f ./$(DEPDIR)/Token.Plo + -rm -f ./$(DEPDIR)/TokenOrQuotedStringCategory.Plo + -rm -f ./$(DEPDIR)/TransactionController.Plo + -rm -f ./$(DEPDIR)/TransactionMap.Plo + -rm -f ./$(DEPDIR)/TransactionState.Plo + -rm -f ./$(DEPDIR)/TransactionUser.Plo + -rm -f ./$(DEPDIR)/TransactionUserMessage.Plo + -rm -f ./$(DEPDIR)/Transport.Plo + -rm -f ./$(DEPDIR)/TransportFailure.Plo + -rm -f ./$(DEPDIR)/TransportSelector.Plo + -rm -f ./$(DEPDIR)/TransportThread.Plo + -rm -f ./$(DEPDIR)/TuIM.Plo + -rm -f ./$(DEPDIR)/TuSelector.Plo + -rm -f ./$(DEPDIR)/Tuple.Plo + -rm -f ./$(DEPDIR)/TupleMarkManager.Plo + -rm -f ./$(DEPDIR)/UInt32Category.Plo + -rm -f ./$(DEPDIR)/UInt32Parameter.Plo + -rm -f ./$(DEPDIR)/UdpTransport.Plo + -rm -f ./$(DEPDIR)/UnknownParameter.Plo + -rm -f ./$(DEPDIR)/Uri.Plo + -rm -f ./$(DEPDIR)/Via.Plo + -rm -f ./$(DEPDIR)/WarningCategory.Plo + -rm -f ./$(DEPDIR)/WorkerThread.Plo + -rm -f ./$(DEPDIR)/WsBaseTransport.Plo + -rm -f ./$(DEPDIR)/WsConnection.Plo + -rm -f ./$(DEPDIR)/WsConnectionBase.Plo + -rm -f ./$(DEPDIR)/WsCookieContext.Plo + -rm -f ./$(DEPDIR)/WsDecorator.Plo + -rm -f ./$(DEPDIR)/WsFrameExtractor.Plo + -rm -f ./$(DEPDIR)/WsTransport.Plo + -rm -f ./$(DEPDIR)/X509Contents.Plo + -rm -f gen/$(DEPDIR)/DayOfWeekHash.Plo + -rm -f gen/$(DEPDIR)/HeaderHash.Plo + -rm -f gen/$(DEPDIR)/MethodHash.Plo + -rm -f gen/$(DEPDIR)/MonthHash.Plo + -rm -f gen/$(DEPDIR)/ParameterHash.Plo + -rm -f ssl/$(DEPDIR)/DtlsTransport.Plo + -rm -f ssl/$(DEPDIR)/Security.Plo + -rm -f ssl/$(DEPDIR)/TlsBaseTransport.Plo + -rm -f ssl/$(DEPDIR)/TlsConnection.Plo + -rm -f ssl/$(DEPDIR)/TlsTransport.Plo + -rm -f ssl/$(DEPDIR)/WssConnection.Plo + -rm -f ssl/$(DEPDIR)/WssTransport.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES \ + uninstall-nobase_resipincludeHEADERS + +.MAKE: $(am__recursive_targets) all check install install-am \ + install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--depfiles check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-libLTLIBRARIES install-man \ + install-nobase_resipincludeHEADERS install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES \ + uninstall-nobase_resipincludeHEADERS + +.PRECIOUS: Makefile + +#GPERFVER="GNU gperf 2.7.2" + +# rule for case sensitive sorts of hash +gen/MethodHash.cxx: MethodHash.gperf + mkdir -p $(abs_srcdir)/gen + gperf $(GPERFOPTS) -Z MethodHash $< > $@ + +# note: the Date header field is case sensitive (RFC 3261 s20.17) +gen/DayOfWeekHash.cxx: DayOfWeekHash.gperf + mkdir -p $(abs_srcdir)/gen + gperf $(GPERFOPTS) -Z DayOfWeekHash $< > $@ +gen/MonthHash.cxx: MonthHash.gperf + mkdir -p $(abs_srcdir)/gen + gperf $(GPERFOPTS) -Z MonthHash $< > $@ + +# rule for insensitive clods +#${SRC}: ${@:%.cxx=%.gperf} -- more portable? +gen/%.cxx: %.gperf + mkdir -p $(abs_srcdir)/gen + gperf $(GPERFOPTS) --ignore-case -Z $* $< > $@ + +############################################################################## +# +# The Vovida Software License, Version 1.0 +# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The names "VOCAL", "Vovida Open Communication Application Library", +# and "Vovida Open Communication Application Library (VOCAL)" must +# not be used to endorse or promote products derived from this +# software without prior written permission. For written +# permission, please contact vocal@vovida.org. +# +# 4. Products derived from this software may not be called "VOCAL", nor +# may "VOCAL" appear in their name, without prior written +# permission of Vovida Networks, Inc. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. +# +# ==================================================================== +# +# This software consists of voluntary contributions made by Vovida +# Networks, Inc. and many individuals on behalf of Vovida Networks, +# Inc. For more information on Vovida Networks, Inc., please see +# . +# +############################################################################## + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libs/resiprocate/resip/stack/Message.cxx b/src/libs/resiprocate/resip/stack/Message.cxx index b94aedf5..14dbcc70 100644 --- a/src/libs/resiprocate/resip/stack/Message.cxx +++ b/src/libs/resiprocate/resip/stack/Message.cxx @@ -4,7 +4,7 @@ #include "resip/stack/Message.hxx" #include "rutil/DataStream.hxx" -#include +#include "rutil/ResipAssert.h" using namespace resip; @@ -23,7 +23,6 @@ Message::Brief::Brief(const Message& source) : { } -#ifndef RESIP_USE_STL_STREAMS std::ostream& resip::operator<<(std::ostream& strm, const resip::Message& msg) @@ -53,8 +52,8 @@ resip::operator<<(std::ostream& strm, return strm; } -#endif +#ifndef RESIP_USE_STL_STREAMS EncodeStream& resip::operator<<(EncodeStream& strm, const resip::Message& msg) @@ -68,6 +67,7 @@ resip::operator<<(EncodeStream& strm, { return brief.mSource.encodeBrief(strm); } +#endif /* ==================================================================== * The Vovida Software License, Version 1.0 diff --git a/src/libs/resiprocate/resip/stack/MessageFilterRule.cxx b/src/libs/resiprocate/resip/stack/MessageFilterRule.cxx index 4376ba13..e3652d44 100644 --- a/src/libs/resiprocate/resip/stack/MessageFilterRule.cxx +++ b/src/libs/resiprocate/resip/stack/MessageFilterRule.cxx @@ -42,12 +42,11 @@ MessageFilterRule::MessageFilterRule(SchemeList schemeList, bool MessageFilterRule::matches(const SipMessage &msg) const { - DebugLog(<< "Matching rule for: " << std::endl << std::endl << msg); const Data scheme = msg.header(h_RequestLine).uri().scheme(); if (!schemeIsInList(scheme)) { - DebugLog(<< "Scheme is not in list. Rule does not match."); + DebugLog(<< " MessageFilterRule::matches: Scheme is not in list. Rule does not match."); return false; } @@ -56,7 +55,7 @@ MessageFilterRule::matches(const SipMessage &msg) const // !rwm! Should be hostport, not host if (!hostIsInList( msg.header(h_RequestLine).uri().host())) { - DebugLog(<< "Host is not in list. Rule does not match."); + DebugLog(<< " MessageFilterRule::matches: Host is not in list. Rule does not match."); return false; } } @@ -64,7 +63,7 @@ MessageFilterRule::matches(const SipMessage &msg) const MethodTypes method = msg.header(h_RequestLine).method(); if (!methodIsInList(method)) { - DebugLog(<< "Method is not in list. Rule does not match."); + DebugLog(<< " MessageFilterRule::matches: Method is not in list. Rule does not match."); return false; } else @@ -76,7 +75,7 @@ MessageFilterRule::matches(const SipMessage &msg) const case PUBLISH: if (!eventIsInList(msg)) { - DebugLog(<< "Event is not in list. Rule does not match."); + DebugLog(<< " MessageFilterRule::matches: Event is not in list. Rule does not match."); return false; } break; diff --git a/src/libs/resiprocate/resip/stack/MessageWaitingContents.cxx b/src/libs/resiprocate/resip/stack/MessageWaitingContents.cxx index ae2a8346..3c105776 100644 --- a/src/libs/resiprocate/resip/stack/MessageWaitingContents.cxx +++ b/src/libs/resiprocate/resip/stack/MessageWaitingContents.cxx @@ -6,7 +6,7 @@ #include "rutil/Logger.hxx" #include "rutil/ParseBuffer.hxx" #include "rutil/WinLeakCheck.hxx" -#include + using namespace resip; using namespace std; @@ -60,7 +60,7 @@ MessageWaitingContents::MessageWaitingContents(const Data& data, const Mime& con { mHeaders[i] = 0; } - assert(0); + resip_assert(0); } MessageWaitingContents::MessageWaitingContents(const MessageWaitingContents& rhs) @@ -271,7 +271,7 @@ resip::skipSipLWS(ParseBuffer& pb) } break; default: - assert(false); + resip_assert(false); } } pb.skipChar(); @@ -359,7 +359,7 @@ MessageWaitingContents::parse(ParseBuffer& pb) default : pb.fail(__FILE__, __LINE__); } - assert(ht != -1); + resip_assert(ht != -1); pb.skipToOneOf(ParseBuffer::Whitespace, Symbols::COLON); pb.skipWhitespace(); @@ -597,7 +597,7 @@ MessageWaitingContents::header(const Data& hn) const "code, before we _do_ start throwing. This is why const-correctness" " should never be made a TODO item "); MessageWaitingContents* ncthis = const_cast(this); - h=ncthis->mExtensions.insert(std::pair(hn,Data::Empty)).first; + h=ncthis->mExtensions.insert(std::make_pair(hn,Data::Empty)).first; } return h->second; } diff --git a/src/libs/resiprocate/resip/stack/MethodHash.hxx b/src/libs/resiprocate/resip/stack/MethodHash.hxx index 15e23bbc..72984fee 100644 --- a/src/libs/resiprocate/resip/stack/MethodHash.hxx +++ b/src/libs/resiprocate/resip/stack/MethodHash.hxx @@ -1,17 +1,20 @@ #if !defined(RESIP_METHODSHASH_HXX) #define RESIP_METHODSHASH_HXX + +#include "rutil/compat.hxx" + namespace resip { -struct methods { char *name; MethodTypes type; }; +struct methods { const char *name; MethodTypes type; }; /* maximum key range = 494, duplicates = 0 */ class MethodHash { private: - static inline unsigned int hash (const char *str, unsigned int len); + static inline unsigned int hash (const char *str, GPERF_SIZE_TYPE len); public: - static const struct methods *in_word_set (const char *str, unsigned int len); + static const struct methods *in_word_set (const char *str, GPERF_SIZE_TYPE len); }; // NOTE the cxx file for this class is AUTO GENERATED. DO NOT EDIT IT. // This file should match it. BUT THIS FILE IS MANUALLY GENERATED. diff --git a/src/libs/resiprocate/resip/stack/MethodTypes.cxx b/src/libs/resiprocate/resip/stack/MethodTypes.cxx index 0078bad6..4caa1a74 100644 --- a/src/libs/resiprocate/resip/stack/MethodTypes.cxx +++ b/src/libs/resiprocate/resip/stack/MethodTypes.cxx @@ -4,7 +4,7 @@ #include #include -#include +#include "rutil/ResipAssert.h" #include "resip/stack/MethodTypes.hxx" #include "resip/stack/Symbols.hxx" diff --git a/src/libs/resiprocate/resip/stack/Mime.hxx b/src/libs/resiprocate/resip/stack/Mime.hxx index 9b05afbd..e86c135d 100644 --- a/src/libs/resiprocate/resip/stack/Mime.hxx +++ b/src/libs/resiprocate/resip/stack/Mime.hxx @@ -77,7 +77,7 @@ class Mime : public ParserCategory defineParam(size, "size", DataParameter, "RFC 2046"); defineParam(smimeType, "smime-type", DataParameter, "RFC 2633"); defineParam(url, "url", QuotedDataParameter, "RFC 4483"); - + #undef defineParam private: diff --git a/src/libs/resiprocate/resip/stack/MonthHash.gperf b/src/libs/resiprocate/resip/stack/MonthHash.gperf new file mode 100644 index 00000000..d98e72b8 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/MonthHash.gperf @@ -0,0 +1,24 @@ +%{ +#include +#include +#include "resip/stack/DateCategory.hxx" + +namespace resip +{ +%} +struct months { const char *name; Month type; }; +%% +Jan, Jan +Feb, Feb +Mar, Mar +Apr, Apr +May, May +Jun, Jun +Jul, Jul +Aug, Aug +Sep, Sep +Oct, Oct +Nov, Nov +Dec, Dec +%% +} diff --git a/src/libs/resiprocate/resip/stack/MultipartMixedContents.cxx b/src/libs/resiprocate/resip/stack/MultipartMixedContents.cxx index afc97982..c30a2b60 100644 --- a/src/libs/resiprocate/resip/stack/MultipartMixedContents.cxx +++ b/src/libs/resiprocate/resip/stack/MultipartMixedContents.cxx @@ -62,7 +62,7 @@ MultipartMixedContents::MultipartMixedContents(const MultipartMixedContents& rhs for ( j = list.begin(); j != list.end(); ++j) { - assert( *j ); + resip_assert( *j ); mContents.push_back( (*j)->clone() ); } } @@ -134,7 +134,7 @@ MultipartMixedContents::encodeParsed(EncodeStream& str) const boundary += boundaryToken; boundary.replace("\"", ""); // remove quotes - assert( mContents.size() > 0 ); + resip_assert( mContents.size() > 0 ); bool first = true; for (vector::const_iterator i = mContents.begin(); @@ -153,7 +153,8 @@ MultipartMixedContents::encodeParsed(EncodeStream& str) const (*i)->encode(str); } - str << Symbols::CRLF << boundary << Symbols::DASHDASH; + // Note: last CRLF isn't strictly required by RFC2046 ABNF, but some implementations seem to require it so we include it + str << Symbols::CRLF << boundary << Symbols::DASHDASH << Symbols::CRLF; return str; } diff --git a/src/libs/resiprocate/resip/stack/NameAddr.cxx b/src/libs/resiprocate/resip/stack/NameAddr.cxx index 8c37f857..e52d33dd 100644 --- a/src/libs/resiprocate/resip/stack/NameAddr.cxx +++ b/src/libs/resiprocate/resip/stack/NameAddr.cxx @@ -84,7 +84,7 @@ NameAddr::operator=(const NameAddr& rhs) { if (this != &rhs) { - assert( &rhs != 0 ); + resip_assert( &rhs != 0 ); ParserCategory::operator=(rhs); mAllContacts = rhs.mAllContacts; @@ -97,7 +97,9 @@ NameAddr::operator=(const NameAddr& rhs) bool NameAddr::operator==(const NameAddr& other) const { - return uri() == other.uri() && displayName() == other.displayName(); + return mAllContacts == other.mAllContacts && + uri() == other.uri() && + displayName() == other.displayName(); } bool @@ -246,7 +248,7 @@ NameAddr::parse(ParseBuffer& pb) { if(mUri.mUnknownParameters.size() > 0) { - assert(!mUnknownUriParametersBuffer); + resip_assert(!mUnknownUriParametersBuffer); mUnknownUriParametersBuffer = new Data; { // Scope stream oDataStream str(*mUnknownUriParametersBuffer); @@ -496,6 +498,10 @@ defineParam(tempGruu, "temp-gruu", QuotedDataParameter, "RFC 5627"); defineParam(expires, "expires", UInt32Parameter, "RFC 3261"); defineParam(q, "q", QValueParameter, "RFC 3261"); defineParam(tag, "tag", DataParameter, "RFC 3261"); +defineParam(index, "index", DataParameter, "RFC 4244"); +defineParam(rc, "rc", DataParameter, "RFC 4244-bis"); +defineParam(mp, "mp", DataParameter, "RFC 4244-bis"); +defineParam(np, "np", DataParameter, "RFC 4244-bis"); #undef defineParam diff --git a/src/libs/resiprocate/resip/stack/NameAddr.hxx b/src/libs/resiprocate/resip/stack/NameAddr.hxx index 02910c8f..083b2fda 100644 --- a/src/libs/resiprocate/resip/stack/NameAddr.hxx +++ b/src/libs/resiprocate/resip/stack/NameAddr.hxx @@ -89,6 +89,10 @@ class NameAddr : public ParserCategory defineParam(expires, "expires", UInt32Parameter, "RFC 3261"); defineParam(q, "q", QValueParameter, "RFC 3261"); defineParam(tag, "tag", DataParameter, "RFC 3261"); + defineParam(index, "index", DataParameter, "RFC 4244"); + defineParam(rc, "rc", DataParameter, "RFC 4244-bis"); + defineParam(mp, "mp", DataParameter, "RFC 4244-bis"); + defineParam(np, "np", DataParameter, "RFC 4244-bis"); #undef defineParam diff --git a/src/libs/resiprocate/resip/stack/ParameterHash.gperf b/src/libs/resiprocate/resip/stack/ParameterHash.gperf index 5012c063..2ccb0d7d 100644 --- a/src/libs/resiprocate/resip/stack/ParameterHash.gperf +++ b/src/libs/resiprocate/resip/stack/ParameterHash.gperf @@ -96,6 +96,22 @@ app-id, ParameterTypes::appId network-user, ParameterTypes::networkUser url, ParameterTypes::url sigcomp-id, ParameterTypes::sigcompId +index, ParameterTypes::index +rc, ParameterTypes::rc +mp, ParameterTypes::mp +np, ParameterTypes::np +utran-cell-id-3gpp, ParameterTypes::utranCellId3gpp +cgi-3gpp, ParameterTypes::cgi3gpp +ccf, ParameterTypes::ccf +ecf, ParameterTypes::ecf +icid-value, ParameterTypes::icidValue +icid-generated-at, ParameterTypes::icidGeneratedAt +orig-ioi, ParameterTypes::origIoi +term-ioi, ParameterTypes::termIoi +content, ParameterTypes::content +encoding, ParameterTypes::encoding addtransport, ParameterTypes::addTransport +ws-src-ip, ParameterTypes::wsSrcIp +ws-src-port, ParameterTypes::wsSrcPort %% } diff --git a/src/libs/resiprocate/resip/stack/ParameterHash.hxx b/src/libs/resiprocate/resip/stack/ParameterHash.hxx index 52d92aa9..dfad462e 100644 --- a/src/libs/resiprocate/resip/stack/ParameterHash.hxx +++ b/src/libs/resiprocate/resip/stack/ParameterHash.hxx @@ -1,16 +1,19 @@ #if !defined(PARAMETERHASH_HXX) #define PARAMETERHASH_HXX + +#include "rutil/compat.hxx" + namespace resip { -struct params { char *name; ParameterTypes::Type type; }; +struct params { const char *name; ParameterTypes::Type type; }; /* maximum key range = 494, duplicates = 0 */ class ParameterHash { private: - static inline unsigned int hash (const char *str, unsigned int len); + static inline unsigned int hash (const char *str, GPERF_SIZE_TYPE len); public: - static const struct params *in_word_set (const char *str, unsigned int len); + static const struct params *in_word_set (const char *str, GPERF_SIZE_TYPE len); }; // NOTE the cxx file for this class is AUTO GENERATED. DO NOT EDIT IT. // This file should match it. BUT THIS FILE IS MANUALLY GENERATED. diff --git a/src/libs/resiprocate/resip/stack/ParameterTypeEnums.hxx b/src/libs/resiprocate/resip/stack/ParameterTypeEnums.hxx index 794d8b97..da4d45dd 100644 --- a/src/libs/resiprocate/resip/stack/ParameterTypeEnums.hxx +++ b/src/libs/resiprocate/resip/stack/ParameterTypeEnums.hxx @@ -103,13 +103,13 @@ class ParameterTypes defineParam(opaque, "opaque", QuotedDataParameter, "RFC ????"), defineParam(permission, "permission", DataParameter, "RFC 2046"), defineParam(protocol, "protocol", QuotedDataParameter, "RFC 1847"), - defineParam(purpose, "purpose", DataParameter, "RFC ????"), + defineParam(purpose, "purpose", DataParameter, "RFC 3261, draft-ietf-cuss-sip-uui-17"), defineParam(q, "q", QValueParameter, "RFC 3261"), defineParam(realm, "realm", QuotedDataParameter, "RFC ????"), defineParam(reason, "reason", DataParameter, "RFC ????"), defineParam(received, "received", DataParameter, "RFC ????"), - defineParam(require, "require", DataParameter, "RFC 5373"), + defineParam(require, "require", ExistsParameter, "RFC 5373"), defineParam(response, "response", QuotedDataParameter, "RFC ????"), defineParam(retryAfter, "retry-after", UInt32Parameter, "RFC ????"), defineParam(rinstance, "rinstance", DataParameter, "Internal"), @@ -141,11 +141,30 @@ class ParameterTypes defineParam(url, "url", QuotedDataParameter, "draft-ietf-sip-content-indirect-mech-05"), - defineParam(sigcompId, "sigcomp-id", QuotedDataParameter, "draft-ietf-rohc-sigcomp-sip"), defineParam(qop, "qop", DataParameter, "RFC 3261"), + + defineParam(index, "index", DataParameter, "RFC 4244"), + defineParam(rc, "rc", DataParameter, "RFC 4244-bis"), + defineParam(mp, "mp", DataParameter, "RFC 4244-bis"), + defineParam(np, "np", DataParameter, "RFC 4244-bis"), + + defineParam(utranCellId3gpp, "utran-cell-id-3gpp", DataParameter, "RFC 3455"), // P-Access-Network-Info + defineParam(cgi3gpp, "cgi-3gpp", DataParameter, "RFC 3455"), // P-Access-Network-Info + defineParam(ccf, "ccf", DataParameter, "RFC 3455"), // P-Charging-Function-Addresses + defineParam(ecf, "ecf", DataParameter, "RFC 3455"), // P-Charging-Function-Addresses + defineParam(icidValue, "icid-value", DataParameter, "RFC 3455"), // P-Charging-Vector + defineParam(icidGeneratedAt, "icid-generated-at", DataParameter, "RFC 3455"), // P-Charging-Vector + defineParam(origIoi, "orig-ioi", DataParameter, "RFC 3455"), // P-Charging-Vector + defineParam(termIoi, "term-ioi", DataParameter, "RFC 3455"), // P-Charging-Vector + + defineParam(content, "content", DataParameter, "draft-ietf-cuss-sip-uui-17"), // User-to-User + defineParam(encoding, "encoding", DataParameter, "draft-ietf-cuss-sip-uui-17"), // User-to-User + defineParam(qopOptions, "qop", DataParameter, "RFC 3261"), defineParam(addTransport, "addTransport", ExistsParameter, "Internal"), + defineParam(wsSrcIp, "ws-src-ip", DataParameter, ""), + defineParam(wsSrcPort, "ws-src-port", UInt32Parameter, ""), MAX_PARAMETER }; diff --git a/src/libs/resiprocate/resip/stack/ParameterTypes.cxx b/src/libs/resiprocate/resip/stack/ParameterTypes.cxx index 6e7bc57d..fd53795d 100644 --- a/src/libs/resiprocate/resip/stack/ParameterTypes.cxx +++ b/src/libs/resiprocate/resip/stack/ParameterTypes.cxx @@ -104,12 +104,12 @@ defineParam(nonce, "nonce", QuotedDataParameter, Auth, "RFC 2617"); defineParam(opaque, "opaque", QuotedDataParameter, Auth, "RFC 2617"); defineParam(permission, "permission", DataParameter, Mime, "RFC 2046"); defineParam(protocol, "protocol", QuotedDataParameter, Mime, "RFC 1847"); -defineParam(purpose, "purpose", DataParameter, GenericUri, "RFC 3261"); +defineParam2(purpose, "purpose", DataParameter, GenericUri, TokenOrQuotedStringCategory, "RFC 3261, draft-ietf-cuss-sip-uui-17"); defineParam3(q, "q", QValueParameter, NameAddr, Token, Mime, "RFC 3261"); defineParam(realm, "realm", QuotedDataParameter, Auth, "RFC 2617"); defineParam(reason, "reason", DataParameter, Token, "RFC 3265"); defineParam(received, "received", DataParameter, Via, "RFC 3261"); -defineParam(require, "require", DataParameter, Token, "RFC 5373"); +defineParam(require, "require", ExistsParameter, Token, "RFC 5373"); defineParam(response, "response", QuotedDataParameter, Auth, "RFC 3261"); defineParam(retryAfter, "retry-after", UInt32Parameter, Token, "RFC 3265"); defineParam(rinstance, "rinstance", DataParameter, Uri, "proprietary (resip)"); @@ -144,9 +144,28 @@ defineParam(url, "url", QuotedDataParameter, Mime, "RFC 4483"); defineParam2(sigcompId, "sigcomp-id", QuotedDataParameter, Uri, Via, "RFC 5049"); defineParam(qop,"qop",DataParameter, Auth, "RFC 3261"); +defineParam(index, "index", DataParameter, NameAddr, "RFC 4244"); +defineParam(rc, "rc", DataParameter, NameAddr, "RFC 4244-bis"); +defineParam(mp, "mp", DataParameter, NameAddr, "RFC 4244-bis"); +defineParam(np, "np", DataParameter, NameAddr, "RFC 4244-bis"); + +defineParam(utranCellId3gpp, "utran-cell-id-3gpp", DataParameter, Token, "RFC 3455"); // P-Access-Network-Info +defineParam(cgi3gpp, "cgi-3gpp", DataParameter, Token, "RFC 3455"); // P-Access-Network-Info +defineParam(ccf, "ccf", DataParameter, Token, "RFC 3455"); // P-Charging-Function-Addresses +defineParam(ecf, "ecf", DataParameter, Token, "RFC 3455"); // P-Charging-Function-Addresses +defineParam(icidValue, "icid-value", DataParameter, Token, "RFC 3455"); // P-Charging-Vector +defineParam(icidGeneratedAt, "icid-generated-at", DataParameter, Token, "RFC 3455"); // P-Charging-Vector +defineParam(origIoi, "orig-ioi", DataParameter, Token, "RFC 3455"); // P-Charging-Vector +defineParam(termIoi, "term-ioi", DataParameter, Token, "RFC 3455"); // P-Charging-Vector + +defineParam(content, "content", DataParameter, TokenOrQuotedStringCategory, "draft-ietf-cuss-sip-uui-17"); // User-to-User +defineParam(encoding, "encoding", DataParameter, TokenOrQuotedStringCategory, "draft-ietf-cuss-sip-uui-17"); // User-to-User + // Internal use only defineParam(qopOptions,"qop",DataParameter, Auth, "RFC 3261"); defineParam(addTransport, "addTransport", ExistsParameter, Uri, "RESIP INTERNAL"); +defineParam(wsSrcIp, "ws-src-ip", DataParameter, Uri, "RESIP INTERNAL (WebSocket)"); +defineParam(wsSrcPort, "ws-src-port", UInt32Parameter, Uri, "RESIP INTERNAL (WebSocket)"); #include "resip/stack/ParameterHash.hxx" diff --git a/src/libs/resiprocate/resip/stack/ParameterTypes.hxx b/src/libs/resiprocate/resip/stack/ParameterTypes.hxx index 7a7858e1..b37cacb4 100644 --- a/src/libs/resiprocate/resip/stack/ParameterTypes.hxx +++ b/src/libs/resiprocate/resip/stack/ParameterTypes.hxx @@ -86,6 +86,7 @@ class Token; class Uri; class Via; class WarningCategory; +class TokenOrQuotedStringCategory; defineParam(data, "data", ExistsParameter, NameAddr, "RFC 3840"); defineParam(control, "control", ExistsParameter, NameAddr, "RFC 3840"); @@ -141,12 +142,12 @@ defineParam(nonce, "nonce", QuotedDataParameter, Auth, "RFC 2617"); defineParam(opaque, "opaque", QuotedDataParameter, Auth, "RFC 2617"); defineParam(permission, "permission", DataParameter, Mime, "RFC 2046"); defineParam(protocol, "protocol", QuotedDataParameter, Mime, "RFC 1847"); -defineParam(purpose, "purpose", DataParameter, GenericUri, "RFC 3261"); +defineParam2(purpose, "purpose", DataParameter, GenericUri, TokenOrQuotedStringCategory, "RFC 3261, draft-ietf-cuss-sip-uui-17"); defineParam3(q, "q", QValueParameter, NameAddr, Token, Mime, "RFC 3261"); defineParam(realm, "realm", QuotedDataParameter, Auth, "RFC 2617"); defineParam(reason, "reason", DataParameter, Token, "RFC 3265"); defineParam(received, "received", DataParameter, Via, "RFC 3261"); -defineParam(require, "require", DataParameter, Token, "RFC 5373"); +defineParam(require, "require", ExistsParameter, Token, "RFC 5373"); defineParam(response, "response", QuotedDataParameter, Auth, "RFC 3261"); defineParam(retryAfter, "retry-after", UInt32Parameter, Token, "RFC 3265"); defineParam(rinstance, "rinstance", DataParameter, Uri, "proprietary (resip)"); @@ -181,9 +182,28 @@ defineParam(url, "url", QuotedDataParameter, Mime, "RFC 4483"); defineParam2(sigcompId, "sigcomp-id", QuotedDataParameter, Uri, Via, "RFC 5049"); defineParam(qop,"qop",DataParameter, Auth, "RFC 3261"); +defineParam(index, "index", DataParameter, NameAddr, "RFC 4244"); +defineParam(rc, "rc", DataParameter, NameAddr, "RFC 4244-bis"); +defineParam(mp, "mp", DataParameter, NameAddr, "RFC 4244-bis"); +defineParam(np, "np", DataParameter, NameAddr, "RFC 4244-bis"); + +defineParam(utranCellId3gpp, "utran-cell-id-3gpp", DataParameter, Token, "RFC 3455"); // P-Access-Network-Info +defineParam(cgi3gpp, "cgi-3gpp", DataParameter, Token, "RFC 3455"); // P-Access-Network-Info +defineParam(ccf, "ccf", DataParameter, Token, "RFC 3455"); // P-Charging-Function-Addresses +defineParam(ecf, "ecf", DataParameter, Token, "RFC 3455"); // P-Charging-Function-Addresses +defineParam(icidValue, "icid-value", DataParameter, Token, "RFC 3455"); // P-Charging-Vector +defineParam(icidGeneratedAt, "icid-generated-at", DataParameter, Token, "RFC 3455"); // P-Charging-Vector +defineParam(origIoi, "orig-ioi", DataParameter, Token, "RFC 3455"); // P-Charging-Vector +defineParam(termIoi, "term-ioi", DataParameter, Token, "RFC 3455"); // P-Charging-Vector + +defineParam(content, "content", DataParameter, TokenOrQuotedStringCategory, "draft-ietf-cuss-sip-uui-17"); // User-to-User +defineParam(encoding, "encoding", DataParameter, TokenOrQuotedStringCategory, "draft-ietf-cuss-sip-uui-17"); // User-to-User + // Internal use only defineParam(qopOptions,"qop",DataParameter, Auth, "RFC 3261"); defineParam(addTransport, "addTransport", ExistsParameter, Uri, "RESIP INTERNAL"); +defineParam(wsSrcIp, "ws-src-ip", DataParameter, Uri, "RESIP INTERNAL (WebSocket)"); +defineParam(wsSrcPort, "ws-src-port", UInt32Parameter, Uri, "RESIP INTERNAL (WebSocket)"); } diff --git a/src/libs/resiprocate/resip/stack/ParserCategories.hxx b/src/libs/resiprocate/resip/stack/ParserCategories.hxx index 71c72ea8..d7b41e9f 100644 --- a/src/libs/resiprocate/resip/stack/ParserCategories.hxx +++ b/src/libs/resiprocate/resip/stack/ParserCategories.hxx @@ -21,6 +21,7 @@ #include "resip/stack/Token.hxx" #include "resip/stack/Via.hxx" #include "resip/stack/WarningCategory.hxx" +#include "resip/stack/TokenOrQuotedStringCategory.hxx" #endif diff --git a/src/libs/resiprocate/resip/stack/ParserCategory.cxx b/src/libs/resiprocate/resip/stack/ParserCategory.cxx index c7df4cae..9c47810b 100644 --- a/src/libs/resiprocate/resip/stack/ParserCategory.cxx +++ b/src/libs/resiprocate/resip/stack/ParserCategory.cxx @@ -14,7 +14,7 @@ #include "resip/stack/ExtensionParameter.hxx" #include -#include +#include "rutil/ResipAssert.h" #include "rutil/Logger.hxx" //#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below @@ -348,7 +348,7 @@ ParserCategory::getParameterByEnum(ParameterTypes::Type type) const void ParserCategory::setParameter(const Parameter* parameter) { - assert(parameter); + resip_assert(parameter); for (ParameterList::iterator it = mParameters.begin(); it != mParameters.end(); it++) diff --git a/src/libs/resiprocate/resip/stack/ParserContainerBase.cxx b/src/libs/resiprocate/resip/stack/ParserContainerBase.cxx index 8b5f4eef..7b84a91c 100644 --- a/src/libs/resiprocate/resip/stack/ParserContainerBase.cxx +++ b/src/libs/resiprocate/resip/stack/ParserContainerBase.cxx @@ -1,4 +1,4 @@ -#include +#include "rutil/ResipAssert.h" #include "resip/stack/ParserContainerBase.hxx" #include "resip/stack/Embedded.hxx" @@ -57,7 +57,7 @@ ParserContainerBase::operator=(const ParserContainerBase& rhs) void ParserContainerBase::pop_front() { - assert(!mParsers.empty()); + resip_assert(!mParsers.empty()); freeParser(mParsers.front()); mParsers.erase(mParsers.begin()); } @@ -65,7 +65,7 @@ ParserContainerBase::pop_front() void ParserContainerBase::pop_back() { - assert(!mParsers.empty()); + resip_assert(!mParsers.empty()); freeParser(mParsers.back()); mParsers.pop_back(); } @@ -118,7 +118,7 @@ EncodeStream& ParserContainerBase::encodeEmbedded(const Data& headerName, EncodeStream& str) const { - assert(!headerName.empty()); + resip_assert(!headerName.empty()); if (!mParsers.empty()) { @@ -154,11 +154,18 @@ ParserContainerBase::copyParsers(const Parsers& parsers) mParsers.reserve(mParsers.size() + parsers.size()); for(Parsers::const_iterator p=parsers.begin(); p!=parsers.end(); ++p) { - mParsers.push_back(*p); + // Copy c'tor and assignment operator for HeaderKit are actually poor + // man's move semantics, so we have to implement real copy semantics here. + mParsers.push_back(HeaderKit::Empty); + HeaderKit& kit(mParsers.back()); - if(kit.pc) + if(p->pc) { - kit.pc = makeParser(*kit.pc); + kit.pc = makeParser(*(p->pc)); + } + else + { + kit.hfv = p->hfv; } } } diff --git a/src/libs/resiprocate/resip/stack/ParserContainerBase.hxx b/src/libs/resiprocate/resip/stack/ParserContainerBase.hxx index fbaa2158..be6ed15f 100644 --- a/src/libs/resiprocate/resip/stack/ParserContainerBase.hxx +++ b/src/libs/resiprocate/resip/stack/ParserContainerBase.hxx @@ -58,7 +58,7 @@ class ParserContainerBase /** @brief clear the mParsers vector */ - inline void clear() {mParsers.clear();} + inline void clear() {freeParsers(); mParsers.clear();} /** @brief pure virtual function to be implemented in derived classes @@ -133,17 +133,25 @@ class ParserContainerBase static const HeaderKit Empty; HeaderKit(): pc(0){} + + // Poor man's move c'tor, watch out! HeaderKit(const HeaderKit& orig) : pc(orig.pc), hfv(orig.hfv) - {} - + { + HeaderKit& nc_orig = const_cast(orig); + std::swap(nc_orig.pc, pc); + hfv.swap(nc_orig.hfv); + } + + // Poor man's move semantics, watch out! HeaderKit& operator=(const HeaderKit& rhs) { if(this!=&rhs) { - pc=rhs.pc; - hfv=rhs.hfv; + HeaderKit& nc_orig = const_cast(rhs); + std::swap(nc_orig.pc, pc); + hfv.swap(nc_orig.hfv); } return *this; } diff --git a/src/libs/resiprocate/resip/stack/Pidf.cxx b/src/libs/resiprocate/resip/stack/Pidf.cxx index 08b04b9a..58d662fd 100644 --- a/src/libs/resiprocate/resip/stack/Pidf.cxx +++ b/src/libs/resiprocate/resip/stack/Pidf.cxx @@ -170,35 +170,33 @@ Pidf::encodeParsed(EncodeStream& str) const void Pidf::parse(ParseBuffer& pb) { -/* - REVISIT WHY THE BELOW WAS REMOVED - REMOVING IT SCREWS UP WHAT GOES OUT IN THE PUBLISH -*/ DebugLog(<< "Pidf::parse(" << Data(pb.start(), int(pb.end()-pb.start())) << ") "); - std::string pidf_namespace; + std::string pidf_namespace; XMLCursor xml(pb); - XMLCursor::AttributeMap attr = xml.getAttributes(); - XMLCursor::AttributeMap::const_iterator it = - std::find_if(attr.begin(), attr.end(), XMLCursor::AttributeValueEqual("urn:ietf:params:xml:ns:pidf")); + XMLCursor::AttributeMap attr = xml.getAttributes(); + XMLCursor::AttributeMap::const_iterator it = + std::find_if(attr.begin(), attr.end(), XMLCursor::AttributeValueEqual("urn:ietf:params:xml:ns:pidf")); - if ( it != attr.end() ) { + if ( it != attr.end() ) + { - std::string key(it->first.data(), it->first.size()); + std::string key(it->first.data(), it->first.size()); - size_t pos = key.find(':'); + size_t pos = key.find(':'); - if ( pos != string::npos) { - pidf_namespace.assign(key, pos+1, key.size()-pos-1); - pidf_namespace.append(1, ':'); - } - } + if ( pos != string::npos) + { + pidf_namespace.assign(key, pos+1, key.size()-pos-1); + pidf_namespace.append(1, ':'); + } + } - const std::string presence = pidf_namespace + "presence"; + const std::string presence = pidf_namespace + "presence"; - if (xml.getTag() == presence.c_str()) + if (xml.getTag() == presence.c_str()) { XMLCursor::AttributeMap::const_iterator i = xml.getAttributes().find("entity"); if (i != xml.getAttributes().end()) @@ -214,8 +212,8 @@ Pidf::parse(ParseBuffer& pb) { do { - const std::string tuple = pidf_namespace + "tuple"; - if (xml.getTag() == tuple.c_str()) + const std::string tuple = pidf_namespace + "tuple"; + if (xml.getTag() == tuple.c_str()) { Tuple t; t.attributes = xml.getAttributes(); @@ -231,10 +229,10 @@ Pidf::parse(ParseBuffer& pb) { do { - const std::string status = pidf_namespace + "status"; - const std::string contact = pidf_namespace + "contact"; - const std::string note = pidf_namespace + "note"; - const std::string timestamp = pidf_namespace + "timestamp"; + const std::string status = pidf_namespace + "status"; + const std::string contact = pidf_namespace + "contact"; + const std::string note = pidf_namespace + "note"; + const std::string timestamp = pidf_namespace + "timestamp"; if (xml.getTag() == status.c_str()) { // look for basic @@ -242,7 +240,7 @@ Pidf::parse(ParseBuffer& pb) { do { - std::string basic = pidf_namespace + "basic"; + std::string basic = pidf_namespace + "basic"; if (xml.getTag() == basic.c_str()) { if (xml.firstChild()) @@ -255,7 +253,7 @@ Pidf::parse(ParseBuffer& pb) xml.parent(); } } - else if (xml.getTag() == contact.c_str()) + else if (xml.getTag() == contact.c_str()) { XMLCursor::AttributeMap::const_iterator i = xml.getAttributes().find("priority"); if (i != xml.getAttributes().end()) @@ -268,7 +266,7 @@ Pidf::parse(ParseBuffer& pb) xml.parent(); } } - else if (xml.getTag() == note.c_str()) + else if (xml.getTag() == note.c_str()) { if (xml.firstChild()) { @@ -276,7 +274,7 @@ Pidf::parse(ParseBuffer& pb) xml.parent(); } } - else if (xml.getTag() == timestamp.c_str()) + else if (xml.getTag() == timestamp.c_str()) { if (xml.firstChild()) { @@ -298,17 +296,6 @@ Pidf::parse(ParseBuffer& pb) { DebugLog(<< "no presence tag!"); } -/* - REVISIT WHY THE ABOVE WAS REMOVED -*/ - - // THIS HERE IS THE ESSENCE OF WHAT IS USED. - // const char* anchor = pb.position(); - const char* anchor = pb.start(); - pb.skipToEnd(); - pb.data(mNote, anchor); - DebugLog(<< "mNote is : " << mNote ); - // END OF - ESSENCE } void @@ -372,6 +359,7 @@ Pidf::merge(const Pidf& other) for (vector::iterator j = getTuples().begin(); j != getTuples().end(); ++j) { + // TODO - only merge over if timestamp is greater if (i->id == j->id) { found = true; diff --git a/src/libs/resiprocate/resip/stack/Pidf.hxx b/src/libs/resiprocate/resip/stack/Pidf.hxx index 003f45ce..4aa4f3dc 100644 --- a/src/libs/resiprocate/resip/stack/Pidf.hxx +++ b/src/libs/resiprocate/resip/stack/Pidf.hxx @@ -24,11 +24,9 @@ class Pidf : public Contents public: static const Pidf Empty; -// only for Pidf (not for CpimContents) RESIP_HeapCount(Pidf); Pidf(const Mime& contentType); explicit Pidf(const Uri& entity); -// end of - only for Pidf (not for CpimContents) Pidf(); Pidf(const Data& txt); Pidf(const HeaderFieldValue& hfv, const Mime& contentType); @@ -45,24 +43,20 @@ class Pidf : public Contents virtual EncodeStream& encodeParsed(EncodeStream& str) const; virtual void parse(ParseBuffer& pb); -// only for Pidf (not for CpimContents) void setSimpleId(const Data& id); void setEntity(const Uri& entity); const Uri& getEntity() const; void setSimpleStatus(bool online, const Data& note = Data::Empty, const Data& contact = Data::Empty); bool getSimpleStatus(Data* note=NULL) const; -// end of - only for Pidf (not for CpimContents) Data& text() {checkParsed(); return mNote;} static bool init(); - -// only for Pidf (not for CpimContents) /** @deprecated - @brief Deprecated - */ + @brief Deprecated + */ class Tuple { public: @@ -81,20 +75,16 @@ class Pidf : public Contents // combine tuples void merge(const Pidf& other); -// end of - only for Pidf (not for CpimContents) private: - Data mNote; // equivalent to mText in Cpim -// only for Pidf (not for CpimContents) + Data mNote; Uri mEntity; std::vector mTuples; -// end of - only for Pidf (not for CpimContents) }; EncodeStream& operator<<(EncodeStream& strm, const Pidf::Tuple& tuple); -// only for Pidf (not for CpimContents) + static bool invokePidfInit = Pidf::init(); -// end of - only for Pidf (not for CpimContents) } diff --git a/src/libs/resiprocate/resip/stack/QuotedDataParameter.cxx b/src/libs/resiprocate/resip/stack/QuotedDataParameter.cxx index 6d77a1f8..0b49fddc 100644 --- a/src/libs/resiprocate/resip/stack/QuotedDataParameter.cxx +++ b/src/libs/resiprocate/resip/stack/QuotedDataParameter.cxx @@ -2,7 +2,7 @@ #include "config.h" #endif -#include +#include "rutil/ResipAssert.h" #include "rutil/ParseException.hxx" #include "resip/stack/QuotedDataParameter.hxx" #include "resip/stack/Symbols.hxx" diff --git a/src/libs/resiprocate/resip/stack/RemoveTransport.hxx b/src/libs/resiprocate/resip/stack/RemoveTransport.hxx new file mode 100644 index 00000000..33c8ffec --- /dev/null +++ b/src/libs/resiprocate/resip/stack/RemoveTransport.hxx @@ -0,0 +1,93 @@ +#ifndef RemoveTransport_Include_Guard +#define RemoveTransport_Include_Guard + +#include "resip/stack/TransactionMessage.hxx" +#include "resip/stack/Transport.hxx" + +namespace resip +{ +class RemoveTransport : public TransactionMessage +{ + public: + explicit RemoveTransport(unsigned int transportKey) : + mTransportKey(transportKey) + {} + virtual ~RemoveTransport(){} + + virtual const Data& getTransactionId() const {return Data::Empty;} + unsigned int getTransportKey() { return mTransportKey; } + + virtual bool isClientTransaction() const {return true;} + virtual EncodeStream& encode(EncodeStream& strm) const + { + return strm << "RemoveTransport: key=" << mTransportKey; + } + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "RemoveTransport: key=" << mTransportKey; + } + + virtual Message* clone() const + { + resip_assert(false); return NULL; + } + + protected: + unsigned int mTransportKey; +}; // class RemoveTransport + +} // namespace resip + +#endif // include guard + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2014 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * . + * + * vi: set shiftwidth=3 expandtab: + */ + diff --git a/src/libs/resiprocate/resip/stack/Rlmi.cxx b/src/libs/resiprocate/resip/stack/Rlmi.cxx index 5cdefc8a..4721c681 100644 --- a/src/libs/resiprocate/resip/stack/Rlmi.cxx +++ b/src/libs/resiprocate/resip/stack/Rlmi.cxx @@ -76,7 +76,6 @@ Rlmi::encodeParsed(EncodeStream& str) const void Rlmi::parse(ParseBuffer& pb) { - const char* anchor = pb.position(); pb.skipToEnd(); pb.data(mText, anchor); diff --git a/src/libs/resiprocate/resip/stack/SdpContents.cxx b/src/libs/resiprocate/resip/stack/SdpContents.cxx index a9d6c74a..5cd1dd5f 100644 --- a/src/libs/resiprocate/resip/stack/SdpContents.cxx +++ b/src/libs/resiprocate/resip/stack/SdpContents.cxx @@ -33,7 +33,8 @@ static const Data fmtp("fmtp"); // RFC2327 6. page 9 // "parsers should be tolerant and accept records terminated with a single // newline character" -void skipEol(ParseBuffer& pb) +void +resip::skipEol(ParseBuffer& pb) { while(!pb.eof() && (*pb.position() == Symbols::SPACE[0] || *pb.position() == Symbols::TAB[0])) @@ -402,18 +403,18 @@ void parseEorP(ParseBuffer& pb, Data& eOrp, Data& freeText) // ^ // // ^ - + pb.data(freeText, anchor); anchor = pb.skipChar(); pb.skipToEndQuote(Symbols::RA_QUOTE[0]); pb.data(eOrp, anchor); pb.skipChar(Symbols::RA_QUOTE[0]); break; - + case '(': // Symbols::LPAREN[0] // mjh@isi.edu (Mark Handley) // ^ - + pb.data(eOrp, anchor); anchor = pb.skipChar(); pb.skipToEndQuote(Symbols::RPAREN[0]); @@ -421,7 +422,7 @@ void parseEorP(ParseBuffer& pb, Data& eOrp, Data& freeText) pb.skipChar(Symbols::RPAREN[0]); break; default: - assert(0); + resip_assert(0); } } @@ -723,20 +724,20 @@ parseTypedTime(ParseBuffer& pb) { switch (*pb.position()) { - case 's' : - pb.skipChar(); - break; - case 'm' : - v *= 60; - pb.skipChar(); - break; - case 'h' : - v *= 3600; - pb.skipChar(); + case 's' : + pb.skipChar(); break; - case 'd' : - v *= 3600*24; - pb.skipChar(); + case 'm' : + v *= 60; + pb.skipChar(); + break; + case 'h' : + v *= 3600; + pb.skipChar(); + break; + case 'd' : + v *= 3600*24; + pb.skipChar(); } } return v; @@ -1313,12 +1314,12 @@ SdpContents::Session::Medium::parse(ParseBuffer& pb) { anchor = pb.skipChar(Symbols::SPACE[0]); pb.skipToOneOf(Symbols::SPACE, Symbols::CRLF); - if(pb.position() != anchor) - { - Data format; - pb.data(format, anchor); - addFormat(format); - } + if(pb.position() != anchor) + { + Data format; + pb.data(format, anchor); + addFormat(format); + } } skipEol(pb); @@ -1344,8 +1345,17 @@ SdpContents::Session::Medium::parse(ParseBuffer& pb) pb.skipChar(); int num = pb.integer(); + if (num > 255) + { + pb.fail(__FILE__, __LINE__, "Too many connection addresses"); + } + Connection& con = mConnections.back(); const Data& addr = con.getAddress(); + if (addr.empty()) + { + pb.fail(__FILE__, __LINE__, "IP address expected"); + } size_t i = addr.size() - 1; for (; i; i--) { @@ -1558,7 +1568,7 @@ SdpContents::Session::Medium::getValues(const Data& key) const } if (!mSession) { - assert(false); + resip_assert(false); static list error; return error; } @@ -1602,7 +1612,7 @@ SdpContents::Session::Medium::CodecContainer& SdpContents::Session::Medium::codecs() { #if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER < 1310) // CJ TODO fix - assert(0); + resip_assert(0); #else if (!mRtpMapDone) { @@ -1684,7 +1694,7 @@ SdpContents::Session::Medium::findFirstMatchingCodecs(const CodecContainer& code { if (*sIter == *eIter) { - if (pMatchingCodec) + if (pMatchingCodec) { *pMatchingCodec = *eIter; } @@ -1708,17 +1718,28 @@ SdpContents::Session::Medium::findFirstMatchingCodecs(const Medium& medium, Code } } -int -SdpContents::Session::Medium::findTelephoneEventPayloadType() const +const Codec& +SdpContents::Session::Medium::findTelephoneEventPayloadCodec() const { const CodecContainer& codecList = codecs(); for (CodecContainer::const_iterator i = codecList.begin(); i != codecList.end(); i++) { if (i->getName() == SdpContents::Session::Codec::TelephoneEvent.getName()) { - return i->payloadType(); + return *i; } } + return emptyCodec; +} + +int +SdpContents::Session::Medium::findTelephoneEventPayloadType() const +{ + const Codec& telephoneEventCodec = findTelephoneEventPayloadCodec(); + if (!(telephoneEventCodec == emptyCodec)) + { + return telephoneEventCodec.payloadType(); + } return -1; } @@ -1837,7 +1858,7 @@ Codec::CodecMap& Codec::getStaticCodecs() // // Build map of static codecs as defined in RFC 3551 // - sStaticCodecs = std::unique_ptr(new CodecMap); + sStaticCodecs = std::auto_ptr(new CodecMap); // Audio codecs sStaticCodecs->insert(make_pair(0,Codec("PCMU",0,8000))); @@ -1882,6 +1903,12 @@ resip::operator==(const Codec& lhs, const Codec& rhs) (lhs.mEncodingParameters == defaultEncodingParameters && rhs.mEncodingParameters.empty()))); } +bool +resip::operator!=(const Codec& lhs, const Codec& rhs) +{ + return !operator==(lhs, rhs); +} + EncodeStream& resip::operator<<(EncodeStream& str, const Codec& codec) { @@ -1897,17 +1924,19 @@ resip::operator<<(EncodeStream& str, const Codec& codec) } const Codec Codec::ULaw_8000("PCMU", 0, 8000); -const Codec Codec::ALaw_8000("PCMA", 8, 8000); -const Codec Codec::G729_8000("G729", 18, 8000); +const Codec Codec::GSM_8000("GSM", 3, 8000); const Codec Codec::G723_8000("G723", 4, 8000); -const Codec Codec::GSM_8000("GSM", 3, 8000); +const Codec Codec::ALaw_8000("PCMA", 8, 8000); +const Codec Codec::G722_8000("G722", 9, 8000); +const Codec Codec::CN("CN", 13, 8000); +const Codec Codec::G729_8000("G729", 18, 8000); +const Codec Codec::H263("H263", 34, 90000); const Codec Codec::TelephoneEvent("telephone-event", 101, 8000); const Codec Codec::FrfDialedDigit("frf-dialed-event",102, 8000); -const Codec Codec::CN("CN", 13, 8000); bool Codec::sStaticCodecsCreated = false; -std::unique_ptr Codec::sStaticCodecs; +std::auto_ptr Codec::sStaticCodecs; /* ==================================================================== * The Vovida Software License, Version 1.0 diff --git a/src/libs/resiprocate/resip/stack/SdpContents.hxx b/src/libs/resiprocate/resip/stack/SdpContents.hxx index 2e45f3f9..bcb030d2 100644 --- a/src/libs/resiprocate/resip/stack/SdpContents.hxx +++ b/src/libs/resiprocate/resip/stack/SdpContents.hxx @@ -138,13 +138,16 @@ class SdpContents : public Contents Data& encodingParameters() {return mEncodingParameters;} static const Codec ULaw_8000; - static const Codec ALaw_8000; - static const Codec G729_8000; - static const Codec G723_8000; static const Codec GSM_8000; + static const Codec G723_8000; + static const Codec ALaw_8000; + static const Codec G722_8000; + static const Codec CN; + static const Codec G729_8000; + static const Codec H263; + static const Codec TelephoneEvent; static const Codec FrfDialedDigit; - static const Codec CN; typedef HashMap CodecMap; // "static" payload types as defined in RFC 3551. @@ -160,7 +163,7 @@ class SdpContents : public Contents Data mParameters; // Format parameters Data mEncodingParameters; - static std::unique_ptr sStaticCodecs; + static std::auto_ptr sStaticCodecs; static bool sStaticCodecsCreated; friend EncodeStream& operator<<(EncodeStream&, const Codec&); }; @@ -230,7 +233,7 @@ class SdpContents : public Contents /** @brief set the address for the session * * @param host IP address to associate with the session - * @param type type of addressing + * @param type type of addressing **/ void setAddress(const Data& host, AddrType type = IP4); @@ -340,7 +343,7 @@ class SdpContents : public Contents * * @param addType address type (IP4 or IP6) * @param address IP address - * @param ttl time to live + * @param ttl time to live * **/ Connection(AddrType addType, @@ -367,7 +370,7 @@ class SdpContents : public Contents /** @brief set the address for the connection * * @param host IP address to associate with the connection - * @param type type of addressing + * @param type type of addressing **/ void setAddress(const Data& host, AddrType type = IP4); unsigned long ttl() const {return mTTL;} @@ -765,6 +768,12 @@ class SdpContents : public Contents // via pMatchingCodec if a non-NULL pointer is passed in. The codec returned if from this medium. const Codec& findFirstMatchingCodecs(const Medium& medium, Codec* pMatchingCodec = 0) const; + /** @brief finds the telephone-event codec + * + * @return telephone-event "codec" + **/ + const Codec& findTelephoneEventPayloadCodec() const; + /** @brief finds the telephone-event payload type * * @return payload type of telephone-event "codec" @@ -1043,13 +1052,20 @@ class SdpContents : public Contents static bool invokeSdpContentsInit = SdpContents::init(); +// Silence compiler warning for invokeSdpContentsInit defined, but not used +static inline void foo(){if(0){(void) invokeSdpContentsInit;}}; + typedef SdpContents::Session::Codec Codec; bool operator==(const SdpContents::Session::Codec& lhs, const SdpContents::Session::Codec& rhs); +bool operator!=(const SdpContents::Session::Codec& lhs, + const SdpContents::Session::Codec& rhs); EncodeStream& operator<<(EncodeStream& str, const SdpContents::Session::Codec& codec); +void skipEol(ParseBuffer& pb); + } #endif diff --git a/src/libs/resiprocate/resip/stack/SecurityTypes.hxx b/src/libs/resiprocate/resip/stack/SecurityTypes.hxx index d73ccf78..5aa26af7 100644 --- a/src/libs/resiprocate/resip/stack/SecurityTypes.hxx +++ b/src/libs/resiprocate/resip/stack/SecurityTypes.hxx @@ -6,8 +6,19 @@ namespace resip namespace SecurityTypes { +typedef enum +{ + OpenSSL +} SSLVendor; + +/** + * Note: + * Before adding to the SSLType enum, please see the comments + * about mTlsCtx in resip/stack/ssl/Security.hxx + */ typedef enum { + NoSSL = 0, SSLv23 = 1, TLSv1 = 2 } SSLType; diff --git a/src/libs/resiprocate/resip/stack/SipConfigParse.cxx b/src/libs/resiprocate/resip/stack/SipConfigParse.cxx new file mode 100644 index 00000000..9efe7df3 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/SipConfigParse.cxx @@ -0,0 +1,217 @@ + +#include "resip/stack/NameAddr.hxx" +#ifdef USE_SSL +#include "resip/stack/ssl/Security.hxx" +#endif +#include "resip/stack/SipConfigParse.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +namespace resip +{ + +SipConfigParse::SipConfigParse() +{ +} + +SipConfigParse::~SipConfigParse() +{ +} + +bool +SipConfigParse::getConfigValue(const resip::Data& name, resip::Uri &value) +{ + Data lowerName(name); lowerName.lowercase(); + ConfigValuesMap::iterator it = mConfigValues.find(lowerName); + if(it != mConfigValues.end()) + { + try + { + if(!it->second.empty()) + { + NameAddr tempNameAddr(it->second); + value = tempNameAddr.uri(); + return true; + } + else + { + value = Uri(); // return an empty Uri + return true; + } + } + catch(resip::BaseException& e) + { + // Try adding sip: to value to see if it will be valid + try + { + NameAddr tempNameAddr(Data("sip:" + it->second)); + value = tempNameAddr.uri(); + return true; + } + catch(resip::BaseException&) + { + cerr << "Invalid Uri setting: " << name << " = " << it->second << ": " << e << endl; + return false; + } + } + } + // Not found + return false; +} + +resip::Uri +SipConfigParse::getConfigUri(const resip::Data& name, const resip::Uri defaultValue, bool useDefaultIfEmpty) +{ + Uri ret(defaultValue); + if(getConfigValue(name, ret) && ret.host().empty() && useDefaultIfEmpty) + { + return defaultValue; + } + return ret; +} + +bool +SipConfigParse::getConfigValue(const resip::Data& name, resip::NameAddr &value) +{ + Data lowerName(name); lowerName.lowercase(); + ConfigValuesMap::iterator it = mConfigValues.find(lowerName); + if(it != mConfigValues.end()) + { + try + { + if(!it->second.empty()) + { + NameAddr tempuri(it->second); + value = tempuri; + return true; + } + else + { + value = NameAddr(); + return true; + } + } + catch(resip::BaseException& e) + { + cerr << "Invalid uri format: " << e << endl; + return false; + } + } + // Not found + return false; +} + +resip::NameAddr +SipConfigParse::getConfigNameAddr(const resip::Data& name, const resip::NameAddr defaultValue, bool useDefaultIfEmpty) +{ + resip::NameAddr ret(defaultValue); + if(getConfigValue(name, ret) && ret.uri().host().empty() && useDefaultIfEmpty) + { + return defaultValue; + } + return ret; +} + +bool +SipConfigParse::getConfigValue(const resip::Data& name, SecurityTypes::SSLType &value) +{ + Data lowerName(name); lowerName.lowercase(); + ConfigValuesMap::iterator it = mConfigValues.find(lowerName); + if(it != mConfigValues.end()) + { +#ifdef USE_SSL + value = Security::parseSSLType(it->second); +#else + value = SecurityTypes::NoSSL; +#endif + } + return false; +} + +SecurityTypes::SSLType +SipConfigParse::getConfigSSLType(const resip::Data& name, SecurityTypes::SSLType defaultValue) +{ + SecurityTypes::SSLType ret = defaultValue; + getConfigValue(name, ret); + return ret; +} + +bool +SipConfigParse::getConfigValue(const resip::Data& name, SecurityTypes::TlsClientVerificationMode &value) +{ + Data lowerName(name); lowerName.lowercase(); + ConfigValuesMap::iterator it = mConfigValues.find(lowerName); + if(it != mConfigValues.end()) + { + if(isEqualNoCase(it->second, "Optional")) + { + value = SecurityTypes::Optional; + } + else if(isEqualNoCase(it->second, "Mandatory")) + { + value = SecurityTypes::Mandatory; + } + else if(isEqualNoCase(it->second, "None")) + { + value = SecurityTypes::None; + } + else + { + Data exceptionString("Unknown TLS client verification mode found in " + name + " setting: " + it->second); + throw Exception(exceptionString, __FILE__, __LINE__); + } + return true; + } + return false; +} + +SecurityTypes::TlsClientVerificationMode +SipConfigParse::getConfigClientVerificationMode(const resip::Data& name, SecurityTypes::TlsClientVerificationMode defaultValue) +{ + SecurityTypes::TlsClientVerificationMode ret = defaultValue; + getConfigValue(name, ret); + return ret; +} + +} + +/* ==================================================================== + * + * Copyright 2016 Daniel Pocock http://danielpocock.com All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/resip/stack/SipConfigParse.hxx b/src/libs/resiprocate/resip/stack/SipConfigParse.hxx new file mode 100644 index 00000000..cbb43f72 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/SipConfigParse.hxx @@ -0,0 +1,78 @@ +#if !defined(SipConfigParse_hxx) +#define SipConfigParse_hxx + + +#include "rutil/ConfigParse.hxx" + +#include "resip/stack/Uri.hxx" +#include "resip/stack/SecurityTypes.hxx" + +namespace resip +{ + +class SipConfigParse : public ConfigParse +{ + +public: + SipConfigParse(); + SipConfigParse(const ConfigParse& c) : ConfigParse(c) {}; + virtual ~SipConfigParse(); + + using resip::ConfigParse::getConfigValue; + bool getConfigValue(const resip::Data& name, resip::Uri &value); + resip::Uri getConfigUri(const resip::Data& name, const resip::Uri defaultValue, bool useDefaultIfEmpty=false); + + bool getConfigValue(const resip::Data& name, resip::NameAddr &value); + resip::NameAddr getConfigNameAddr(const resip::Data& name, const resip::NameAddr defaultValue, bool useDefaultIfEmpty=false); + + bool getConfigValue(const resip::Data& name, SecurityTypes::SSLType &value); + SecurityTypes::SSLType getConfigSSLType(const resip::Data& name, SecurityTypes::SSLType defaultValue); + + bool getConfigValue(const resip::Data& name, SecurityTypes::TlsClientVerificationMode &value); + SecurityTypes::TlsClientVerificationMode getConfigClientVerificationMode(const resip::Data& name, SecurityTypes::TlsClientVerificationMode defaultValue); + + // Must define this so instances of SipConfigParse can be instantiated + virtual void printHelpText(int argc, char **argv) {}; +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright 2016 Daniel Pocock http://danielpocock.com All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/resip/stack/SipMessage.cxx b/src/libs/resiprocate/resip/stack/SipMessage.cxx index c540054f..659b425c 100644 --- a/src/libs/resiprocate/resip/stack/SipMessage.cxx +++ b/src/libs/resiprocate/resip/stack/SipMessage.cxx @@ -27,24 +27,26 @@ using namespace std; bool SipMessage::checkContentLength=true; -SipMessage::SipMessage(const Transport* fromWire) +SipMessage::SipMessage(const Tuple *receivedTransportTuple) : mIsDecorated(false), mIsBadAck200(false), - mIsExternal(fromWire != 0), + mIsExternal(receivedTransportTuple != 0), // may be modified later by setFromTU or setFromExternal mHeaders(StlPoolAllocator(&mPool)), #ifndef __SUNPRO_CC mUnknownHeaders(StlPoolAllocator, PoolBase >(&mPool)), #else mUnknownHeaders(), #endif - mTransport(fromWire), - mRFC2543TransactionId(), mRequest(false), mResponse(false), mInvalid(false), mCreatedTime(Timer::getTimeMicroSec()), mTlsDomain(Data::Empty) { + if(receivedTransportTuple) + { + mReceivedTransportTuple = *receivedTransportTuple; + } // !bwc! TODO make this tunable mHeaders.reserve(16); clear(); @@ -81,6 +83,19 @@ SipMessage::operator=(const SipMessage& rhs) SipMessage::~SipMessage() { +//#define DINKYPOOL_PROFILING +#ifdef DINKYPOOL_PROFILING + if (mPool.getHeapBytes() > 0) + { + InfoLog(<< "SipMessage mPool filled up and used " << mPool.getHeapBytes() << " bytes on the heap, consider increasing the mPool size (sizeof SipMessage is " << sizeof(SipMessage) << " bytes): msg=" + << std::endl << *this); + } + else + { + InfoLog(<< "SipMessage mPool used " << mPool.getPoolBytes() << " bytes of a total " << mPool.getPoolSizeBytes() << " bytes (sizeof SipMessage is " << sizeof(SipMessage) << " bytes): msg=" + << std::endl << *this); + } +#endif freeMem(); } @@ -90,7 +105,7 @@ SipMessage::clear(bool leaveResponseStuff) if(!leaveResponseStuff) { memset(mHeaderIndices,0,sizeof(mHeaderIndices)); - mHeaders.clear(); + clearHeaders(); // !bwc! The "invalid" 0 index. mHeaders.push_back(getEmptyHfvl()); @@ -114,7 +129,7 @@ SipMessage::init(const SipMessage& rhs) mIsDecorated = rhs.mIsDecorated; mIsBadAck200 = rhs.mIsBadAck200; mIsExternal = rhs.mIsExternal; - mTransport = rhs.mTransport; + mReceivedTransportTuple = rhs.mReceivedTransportTuple; mSource = rhs.mSource; mDestination = rhs.mDestination; mRFC2543TransactionId = rhs.mRFC2543TransactionId; @@ -134,7 +149,7 @@ SipMessage::init(const SipMessage& rhs) memcpy(&mHeaderIndices,&rhs.mHeaderIndices,sizeof(mHeaderIndices)); // .bwc. Clear out the pesky invalid 0 index. - mHeaders.clear(); + clearHeaders(); mHeaders.reserve(rhs.mHeaders.size()); for (TypedHeaders::const_iterator i = rhs.mHeaders.begin(); i != rhs.mHeaders.end(); i++) @@ -215,12 +230,7 @@ SipMessage::freeMem(bool leaveResponseStuff) if(!leaveResponseStuff) { - for (TypedHeaders::iterator i = mHeaders.begin(); - i != mHeaders.end(); i++) - { - freeHfvl(*i); - } - mHeaders.clear(); + clearHeaders(); for (vector::iterator i = mBufferList.begin(); i != mBufferList.end(); i++) @@ -246,11 +256,22 @@ SipMessage::freeMem(bool leaveResponseStuff) } } -SipMessage* -SipMessage::make(const Data& data, bool isExternal) +void +SipMessage::clearHeaders() { - Transport* external = (Transport*)(0xFFFF); - SipMessage* msg = new SipMessage(isExternal ? external : 0); + for (TypedHeaders::iterator i = mHeaders.begin(); i != mHeaders.end(); i++) + { + freeHfvl(*i); + } + mHeaders.clear(); +} + +SipMessage* +SipMessage::make(const Data& data, bool isExternal) +{ + Tuple fakeWireTuple; + fakeWireTuple.setType(UDP); + SipMessage* msg = new SipMessage(isExternal ? &fakeWireTuple : 0); size_t len = data.size(); char *buffer = new char[len + 5]; @@ -326,7 +347,7 @@ SipMessage::parseAllHeaders() scs->parseAll(); } - assert(mStartLine); + resip_assert(mStartLine); mStartLine->checkParsed(); @@ -342,7 +363,7 @@ SipMessage::getTransactionId() const throw Exception("No Via in message", __FILE__,__LINE__); } - assert(exists(h_Vias) && !header(h_Vias).empty()); + resip_assert(exists(h_Vias) && !header(h_Vias).empty()); if( exists(h_Vias) && header(h_Vias).front().exists(p_branch) && header(h_Vias).front().param(p_branch).hasMagicCookie() && (!header(h_Vias).front().param(p_branch).getTransactionId().empty()) @@ -363,7 +384,7 @@ SipMessage::getTransactionId() const void SipMessage::compute2543TransactionHash() const { - assert (mRFC2543TransactionId.empty()); + resip_assert (mRFC2543TransactionId.empty()); /* From rfc3261, 17.2.3 The INVITE request matches a transaction if the Request-URI, To tag, @@ -561,7 +582,7 @@ SipMessage::method() const } else { - assert(0); + resip_assert(0); } } catch(resip::ParseException&) @@ -592,7 +613,7 @@ SipMessage::methodStr() const } else { - assert(0); + resip_assert(0); } } catch(resip::ParseException&) @@ -642,7 +663,7 @@ SipMessage::encodeBrief(EncodeStream& str) const { str << getTransactionId(); } - catch(SipMessage::Exception&) + catch(BaseException&) // Could be SipMessage::Exception or ParseException { str << "BAD-VIA"; } @@ -682,7 +703,7 @@ SipMessage::encodeBrief(EncodeStream& str) const bool SipMessage::isClientTransaction() const { - assert(mRequest || mResponse); + resip_assert(mRequest || mResponse); return ((mIsExternal && mResponse) || (!mIsExternal && mRequest)); } @@ -970,7 +991,7 @@ SipMessage::setRawBody(const HeaderFieldValue& body) void -SipMessage::setContents(unique_ptr contents) +SipMessage::setContents(auto_ptr contents) { Contents* contentsP = contents.release(); @@ -1006,8 +1027,8 @@ SipMessage::setContents(unique_ptr contents) if (mContents->exists(h_ContentType)) { header(h_ContentType) = mContents->header(h_ContentType); - assert( header(h_ContentType).type() == mContents->getType().type() ); - assert( header(h_ContentType).subType() == mContents->getType().subType() ); + resip_assert( header(h_ContentType).type() == mContents->getType().type() ); + resip_assert( header(h_ContentType).subType() == mContents->getType().subType() ); } else { @@ -1020,24 +1041,24 @@ SipMessage::setContents(const Contents* contents) { if (contents) { - setContents(unique_ptr(contents->clone())); + setContents(auto_ptr(contents->clone())); } else { - setContents(unique_ptr(nullptr)); + setContents(auto_ptr(0)); } } Contents* SipMessage::getContents() const { - if (mContents == nullptr && mContentsHfv.getBuffer() != nullptr) + if (mContents == 0 && mContentsHfv.getBuffer() != 0) { if (empty(h_ContentType) || !const_header(h_ContentType).isWellFormed()) { StackLog(<< "SipMessage::getContents: ContentType header does not exist - implies no contents"); - return nullptr; + return 0; } DebugLog(<< "SipMessage::getContents: " << const_header(h_ContentType).type() @@ -1058,7 +1079,7 @@ SipMessage::getContents() const { mContents = ContentsFactoryBase::getFactoryMap()[const_header(h_ContentType)]->create(mContentsHfv, const_header(h_ContentType)); } - assert( mContents ); + resip_assert( mContents ); // copy contents headers into the contents if (!empty(h_ContentDisposition)) @@ -1082,17 +1103,17 @@ SipMessage::getContents() const return mContents; } -unique_ptr +auto_ptr SipMessage::releaseContents() { Contents* c=getContents(); - // .bwc. unique_ptr owns the Contents. No other references allowed! - unique_ptr ret(c ? c->clone() : nullptr); - setContents(std::unique_ptr(nullptr)); + // .bwc. auto_ptr owns the Contents. No other references allowed! + auto_ptr ret(c ? c->clone() : 0); + setContents(std::auto_ptr(0)); if (ret.get() != 0 && !ret->isWellFormed()) { - ret.reset(nullptr); + ret.reset(0); } return ret; @@ -1108,7 +1129,7 @@ SipMessage::header(const ExtensionHeader& headerName) const if (isEqualNoCase(i->first, headerName.getName())) { HeaderFieldValueList* hfvs = i->second; - if (hfvs->getParserContainer() == nullptr) + if (hfvs->getParserContainer() == 0) { SipMessage* nc_this(const_cast(this)); hfvs->setParserContainer(nc_this->makeParserContainer(hfvs, Headers::RESIP_DO_NOT_USE)); @@ -1117,7 +1138,7 @@ SipMessage::header(const ExtensionHeader& headerName) const } } // missing extension header - assert(false); + resip_assert(false); return *(StringCategories*)0; } @@ -1181,6 +1202,7 @@ SipMessage::addHeader(Headers::Type header, const char* headerName, int headerLe { if (header != Headers::UNKNOWN) { + resip_assert(header >= Headers::UNKNOWN && header < Headers::MAX_HEADERS); HeaderFieldValueList* hfvl=0; if (mHeaderIndices[header] == 0) { @@ -1231,7 +1253,7 @@ SipMessage::addHeader(Headers::Type header, const char* headerName, int headerLe } else { - assert(headerLen >= 0); + resip_assert(headerLen >= 0); for (UnknownHeaders::iterator i = mUnknownHeaders.begin(); i != mUnknownHeaders.end(); i++) { @@ -1261,7 +1283,7 @@ SipMessage::addHeader(Headers::Type header, const char* headerName, int headerLe RequestLine& SipMessage::header(const RequestLineType& l) { - assert (!isResponse()); + resip_assert (!isResponse()); if (mStartLine == 0 ) { mStartLine = new (mStartLineMem) RequestLine; @@ -1273,11 +1295,11 @@ SipMessage::header(const RequestLineType& l) const RequestLine& SipMessage::header(const RequestLineType& l) const { - assert (!isResponse()); + resip_assert (!isResponse()); if (mStartLine == 0 ) { // request line missing - assert(false); + resip_assert(false); } return *static_cast(mStartLine); } @@ -1285,7 +1307,7 @@ SipMessage::header(const RequestLineType& l) const StatusLine& SipMessage::header(const StatusLineType& l) { - assert (!isRequest()); + resip_assert (!isRequest()); if (mStartLine == 0 ) { mStartLine = new (mStartLineMem) StatusLine; @@ -1297,11 +1319,11 @@ SipMessage::header(const StatusLineType& l) const StatusLine& SipMessage::header(const StatusLineType& l) const { - assert (!isRequest()); + resip_assert (!isRequest()); if (mStartLine == 0 ) { // status line missing - assert(false); + resip_assert(false); } return *static_cast(mStartLine); } @@ -1506,6 +1528,13 @@ defineMultiHeader(ServiceRoute, "Service-Route", NameAddr, "RFC 3608"); defineHeader(ContentTransferEncoding, "Content-Transfer-Encoding", StringCategory, "RFC ?"); defineHeader(Organization, "Organization", StringCategory, "RFC 3261"); +defineHeader(SecWebSocketKey, "Sec-WebSocket-Key", StringCategory, "RFC 6455"); +defineHeader(SecWebSocketKey1, "Sec-WebSocket-Key1", StringCategory, "draft-hixie- thewebsocketprotocol-76"); +defineHeader(SecWebSocketKey2, "Sec-WebSocket-Key2", StringCategory, "draft-hixie- thewebsocketprotocol-76"); +defineHeader(Origin, "Origin", StringCategory, "draft-hixie- thewebsocketprotocol-76"); +defineHeader(Host, "Host", StringCategory, "draft-hixie- thewebsocketprotocol-76"); +defineHeader(SecWebSocketAccept, "Sec-WebSocket-Accept", StringCategory, "RFC 6455"); +defineMultiHeader(Cookie, "Cookie", StringCategory, "RFC 6265"); defineHeader(Server, "Server", StringCategory, "RFC 3261"); defineHeader(Subject, "Subject", StringCategory, "RFC 3261"); defineHeader(UserAgent, "User-Agent", StringCategory, "RFC 3261"); @@ -1544,6 +1573,13 @@ defineHeader(RAck, "RAck", RAckCategory, "RFC 3262"); defineMultiHeader(RemotePartyId, "Remote-Party-ID", NameAddr, "draft-ietf-sip-privacy-04"); // ?bwc? Not in 3323, should we keep? defineMultiHeader(HistoryInfo, "History-Info", NameAddr, "RFC 4244"); +defineMultiHeader(PAccessNetworkInfo, "P-Access-Network-Info", Token, "RFC 7315"); // section 5.4. +defineHeader(PChargingVector, "P-Charging-Vector", Token, "RFC 3455"); +defineHeader(PChargingFunctionAddresses, "P-Charging-Function-Addresses", Token, "RFC 3455"); +defineMultiHeader(PVisitedNetworkID, "P-Visited-Network-ID", TokenOrQuotedStringCategory, "RFC 3455"); + +defineMultiHeader(UserToUser, "User-to-User", TokenOrQuotedStringCategory, "draft-ietf-cuss-sip-uui-17"); + #endif const HeaderFieldValueList* @@ -1608,7 +1644,7 @@ SipMessage::clearForceTarget() const Uri& SipMessage::getForceTarget() const { - assert(mForceTarget); + resip_assert(mForceTarget); return *mForceTarget; } @@ -1692,9 +1728,9 @@ SipMessage::mergeUri(const Uri& source) } void -SipMessage::setSecurityAttributes(unique_ptr sec) +SipMessage::setSecurityAttributes(auto_ptr sec) { - mSecurityAttributes = std::move(sec); + mSecurityAttributes = sec; } void @@ -1746,7 +1782,7 @@ SipMessage::copyOutboundDecoratorsToStackCancel(SipMessage& cancel) { if((*i)->copyToStackCancels()) { - cancel.addOutboundDecorator(std::move(*(new unique_ptr((*i)->clone())))); + cancel.addOutboundDecorator(std::auto_ptr((*i)->clone())); } } } @@ -1760,7 +1796,7 @@ SipMessage::copyOutboundDecoratorsToStackFailureAck(SipMessage& ack) { if((*i)->copyToStackFailureAcks()) { - ack.addOutboundDecorator(std::move(*(new unique_ptr((*i)->clone())))); + ack.addOutboundDecorator(std::auto_ptr((*i)->clone())); } } } diff --git a/src/libs/resiprocate/resip/stack/SipMessage.hxx b/src/libs/resiprocate/resip/stack/SipMessage.hxx index fcb516d6..0e4b4ec7 100644 --- a/src/libs/resiprocate/resip/stack/SipMessage.hxx +++ b/src/libs/resiprocate/resip/stack/SipMessage.hxx @@ -17,12 +17,15 @@ #include "resip/stack/Tuple.hxx" #include "resip/stack/Uri.hxx" #include "resip/stack/MessageDecorator.hxx" +#include "resip/stack/Cookie.hxx" +#include "resip/stack/WsCookieContext.hxx" #include "rutil/BaseException.hxx" #include "rutil/Data.hxx" #include "rutil/DinkyPool.hxx" #include "rutil/StlPoolAllocator.hxx" #include "rutil/Timer.hxx" #include "rutil/HeapInstanceCounter.hxx" +#include "rutil/SharedPtr.hxx" namespace resip { @@ -30,7 +33,6 @@ namespace resip class Contents; class ExtensionHeader; class SecurityAttributes; -class Transport; /** @ingroup resip_crit @@ -159,7 +161,7 @@ class SipMessage : public TransactionMessage typedef std::list< std::pair > UnknownHeaders; #endif - explicit SipMessage(const Transport* fromWire = 0); + explicit SipMessage(const Tuple *receivedTransport = 0); /// @todo .dlb. public, allows pass by value to compile. SipMessage(const SipMessage& message); @@ -225,14 +227,32 @@ class SipMessage : public TransactionMessage mIsExternal = true; } - /** @brief Check if SipMessage came off the wire. - - @return true if the message came from an IP interface, false otherwise. + /** + @brief Check if SipMessage is to be treated as it came off the wire. + + @return true if the message came from an IP interface or if it was + an internally generated response to an internally generated + request (ie: 408), false otherwise. */ inline bool isExternal() const { return mIsExternal; } + + /** + @brief Check if SipMessage came off the wire. + + @note differs from isExternal(), since isExternal() also returns true + for internally generated responses to internally generate requests + (ie: 408, etc.). isFromWire only ever returns true if the message + actually came off the wire. + + @return true if the message came from an IP interface, false otherwise. + */ + inline bool isFromWire() const + { + return mReceivedTransportTuple.getType() != UNKNOWN_TRANSPORT; + } /// @brief Check if SipMessage is a client transaction /// @return true if the message is external and is a response or @@ -386,6 +406,13 @@ class SipMessage : public TransactionMessage defineHeader(ContentTransferEncoding, "Content-Transfer-Encoding", StringCategory, "RFC 1521"); defineHeader(Organization, "Organization", StringCategory, "RFC 3261"); + defineHeader(SecWebSocketKey, "Sec-WebSocket-Key", StringCategory, "RFC 6455"); + defineHeader(SecWebSocketKey1, "Sec-WebSocket-Key1", StringCategory, "draft-hixie- thewebsocketprotocol-76"); + defineHeader(SecWebSocketKey2, "Sec-WebSocket-Key2", StringCategory, "draft-hixie- thewebsocketprotocol-76"); + defineHeader(Origin, "Origin", StringCategory, "draft-hixie- thewebsocketprotocol-76"); + defineHeader(Host, "Host", StringCategory, "draft-hixie- thewebsocketprotocol-76"); + defineHeader(SecWebSocketAccept, "Sec-WebSocket-Accept", StringCategory, "RFC 6455"); + defineMultiHeader(Cookie, "Cookie", StringCategory, "RFC 6265"); defineHeader(Server, "Server", StringCategory, "RFC 3261"); defineHeader(Subject, "Subject", StringCategory, "RFC 3261"); defineHeader(UserAgent, "User-Agent", StringCategory, "RFC 3261"); @@ -422,6 +449,13 @@ class SipMessage : public TransactionMessage defineMultiHeader(Via, "Via", Via, "RFC 3261"); defineHeader(RAck, "RAck", RAckCategory, "RFC 3262"); + defineMultiHeader(PAccessNetworkInfo, "P-Access-Network-Info", Token, "RFC 7315"); // section 5.4. + defineHeader(PChargingVector, "P-Charging-Vector", Token, "RFC 3455"); + defineHeader(PChargingFunctionAddresses, "P-Charging-Function-Addresses", Token, "RFC 3455"); + defineMultiHeader(PVisitedNetworkID, "P-Visited-Network-ID", TokenOrQuotedStringCategory, "RFC 3455"); + + defineMultiHeader(UserToUser, "User-to-User", TokenOrQuotedStringCategory, "draft-ietf-cuss-sip-uui-17"); + /// unknown header interface const StringCategories& header(const ExtensionHeader& symbol) const; StringCategories& header(const ExtensionHeader& symbol); @@ -461,14 +495,14 @@ class SipMessage : public TransactionMessage **/ Contents* getContents() const; /// Removes the contents from the message - std::unique_ptr releaseContents(); + std::auto_ptr releaseContents(); /// @brief Set the contents of the message /// @param contents to store in the message void setContents(const Contents* contents); /// @brief Set the contents of the message /// @param contents to store in the message - void setContents(std::unique_ptr contents); + void setContents(std::auto_ptr contents); /// @internal transport interface void setStartLine(const char* start, int len); @@ -480,10 +514,14 @@ class SipMessage : public TransactionMessage const char* headerName, int headerLen, const char* start, int len); - /// @brief Interface used to determine which Transport was used to receive a - /// particular SipMessage. If the SipMessage was not received from the - /// wire, getReceivedTransport() returns 0. Set in constructor - const Transport* getReceivedTransport() const { return mTransport; } + // Returns the source tuple for the transport that the message was received from + // only makes sense for messages received from the wire. Differs from Source + // since it contains the transport bind address instead of the actual source + // address. + const Tuple& getReceivedTransportTuple() const { return mReceivedTransportTuple; } + + /// Set Tuple for transport from whence this message came + void setReceivedTransportTuple(const Tuple& transportTuple) { mReceivedTransportTuple = transportTuple;} // Returns the source tuple that the message was received from // only makes sense for messages received from the wire @@ -498,7 +536,7 @@ class SipMessage : public TransactionMessage void addBuffer(char* buf); - UInt64 getCreatedTimeMicroSec() {return mCreatedTime;} + UInt64 getCreatedTimeMicroSec() const {return mCreatedTime;} /// deal with a notion of an "out-of-band" forced target for SIP routing void setForceTarget(const Uri& uri); @@ -512,16 +550,22 @@ class SipMessage : public TransactionMessage const std::list& getTlsPeerNames() const { return mTlsPeerNames; } void setTlsPeerNames(const std::list& tlsPeerNames) { mTlsPeerNames = tlsPeerNames; } + const CookieList& getWsCookies() const { return mWsCookies; } + void setWsCookies(const CookieList& wsCookies) { mWsCookies = wsCookies; } + + SharedPtr getWsCookieContext() const { return mWsCookieContext; } + void setWsCookieContext(SharedPtr wsCookieContext) { mWsCookieContext = wsCookieContext; } + Data getCanonicalIdentityString() const; SipMessage& mergeUri(const Uri& source); - void setSecurityAttributes(std::unique_ptr); + void setSecurityAttributes(std::auto_ptr); const SecurityAttributes* getSecurityAttributes() const { return mSecurityAttributes.get(); } /// @brief Call a MessageDecorator to process the message before it is /// sent to the transport - void addOutboundDecorator(std::unique_ptr md){mOutboundDecorators.push_back(md.release());} + void addOutboundDecorator(std::auto_ptr md){mOutboundDecorators.push_back(md.release());} void clearOutboundDecorators(); void callOutboundDecorators(const Tuple &src, const Tuple &dest, @@ -539,6 +583,8 @@ class SipMessage : public TransactionMessage void clear(bool leaveResponseStuff=false); // !bwc! Frees all heap-allocated memory owned. void freeMem(bool leaveResponseStuff=false); + // Clears mHeaders and cleans up memory + void clearHeaders(); // !bwc! Initializes members. Will not free heap-allocated memory. // Will begin by calling clear(). @@ -612,12 +658,16 @@ class SipMessage : public TransactionMessage return new (ptr) ParserContainer(hfvs, type, mPool); } - // indicates this message came from the wire, set by the Transport + // indicates this message came from the wire or we want it to look like it + // came from the wire (ie. internally generated responses to an internally + // generated request), set by the Transport and setFromTu and setFromExternal APIs bool mIsExternal; - // !bwc! Would be nice to tweak this to automatically make SipMessage 4KB, - // but I don't know how ugly it would be. - DinkyPool<2968> mPool; + // Sizing so that average SipMessages don't need to allocate heap memory + // To profile current sizing, enable DINKYPOOL_PROFILING in SipMessage.cxx + // and look for DebugLog message in SipMessage destructor to know when heap + // allocations are occuring and how much of the pool is used. + DinkyPool<3732> mPool; typedef std::vector mTlsPeerNames; + std::list mTlsPeerNames; - std::unique_ptr mSecurityAttributes; + // cookies associated with this message from the WebSocket Upgrade request + CookieList mWsCookies; + + // parsed cookie authentication elements associated with this message from the WebSocket Upgrade request + SharedPtr mWsCookieContext; + + std::auto_ptr mSecurityAttributes; std::vector mOutboundDecorators; diff --git a/src/libs/resiprocate/resip/stack/SipStack.cxx b/src/libs/resiprocate/resip/stack/SipStack.cxx index d2296f4e..9f5c1c09 100644 --- a/src/libs/resiprocate/resip/stack/SipStack.cxx +++ b/src/libs/resiprocate/resip/stack/SipStack.cxx @@ -30,6 +30,7 @@ #include "rutil/AsyncProcessHandler.hxx" #include "resip/stack/TcpTransport.hxx" #include "resip/stack/UdpTransport.hxx" +#include "resip/stack/WsTransport.hxx" #include "resip/stack/TransactionUser.hxx" #include "resip/stack/TransactionUserMessage.hxx" #include "resip/stack/TransactionControllerThread.hxx" @@ -40,6 +41,7 @@ #include "resip/stack/ssl/Security.hxx" #include "resip/stack/ssl/DtlsTransport.hxx" #include "resip/stack/ssl/TlsTransport.hxx" +#include "resip/stack/ssl/WssTransport.hxx" #endif #if defined(WIN32) && !defined(__GNUC__) @@ -55,7 +57,8 @@ SipStack::SipStack(const SipStackOptions& options) : TransactionController::MaxTUFifoSize), mTuSelector(mTUFifo), mAppTimers(mTuSelector), - mStatsManager(*this) + mStatsManager(*this), + mNextTransportKey(1) { // WARNING - don't forget to add new member initialization to the init() method init(options); @@ -69,8 +72,17 @@ SipStack::SipStack(Security* pSecurity, bool stateless, AfterSocketCreationFuncPtr socketFunc, Compression *compression, - FdPollGrp *pollGrp) : + FdPollGrp *pollGrp, + bool useDnsVip) : +#ifdef WIN32 + // If PollGrp is not passed in, then EventStackThead isn't being used and application + // is most likely implementing a select/process loop to drive the stack - in this case + // we want windows to default to fdset implementation, since the Poll implementation on + // windows does not support the select/process loop + mPollGrp(pollGrp?pollGrp:FdPollGrp::create("fdset")), +#else mPollGrp(pollGrp?pollGrp:FdPollGrp::create()), +#endif mPollGrpIsMine(!pollGrp), #ifdef USE_SSL mSecurity( pSecurity ? pSecurity : new Security()), @@ -88,13 +100,15 @@ SipStack::SipStack(Security* pSecurity, mTuSelector(mTUFifo), mAppTimers(mTuSelector), mStatsManager(*this), - mTransactionController(new TransactionController(*this, mAsyncProcessHandler)), + mTransactionController(new TransactionController(*this, mAsyncProcessHandler, useDnsVip)), mTransactionControllerThread(0), mTransportSelectorThread(0), - mRunning(false), + mInternalThreadsRunning(false), + mProcessingHasStarted(false), mShuttingDown(false), mStatisticsManagerEnabled(true), - mSocketFunc(socketFunc) + mSocketFunc(socketFunc), + mNextTransportKey(1) { Timer::getTimeMs(); // initalize time offsets Random::initialize(); @@ -104,7 +118,7 @@ SipStack::SipStack(Security* pSecurity, #ifdef USE_SSL pSecurity->preload(); #else - assert(0); + resip_assert(0); #endif } @@ -142,7 +156,15 @@ SipStack::init(const SipStackOptions& options) } else { +#ifdef WIN32 + // If PollGrp is not passed in, then EventStackThead isn't being used and application + // is most likely implementing a select/process loop to drive the stack - in this case + // we want windows to default to fdset implementation, since the Poll implementation on + // windows does not support the select/process loop + mPollGrp = FdPollGrp::create("fdset"); +#else mPollGrp = FdPollGrp::create(); +#endif mPollGrpIsMine=true; } @@ -151,7 +173,7 @@ SipStack::init(const SipStackOptions& options) mSecurity->preload(); #else mSecurity = 0; - assert(options.mSecurity==0); + resip_assert(options.mSecurity==0); #endif if(options.mAsyncProcessHandler) @@ -180,12 +202,13 @@ SipStack::init(const SipStackOptions& options) // WATCHOUT: the transaction controller constructor will // grab the security, DnsStub, compression and statsManager - mTransactionController = new TransactionController(*this, mAsyncProcessHandler); + mTransactionController = new TransactionController(*this, mAsyncProcessHandler, options.mUseDnsVip); mTransactionController->transportSelector().setPollGrp(mPollGrp); mTransactionControllerThread = 0; mTransportSelectorThread = 0; - mRunning = false; + mInternalThreadsRunning = false; + mProcessingHasStarted = false; mShuttingDown = false; mStatisticsManagerEnabled = true; mSocketFunc = options.mSocketFunc; @@ -227,18 +250,17 @@ SipStack::~SipStack() delete mAsyncProcessHandler; mAsyncProcessHandler=0; } - } void SipStack::run() { - if(mRunning) + if(mInternalThreadsRunning) { return; } - mRunning=true; + mInternalThreadsRunning=true; delete mDnsThread; mDnsThread=new DnsThread(*mDnsStub); mDnsThread->run(); @@ -259,7 +281,7 @@ SipStack::shutdown() { Lock lock(mShutdownMutex); - assert(!mShuttingDown); + resip_assert(!mShuttingDown); mShuttingDown = true; } @@ -286,7 +308,22 @@ SipStack::shutdownAndJoinThreads() mTransportSelectorThread->shutdown(); mTransportSelectorThread->join(); } - mRunning=false; + mInternalThreadsRunning=false; +} + +void +SipStack::onReload() +{ + reloadCertificates(); +} + +void +SipStack::reloadCertificates() +{ + for(SecureTransportMap::iterator itS = mSecureTransports.begin(); itS != mSecureTransports.end(); itS++) + { + itS->second->onReload(); + } } Transport* @@ -299,10 +336,14 @@ SipStack::addTransport( TransportType protocol, const Data& privateKeyPassPhrase, SecurityTypes::SSLType sslType, unsigned transportFlags, + const Data& certificateFilename, const Data& privateKeyFilename, SecurityTypes::TlsClientVerificationMode cvm, - bool useEmailAsSIP) + bool useEmailAsSIP, + SharedPtr wsConnectionValidator, + SharedPtr wsCookieContextFactory, + const Data& netNs) { - assert(!mShuttingDown); + resip_assert(!mShuttingDown); // If address is specified, ensure it is valid if(!ipInterface.empty()) @@ -329,6 +370,14 @@ SipStack::addTransport( TransportType protocol, } } +#ifdef USE_NETNS + if(!netNs.empty() && protocol != TCP) + { + ErrLog(<< "Failed to create transport, netns is currently only supported for TCP. Cannot use netns: " << netNs); + throw Transport::Exception("netns only supported for TCP", __FILE__,__LINE__); + } +#endif + InternalTransport* transport=0; Fifo& stateMacFifo = mTransactionController->transportSelector().stateMacFifo(); try @@ -339,7 +388,8 @@ SipStack::addTransport( TransportType protocol, transport = new UdpTransport(stateMacFifo, port, version, stun, ipInterface, mSocketFunc, *mCompression, transportFlags); break; case TCP: - transport = new TcpTransport(stateMacFifo, port, version, ipInterface, mSocketFunc, *mCompression, transportFlags); + transport = + new TcpTransport(stateMacFifo, port, version, ipInterface, mSocketFunc, *mCompression, transportFlags, netNs); break; case TLS: #if defined( USE_SSL ) @@ -354,10 +404,13 @@ SipStack::addTransport( TransportType protocol, *mCompression, transportFlags, cvm, - useEmailAsSIP); + useEmailAsSIP, + certificateFilename, + privateKeyFilename, + privateKeyPassPhrase); #else - CritLog (<< "TLS not supported in this stack. You don't have openssl"); - assert(0); + CritLog (<< "Can't add TLS transport: TLS not supported in this stack. You don't have openssl."); + throw Transport::Exception("Can't add TLS transport: TLS not supported in this stack. You don't have openssl.", __FILE__,__LINE__); #endif break; case DTLS: @@ -369,14 +422,55 @@ SipStack::addTransport( TransportType protocol, *mSecurity, sipDomainname, mSocketFunc, - *mCompression); + *mCompression, + certificateFilename, + privateKeyFilename, + privateKeyPassPhrase); #else - CritLog (<< "DTLS not supported in this stack."); - assert(0); + CritLog (<< "Can't add DTLS transport: DTLS not supported in this stack."); + throw Transport::Exception("Can't add DTLS transport: DTLS not supported in this stack.", __FILE__,__LINE__); +#endif + break; + + case WS: + transport = new WsTransport(stateMacFifo, + port, + version, + ipInterface, + mSocketFunc, + *mCompression, + transportFlags, + wsConnectionValidator, + wsCookieContextFactory); + break; + + case WSS: +#if defined( USE_SSL ) + transport = new WssTransport(stateMacFifo, + port, + version, + ipInterface, + *mSecurity, + sipDomainname, + sslType, + mSocketFunc, + *mCompression, + transportFlags, + cvm, + useEmailAsSIP, + wsConnectionValidator, + wsCookieContextFactory, + certificateFilename, + privateKeyFilename, + privateKeyPassPhrase); +#else + CritLog (<< "Can't add WSS transport: Secure Websockets not supported in this stack. You don't have openssl."); + throw Transport::Exception("Can't add WSS transport: Secure Websockets not supported in this stack. You don't have openssl.", __FILE__,__LINE__); #endif break; default: - assert(0); + CritLog (<< "Can't add unknown transport."); + throw Transport::Exception("Can't add unknown transport.", __FILE__,__LINE__); break; } } @@ -389,14 +483,57 @@ SipStack::addTransport( TransportType protocol, << ": " << e); throw; } - addTransport(std::unique_ptr(transport)); + addTransport(std::auto_ptr(transport)); return transport; } void -SipStack::addTransport(std::unique_ptr transport) +SipStack::addTransport(std::auto_ptr transport) { - //.dcm. once addTransport starts throwing, need to back out alias + // Ensure we will be able to add the transport in the transport selector by ensure we + // don't have any transport collisions. Note: We store two set's here in order to + // avoid needing to ask the TransportSelector under some form of locking. + Tuple tuple(transport->interfaceName(), transport->port(), + transport->ipVersion(), transport->transport(), + Data::Empty, // target domain + transport->netNs()); + if(!isSecure(transport->transport())) + { + if(mNonSecureTransports.count(tuple) == 0) + { + // All is good - assign key to transport then add to mNonSecureTransports list + transport->setKey(mNextTransportKey++); + tuple.mTransportKey = transport->getKey(); + mNonSecureTransports[tuple] = transport.get(); + } + else + { + // Nonsecure transport collision with existing transport + ErrLog(<< "Failed to add non-secure transport, transport with similar properties already exists: " << tuple); + throw Transport::Exception("Failed to add non-secure transport, transport with similar properties already exists.", __FILE__,__LINE__); + return; + } + } + else + { + tuple.setTargetDomain(transport->tlsDomain()); + TransportSelector::TlsTransportKey tlsKey(tuple); + if(mSecureTransports.count(tlsKey) == 0) + { + // All is good - assign key to transport then add to mNonSecureTransports list + transport->setKey(mNextTransportKey++); + tlsKey.mTuple.mTransportKey = transport->getKey(); + mSecureTransports[tlsKey] = transport.get(); + } + else + { + // Secure transport collision with existing transport + ErrLog(<< "Failed to add secure transport, transport with similar properties already exists: " << tuple); + throw Transport::Exception("Failed to add secure transport, transport with similar properties already exists.", __FILE__,__LINE__); + return; + } + } + if (!transport->interfaceName().empty()) { addAlias(transport->interfaceName(), transport->port()); @@ -411,16 +548,136 @@ SipStack::addTransport(std::unique_ptr transport) } while(!ipIfs.empty()) { - if(DnsUtil::isIpV4Address(ipIfs.back().second)== - (transport->ipVersion()==V4)) + if(DnsUtil::isIpV4Address(ipIfs.back().second) == (transport->ipVersion()==V4)) { addAlias(ipIfs.back().second, transport->port()); } ipIfs.pop_back(); } } - mPorts.insert(transport->port()); - mTransactionController->transportSelector().addTransport(std::move(transport), true); + { + Lock lock(mPortsMutex); + mPorts[transport->port()]++; // add port / increment reference count + } + + // Add to CongestionManager if required + if(mCongestionManager) + { + transport->setCongestionManager(mCongestionManager); + } + + // Set Sip Message Logging Handler if one was provided + if(mTransportSipMessageLoggingHandler.get()) + { + transport->setSipMessageLoggingHandler(mTransportSipMessageLoggingHandler); + } + + if(mProcessingHasStarted) + { + // Stack is running. Need to queue add request for TransactionController Thread + mTransactionController->addTransport(transport); + } + else + { + // Stack isn't running yet - just add transport directly on transport selector from this thread + mTransactionController->transportSelector().addTransport(transport, false /* isStackRunning */); + } +} + +void +SipStack::removeTransport(unsigned int transportKey) +{ + Tuple removeTuple; + Transport* transportToRemove = 0; + + // Find transport using Key in SipStack lists(sets) + for(NonSecureTransportMap::iterator itNS = mNonSecureTransports.begin(); itNS != mNonSecureTransports.end(); itNS++) + { + if(itNS->first.mTransportKey == transportKey) + { + removeTuple = itNS->first; + transportToRemove = itNS->second; + mNonSecureTransports.erase(itNS); + break; + } + } + // If not found look in Secure list(set) + if(!transportToRemove) + { + for(SecureTransportMap::iterator itS = mSecureTransports.begin(); itS != mSecureTransports.end(); itS++) + { + if(itS->first.mTuple.mTransportKey == transportKey) + { + removeTuple = itS->first.mTuple; + transportToRemove = itS->second; + mSecureTransports.erase(itS); + break; + } + } + } + if(!transportToRemove) + { + WarningLog (<< "removeTransport: could not find transport specified by transportKey=" << transportKey); + return; + } + + if(mSecureTransports.size() == 0 && mNonSecureTransports.size() == 0) + { + // If we have no more transports we can just clear out the mDomains map and mUri + Lock lock(mDomainsMutex); + mDomains.clear(); + mUri.host().clear(); + mUri.port() = 0; + } + else if(!transportToRemove->interfaceName().empty()) + { + removeAlias(transportToRemove->interfaceName(), transportToRemove->port()); + } + else + { + // Warning: This removal could produce unexpected results if the querying of the + // current interface addresses yields a different result then when we added the + // transport. + // Using INADDR_ANY, get all IP interfaces + std::list > ipIfs(DnsUtil::getInterfaces()); + if(transportToRemove->ipVersion()==V4) + { + ipIfs.push_back(std::make_pair("lo0","127.0.0.1")); + } + while(!ipIfs.empty()) + { + if(DnsUtil::isIpV4Address(ipIfs.back().second) == (transportToRemove->ipVersion()==V4)) + { + removeAlias(ipIfs.back().second, transportToRemove->port()); + } + ipIfs.pop_back(); + } + } + + // Remove from port map if reference count is 0 + { + Lock lock(mPortsMutex); + std::map::iterator itP = mPorts.find(transportToRemove->port()); + if(itP != mPorts.end()) + { + // Decrement reference count and erase if 0 + if(--itP->second == 0) + { + mPorts.erase(itP); + } + } + } + + if(mProcessingHasStarted) + { + // Stack is running. Need to queue remove request for TransactionController Thread + mTransactionController->removeTransport(transportKey); + } + else + { + // Stack isn't running yet - just remove transport directly on transport selector from this thread + mTransactionController->transportSelector().removeTransport(transportKey); + } } Fifo& @@ -434,16 +691,40 @@ SipStack::addAlias(const Data& domain, int port) { int portToUse = (port == 0) ? Symbols::DefaultSipPort : port; - //DebugLog (<< "Adding domain alias: " << domain << ":" << portToUse); - assert(!mShuttingDown); - mDomains.insert(domain + ":" + Data(portToUse)); + DebugLog (<< "Adding domain alias: " << domain << ":" << portToUse); + resip_assert(!mShuttingDown); + Lock lock(mDomainsMutex); + mDomains[domain + ":" + Data(portToUse)]++; if(mUri.host().empty()) { - mUri.host()=*mDomains.begin(); + mUri.host() = domain; + mUri.port() = portToUse; + } +} + +void +SipStack::removeAlias(const Data& domain, int port) +{ + int portToUse = (port == 0) ? Symbols::DefaultSipPort : port; + + DebugLog (<< "Removing domain alias: " << domain << ":" << portToUse); + resip_assert(!mShuttingDown); + + Lock lock(mDomainsMutex); + DomainsMap::iterator it = mDomains.find(domain + ":" + Data(portToUse)); + if(it != mDomains.end()) + { + if(--it->second == 0) + { + mDomains.erase(it); + } } + // TODO - could reset mUri to be first item in Domain map - would need + // to seperate domain name and port though. Not sure who is using mUri + // anyway. } Data @@ -456,7 +737,7 @@ SipStack::getHostname() { ErrLog(<< "gethostname failed with return " << err << " Returning " "\"localhost\""); - assert(0); + resip_assert(0); return "localhost"; } @@ -468,10 +749,10 @@ SipStack::getHostname() ErrLog( << "gethostbyname failed - name server is probably down" ); return "localhost"; } - assert( hostEnt ); + resip_assert( hostEnt ); struct in_addr* addr = (struct in_addr*) hostEnt->h_addr_list[0]; - assert( addr ); + resip_assert( addr ); // if you change this, please #def old version for windows char* addrA = inet_ntoa( *addr ); @@ -493,7 +774,7 @@ SipStack::getHostAddress() { ErrLog(<< "gethostname failed with return " << err << " Returning " "\"127.0.0.1\""); - assert(0); + resip_assert(0); return "127.0.0.1"; } @@ -501,7 +782,7 @@ SipStack::getHostAddress() if(!hostEnt) { ErrLog(<< "gethostbyname failed, returning \"127.0.0.1\""); - assert(0); + resip_assert(0); return "127.0.0.1"; } @@ -510,7 +791,7 @@ SipStack::getHostAddress() { ErrLog(<< "gethostbyname returned a hostent* with an empty h_addr_list," " returning \"127.0.0.1\""); - assert(0); + resip_assert(0); return "127.0.0.1"; } @@ -526,6 +807,7 @@ SipStack::getHostAddress() bool SipStack::isMyDomain(const Data& domain, int port) const { + Lock lock(mDomainsMutex); return (mDomains.count(domain + ":" + Data(port == 0 ? Symbols::DefaultSipPort : port)) != 0); } @@ -533,12 +815,14 @@ SipStack::isMyDomain(const Data& domain, int port) const bool SipStack::isMyPort(int port) const { + Lock lock(mPortsMutex); return mPorts.count(port) != 0; } const Uri& SipStack::getUri() const { + Lock lock(mDomainsMutex); if(mUri.host().empty()) { CritLog(<< "There are no associated transports"); @@ -566,7 +850,7 @@ SipStack::send(const SipMessage& msg, TransactionUser* tu) } void -SipStack::send(std::unique_ptr msg, TransactionUser* tu) +SipStack::send(std::auto_ptr msg, TransactionUser* tu) { DebugLog (<< "SEND: " << msg->brief()); @@ -580,7 +864,7 @@ SipStack::send(std::unique_ptr msg, TransactionUser* tu) } void -SipStack::sendTo(std::unique_ptr msg, const Uri& uri, TransactionUser* tu) +SipStack::sendTo(std::auto_ptr msg, const Uri& uri, TransactionUser* tu) { if (tu) msg->setTransactionUser(tu); msg->setForceTarget(uri); @@ -590,9 +874,9 @@ SipStack::sendTo(std::unique_ptr msg, const Uri& uri, TransactionUse } void -SipStack::sendTo(std::unique_ptr msg, const Tuple& destination, TransactionUser* tu) +SipStack::sendTo(std::auto_ptr msg, const Tuple& destination, TransactionUser* tu) { - assert(!mShuttingDown); + resip_assert(!mShuttingDown); if (tu) msg->setTransactionUser(tu); msg->setDestination(destination); @@ -621,7 +905,7 @@ SipStack::sendTo(const SipMessage& msg, const Uri& uri, TransactionUser* tu) void SipStack::sendTo(const SipMessage& msg, const Tuple& destination, TransactionUser* tu) { - assert(!mShuttingDown); + resip_assert(!mShuttingDown); SipMessage* toSend = static_cast(msg.clone()); if (tu) toSend->setTransactionUser(tu); @@ -641,16 +925,16 @@ SipStack::checkAsyncProcessHandler() } void -SipStack::post(std::unique_ptr message) +SipStack::post(std::auto_ptr message) { - assert(!mShuttingDown); + resip_assert(!mShuttingDown); mTuSelector.add(message.release(), TimeLimitFifo::InternalElement); } void SipStack::post(const ApplicationMessage& message) { - assert(!mShuttingDown); + resip_assert(!mShuttingDown); Message* toPost = message.clone(); mTuSelector.add(toPost, TimeLimitFifo::InternalElement); } @@ -659,7 +943,7 @@ void SipStack::post(const ApplicationMessage& message, unsigned int secondsLater, TransactionUser* tu) { - assert(!mShuttingDown); + resip_assert(!mShuttingDown); postMS(message, secondsLater*1000, tu); } @@ -667,7 +951,7 @@ void SipStack::postMS(const ApplicationMessage& message, unsigned int ms, TransactionUser* tu) { - assert(!mShuttingDown); + resip_assert(!mShuttingDown); Message* toPost = message.clone(); if (tu) toPost->setTransactionUser(tu); Lock lock(mAppTimerMutex); @@ -678,20 +962,20 @@ SipStack::postMS(const ApplicationMessage& message, unsigned int ms, } void -SipStack::post(std::unique_ptr message, +SipStack::post(std::auto_ptr message, unsigned int secondsLater, TransactionUser* tu) { - postMS(std::move(message), secondsLater*1000, tu); + postMS(message, secondsLater*1000, tu); } void -SipStack::postMS( std::unique_ptr message, +SipStack::postMS( std::auto_ptr message, unsigned int ms, TransactionUser* tu) { - assert(!mShuttingDown); + resip_assert(!mShuttingDown); if (tu) message->setTransactionUser(tu); Lock lock(mAppTimerMutex); mAppTimers.add(ms, message.release()); @@ -707,9 +991,9 @@ SipStack::abandonServerTransaction(const Data& tid) } void -SipStack::cancelClientInviteTransaction(const Data& tid) +SipStack::cancelClientInviteTransaction(const Data& tid, const Tokens* reasons) { - mTransactionController->cancelClientInviteTransaction(tid); + mTransactionController->cancelClientInviteTransaction(tid, reasons); } bool @@ -780,11 +1064,6 @@ SipStack::setFallbackPostNotify(AsyncProcessHandler *handler) void SipStack::processTimers() { - if(!mShuttingDown && mStatisticsManagerEnabled) - { - mStatsManager.process(); - } - if(!mTransactionControllerThread) { mTransactionController->process(); @@ -809,8 +1088,7 @@ SipStack::processTimers() void SipStack::process(FdSet& fdset) { - if (mPollGrp) - mPollGrp->processFdSet(fdset); + mPollGrp->processFdSet(fdset); processTimers(); } @@ -821,9 +1099,7 @@ SipStack::process(unsigned int timeoutMs) // waitAndProcess() with a timeout of 0, which should improve efficiency // somewhat. processTimers(); - bool result = false; - if (mPollGrp) - result = mPollGrp->waitAndProcess(resipMin(timeoutMs, getTimeTillNextProcessMS())); + bool result=mPollGrp->waitAndProcess(resipMin(timeoutMs, getTimeTillNextProcessMS())); return result; } @@ -832,6 +1108,7 @@ unsigned int SipStack::getTimeTillNextProcessMS() { Lock lock(mAppTimerMutex); + mProcessingHasStarted = true; unsigned int dnsNextProcess = (mDnsThread ? INT_MAX : mDnsStub->getTimeTillNextProcessMS()); @@ -849,8 +1126,7 @@ SipStack::getTimeTillNextProcessMS() void SipStack::buildFdSet(FdSet& fdset) { - if (mPollGrp) - mPollGrp->buildFdSet(fdset); + mPollGrp->buildFdSet(fdset); } Security* @@ -886,9 +1162,9 @@ SipStack::pollStatistics() } void -SipStack::registerTransactionUser(TransactionUser& tu) +SipStack::registerTransactionUser(TransactionUser& tu, const bool front) { - mTuSelector.registerTransactionUser(tu); + mTuSelector.registerTransactionUser(tu, front); } void @@ -953,6 +1229,12 @@ SipStack::getDnsCacheDump(std::pair key, GetDnsCac mDnsStub->getDnsCacheDump(key, handler); } +void +SipStack::reloadDnsServers() +{ + mDnsStub->reloadDnsServers(); +} + volatile bool& SipStack::statisticsManagerEnabled() { @@ -968,24 +1250,30 @@ SipStack::statisticsManagerEnabled() const EncodeStream& SipStack::dump(EncodeStream& strm) const { - Lock lock(mAppTimerMutex); - strm << "SipStack: " << (this->mSecurity ? "with security " : "without security ") - << std::endl - << "domains: " << Inserter(this->mDomains) - << std::endl - << " TUFifo size=" << this->mTUFifo.size() << std::endl - << " Timers size=" << this->mTransactionController->mTimers.size() << std::endl - << " AppTimers size=" << this->mAppTimers.size() << std::endl - << " ServerTransactionMap size=" << this->mTransactionController->mServerTransactionMap.size() << std::endl + strm << "SipStack: " << (this->mSecurity ? "with security " : "without security ") << std::endl; + { + Lock lock(mDomainsMutex); + strm << "domains: " << Inserter(this->mDomains) << std::endl; + } + strm << " TUFifo size=" << this->mTUFifo.size() << std::endl + << " Timers size=" << this->mTransactionController->mTimers.size() << std::endl; + { + Lock lock(mAppTimerMutex); + strm << " AppTimers size=" << this->mAppTimers.size() << std::endl; + } + strm << " ServerTransactionMap size=" << this->mTransactionController->mServerTransactionMap.size() << std::endl << " ClientTransactionMap size=" << this->mTransactionController->mClientTransactionMap.size() << std::endl - << " Exact Transports=" << Inserter(this->mTransactionController->mTransportSelector.mExactTransports) << std::endl - << " Any Transports=" << Inserter(this->mTransactionController->mTransportSelector.mAnyInterfaceTransports) << std::endl; + // !slg! TODO - There is technically a threading concern with the following three lines and the runtime addTransport or removeTransport call + << " Exact interface / Specific port=" << Inserter(this->mTransactionController->mTransportSelector.mExactTransports) << std::endl + << " Any interface / Specific port=" << Inserter(this->mTransactionController->mTransportSelector.mAnyInterfaceTransports) << std::endl + << " Exact interface / Any port =" << Inserter(this->mTransactionController->mTransportSelector.mAnyPortTransports) << std::endl + << " Any interface / Any port=" << Inserter(this->mTransactionController->mTransportSelector.mAnyPortAnyInterfaceTransports) << std::endl + << " TLS Transports=" << Inserter(this->mTransactionController->mTransportSelector.mTlsTransports) << std::endl; return strm; } EncodeStream& -resip::operator<<(EncodeStream& strm, -const SipStack& stack) +resip::operator<<(EncodeStream& strm, const SipStack& stack) { return stack.dump(strm); } @@ -1002,6 +1290,13 @@ SipStack::enableFlowTimer(const resip::Tuple& flow) mTransactionController->enableFlowTimer(flow); } +void +SipStack::invokeAfterSocketCreationFunc(TransportType type) +{ + // Stack is assummed to be running. Need to queue invoke request for TransactionController Thread + mTransactionController->invokeAfterSocketCreationFunc(type); +} + /* ==================================================================== * The Vovida Software License, Version 1.0 * diff --git a/src/libs/resiprocate/resip/stack/SipStack.hxx b/src/libs/resiprocate/resip/stack/SipStack.hxx index eaf73b9f..de178eb4 100644 --- a/src/libs/resiprocate/resip/stack/SipStack.hxx +++ b/src/libs/resiprocate/resip/stack/SipStack.hxx @@ -15,10 +15,14 @@ #include "rutil/TransportType.hxx" #include "rutil/BaseException.hxx" #include "resip/stack/TransactionController.hxx" +#include "resip/stack/TransportSelector.hxx" #include "resip/stack/SecurityTypes.hxx" #include "resip/stack/StatisticsManager.hxx" #include "resip/stack/TuSelector.hxx" +#include "resip/stack/WsConnectionValidator.hxx" +#include "resip/stack/WsCookieContextFactory.hxx" #include "rutil/dns/DnsStub.hxx" +#include "rutil/SharedPtr.hxx" /** Let external applications know that this version of the stack @@ -92,6 +96,11 @@ class FdPollGrp; See EventStackThread. The SipStack does NOT take ownership; the application (or a helper such as EventStackSimpleMgr) must release this object after the SipStack is destructed. + + mUseDnsVip + Set to true to enable Whitelisting of DNS entries. A feature + that usually desired by UA's that want to stick to a known + good server / dns result. **/ class SipStackOptions { @@ -99,7 +108,8 @@ class SipStackOptions SipStackOptions() : mSecurity(0), mExtraNameserverList(0), mAsyncProcessHandler(0), mStateless(false), - mSocketFunc(0), mCompression(0), mPollGrp(0) + mSocketFunc(0), mCompression(0), mPollGrp(0), + mUseDnsVip(false) { } @@ -110,6 +120,7 @@ class SipStackOptions AfterSocketCreationFuncPtr mSocketFunc; Compression *mCompression; FdPollGrp* mPollGrp; + bool mUseDnsVip; }; @@ -187,9 +198,14 @@ class SipStack : public FdSetIOObserver SigComp. If set to 0, then SigComp compression will be disabled. - @param pollGrp Polling group to support file-io callbacks; if one - is not passed, one will be created. Ownership is - not taken. + @param pollGrp Polling group to support file-io callbacks; if one + is not passed, one will be created. Ownership is + not taken. + + @param useDnsVip + Set to true to enable Whitelisting of DNS entries. A feature + that usually desired by UA's that want to stick to a known + good server / dns result. */ SipStack(Security* security=0, const DnsStub::NameserverList& additional = DnsStub::EmptyNameserverList, @@ -197,7 +213,8 @@ class SipStack : public FdSetIOObserver bool stateless=false, AfterSocketCreationFuncPtr socketFunc = 0, Compression *compression = 0, - FdPollGrp* pollGrp = 0); + FdPollGrp* pollGrp = 0, + bool useDnsVip = false); virtual ~SipStack(); @@ -234,6 +251,22 @@ class SipStack : public FdSetIOObserver */ void shutdownAndJoinThreads(); + /** + @brief reload configuration + @details Perform actions typically associated with the HUP signal, + for example, reloading certificate files from disk. + @note If an application never calls this method, for example, + because it is on a platform without signal support, the + SipStack still works anyway. + */ + void onReload(); + + /** + @brief reload the TLS X.509 certificates + @details reloads the X.509 certificate for each transport. + */ + void reloadCertificates(); + /** @brief thrown when the stack is unable to function. @details For instance, the stack cannot process messages because @@ -260,6 +293,20 @@ class SipStack : public FdSetIOObserver const char* name() const { return "SipStack::Exception"; } }; + /** + Used by the application to provide a handler that will get called for all + inbound and outbound SIP messages on transports that are added after calling this. + + @note If you want a custom handler per transport then + you can call setSipMessageLoggingHandler on the + Transport pointer returned from addTransport + + @param handler SharedPtr to a handler to call for inbound and + outbound SIP messages for all transports added + after calling this. + */ + void setTransportSipMessageLoggingHandler(SharedPtr handler) { mTransportSipMessageLoggingHandler = handler; } + /** Used by the application to add in a new built-in transport. The transport is created and then added to the Transport Selector. @@ -300,20 +347,27 @@ class SipStack : public FdSetIOObserver because many commercial CAs offer email certificates but not sip: certificates. For reasons of standards compliance, it is disabled by default. + + @param netNs Set the network namespace (netns) in which the Transport is + to bind the the given address and port. + */ - Transport* addTransport( TransportType protocol, - int port, - IpVersion version=V4, - StunSetting stun=StunDisabled, - const Data& ipInterface = Data::Empty, - const Data& sipDomainname = Data::Empty, // only used - // for TLS - // based stuff - const Data& privateKeyPassPhrase = Data::Empty, - SecurityTypes::SSLType sslType = SecurityTypes::TLSv1, - unsigned transportFlags = 0, - SecurityTypes::TlsClientVerificationMode cvm = SecurityTypes::None, - bool useEmailAsSIP = false); + Transport* addTransport(TransportType protocol, + int port, + IpVersion version=V4, + StunSetting stun=StunDisabled, + const Data& ipInterface = Data::Empty, + const Data& sipDomainname = Data::Empty, // only used for TLS based stuff + const Data& privateKeyPassPhrase = Data::Empty, + SecurityTypes::SSLType sslType = SecurityTypes::SSLv23, + unsigned transportFlags = 0, + const Data& certificateFilename = "", const Data& privateKeyFilename = "", + SecurityTypes::TlsClientVerificationMode cvm = SecurityTypes::None, + bool useEmailAsSIP = false, + SharedPtr = SharedPtr(), + SharedPtr = SharedPtr(), + const Data& netns = Data::Empty + ); /** Used to plug-in custom transports. Adds the transport to the Transport @@ -322,7 +376,15 @@ class SipStack : public FdSetIOObserver @param transport Pointer to an externally created transport. SipStack assumes ownership. */ - void addTransport( std::unique_ptr transport); + void addTransport(std::auto_ptr transport); + + /** + Used to remove a previously added transport. + + @param transportKey The key for the transpor to remove. Use Transport::getKey + to get the key of a transport after it is added to the stack. + */ + void removeTransport(unsigned int transportKey); /** Returns the fifo that subclasses of Transport should use for the rxFifo @@ -336,7 +398,7 @@ class SipStack : public FdSetIOObserver @brief add an alias for this sip element @details Used to add an alias for this sip element. e.g. foobar.com and boo.com - are both handled by this stack. Not threadsafe. Alias is added + are both handled by this stack. Alias is added to internal list of Domains and can be checked with isMyDomain. @param domain Domain name that this stack is responsible for. @@ -346,6 +408,19 @@ class SipStack : public FdSetIOObserver */ void addAlias(const Data& domain, int port); + /** + @brief removes an alias from this sip element + + @details Used to remove an existing alias from this sip element. + Only removed if reference count hits 0. + + @param domain Domain name that this stack is responsible for. + + @param port Port for domain that this stack is responsible for. + @ingroup resip_config + */ + void removeAlias(const Data& domain, int port); + /** Returns true if domain is handled by this stack. Convenience for Transaction Users. @@ -397,14 +472,14 @@ class SipStack : public FdSetIOObserver */ void send(const SipMessage& msg, TransactionUser* tu=0); - void send(std::unique_ptr msg, TransactionUser* tu = 0); + void send(std::auto_ptr msg, TransactionUser* tu = 0); /** @brief this is only if you want to send to a destination not in the route. @note You probably don't want to use it. */ - void sendTo(std::unique_ptr msg, const Uri& uri, TransactionUser* tu=0); + void sendTo(std::auto_ptr msg, const Uri& uri, TransactionUser* tu=0); /** @brief this is only if you want to send to a destination not in the route. @note You probably don't want to use it. */ - void sendTo(std::unique_ptr msg, const Tuple& tuple, TransactionUser* tu=0); + void sendTo(std::auto_ptr msg, const Tuple& tuple, TransactionUser* tu=0); /** @brief send a message to a destination not in the route @@ -468,7 +543,7 @@ class SipStack : public FdSetIOObserver @param tu TransactionUser to post to. */ - void post(std::unique_ptr message, + void post(std::auto_ptr message, unsigned int secondsLater, TransactionUser* tu=0); @@ -484,7 +559,7 @@ class SipStack : public FdSetIOObserver @param tu TransactionUser to post to. */ - void postMS(const std::unique_ptr message, + void postMS(const std::auto_ptr message, unsigned int ms, TransactionUser* tu=0); @@ -495,7 +570,7 @@ class SipStack : public FdSetIOObserver @param message ApplicationMessage to post */ - void post(std::unique_ptr message); + void post(std::auto_ptr message); /** @brief Makes the message available to the TU later @@ -564,8 +639,10 @@ class SipStack : public FdSetIOObserver the TU of the obligation to handle any INVITE/200 that come in (usually by sending an ACK to the 200, and then a BYE). @param tid The transaction identifier of the INVITE request sent. + @param reasons Optional reason headers to be added to any resulting CANCEL + request. */ - void cancelClientInviteTransaction(const Data& tid); + void cancelClientInviteTransaction(const Data& tid, const Tokens* reasons); /** @brief does the stack have new messages for the TU? @@ -725,7 +802,6 @@ class SipStack : public FdSetIOObserver */ virtual void processTimers(); - /** @brief Sets the interval that determines the time between Statistics messages @ingroup resip_config @@ -752,6 +828,9 @@ class SipStack : public FdSetIOObserver mStatsManager.setExternalStatsHandler(handler); } + /** @brief get statistics manager **/ + const StatisticsManager* getStatisticsManager() {return(&mStatsManager);} + /** @brief output current state of the stack - for debug **/ EncodeStream& dump(EncodeStream& strm) const; @@ -765,7 +844,7 @@ class SipStack : public FdSetIOObserver receiveAny, the SipStack will call postToTu on the appropriate Tu. Messages not associated with a registered TU go into SipStack::mTuFifo. */ - void registerTransactionUser(TransactionUser&); + void registerTransactionUser(TransactionUser&, const bool front = false); /** @brief Queue a shutdown request to the specified TU **/ void requestTransactionUserShutdown(TransactionUser&); @@ -837,6 +916,12 @@ class SipStack : public FdSetIOObserver */ void getDnsCacheDump(std::pair key, GetDnsCacheDumpHandler* handler); + /** + @brief Check if DnsServers list has changed, and if so reinitializes + the DNS resolver (ares). Any lookups currenlty in progress will fail. + */ + void reloadDnsServers(); + /** @todo is this documented correctly? [!] @brief Enable Statistics Manager @@ -891,6 +976,16 @@ class SipStack : public FdSetIOObserver mTransactionController->setFixBadCSeqNumbers(pFixBadCSeqNumbers); } + bool setUdpOnlyOnNumeric(bool value) + { + return mTransactionController->transportSelector().setUdpOnlyOnNumeric(value); + } + + bool getUdpOnlyOnNumeric() const + { + return mTransactionController->transportSelector().getUdpOnlyOnNumeric(); + } + /** @todo should this be fixed to work with other applicable transports? [] @brief Used to enable/disable content-length checking on datagram-based @@ -990,6 +1085,15 @@ class SipStack : public FdSetIOObserver void terminateFlow(const resip::Tuple& flow); void enableFlowTimer(const resip::Tuple& flow); + // Will call the AfterSocketCreationFuncPtr that was provided at SIPStack creation + // time to all sockets that match the passed in type. Use UNKNOWN_TRANSPORT + // in order to call for all transport types. + // The stack thread(s) must be running when this is called. + // Can be used to update QOS to a new value on existing sockets, without needing + // to restart the SipStack. + // Note: DNS sockets are not currently supported + void invokeAfterSocketCreationFunc(TransportType type = UNKNOWN_TRANSPORT); + private: /// Performs bulk of work of constructor. // WATCHOUT: can only be called once (just like constructor) @@ -1050,27 +1154,44 @@ class SipStack : public FdSetIOObserver /** @brief All aspects of the Transaction State Machine / DNS resolver **/ TransactionController* mTransactionController; - std::unique_ptr > mStateMacFifoBuffer; TransactionControllerThread* mTransactionControllerThread; TransportSelectorThread* mTransportSelectorThread; - bool mRunning; + bool mInternalThreadsRunning; + bool mProcessingHasStarted; + /** @brief store all domains that this stack is responsible for. @note Controlled by addAlias and addTransport interface and checks can be made with isMyDomain() */ - std::set mDomains; + typedef std::map DomainsMap; + DomainsMap mDomains; // Second item (unsigned int) is for reference counting + Uri mUri; + mutable Mutex mDomainsMutex; // Protects both mDomains and mUri, since they are related /** store all ports that this stack is lisenting on. Controlled by addTransport and checks can be made with isMyPort() */ - std::set mPorts; + std::map mPorts; // Second item (unsigned int) is for reference counting + mutable Mutex mPortsMutex; + + // Used to ensure new Transport additions will always succeed without needing to ask + // TransportSelector if add will be valid and introduce locking + // Note: We could add a Mutex here and add thread safe accesor methods to transport pointers + // as a convience to API users + typedef std::map NonSecureTransportMap; + NonSecureTransportMap mNonSecureTransports; + typedef std::map SecureTransportMap; + SecureTransportMap mSecureTransports; - Uri mUri; bool mShuttingDown; mutable Mutex mShutdownMutex; volatile bool mStatisticsManagerEnabled; AfterSocketCreationFuncPtr mSocketFunc; + unsigned int mNextTransportKey; + + SharedPtr mTransportSipMessageLoggingHandler; + friend class Executive; friend class StatelessHandler; friend class StatisticsManager; @@ -1087,7 +1208,7 @@ inline void SipStack::sendOverExistingConnection(const SipMessage& msg, const Tuple& tuple, TransactionUser* tu) { - assert(tuple.mFlowKey); + resip_assert(tuple.mFlowKey); Tuple tup(tuple); tup.onlyUseExistingConnection = true; sendTo(msg, tuple, tu); diff --git a/src/libs/resiprocate/resip/stack/StatelessHandler.cxx b/src/libs/resiprocate/resip/stack/StatelessHandler.cxx index bc700adb..c6aa155d 100644 --- a/src/libs/resiprocate/resip/stack/StatelessHandler.cxx +++ b/src/libs/resiprocate/resip/stack/StatelessHandler.cxx @@ -46,7 +46,7 @@ void StatelessHandler::process() { Message* msg = mController.mStateMacFifo.getNext(); - assert(msg); + resip_assert(msg); SipMessage* sip = dynamic_cast(msg); TransportFailure* transport = dynamic_cast(msg); @@ -86,13 +86,13 @@ StatelessHandler::process() } else // no dns for sip responses { - assert(sip->isResponse()); + resip_assert(sip->isResponse()); DebugLog (<< "Processing response from TU: " << msg->brief()); const Via& via = sip->const_header(h_Vias).front(); int port = via.sentPort(); if (sip->hasForceTarget()) { - assert( /*Unimplemented*/ 0 ); + resip_assert( /*Unimplemented*/ 0 ); } else { @@ -125,7 +125,7 @@ StatelessMessage::StatelessMessage(TransportSelector& selector, SipMessage* msg) void StatelessMessage::rewriteRequest(const Uri& rewrite) { - assert(mMsg->isRequest()); + resip_assert(mMsg->isRequest()); if (mMsg->const_header(h_RequestLine).uri() != rewrite) { InfoLog (<< "Rewriting request-uri to " << rewrite); diff --git a/src/libs/resiprocate/resip/stack/Symbols.cxx b/src/libs/resiprocate/resip/stack/Symbols.cxx index 5ca1d335..84c0b44d 100644 --- a/src/libs/resiprocate/resip/stack/Symbols.cxx +++ b/src/libs/resiprocate/resip/stack/Symbols.cxx @@ -51,6 +51,8 @@ const char* Symbols::TCP = "TCP"; const char* Symbols::TLS = "TLS"; const char* Symbols::DTLS = "DTLS"; const char* Symbols::SCTP = "SCTP"; +const char* Symbols::WS = "WS"; +const char* Symbols::WSS = "WSS"; const char* Symbols::SRVUDP = "_udp."; const char* Symbols::SRVTCP = "_tcp."; const char* Symbols::SRVTLS = "_tls."; @@ -72,9 +74,12 @@ const char* Symbols::Basic = "Basic"; const char * const Symbols::MagicCookie = "z9hG4bK"; const char * const Symbols::resipCookie= "-524287-"; +const char * const Symbols::WebsocketMagicGUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; const int Symbols::DefaultSipPort = 5060; const int Symbols::SipTlsPort = 5061; +const int Symbols::SipWsPort = 80; +const int Symbols::SipWssPort = 443; const int Symbols::DefaultSipsPort = 5061; const char* Symbols::SrvSip = "_sip"; @@ -88,7 +93,9 @@ const char* Symbols::NaptrTcp = "D2T"; const char* Symbols::audio = "audio"; const char* Symbols::RTP_AVP = "RTP/AVP"; +const char* Symbols::RTP_AVPF = "RTP/AVPF"; const char* Symbols::RTP_SAVP = "RTP/SAVP"; // used for SRTP +const char* Symbols::RTP_SAVPF = "RTP/SAVPF"; // used for SRTP, usually WebRTC const char* Symbols::UDP_TLS_RTP_SAVP = "UDP/TLS/RTP/SAVP"; // used for DTLS-SRTP const char* Symbols::Presence = "presence"; @@ -114,10 +121,14 @@ const char* Symbols::Credential = "credential"; const char* Symbols::SipProfile = "sip-profile"; -const char* Symbols::id = "id"; // from RFC 3323 +const char* Symbols::id = "id"; // from RFC 3325 const char* Symbols::Gruu = "gruu"; +const char* Symbols::Uui = "uui"; +const char* Symbols::Hex = "hex"; +const char* Symbols::IsdnInterwork = "isdn-interwork"; +const char* Symbols::IsdnUui = "isdn-uui"; #if defined(WIN32) const char *Symbols::pathSep = "\\"; diff --git a/src/libs/resiprocate/resip/stack/Symbols.hxx b/src/libs/resiprocate/resip/stack/Symbols.hxx index c4fb6597..588e12b9 100644 --- a/src/libs/resiprocate/resip/stack/Symbols.hxx +++ b/src/libs/resiprocate/resip/stack/Symbols.hxx @@ -52,6 +52,8 @@ class Symbols static const char* TLS; static const char* DTLS; static const char* SCTP; + static const char* WS; + static const char* WSS; static const char* SRVUDP; static const char* SRVTCP; static const char* SRVTLS; @@ -73,9 +75,12 @@ class Symbols static const char * const MagicCookie; static const char * const resipCookie; + static const char * const WebsocketMagicGUID; static const int DefaultSipPort; static const int SipTlsPort; + static const int SipWsPort; + static const int SipWssPort; static const int DefaultSipsPort; static const char* SrvSip; @@ -89,7 +94,9 @@ class Symbols static const char* audio; static const char* RTP_AVP; + static const char* RTP_AVPF; static const char* RTP_SAVP; + static const char* RTP_SAVPF; static const char* UDP_TLS_RTP_SAVP; static const char* Presence; @@ -118,6 +125,11 @@ class Symbols static const char* id; static const char* Gruu; + + static const char* Uui; // from draft-ietf-cuss-sip-uui-17 + static const char* Hex; // from draft-ietf-cuss-sip-uui-17 + static const char* IsdnInterwork; // from draft-johnston-sipping-cc-uui-09 + static const char* IsdnUui; // from draft-johnston-sipping-cc-uui-09 }; } diff --git a/src/libs/resiprocate/resip/stack/TcpBaseTransport.cxx b/src/libs/resiprocate/resip/stack/TcpBaseTransport.cxx index 59a368e3..bbf6b3fd 100644 --- a/src/libs/resiprocate/resip/stack/TcpBaseTransport.cxx +++ b/src/libs/resiprocate/resip/stack/TcpBaseTransport.cxx @@ -3,10 +3,12 @@ #endif #include +#include "rutil/compat.hxx" #include "rutil/Socket.hxx" #include "rutil/Data.hxx" #include "rutil/DnsUtil.hxx" #include "rutil/Logger.hxx" +#include "rutil/NetNs.hxx" #include "resip/stack/TcpBaseTransport.hxx" #define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT @@ -23,11 +25,17 @@ TcpBaseTransport::TcpBaseTransport(Fifo& fifo, const Data& pinterface, AfterSocketCreationFuncPtr socketFunc, Compression &compression, - unsigned transportFlags) - : InternalTransport(fifo, portNum, version, pinterface, socketFunc, compression, transportFlags) + unsigned transportFlags, + const Data& netNs) + : InternalTransport(fifo, portNum, version, pinterface, socketFunc, compression, transportFlags, netNs) { if ( (mTransportFlags & RESIP_TRANSPORT_FLAG_NOBIND)==0 ) { +#ifdef USE_NETNS + DebugLog(<< "TcpBaseTransport: " << this << " netns: " << netNs); + // setns here + NetNs::setNs(netNs); +#endif mFd = InternalTransport::socket(TCP, version); } } @@ -123,7 +131,7 @@ TcpBaseTransport::setPollGrp(FdPollGrp *grp) void TcpBaseTransport::buildFdSet( FdSet& fdset) { - assert( mPollGrp==NULL ); + resip_assert( mPollGrp==NULL ); mConnectionManager.buildFdSet(fdset); if ( mFd!=INVALID_SOCKET ) { @@ -153,7 +161,10 @@ TcpBaseTransport::processListen() int e = getErrno(); switch (e) { - case EWOULDBLOCK: + case EAGAIN: +#if EAGAIN != EWOULDBLOCK + case EWOULDBLOCK: // Treat EGAIN and EWOULDBLOCK as the same: http://stackoverflow.com/questions/7003234/which-systems-define-eagain-and-ewouldblock-as-different-values +#endif // !jf! this can not be ready in some cases // !kw! this will happen every epoll cycle return 0; @@ -162,19 +173,30 @@ TcpBaseTransport::processListen() } return -1; } + if(!configureConnectedSocket(sock)) + { + throw Exception("Failed to configure connected socket", __FILE__,__LINE__); + } makeSocketNonBlocking(sock); - DebugLog (<< "Received TCP connection from: " << tuple << " as fd=" << sock); + DebugLog (<< this << " Received TCP connection from: " << tuple << " mTuple: " << mTuple << " as fd=" << sock); if (mSocketFunc) { mSocketFunc(sock, transport(), __FILE__, __LINE__); } - if(!mConnectionManager.findConnection(tuple)) + Connection* c = mConnectionManager.findConnection(tuple); + if(!c) { createConnection(tuple, sock, true); } + else if(false == c->isServer()) + { + InfoLog( << "Have client connection for " << tuple << ", but got server one, recreate connection" ); + delete c; + createConnection(tuple, sock, true); + } else { InfoLog(<<"Someone probably sent a reciprocal SYN at us."); @@ -190,6 +212,9 @@ TcpBaseTransport::makeOutgoingConnection(const Tuple &dest, TransportFailure::FailureReason &failReason, int &failSubCode) { // attempt to open +#ifdef USE_NETNS + NetNs::setNs(netNs()); +#endif Socket sock = InternalTransport::socket( TCP, ipVersion()); // fdset.clear(sock); !kw! removed as part of epoll impl @@ -198,8 +223,14 @@ TcpBaseTransport::makeOutgoingConnection(const Tuple &dest, int err = getErrno(); InfoLog (<< "Failed to create a socket " << strerror(err)); error(err); - mConnectionManager.gc(ConnectionManager::MinimumGcAge, 1); // free one up + if(mConnectionManager.gc(ConnectionManager::MinimumGcAge, 1) == 0) + { + mConnectionManager.gcWithTarget(1); // free one up + } +#ifdef USE_NETNS + NetNs::setNs(netNs()); +#endif sock = InternalTransport::socket( TCP, ipVersion()); if ( sock == INVALID_SOCKET ) { @@ -212,9 +243,27 @@ TcpBaseTransport::makeOutgoingConnection(const Tuple &dest, } } - assert(sock != INVALID_SOCKET); + resip_assert(sock != INVALID_SOCKET); DebugLog (<<"Opening new connection to " << dest); + char _sa[RESIP_MAX_SOCKADDR_SIZE]; + sockaddr *sa = reinterpret_cast(_sa); + resip_assert(RESIP_MAX_SOCKADDR_SIZE >= mTuple.length()); + mTuple.copySockaddrAnyPort(sa); +#ifdef USE_NETNS + NetNs::setNs(netNs()); +#endif + if(::bind(sock, sa, mTuple.length()) != 0) + { + WarningLog( << "Error in binding to source interface address. " << strerror(errno)); + failReason = TransportFailure::Failure; + failSubCode = errno; + return NULL; + } + if(!configureConnectedSocket(sock)) + { + throw Exception("Failed to configure connected socket", __FILE__,__LINE__); + } makeSocketNonBlocking(sock); if (mSocketFunc) { @@ -231,7 +280,10 @@ TcpBaseTransport::makeOutgoingConnection(const Tuple &dest, switch (err) { case EINPROGRESS: - case EWOULDBLOCK: + case EAGAIN: +#if EAGAIN != EWOULDBLOCK + case EWOULDBLOCK: // Treat EGAIN and EWOULDBLOCK as the same: http://stackoverflow.com/questions/7003234/which-systems-define-eagain-and-ewouldblock-as-different-values +#endif break; default: { @@ -249,8 +301,9 @@ TcpBaseTransport::makeOutgoingConnection(const Tuple &dest, // This will add the connection to the manager Connection *conn = createConnection(dest, sock, false); - assert(conn); - conn->mRequestPostConnectSocketFuncCall = true; + resip_assert(conn); + conn->mFirstWriteAfterConnectedPending = true; + return conn; } @@ -267,41 +320,63 @@ TcpBaseTransport::processAllWriteRequests() //DebugLog (<< "TcpBaseTransport::processAllWriteRequests() using " << conn); +#ifdef WIN32 + if(conn && mPollGrp && mPollGrp->getImplType() == FdPollGrp::PollImpl) + { + // Workaround for bug in WSAPoll implementation: see + // http://daniel.haxx.se/blog/2012/10/10/wsapoll-is-broken/ + // http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/18769abd-fca0-4d3c-9884-1a38ce27ae90/wsapoll-and-nonblocking-connects-to-nonexistent-ports?forum=wsk + // Note: This is not an ideal solution - since we won't cleanup the connection until + // after the connect has timedout and someone else tries to write to the same + // destination. However the only impact to users is that requests will take the + // full 32 seconds transaction timeout to get an error vs the 21s connect timeout + // observered when using the select implemention (vs Poll). This does save us from + // having to use some form of timer to periodically check the connect state though. + if(conn->checkConnectionTimedout()) + { + // If checkConnectionTimedout returns true, then connection is no longer available. + // Clear conn so that we create a new connection below. + conn = 0; + } + } +#endif + // There is no connection yet, so make a client connection if (conn == 0 && - !data->destination.onlyUseExistingConnection && - data->command == 0) // SendData commands (ie. close connection and enable flow timers) shouldn't cause new connections to form + !data->destination.onlyUseExistingConnection && + data->command == 0) // SendData commands (ie. close connection and enable flow timers) shouldn't cause new connections to form { TransportFailure::FailureReason failCode = TransportFailure::Failure; int subCode = 0; - if((conn=makeOutgoingConnection(data->destination, failCode, subCode)) == NULL) + if((conn = makeOutgoingConnection(data->destination, failCode, subCode)) == 0) { + DebugLog (<< "Failed to create connection: " << data->destination); fail(data->transactionId, failCode, subCode); delete data; - return; // .kw. WHY? What about messages left in queue? + // NOTE: We fail this one but don't give up on others in queue + return; } - assert(conn->getSocket() != INVALID_SOCKET); - // .kw. why do below? We already have the conn, who uses key? - data->destination.mFlowKey = conn->getSocket(); // !jf! + resip_assert(conn->getSocket() != INVALID_SOCKET); + data->destination.mFlowKey = conn->getSocket(); } if (conn == 0) { - DebugLog (<< "Failed to create/get connection: " << data->destination); + DebugLog (<< "Failed to find connection: " << data->destination); fail(data->transactionId, TransportFailure::TransportNoExistConn, 0); delete data; // NOTE: We fail this one but don't give up on others in queue } else // have a connection { - if (mTransportLogger) + // Check if we have written anything or not on the connection. If not, then this is either the first or + // a subsequent transaction trying to use this connection attempt - set TcpConnectState for this + // transaction to ConnectStarted + if (conn->mFirstWriteAfterConnectedPending == true) { - sockaddr_in addr; - memset(&addr, 0, sizeof addr); - addr = (const sockaddr_in&)data->destination.getSockaddr(); - mTransportLogger->onSipMessage(TransportLogger::Flow_Sent, (const char*)data->data.c_str(), data->data.size(), (const sockaddr*)&addr, sizeof addr); + // Notify the transaction state that we have started a TCP connect, so that it can run a TCP connect timer + setTcpConnectState(data->transactionId, TcpConnectState::ConnectStarted); } - conn->requestWrite(data); } } @@ -310,55 +385,60 @@ TcpBaseTransport::processAllWriteRequests() void TcpBaseTransport::process() { - mStateMachineFifo.flush(); - // called within SipStack's thread. There is some risk of // recursion here if connection starts doing anything fancy. // For backward-compat when not-epoll, don't handle transmit synchronously // now, but rather wait for the process() call if (mPollGrp) { - processAllWriteRequests(); + processAllWriteRequests(); } + mStateMachineFifo.flush(); } void TcpBaseTransport::process(FdSet& fdSet) { - assert( mPollGrp==NULL ); + resip_assert( mPollGrp==NULL ); processAllWriteRequests(); // process the connections in ConnectionManager mConnectionManager.process(fdSet); - mStateMachineFifo.flush(); - // process our own listen/accept socket for incoming connections if (mFd!=INVALID_SOCKET && fdSet.readyToRead(mFd)) { processListen(); } + + mStateMachineFifo.flush(); } void -TcpBaseTransport::processPollEvent(FdPollEventMask mask) { - if ( mask & FPEM_Read ) +TcpBaseTransport::processPollEvent(FdPollEventMask mask) +{ + if (mask & FPEM_Read) { - while ( processListen() > 0 ) - ; + while(processListen() > 0); } } void TcpBaseTransport::setRcvBufLen(int buflen) { - assert(0); // not implemented yet + resip_assert(0); // not implemented yet // need to store away the length and use when setting up new connections } - - +void +TcpBaseTransport::invokeAfterSocketCreationFunc() const +{ + // Call for base socket + InternalTransport::invokeAfterSocketCreationFunc(); + // Call for each connection + mConnectionManager.invokeAfterSocketCreationFunc(); +} /* ==================================================================== diff --git a/src/libs/resiprocate/resip/stack/TcpBaseTransport.hxx b/src/libs/resiprocate/resip/stack/TcpBaseTransport.hxx index 7460b36f..f84f941c 100644 --- a/src/libs/resiprocate/resip/stack/TcpBaseTransport.hxx +++ b/src/libs/resiprocate/resip/stack/TcpBaseTransport.hxx @@ -19,11 +19,10 @@ class TcpBaseTransport : public InternalTransport, public FdPollItemIf const Data& interfaceName, AfterSocketCreationFuncPtr socketFunc, Compression &compression, - unsigned transportFlags = 0); + unsigned transportFlags = 0, + const Data& netNs = Data::Empty); virtual ~TcpBaseTransport(); - - virtual void processPollEvent(FdPollEventMask mask); virtual void process(FdSet& fdset); virtual void buildFdSet( FdSet& fdset); @@ -36,6 +35,8 @@ class TcpBaseTransport : public InternalTransport, public FdPollItemIf ConnectionManager& getConnectionManager() {return mConnectionManager;} const ConnectionManager& getConnectionManager() const {return mConnectionManager;} + virtual void invokeAfterSocketCreationFunc() const; + protected: /** Performs constructor activities that depend on virtual * functions specified by derived classes. Derived classes diff --git a/src/libs/resiprocate/resip/stack/TcpConnectState.cxx b/src/libs/resiprocate/resip/stack/TcpConnectState.cxx new file mode 100644 index 00000000..53135a50 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TcpConnectState.cxx @@ -0,0 +1,83 @@ +#include "TcpConnectState.hxx" + +using namespace resip; + +TcpConnectState::TcpConnectState(const Data& transactionId, State state) + : mTransactionId(transactionId), + mState(state) +{ +} + +const Data& +TcpConnectState::getTransactionId() const +{ + return mTransactionId; +} + +bool +TcpConnectState::isClientTransaction() const +{ + // not strictly true + return true; +} + +EncodeStream& +TcpConnectState::encodeBrief(EncodeStream& str) const +{ + return str << "TcpConnectState: " << mTransactionId << ", state=" << (mState == ConnectStarted ? "ConnectStarted" : "Connected"); +} + +EncodeStream& +TcpConnectState::encode(EncodeStream& strm) const +{ + return encodeBrief(strm); +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * . + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/TcpConnectState.hxx b/src/libs/resiprocate/resip/stack/TcpConnectState.hxx new file mode 100644 index 00000000..83e42a52 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TcpConnectState.hxx @@ -0,0 +1,91 @@ +#ifndef RESIP_TcpConnectState_hxx +#define RESIP_TcpConnectState_hxx + +#include +#include "resip/stack/TransactionMessage.hxx" +#include "rutil/Data.hxx" +#include "rutil/HeapInstanceCounter.hxx" + +namespace resip +{ + +/** This message is used to indicate to the transaction state that a TCP + based transport is trying to TCP Connect or has completed a TCP connect. +*/ +class TcpConnectState : public TransactionMessage +{ +public: + RESIP_HeapCount(TcpConnectState); + enum State + { + ConnectStarted = 0, + Connected = 1 + }; + + TcpConnectState(const Data& transactionId, State state); + + virtual const Data& getTransactionId() const; + virtual bool isClientTransaction() const; + + State getState() const { return mState; } + + virtual EncodeStream& encodeBrief(EncodeStream& str) const; + virtual EncodeStream& encode(EncodeStream& strm) const; + +private: + Data mTransactionId; + State mState; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * . + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/resip/stack/TcpConnection.cxx b/src/libs/resiprocate/resip/stack/TcpConnection.cxx index 64a712bd..11ac6083 100644 --- a/src/libs/resiprocate/resip/stack/TcpConnection.cxx +++ b/src/libs/resiprocate/resip/stack/TcpConnection.cxx @@ -12,8 +12,8 @@ using namespace resip; #define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT TcpConnection::TcpConnection(Transport* transport,const Tuple& who, Socket fd, - Compression &compression) - : Connection(transport,who, fd, compression) + Compression &compression, bool isServer) + : Connection(transport,who, fd, compression, isServer) { DebugLog (<< "Creating TCP connection " << who << " on " << fd); } @@ -21,8 +21,8 @@ TcpConnection::TcpConnection(Transport* transport,const Tuple& who, Socket fd, int TcpConnection::read( char* buf, int count ) { - assert(buf); - assert(count > 0); + resip_assert(buf); + resip_assert(count > 0); #if defined(WIN32) int bytesRead = ::recv(getSocket(), buf, count, 0); @@ -36,13 +36,13 @@ TcpConnection::read( char* buf, int count ) switch (e) { case EAGAIN: -#ifdef WIN32 //EWOULDBLOCK is not returned from recv on *nix/*bsd - case EWOULDBLOCK: +#if EAGAIN != EWOULDBLOCK + case EWOULDBLOCK: // Treat EGAIN and EWOULDBLOCK as the same: http://stackoverflow.com/questions/7003234/which-systems-define-eagain-and-ewouldblock-as-different-values #endif - InfoLog (<< "No data ready to read"); + StackLog (<< "No data ready to read"); return 0; case EINTR: - InfoLog (<< "The call was interrupted by a signal before any data was read."); + DebugLog (<< "The call was interrupted by a signal before any data was read."); return 0; break; case EIO: @@ -55,10 +55,10 @@ TcpConnection::read( char* buf, int count ) InfoLog (<< "fd is attached to an object which is unsuitable for reading."); break; case EFAULT: - InfoLog (<< "buf is outside your accessible address space."); + ErrLog (<< "buf is outside your accessible address space."); break; default: - InfoLog (<< "Some other error"); + ErrLog (<< "Some other error, code = " << e); break; } @@ -82,8 +82,8 @@ TcpConnection::write( const char* buf, const int count ) { //DebugLog (<< "Writing " << buf); // Note: this can end up writing garbage to the logs following the message for non-null terminated buffers - assert(buf); - assert(count > 0); + resip_assert(buf); + resip_assert(count > 0); #if defined(WIN32) int bytesWritten = ::send(getSocket(), buf, count, 0); @@ -94,10 +94,11 @@ TcpConnection::write( const char* buf, const int count ) if (bytesWritten == INVALID_SOCKET) { int e = getErrno(); + //setFailureReason(TransportFailure::ConnectionException, e+1000); 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 { - // TCP buffers are backed up - we couldn't write anything - but we shouldn't treat this an error - return we wrote 0 bytes - return 0; + // TCP buffers are backed up - we couldn't write anything - but we shouldn't treat this an error - return we wrote 0 bytes + return 0; } InfoLog (<< "Failed write on " << getSocket() << " " << strerror(e)); Transport::error(e); diff --git a/src/libs/resiprocate/resip/stack/TcpConnection.hxx b/src/libs/resiprocate/resip/stack/TcpConnection.hxx index 815a0ead..7cfa9582 100644 --- a/src/libs/resiprocate/resip/stack/TcpConnection.hxx +++ b/src/libs/resiprocate/resip/stack/TcpConnection.hxx @@ -11,7 +11,7 @@ class Tuple; class TcpConnection : public Connection { public: - TcpConnection( Transport* transport, const Tuple& who, Socket fd, Compression &compression); + TcpConnection( Transport* transport, const Tuple& who, Socket fd, Compression &compression, bool isServer); int read( char* buf, const int count ); int write( const char* buf, const int count ); diff --git a/src/libs/resiprocate/resip/stack/TcpTransport.cxx b/src/libs/resiprocate/resip/stack/TcpTransport.cxx index 8c0dd874..c3ff63f1 100644 --- a/src/libs/resiprocate/resip/stack/TcpTransport.cxx +++ b/src/libs/resiprocate/resip/stack/TcpTransport.cxx @@ -20,16 +20,24 @@ TcpTransport::TcpTransport(Fifo& fifo, int portNum, IpVersion version, const Data& pinterface, AfterSocketCreationFuncPtr socketFunc, Compression &compression, - unsigned transportFlags) - : TcpBaseTransport(fifo, portNum, version, pinterface, socketFunc, compression, transportFlags) + unsigned transportFlags, + const Data& netNs) + : TcpBaseTransport(fifo, portNum, version, pinterface, socketFunc, compression, transportFlags, netNs) { - mTuple.setType(transport()); + mTuple.setType(TCP); init(); +#ifdef USE_NETNS InfoLog (<< "Creating TCP transport host=" << pinterface << " port=" << mTuple.getPort() - << " ipv4=" << bool(version==V4) ); + << " ipv4=" << bool(version==V4) + << " netns=" << netNs); +#else + InfoLog (<< "Creating TCP transport host=" << pinterface + << " port=" << mTuple.getPort() + << " ipv4=" << bool(version==V4)); +#endif mTxFifo.setDescription("TcpTransport::mTxFifo"); } @@ -41,9 +49,8 @@ TcpTransport::~TcpTransport() Connection* TcpTransport::createConnection(const Tuple& who, Socket fd, bool server) { - assert(this); - Connection* conn = new TcpConnection(this,who, fd, mCompression); - conn->setTransportLogger(mTransportLogger); + resip_assert(this); + Connection* conn = new TcpConnection(this, who, fd, mCompression, server); return conn; } diff --git a/src/libs/resiprocate/resip/stack/TcpTransport.hxx b/src/libs/resiprocate/resip/stack/TcpTransport.hxx index 67748d24..340b10be 100644 --- a/src/libs/resiprocate/resip/stack/TcpTransport.hxx +++ b/src/libs/resiprocate/resip/stack/TcpTransport.hxx @@ -18,11 +18,10 @@ class TcpTransport : public TcpBaseTransport const Data& interfaceObj, AfterSocketCreationFuncPtr socketFunc=0, Compression &compression = Compression::Disabled, - unsigned transportFlags = 0); + unsigned transportFlags = 0, + const Data& netNs = Data::Empty); virtual ~TcpTransport(); - TransportType transport() const { return TCP; } - protected: Connection* createConnection(const Tuple& who, Socket fd, bool server=false); }; diff --git a/src/libs/resiprocate/resip/stack/TerminateFlow.hxx b/src/libs/resiprocate/resip/stack/TerminateFlow.hxx index 2648a3e7..65ccdd9e 100644 --- a/src/libs/resiprocate/resip/stack/TerminateFlow.hxx +++ b/src/libs/resiprocate/resip/stack/TerminateFlow.hxx @@ -1,94 +1,94 @@ -#ifndef TerminateFlow_Include_Guard -#define TerminateFlow_Include_Guard - -#include "resip/stack/TransactionMessage.hxx" -#include "resip/stack/Tuple.hxx" - -namespace resip -{ -class TerminateFlow : public TransactionMessage -{ - public: - explicit TerminateFlow(const resip::Tuple& flow) : - mFlow(flow) - {} - virtual ~TerminateFlow(){} - - virtual const Data& getTransactionId() const {return Data::Empty;} - const Tuple& getFlow() const { return mFlow; } - - virtual bool isClientTransaction() const {return true;} - virtual EncodeStream& encode(EncodeStream& strm) const - { - return strm << "TerminateFlow: " << mFlow; - } - virtual EncodeStream& encodeBrief(EncodeStream& strm) const - { - return strm << "TerminateFlow: " << mFlow; - } - - virtual Message* clone() const - { - return new TerminateFlow(*this); - } - - protected: - const resip::Tuple mFlow; - -}; // class TerminateFlow - -} // namespace resip - -#endif // include guard - -/* ==================================================================== - * The Vovida Software License, Version 1.0 - * - * Copyright (c) 2004 Vovida Networks, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The names "VOCAL", "Vovida Open Communication Application Library", - * and "Vovida Open Communication Application Library (VOCAL)" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact vocal@vovida.org. - * - * 4. Products derived from this software may not be called "VOCAL", nor - * may "VOCAL" appear in their name, without prior written - * permission of Vovida Networks, Inc. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND - * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA - * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES - * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ==================================================================== - * - * This software consists of voluntary contributions made by Vovida - * Networks, Inc. and many individuals on behalf of Vovida Networks, - * Inc. For more information on Vovida Networks, Inc., please see - * . - * - * vi: set shiftwidth=3 expandtab: - */ - +#ifndef TerminateFlow_Include_Guard +#define TerminateFlow_Include_Guard + +#include "resip/stack/TransactionMessage.hxx" +#include "resip/stack/Tuple.hxx" + +namespace resip +{ +class TerminateFlow : public TransactionMessage +{ + public: + explicit TerminateFlow(const resip::Tuple& flow) : + mFlow(flow) + {} + virtual ~TerminateFlow(){} + + virtual const Data& getTransactionId() const {return Data::Empty;} + const Tuple& getFlow() const { return mFlow; } + + virtual bool isClientTransaction() const {return true;} + virtual EncodeStream& encode(EncodeStream& strm) const + { + return strm << "TerminateFlow: " << mFlow; + } + virtual EncodeStream& encodeBrief(EncodeStream& strm) const + { + return strm << "TerminateFlow: " << mFlow; + } + + virtual Message* clone() const + { + return new TerminateFlow(*this); + } + + protected: + const resip::Tuple mFlow; + +}; // class TerminateFlow + +} // namespace resip + +#endif // include guard + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2004 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * . + * + * vi: set shiftwidth=3 expandtab: + */ + diff --git a/src/libs/resiprocate/resip/stack/TimerMessage.cxx b/src/libs/resiprocate/resip/stack/TimerMessage.cxx index be44e29d..eb45e1d7 100644 --- a/src/libs/resiprocate/resip/stack/TimerMessage.cxx +++ b/src/libs/resiprocate/resip/stack/TimerMessage.cxx @@ -2,7 +2,7 @@ #include "config.h" #endif -#include +#include "rutil/ResipAssert.h" #include "resip/stack/TimerMessage.hxx" using namespace resip; @@ -48,6 +48,7 @@ TimerMessage::isClientTransaction() const case Timer::TimerStaleClient: case Timer::TimerCleanUp: case Timer::TimerStateless: + case Timer::TcpConnectTimer: return true; case Timer::TimerG: @@ -59,14 +60,14 @@ TimerMessage::isClientTransaction() const return false; case Timer::TimerC: - assert(0); + resip_assert(0); break; default: - assert(0); + resip_assert(0); break; } - assert(0); + resip_assert(0); return false; } diff --git a/src/libs/resiprocate/resip/stack/TimerQueue.cxx b/src/libs/resiprocate/resip/stack/TimerQueue.cxx index e8d22ad0..2e6d060f 100644 --- a/src/libs/resiprocate/resip/stack/TimerQueue.cxx +++ b/src/libs/resiprocate/resip/stack/TimerQueue.cxx @@ -3,7 +3,7 @@ #include "config.h" #endif -#include +#include "rutil/ResipAssert.h" #include #include "resip/stack/TimerQueue.hxx" @@ -31,6 +31,15 @@ DtlsTimerQueue::DtlsTimerQueue( Fifo& fifo ) { } +DtlsTimerQueue::~DtlsTimerQueue() +{ + while(!mTimers.empty()) + { + delete mTimers.top().getMessage(); + mTimers.pop(); + } +} + #endif UInt64 @@ -54,10 +63,19 @@ DtlsTimerQueue::add( SSL *ssl, unsigned long msOffset ) #endif +BaseTimeLimitTimerQueue::~BaseTimeLimitTimerQueue() +{ + while(!mTimers.empty()) + { + delete mTimers.top().getMessage(); + mTimers.pop(); + } +} + UInt64 BaseTimeLimitTimerQueue::add(unsigned int timeMs,Message* payload) { - assert(payload); + resip_assert(payload); DebugLog(<< "Adding application timer: " << payload->brief() << " ms=" << timeMs); mTimers.push(TimerWithPayload(timeMs,payload)); return mTimers.top().getWhen(); @@ -66,7 +84,7 @@ BaseTimeLimitTimerQueue::add(unsigned int timeMs,Message* payload) void BaseTimeLimitTimerQueue::processTimer(const TimerWithPayload& timer) { - assert(timer.getMessage()); + resip_assert(timer.getMessage()); addToFifo(timer.getMessage(), TimeLimitFifo::InternalElement); } @@ -90,10 +108,19 @@ TimeLimitTimerQueue::addToFifo(Message*msg, TimeLimitFifo::DepthUsage d TuSelectorTimerQueue::TuSelectorTimerQueue(TuSelector& sel) : mFifoSelector(sel) {} +TuSelectorTimerQueue::~TuSelectorTimerQueue() +{ + while(!mTimers.empty()) + { + delete mTimers.top().getMessage(); + mTimers.pop(); + } +} + UInt64 TuSelectorTimerQueue::add(unsigned int timeMs,Message* payload) { - assert(payload); + resip_assert(payload); DebugLog(<< "Adding application timer: " << payload->brief() << " ms=" << timeMs); mTimers.push(TimerWithPayload(timeMs,payload)); return mTimers.top().getWhen(); diff --git a/src/libs/resiprocate/resip/stack/TimerQueue.hxx b/src/libs/resiprocate/resip/stack/TimerQueue.hxx index 5a30b44e..5753cca4 100644 --- a/src/libs/resiprocate/resip/stack/TimerQueue.hxx +++ b/src/libs/resiprocate/resip/stack/TimerQueue.hxx @@ -5,13 +5,10 @@ #include "config.h" #endif +#include #include #include #include -#if _MSC_VER >= 1700 -# include -#endif - #include "resip/stack/TimerMessage.hxx" #include "resip/stack/DtlsMessage.hxx" #include "rutil/Fifo.hxx" @@ -35,7 +32,6 @@ class TuSelector; * When using this in the main loop, call process() on this. * During Transaction processing, TimerMessages and SIP messages are generated. * - * @todo !dcm! - refactor, templatize @todo .dlb. timer wheel for transaction-bound timers and a heap for everything longer. */ @@ -47,8 +43,6 @@ class TimerQueue // thing subclasses must implement. virtual void processTimer(const T& timer)=0; - - /// @brief deletes the message associated with the timer as well. virtual ~TimerQueue() { @@ -60,11 +54,11 @@ class TimerQueue } } - /// @brief provides the time in milliseconds before the next timer will fire + /// @brief provides the time in milliseconds before the next timer will fire /// @retval milliseconds time until the next timer will fire - /// @retval 0 implies that timers occur in the past - /// @retval INT_MAX implies that there are no timers - /// + /// @retval 0 implies that timers occur in the past + /// @retval INT_MAX implies that there are no timers + /// unsigned int msTillNextTimer() { if (!mTimers.empty()) @@ -120,12 +114,12 @@ class TimerQueue { return (int)mTimers.size(); } + bool empty() const { return mTimers.empty(); } - std::ostream& encode(std::ostream& str) const { if(mTimers.size() > 0) @@ -165,6 +159,7 @@ class TimerQueue class BaseTimeLimitTimerQueue : public TimerQueue { public: + ~BaseTimeLimitTimerQueue(); UInt64 add(unsigned int timeMs,Message* payload); virtual void processTimer(const TimerWithPayload& timer); protected: @@ -193,6 +188,7 @@ class TuSelectorTimerQueue : public TimerQueue { public: TuSelectorTimerQueue(TuSelector& sel); + ~TuSelectorTimerQueue(); UInt64 add(unsigned int timeMs,Message* payload); virtual void processTimer(const TimerWithPayload& timer); private: @@ -223,8 +219,9 @@ class TransactionTimerQueue : public TimerQueue class DtlsTimerQueue : public TimerQueue { public: - DtlsTimerQueue( Fifo& fifo ) ; - UInt64 add( SSL *, unsigned long msOffset ) ; + DtlsTimerQueue(Fifo& fifo); + ~DtlsTimerQueue(); + UInt64 add(SSL *, unsigned long msOffset); virtual void processTimer(const TimerWithPayload& timer) ; private: diff --git a/src/libs/resiprocate/resip/stack/Token.cxx b/src/libs/resiprocate/resip/stack/Token.cxx index f4ca3c51..53831ad8 100644 --- a/src/libs/resiprocate/resip/stack/Token.cxx +++ b/src/libs/resiprocate/resip/stack/Token.cxx @@ -203,7 +203,16 @@ defineParam(effectiveBy, "effective-by", UInt32Parameter, "RFC 6080"); defineParam(document, "document", DataParameter, "draft-ietf-sipping-config-framework-07 (removed in 08)"); defineParam(appId, "app-id", DataParameter, "draft-ietf-sipping-config-framework-05 (renamed to auid in 06, which was then removed in 08)"); defineParam(networkUser, "network-user", DataParameter, "draft-ietf-sipping-config-framework-11 (removed in 12)"); -defineParam(require, "require", DataParameter, "RFC 5373"); +defineParam(require, "require", ExistsParameter, "RFC 5373"); + +defineParam(utranCellId3gpp, "utran-cell-id-3gpp", DataParameter, "RFC 3455"); // P-Access-Network-Info +defineParam(cgi3gpp, "cgi-3gpp", DataParameter, "RFC 3455"); // P-Access-Network-Info +defineParam(ccf, "ccf", DataParameter, "RFC 3455"); // P-Charging-Function-Addresses +defineParam(ecf, "ecf", DataParameter, "RFC 3455"); // P-Charging-Function-Addresses +defineParam(icidValue, "icid-value", DataParameter, "RFC 3455"); // P-Charging-Vector +defineParam(icidGeneratedAt, "icid-generated-at", DataParameter, "RFC 3455"); // P-Charging-Vector +defineParam(origIoi, "orig-ioi", DataParameter, "RFC 3455"); // P-Charging-Vector +defineParam(termIoi, "term-ioi", DataParameter, "RFC 3455"); // P-Charging-Vector #undef defineParam diff --git a/src/libs/resiprocate/resip/stack/Token.hxx b/src/libs/resiprocate/resip/stack/Token.hxx index eb996036..a80413b0 100644 --- a/src/libs/resiprocate/resip/stack/Token.hxx +++ b/src/libs/resiprocate/resip/stack/Token.hxx @@ -83,7 +83,16 @@ class Token : public ParserCategory defineParam(document, "document", DataParameter, "draft-ietf-sipping-config-framework-07 (removed in 08)"); defineParam(appId, "app-id", DataParameter, "draft-ietf-sipping-config-framework-05 (renamed to auid in 06, which was then removed in 08)"); defineParam(networkUser, "network-user", DataParameter, "draft-ietf-sipping-config-framework-11 (removed in 12)"); - defineParam(require, "require", DataParameter, "RFC 5373"); + defineParam(require, "require", ExistsParameter, "RFC 5373"); + + defineParam(utranCellId3gpp, "utran-cell-id-3gpp", DataParameter, "RFC 3455"); // P-Access-Network-Info + defineParam(cgi3gpp, "cgi-3gpp", DataParameter, "RFC 3455"); // P-Access-Network-Info + defineParam(ccf, "ccf", DataParameter, "RFC 3455"); // P-Charging-Function-Addresses + defineParam(ecf, "ecf", DataParameter, "RFC 3455"); // P-Charging-Function-Addresses + defineParam(icidValue, "icid-value", DataParameter, "RFC 3455"); // P-Charging-Vector + defineParam(icidGeneratedAt, "icid-generated-at", DataParameter, "RFC 3455"); // P-Charging-Vector + defineParam(origIoi, "orig-ioi", DataParameter, "RFC 3455"); // P-Charging-Vector + defineParam(termIoi, "term-ioi", DataParameter, "RFC 3455"); // P-Charging-Vector #undef defineParam diff --git a/src/libs/resiprocate/resip/stack/TokenOrQuotedStringCategory.cxx b/src/libs/resiprocate/resip/stack/TokenOrQuotedStringCategory.cxx new file mode 100644 index 00000000..76fb6331 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TokenOrQuotedStringCategory.cxx @@ -0,0 +1,272 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include "resip/stack/TokenOrQuotedStringCategory.hxx" +#include "rutil/Logger.hxx" +#include "rutil/ParseBuffer.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +//============================ +// TokenOrQuotedStringCategory +//============================ +TokenOrQuotedStringCategory::TokenOrQuotedStringCategory() + : ParserCategory(), + mValue(), + mQuoted(false) +{} + +TokenOrQuotedStringCategory::TokenOrQuotedStringCategory(const Data& value, + bool quoted) + : ParserCategory(), + mValue(value), + mQuoted(quoted) +{} + +TokenOrQuotedStringCategory::TokenOrQuotedStringCategory(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool) + : ParserCategory(hfv, type, pool), + mValue(), + mQuoted(false) +{} + +TokenOrQuotedStringCategory::TokenOrQuotedStringCategory(const TokenOrQuotedStringCategory& rhs, + PoolBase* pool) + : ParserCategory(rhs, pool), + mValue(rhs.mValue), + mQuoted(rhs.mQuoted) +{} + +TokenOrQuotedStringCategory& +TokenOrQuotedStringCategory::operator=(const TokenOrQuotedStringCategory& rhs) +{ + if (this != &rhs) + { + ParserCategory::operator=(rhs); + mValue = rhs.mValue; + mQuoted = rhs.mQuoted; + } + return *this; +} + +ParserCategory* +TokenOrQuotedStringCategory::clone() const +{ + return new TokenOrQuotedStringCategory(*this); +} + +ParserCategory* +TokenOrQuotedStringCategory::clone(void* location) const +{ + return new (location) TokenOrQuotedStringCategory(*this); +} + +ParserCategory* +TokenOrQuotedStringCategory::clone(PoolBase* pool) const +{ + return new (pool) TokenOrQuotedStringCategory(*this, pool); +} + +bool +TokenOrQuotedStringCategory::isEqual(const TokenOrQuotedStringCategory& rhs) const +{ + return ((value() == rhs.value()) && (isQuoted() == rhs.isQuoted())); +} + +bool +TokenOrQuotedStringCategory::operator==(const TokenOrQuotedStringCategory& rhs) const +{ + return ((value() == rhs.value()) && (isQuoted() == rhs.isQuoted())); +} + +bool +TokenOrQuotedStringCategory::operator!=(const TokenOrQuotedStringCategory& rhs) const +{ + return ((value() != rhs.value()) || (isQuoted() != rhs.isQuoted())); +} + +bool +TokenOrQuotedStringCategory::operator<(const TokenOrQuotedStringCategory& rhs) const +{ + // don't use mQuoted for operator < + return (value() < rhs.value()); +} + +void +TokenOrQuotedStringCategory::parse(ParseBuffer& pb) +{ + const char* startMark = pb.skipWhitespace(); + if (*pb.position() == Symbols::DOUBLE_QUOTE[0]) + { + setQuoted(true); + pb.skipChar(); + startMark = pb.position(); + pb.skipToEndQuote(); + } + else + { + setQuoted(false); + pb.skipToOneOf(ParseBuffer::Whitespace, Symbols::SEMI_COLON); + } + pb.data(mValue, startMark); + pb.skipToChar(Symbols::SEMI_COLON[0]); + parseParameters(pb); +} + +EncodeStream& +TokenOrQuotedStringCategory::encodeParsed(EncodeStream& str) const +{ + str << quotedValue(); + encodeParameters(str); + return str; +} + +const Data& TokenOrQuotedStringCategory::value() const +{ + checkParsed(); + return mValue; +} + +Data& TokenOrQuotedStringCategory::value() +{ + checkParsed(); + return mValue; +} + +Data TokenOrQuotedStringCategory::quotedValue() const +{ + checkParsed(); + Data tokenValue; + if (mQuoted) + { + tokenValue += Symbols::DOUBLE_QUOTE; + } + // mValue does not contain quoted string + tokenValue += mValue; + if (mQuoted) + { + tokenValue += Symbols::DOUBLE_QUOTE; + } + return tokenValue; +} + +ParameterTypes::Factory TokenOrQuotedStringCategory::ParameterFactories[ParameterTypes::MAX_PARAMETER] = { 0 }; + +Parameter* +TokenOrQuotedStringCategory::createParam(ParameterTypes::Type type, + ParseBuffer& pb, + const std::bitset<256>& terminators, + PoolBase* pool) +{ + if ((type > ParameterTypes::UNKNOWN) && (type < ParameterTypes::MAX_PARAMETER) && ParameterFactories[type]) + { + return ParameterFactories[type](type, pb, terminators, pool); + } + return 0; +} + +bool +TokenOrQuotedStringCategory::exists(const Param& paramType) const +{ + checkParsed(); + bool ret = (getParameterByEnum(paramType.getTypeNum()) != NULL); + return ret; +} + +void +TokenOrQuotedStringCategory::remove(const Param& paramType) +{ + checkParsed(); + removeParameterByEnum(paramType.getTypeNum()); +} + +#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ +_enum##_Param::DType& \ +TokenOrQuotedStringCategory::param(const _enum##_Param& paramType) \ +{ \ + checkParsed(); \ + _enum##_Param::Type* p = \ + static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ + if (!p) \ + { \ + p = new _enum##_Param::Type(paramType.getTypeNum()); \ + mParameters.push_back(p); \ + } \ + return p->value(); \ +} \ + \ +const _enum##_Param::DType& \ +TokenOrQuotedStringCategory::param(const _enum##_Param& paramType) const \ +{ \ + checkParsed(); \ + _enum##_Param::Type* p = \ + static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ + if (!p) \ + { \ + InfoLog(<< "Missing parameter " _name " " << ParameterTypes::ParameterNames[paramType.getTypeNum()]); \ + DebugLog(<< *this); \ + throw Exception("Missing parameter " _name, __FILE__, __LINE__); \ + } \ + return p->value(); \ +} + +defineParam(purpose, "purpose", DataParameter, "draft-ietf-cuss-sip-uui-17"); // User-to-User +defineParam(content, "content", DataParameter, "draft-ietf-cuss-sip-uui-17"); // User-to-User +defineParam(encoding, "encoding", DataParameter, "draft-ietf-cuss-sip-uui-17"); // User-to-User + +#undef defineParam + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * . + * + */ diff --git a/src/libs/resiprocate/resip/stack/TokenOrQuotedStringCategory.hxx b/src/libs/resiprocate/resip/stack/TokenOrQuotedStringCategory.hxx new file mode 100644 index 00000000..fa08c250 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/TokenOrQuotedStringCategory.hxx @@ -0,0 +1,135 @@ +#if !defined(RESIP_TOKEN_OR_QUOTED_STRING_CATEGORY_HXX) +#define RESIP_TOKEN_OR_QUOTED_STRING_CATEGORY_HXX + +#include +#include "rutil/Data.hxx" +#include "resip/stack/ParserCategory.hxx" +#include "resip/stack/ParserContainer.hxx" + +namespace resip +{ + +/** + @ingroup sip_grammar + @brief Generically represents a token whose value can be + wrapped and encoded using double quotes. +*/ + +class TokenOrQuotedStringCategory : public ParserCategory +{ + public: + enum {commaHandling = CommasAllowedOutputCommas}; + + TokenOrQuotedStringCategory(); + explicit TokenOrQuotedStringCategory(const Data& value, bool quoted); + TokenOrQuotedStringCategory(const HeaderFieldValue& hfv, + Headers::Type type, + PoolBase* pool = 0); + TokenOrQuotedStringCategory(const TokenOrQuotedStringCategory& rhs, + PoolBase* pool = 0); + TokenOrQuotedStringCategory& operator=(const TokenOrQuotedStringCategory& rhs); + + virtual ParserCategory* clone() const; + virtual ParserCategory* clone(void* location) const; + virtual ParserCategory* clone(PoolBase* pool) const; + + bool isEqual(const TokenOrQuotedStringCategory& rhs) const; + bool operator==(const TokenOrQuotedStringCategory& rhs) const; + bool operator!=(const TokenOrQuotedStringCategory& rhs) const; + bool operator<(const TokenOrQuotedStringCategory& rhs) const; + + virtual void parse(ParseBuffer& pb); + virtual EncodeStream& encodeParsed(EncodeStream& str) const; + + // Gets the value (ie; no parameters) of this Token as a Data&. + const Data& value() const; + Data& value(); + + // mValue will be enclosed in quotes e.g. "foo" + bool isQuoted() const { return mQuoted; } + void setQuoted(bool b) { mQuoted = b; }; + + Data quotedValue() const; + + // Inform the compiler that overloads of these may be found in ParserCategory, too. + using ParserCategory::exists; + using ParserCategory::remove; + using ParserCategory::param; + + virtual Parameter* createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool); + bool exists(const Param& paramType) const; + void remove(const Param& paramType); + +#define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ + const _enum##_Param::DType& param(const _enum##_Param& paramType) const; \ + _enum##_Param::DType& param(const _enum##_Param& paramType); \ + friend class _enum##_Param + + defineParam(purpose, "purpose", DataParameter, "draft-ietf-cuss-sip-uui-17"); // User-to-User + defineParam(content, "content", DataParameter, "draft-ietf-cuss-sip-uui-17"); // User-to-User + defineParam(encoding, "encoding", DataParameter, "draft-ietf-cuss-sip-uui-17"); // User-to-User + +#undef defineParam + + private: + Data mValue; + bool mQuoted; + + static ParameterTypes::Factory ParameterFactories[ParameterTypes::MAX_PARAMETER]; +}; + +typedef ParserContainer TokenOrQuotedStringCategories; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * . + * + */ diff --git a/src/libs/resiprocate/resip/stack/TransactionController.cxx b/src/libs/resiprocate/resip/stack/TransactionController.cxx index cf130afb..11fc8f83 100644 --- a/src/libs/resiprocate/resip/stack/TransactionController.cxx +++ b/src/libs/resiprocate/resip/stack/TransactionController.cxx @@ -6,8 +6,11 @@ #include "resip/stack/ApplicationMessage.hxx" #include "resip/stack/CancelClientInviteTransaction.hxx" #include "resip/stack/Helper.hxx" +#include "resip/stack/AddTransport.hxx" +#include "resip/stack/RemoveTransport.hxx" #include "resip/stack/TerminateFlow.hxx" #include "resip/stack/EnableFlowTimer.hxx" +#include "resip/stack/InvokeAfterSocketCreationFunc.hxx" #include "resip/stack/ZeroOutStatistics.hxx" #include "resip/stack/PollStatistics.hxx" #include "resip/stack/ShutdownMessage.hxx" @@ -35,7 +38,8 @@ unsigned int TransactionController::MaxTUFifoSize = 0; unsigned int TransactionController::MaxTUFifoTimeDepthSecs = 0; TransactionController::TransactionController(SipStack& stack, - AsyncProcessHandler* handler) : + AsyncProcessHandler* handler, + bool useDnsVip) : mStack(stack), mDiscardStrayResponses(true), mFixBadDialogIdentifiers(true), @@ -47,7 +51,8 @@ TransactionController::TransactionController(SipStack& stack, mTransportSelector(mStateMacFifo, stack.getSecurity(), stack.getDnsStub(), - stack.getCompression()), + stack.getCompression(), + useDnsVip), mTimers(mTimerFifo), mShuttingDown(false), mStatsManager(stack.mStatsManager), @@ -111,6 +116,13 @@ TransactionController::process(int timeout) timeout=-1; } + // Check if Statistics Manager needs to be polled - note: all statistic manager polls should happen from the + // TransactionController thread / process loop + if(mStack.mStatisticsManagerEnabled) + { + mStatsManager.process(); + } + // If non-zero is passed for timeout, we understand that the caller is ok // with us waiting up to that long on this call. A non-zero timeout is // passed by TransactionControllerThread, for example. This gets us @@ -248,9 +260,21 @@ TransactionController::abandonServerTransaction(const Data& tid) } void -TransactionController::cancelClientInviteTransaction(const Data& tid) +TransactionController::cancelClientInviteTransaction(const Data& tid, const resip::Tokens* reasons) { - mStateMacFifo.add(new CancelClientInviteTransaction(tid)); + mStateMacFifo.add(new CancelClientInviteTransaction(tid, reasons)); +} + +void +TransactionController::addTransport(std::auto_ptr transport) +{ + mStateMacFifo.add(new AddTransport(transport)); +} + +void +TransactionController::removeTransport(unsigned int transportKey) +{ + mStateMacFifo.add(new RemoveTransport(transportKey)); } void @@ -271,6 +295,12 @@ TransactionController::setInterruptor(AsyncProcessHandler* handler) mStateMacFifo.setInterruptor(handler); } +void +TransactionController::invokeAfterSocketCreationFunc(TransportType type) +{ + mStateMacFifo.add(new InvokeAfterSocketCreationFunc(type)); +} + /* ==================================================================== * The Vovida Software License, Version 1.0 * diff --git a/src/libs/resiprocate/resip/stack/TransactionController.hxx b/src/libs/resiprocate/resip/stack/TransactionController.hxx index fcfba306..b0a2b803 100644 --- a/src/libs/resiprocate/resip/stack/TransactionController.hxx +++ b/src/libs/resiprocate/resip/stack/TransactionController.hxx @@ -27,8 +27,7 @@ class TransactionController static unsigned int MaxTUFifoSize; static unsigned int MaxTUFifoTimeDepthSecs; - TransactionController(SipStack& stack, - AsyncProcessHandler* handler); + TransactionController(SipStack& stack, AsyncProcessHandler* handler, bool useDnsVip); ~TransactionController(); void process(int timeout=0); @@ -96,11 +95,16 @@ class TransactionController } void abandonServerTransaction(const Data& tid); - void cancelClientInviteTransaction(const Data& tid); + void cancelClientInviteTransaction(const Data& tid, const resip::Tokens* reasons); + void addTransport(std::auto_ptr transport); + void removeTransport(unsigned int transportKey); void terminateFlow(const resip::Tuple& flow); void enableFlowTimer(const resip::Tuple& flow); void setInterruptor(AsyncProcessHandler* handler); + + void invokeAfterSocketCreationFunc(TransportType type); + private: TransactionController(const TransactionController& rhs); TransactionController& operator=(const TransactionController& rhs); diff --git a/src/libs/resiprocate/resip/stack/TransactionMap.cxx b/src/libs/resiprocate/resip/stack/TransactionMap.cxx index a6ce89e1..e432153c 100644 --- a/src/libs/resiprocate/resip/stack/TransactionMap.cxx +++ b/src/libs/resiprocate/resip/stack/TransactionMap.cxx @@ -69,7 +69,7 @@ TransactionMap::erase(const Data& tid ) else { InfoLog (<< "Couldn't find " << tid << " to remove"); - assert(0); + resip_assert(0); } } diff --git a/src/libs/resiprocate/resip/stack/TransactionMap.hxx b/src/libs/resiprocate/resip/stack/TransactionMap.hxx index a047812a..ac158f60 100644 --- a/src/libs/resiprocate/resip/stack/TransactionMap.hxx +++ b/src/libs/resiprocate/resip/stack/TransactionMap.hxx @@ -23,7 +23,16 @@ class TransactionMap private: -#if defined(__INTEL_COMPILER ) || (defined(WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1310)) // !slg! not sure if this works on __INTEL_COMPILER + // We treat branch parameters as case insensitive (RFC3261): + // 7.3.1 Header Field Format + // .... + // When comparing header fields, field names are always case- + // insensitive.Unless otherwise stated in the definition of a + // particular header field, field values, parameter names, and parameter + // values are case-insensitive.Tokens are always case-insensitive. + // Unless specified otherwise, values expressed as quoted strings are + // case-sensitive. +#if defined(__INTEL_COMPILER ) || (defined(WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1310) && (_MSC_VER < 1900)) // !slg! not sure if this works on __INTEL_COMPILER /** @internal */ @@ -83,7 +92,7 @@ class TransactionMap // .bwc. If rutil/HashMap.hxx fails to find a hash_map impl for the // platform we're using, it will #define HashMap to a std::map, which // takes different template args. We try to compensate for this here. -#if defined(__INTEL_COMPILER ) || (defined(WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1310)) +#if defined(__INTEL_COMPILER ) || (defined(WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1310) && (_MSC_VER < 1900)) typedef HashMap Map; #elif defined(HASH_MAP_NAMESPACE) typedef HashMap Map; diff --git a/src/libs/resiprocate/resip/stack/TransactionMessage.hxx b/src/libs/resiprocate/resip/stack/TransactionMessage.hxx index f7796e1f..8bf0300d 100644 --- a/src/libs/resiprocate/resip/stack/TransactionMessage.hxx +++ b/src/libs/resiprocate/resip/stack/TransactionMessage.hxx @@ -1,7 +1,7 @@ #ifndef RESIP_TransactionMessage_hxx #define RESIP_TransactionMessage_hxx -#include +#include "rutil/ResipAssert.h" #include "resip/stack/Message.hxx" #include "rutil/HeapInstanceCounter.hxx" @@ -19,7 +19,7 @@ class TransactionMessage : public Message // purpose of determining which TransactionMap to use virtual bool isClientTransaction() const = 0; - virtual Message* clone() const {assert(false); return NULL;} + virtual Message* clone() const {resip_assert(false); return NULL;} }; } diff --git a/src/libs/resiprocate/resip/stack/TransactionState.cxx b/src/libs/resiprocate/resip/stack/TransactionState.cxx index 8d24889e..51c05b17 100644 --- a/src/libs/resiprocate/resip/stack/TransactionState.cxx +++ b/src/libs/resiprocate/resip/stack/TransactionState.cxx @@ -4,9 +4,12 @@ #include "resip/stack/AbandonServerTransaction.hxx" #include "resip/stack/CancelClientInviteTransaction.hxx" +#include "resip/stack/AddTransport.hxx" +#include "resip/stack/RemoveTransport.hxx" #include "resip/stack/TerminateFlow.hxx" #include "resip/stack/EnableFlowTimer.hxx" #include "resip/stack/ZeroOutStatistics.hxx" +#include "resip/stack/InvokeAfterSocketCreationFunc.hxx" #include "resip/stack/PollStatistics.hxx" #include "resip/stack/ConnectionTerminated.hxx" #include "resip/stack/KeepAlivePong.hxx" @@ -32,6 +35,7 @@ #include "resip/stack/TuSelector.hxx" #include "resip/stack/InteropHelper.hxx" #include "resip/stack/KeepAliveMessage.hxx" +#include "rutil/ResipAssert.h" #include "rutil/DnsUtil.hxx" #include "rutil/Logger.hxx" #include "rutil/MD5Stream.hxx" @@ -43,7 +47,8 @@ using namespace resip; #define RESIPROCATE_SUBSYSTEM Subsystem::TRANSACTION -unsigned long TransactionState::StatelessIdCounter = 0; +UInt64 TransactionState::DnsGreylistDurationMs = 32000; // default to 32 seconds, application can override +UInt32 TransactionState::StatelessIdCounter = 0; TransactionState::TransactionState(TransactionController& controller, Machine m, State s, const Data& id, MethodTypes method, const Data& methodText, TransactionUser* tu) : @@ -51,6 +56,7 @@ TransactionState::TransactionState(TransactionController& controller, Machine m, mMachine(m), mState(s), mIsAbandoned(false), + mPendingCancelReasons(0), mIsReliable(true), // !jf! mNextTransmission(0), mDnsResult(0), @@ -60,10 +66,11 @@ TransactionState::TransactionState(TransactionController& controller, Machine m, mCurrentMethodType(UNKNOWN), mCurrentResponseCode(0), mAckIsValid(false), - mWaitingForDnsResult(false), + mPendingOperation(None), mTransactionUser(tu), mFailureReason(TransportFailure::None), - mFailureSubCode(0) + mFailureSubCode(0), + mTcpConnectTimerStarted(false) { StackLog (<< "Creating new TransactionState: " << *this); } @@ -99,7 +106,7 @@ TransactionState::handleInternalCancel(SipMessage* cancel, // Make sure the branch in the CANCEL matches the current // branch of the INVITE, in case we have done a DNS failover (the transport // sequences could be different by now) - cancel->header(h_Vias).front().param(p_branch)=clientInvite.mNextTransmission->const_header(h_Vias).front().param(p_branch); + cancel->header(h_Vias).front().param(p_branch) = clientInvite.mNextTransmission->const_header(h_Vias).front().param(p_branch); state->processClientNonInvite(cancel); // for the INVITE in case we never get a 487 clientInvite.mController.mTimers.add(Timer::TimerCleanUp, clientInvite.mId, 128*Timer::T1); @@ -108,7 +115,7 @@ TransactionState::handleInternalCancel(SipMessage* cancel, bool TransactionState::handleBadRequest(const resip::SipMessage& badReq, TransactionController& controller) { - assert(badReq.isRequest() && badReq.method() != ACK); + resip_assert(badReq.isRequest() && badReq.method() != ACK); try { SipMessage* error = Helper::makeResponse(badReq,400); @@ -143,7 +150,7 @@ TransactionState::handleBadRequest(const resip::SipMessage& badReq, TransactionC TransactionState::~TransactionState() { - assert(mState != Bogus); + resip_assert(mState != Bogus); if (mDnsResult) { @@ -158,6 +165,8 @@ TransactionState::~TransactionState() mNextTransmission = 0; mMethodText = 0; + setPendingCancelReasons(0); + mState = Bogus; } @@ -241,8 +250,11 @@ TransactionState::processSipMessageAsNew(SipMessage* sip, TransactionController& } else if (method == CANCEL) { - TransactionState* matchingInvite = - controller.mServerTransactionMap.find(sip->getTransactionId()); + // Note: For cancel requests the tid member passed in will have the token "cancel" appended + // to it, so that the cancel request can be treated as it's own transaction. sip->getTransactionId() + // will be the original tid from the wire and should match the tid of the INVITE request being + // cancelled. + TransactionState* matchingInvite = controller.mServerTransactionMap.find(sip->getTransactionId()); if (matchingInvite == 0) { InfoLog (<< "No matching INVITE for incoming (from wire) CANCEL to uas"); @@ -256,7 +268,7 @@ TransactionState::processSipMessageAsNew(SipMessage* sip, TransactionController& } else { - assert(matchingInvite); + resip_assert(matchingInvite); TransactionState* state = TransactionState::makeCancelTransaction(matchingInvite, ServerNonInvite, tid); state->startServerNonInviteTimerTrying(*sip,tid); state->sendToTU(sip); @@ -330,6 +342,12 @@ TransactionState::processSipMessageAsNew(SipMessage* sip, TransactionController& StackLog (<< *sip); matchingInvite->mIsAbandoned = true; + // If there are reason headers on the cancel we store them for use later when the + // cancel is able to be sent out. + if (sip->exists(h_Reasons)) + { + matchingInvite->setPendingCancelReasons(&sip->header(h_Reasons)); + } return false; } else if (matchingInvite->mState == Completed) @@ -390,36 +408,44 @@ TransactionState::processSipMessageAsNew(SipMessage* sip, TransactionController& return true; } +void +TransactionState::setPendingCancelReasons(const Tokens* reasons) +{ + if (reasons) + { + if (mPendingCancelReasons) + { + *mPendingCancelReasons = *reasons; // copy + } + else + { + mPendingCancelReasons = new Tokens(*reasons); // create and copy + } + } + else + { + delete mPendingCancelReasons; + mPendingCancelReasons = 0; + } +} + void TransactionState::process(TransactionController& controller, TransactionMessage* message) -{ +{ + // Note: KeepAliveMessage is a special SipMessage - check for it first + KeepAliveMessage* keepAlive = dynamic_cast(message); + if (keepAlive) { - KeepAliveMessage* keepAlive = dynamic_cast(message); - if (keepAlive) - { - StackLog ( << "Sending keep alive to: " << keepAlive->getDestination()); - controller.mTransportSelector.transmit(keepAlive, keepAlive->getDestination()); - delete keepAlive; - return; - } - - ConnectionTerminated* term = dynamic_cast(message); - if (term) - { - if(term->hasTransactionUser()) - { - controller.mTuSelector.add(term); - } - else - { - // .bwc. This means we are using this message to close a connection. - controller.mTransportSelector.closeConnection(term->getFlow()); - } - delete term; - return; - } + StackLog ( << "Sending keep alive to: " << keepAlive->getDestination()); + controller.mTransportSelector.transmit(keepAlive, keepAlive->getDestination()); + delete keepAlive; + return; + } + SipMessage* sip = dynamic_cast(message); + if(!sip) + { KeepAlivePong* pong = dynamic_cast(message); if (pong) { @@ -428,6 +454,14 @@ TransactionState::process(TransactionController& controller, return; } + ConnectionTerminated* term = dynamic_cast(message); + if (term) + { + controller.mTuSelector.add(term); + delete term; + return; + } + TerminateFlow* termFlow = dynamic_cast(message); if(termFlow) { @@ -459,6 +493,28 @@ TransactionState::process(TransactionController& controller, delete pollStatistics; return; } + + AddTransport* addTransport = dynamic_cast(message); + if(addTransport) + { + controller.mTransportSelector.addTransport(addTransport->getTransport(), true /* isStackRunning */); + delete addTransport; + return; + } + + RemoveTransport* removeTransport = dynamic_cast(message); + if(removeTransport) + { + controller.mTransportSelector.removeTransport(removeTransport->getTransportKey()); + delete removeTransport; + return; + } + + InvokeAfterSocketCreationFunc* invokeAfterSocketCreationFunc = dynamic_cast(message); + if(invokeAfterSocketCreationFunc) + { + controller.mTransportSelector.invokeAfterSocketCreationFunc(invokeAfterSocketCreationFunc->getTransportType()); + } } // .bwc. We can't do anything without a tid here. Check this first. @@ -467,7 +523,7 @@ TransactionState::process(TransactionController& controller, { tid = message->getTransactionId(); } - catch(SipMessage::Exception&) + catch(resip::BaseException&) { // .bwc This is not our error. Do not ErrLog. DebugLog( << "TransactionState::process dropping message with invalid tid " << message->brief()); @@ -475,7 +531,6 @@ TransactionState::process(TransactionController& controller, return; } - SipMessage* sip = dynamic_cast(message); MethodTypes method = UNKNOWN; if(sip) @@ -527,7 +582,7 @@ TransactionState::process(TransactionController& controller, { sip->parseAllHeaders(); } - catch(resip::ParseException& e) + catch(resip::BaseException& e) { if(sip->isRequest() && method!=ACK) { @@ -547,9 +602,13 @@ TransactionState::process(TransactionController& controller, TransactionState* state = 0; if (message->isClientTransaction()) - state = controller.mClientTransactionMap.find(tid); + { + state = controller.mClientTransactionMap.find(tid); + } else - state = controller.mServerTransactionMap.find(tid); + { + state = controller.mServerTransactionMap.find(tid); + } if (state && sip && sip->isExternal()) { @@ -585,7 +644,8 @@ TransactionState::process(TransactionController& controller, // Overwrite tag. if(from.exists(p_tag)) { - if(sip->const_header(h_From).param(p_tag) != from.param(p_tag)) + if(!sip->const_header(h_From).exists(p_tag) || + sip->const_header(h_From).param(p_tag) != from.param(p_tag)) { InfoLog(<<"Other end modified our local tag... correcting."); sip->header(h_From).param(p_tag) = from.param(p_tag); @@ -593,11 +653,8 @@ TransactionState::process(TransactionController& controller, } else if(sip->const_header(h_From).exists(p_tag)) { - if(sip->const_header(h_From).exists(p_tag)) - { - InfoLog(<<"Other end added a local tag for us... removing."); - sip->header(h_From).remove(p_tag); - } + InfoLog(<<"Other end added a local tag for us... removing."); + sip->header(h_From).remove(p_tag); } } else @@ -613,7 +670,8 @@ TransactionState::process(TransactionController& controller, // Overwrite tag. if(to.exists(p_tag)) { - if(sip->const_header(h_To).param(p_tag) != to.param(p_tag)) + if(!sip->const_header(h_To).exists(p_tag) || + sip->const_header(h_To).param(p_tag) != to.param(p_tag)) { InfoLog(<<"Other end modified the (existing) remote tag... " "correcting."); @@ -637,20 +695,11 @@ TransactionState::process(TransactionController& controller, if(state->mController.getFixBadCSeqNumbers()) { unsigned int old=state->mNextTransmission->const_header(h_CSeq).sequence(); - if(sip->const_header(h_CSeq).sequence()!=old) + if(sip->const_header(h_CSeq).sequence() != old) { InfoLog(<<"Other end changed our CSeq number... replacing."); sip->header(h_CSeq).sequence()=old; } - - if(state->mNextTransmission->exists(h_RAck)) - { - if(!(sip->const_header(h_RAck)==state->mNextTransmission->const_header(h_RAck))) - { - InfoLog(<<"Other end changed our RAck... replacing."); - sip->header(h_RAck)=state->mNextTransmission->const_header(h_RAck); - } - } } } // .bwc. This code ensures that the transaction state-machine can recover @@ -699,6 +748,23 @@ TransactionState::process(TransactionController& controller, } break; } + + // .bwc. in private email 1 Feb 2013: + // According to the spec, there is no such thing as a reliable NIT + // retransmission; what we have just observed is a transaction id collision + // technically. Maybe a reliable NIT transaction collision needs special + // handling? It is probably a lot more common that this is a confused client, + // than a client that has innocently used the same tid as some other client, + // though. Maybe we should just ignore such requests? + if(sip->isExternal() && sip->isRequest() && + method != ACK && + state->mIsReliable) + { + InfoLog(<<"Someone sent us a request with a repeated transaction ID " + "over a reliable transport. Discarding the request."); + delete sip; + return; + } } if (state) // found transaction for sip msg @@ -712,7 +778,7 @@ TransactionState::process(TransactionController& controller, break; case ClientInvite: // ACK from TU will be Stateless - assert (!sip || !(state->isFromTU(sip) && sip->isRequest() && method == ACK)); + resip_assert (!sip || !(state->isFromTU(sip) && sip->isRequest() && method == ACK)); state->processClientInvite(message); break; case ServerNonInvite: @@ -732,7 +798,7 @@ TransactionState::process(TransactionController& controller, break; default: CritLog(<<"internal state error"); - assert(0); + resip_assert(0); return; } } @@ -746,7 +812,7 @@ TransactionState::process(TransactionController& controller, delete sip; } } - catch(resip::ParseException& e) + catch(resip::BaseException& e) { StackLog ( << "Got badly formatted sip message, error: " << e.what()); if(sip->isRequest() && sip->method()!=ACK) @@ -839,7 +905,7 @@ TransactionState::processTimer(TransactionController& controller, break; default: CritLog(<<"internal state error"); - assert(0); + resip_assert(0); return; } } @@ -892,6 +958,12 @@ TransactionState::processStateless(TransactionMessage* message) delete message; delete this; } + else if (isTcpConnectState(message)) + { + // stateless mode is not supported + //processTcpConnectState(message); + delete message; + } else if (isTimer(message)) { TimerMessage* timer = dynamic_cast(message); @@ -903,7 +975,7 @@ TransactionState::processStateless(TransactionMessage* message) else { delete timer; - assert(0); + resip_assert(0); } } else if(dynamic_cast(message)) @@ -919,7 +991,7 @@ TransactionState::processStateless(TransactionMessage* message) else { delete message; - assert(0); + resip_assert(0); } } @@ -929,9 +1001,9 @@ TransactionState::saveOriginalContactAndVia(const SipMessage& sip) if(sip.exists(h_Contacts) && sip.const_header(h_Contacts).size() == 1 && sip.const_header(h_Contacts).front().isWellFormed()) { - mOriginalContact = std::unique_ptr(new NameAddr(sip.header(h_Contacts).front())); + mOriginalContact = std::auto_ptr(new NameAddr(sip.header(h_Contacts).front())); } - mOriginalVia = std::unique_ptr(new Via(sip.header(h_Vias).front())); + mOriginalVia = std::auto_ptr(new Via(sip.header(h_Vias).front())); } void TransactionState::restoreOriginalContactAndVia() @@ -999,7 +1071,7 @@ TransactionState::processClientNonInvite(TransactionMessage* msg) } else { - assert(0); + resip_assert(0); delete sip; } @@ -1018,14 +1090,14 @@ TransactionState::processClientNonInvite(TransactionMessage* msg) { mDnsResult->destroy(); mDnsResult=0; - mWaitingForDnsResult=false; + mPendingOperation=None; } resetNextTransmission(0); } } else { - assert(0); + resip_assert(0); delete sip; } } @@ -1068,13 +1140,22 @@ TransactionState::processClientNonInvite(TransactionMessage* msg) } break; + case Timer::TcpConnectTimer: + if (mTcpConnectTimerStarted) // Ignore timer if we went connected (note: when we connect we set mTcpConnectTimerStarted to false) + { + TransportFailure failure(mId, TransportFailure::ConnectionException); + processTransportFailure(&failure); + } + delete msg; + break; + case Timer::TimerF: if (mState == Trying || mState == Proceeding) { // !bwc! We hold onto this until we get a response from the wire // in client transactions, for this contingency. - assert(mNextTransmission); - if(mWaitingForDnsResult) + resip_assert(mNextTransmission); + if(mPendingOperation == Dns) { WarningLog(<< "Transaction timed out while waiting for DNS " "result uri=" << @@ -1109,6 +1190,11 @@ TransactionState::processClientNonInvite(TransactionMessage* msg) processTransportFailure(msg); delete msg; } + else if (isTcpConnectState(msg)) + { + processTcpConnectState(msg); + delete msg; + } else if(dynamic_cast(msg)) { handleSync(mDnsResult); @@ -1153,7 +1239,7 @@ TransactionState::processClientInvite(TransactionMessage* msg) break; case CANCEL: - assert(0); + resip_assert(0); delete msg; break; @@ -1186,6 +1272,11 @@ TransactionState::processClientInvite(TransactionMessage* msg) if(mIsAbandoned) { SipMessage* cancel = Helper::makeCancel(*mNextTransmission); + if (mPendingCancelReasons) + { + cancel->header(h_Reasons) = *mPendingCancelReasons; + setPendingCancelReasons(0); // release memory + } // Iterate through message decorators on the INVITE and see if any need to be copied to the CANCEL mNextTransmission->copyOutboundDecoratorsToStackCancel(*cancel); handleInternalCancel(cancel, *this); @@ -1216,6 +1307,7 @@ TransactionState::processClientInvite(TransactionMessage* msg) sendToTU(sip); // don't delete msg //terminateClientTransaction(mId); mMachine = ClientStale; + mState = Completed; // !bwc! We have a final response. We don't need either of // mMsgToRetransmit or mNextTransmission. We ignore further // traffic. @@ -1224,7 +1316,7 @@ TransactionState::processClientInvite(TransactionMessage* msg) { mDnsResult->destroy(); mDnsResult=0; - mWaitingForDnsResult=false; + mPendingOperation=None; } StackLog (<< "Received 2xx on client invite transaction"); StackLog (<< *this); @@ -1246,7 +1338,7 @@ TransactionState::processClientInvite(TransactionMessage* msg) resetNextTransmission(ack); // want to use the same transport as was selected for Invite - assert(mTarget.getType() != UNKNOWN_TRANSPORT); + resip_assert(mTarget.getType() != UNKNOWN_TRANSPORT); sendCurrentToWire(); sendToTU(sip); // don't delete msg terminateClientTransaction(mId); @@ -1271,13 +1363,13 @@ TransactionState::processClientInvite(TransactionMessage* msg) mNextTransmission->copyOutboundDecoratorsToStackFailureAck(*ack); resetNextTransmission(ack); sendCurrentToWire(); - if(mDnsResult) - { - mDnsResult->destroy(); - mDnsResult=0; - mWaitingForDnsResult=false; - } sendToTU(sip); // don't delete msg + if (mDnsResult) + { + mDnsResult->destroy(); + mDnsResult = 0; + mPendingOperation = None; + } } else if (mState == Completed) { @@ -1295,7 +1387,7 @@ TransactionState::processClientInvite(TransactionMessage* msg) */ CritLog( << "State invalid"); // !ah! syslog - assert(0); + resip_assert(0); delete sip; } } @@ -1303,12 +1395,12 @@ TransactionState::processClientInvite(TransactionMessage* msg) else { delete sip; - assert(0); + resip_assert(0); } break; case CANCEL: - assert(0); + resip_assert(0); delete sip; break; @@ -1340,12 +1432,21 @@ TransactionState::processClientInvite(TransactionMessage* msg) delete msg; break; + case Timer::TcpConnectTimer: + if (mTcpConnectTimerStarted) // Ignore timer if we went connected (note: when we connect we set mTcpConnectTimerStarted to false) + { + TransportFailure failure(mId, TransportFailure::ConnectionException); + processTransportFailure(&failure); + } + delete msg; + break; + case Timer::TimerB: if (mState == Calling) { - assert(mNextTransmission && mNextTransmission->isRequest() && + resip_assert(mNextTransmission && mNextTransmission->isRequest() && mNextTransmission->method()==INVITE); - if(mWaitingForDnsResult) + if(mPendingOperation == Dns) { WarningLog(<< "Transaction timed out while waiting for DNS " "result uri=" << @@ -1370,13 +1471,13 @@ TransactionState::processClientInvite(TransactionMessage* msg) case Timer::TimerCleanUp: // !ah! Cancelled Invite Cleanup Timer fired. - StackLog (<< "Timer::TimerCleanUp: " << *this << std::endl << *mNextTransmission); if (mState == Proceeding) { - assert(mNextTransmission && mNextTransmission->isRequest() && + resip_assert(mNextTransmission && mNextTransmission->isRequest() && mNextTransmission->method() == INVITE); + StackLog (<< "Timer::TimerCleanUp: " << *this << std::endl << *mNextTransmission); InfoLog(<<"Making 408 for canceled invite that received no response: "<< mNextTransmission->brief()); - if(mWaitingForDnsResult) + if(mPendingOperation == Dns) { WarningLog(<< "Transaction timed out while waiting for DNS " "result uri=" << @@ -1403,13 +1504,24 @@ TransactionState::processClientInvite(TransactionMessage* msg) processTransportFailure(msg); delete msg; } + else if (isTcpConnectState(msg)) + { + processTcpConnectState(msg); + delete msg; + } else if (isCancelClientTransaction(msg)) { + CancelClientInviteTransaction* pCancelMsg = dynamic_cast(msg); + // TU wants to CANCEL this transaction. See if we can... if(mState==Proceeding) { // We can send the CANCEL now. - SipMessage* cancel=Helper::makeCancel(*mNextTransmission); + SipMessage* cancel = Helper::makeCancel(*mNextTransmission); + if (pCancelMsg->getReasons()) + { + cancel->header(h_Reasons) = *pCancelMsg->getReasons(); + } mNextTransmission->copyOutboundDecoratorsToStackCancel(*cancel); TransactionState::handleInternalCancel(cancel, *this); } @@ -1417,6 +1529,7 @@ TransactionState::processClientInvite(TransactionMessage* msg) { // We can't send the CANCEL yet, remember to. mIsAbandoned = true; + setPendingCancelReasons(pCancelMsg->getReasons()); } delete msg; } @@ -1448,7 +1561,7 @@ TransactionState::processServerNonInvite(TransactionMessage* msg) { if(mIsAbandoned) { - assert(mState == Completed); + resip_assert(mState == Completed); mIsAbandoned=false; // put a 500 in mNextTransmission SipMessage* req = dynamic_cast(msg); @@ -1457,6 +1570,14 @@ TransactionState::processServerNonInvite(TransactionMessage* msg) } else { + // We have already sent a 100, but we have just received a retransmission. Requests + // likely crossed on the wire. We need to respond with another 100, but the last one was + // cleared so re-create the 100 now. + SipMessage* sip = dynamic_cast(msg); + if (sip && mMsgToRetransmit.empty() && !mNextTransmission) + { + resetNextTransmission(make100(sip)); + } sendCurrentToWire(); } delete msg; @@ -1466,7 +1587,7 @@ TransactionState::processServerNonInvite(TransactionMessage* msg) CritLog (<< "Fatal error in TransactionState::processServerNonInvite " << msg->brief() << " state=" << *this); - assert(0); + resip_assert(0); delete msg; return; } @@ -1521,7 +1642,7 @@ TransactionState::processServerNonInvite(TransactionMessage* msg) CritLog (<< "Fatal error in TransactionState::processServerNonInvite " << msg->brief() << " state=" << *this); - assert(0); + resip_assert(0); delete sip; return; } @@ -1536,7 +1657,7 @@ TransactionState::processServerNonInvite(TransactionMessage* msg) else if (isTimer(msg)) { TimerMessage* timer = dynamic_cast(msg); - assert(timer); + resip_assert(timer); switch (timer->getType()) { case Timer::TimerJ: @@ -1565,8 +1686,11 @@ TransactionState::processServerNonInvite(TransactionMessage* msg) } else if (isTransportError(msg)) { - processTransportFailure(msg); + // Failed to send response - transport has likely been removed + WarningLog (<< "Failed to send response to server transaction (transport was likely removed)." << *this); delete msg; + terminateServerTransaction(mId); + delete this; } else if (isAbandonServerTransaction(msg)) { @@ -1698,7 +1822,7 @@ TransactionState::processServerInvite(TransactionMessage* msg) break; case CANCEL: - assert(0); + resip_assert(0); delete sip; break; @@ -1805,7 +1929,7 @@ TransactionState::processServerInvite(TransactionMessage* msg) break; case CANCEL: - assert(0); + resip_assert(0); delete sip; break; @@ -1864,15 +1988,18 @@ TransactionState::processServerInvite(TransactionMessage* msg) default: CritLog(<<"unexpected timer fired: " << timer->getType()); - assert(0); // programming error if any other timer fires + resip_assert(0); // programming error if any other timer fires break; } delete timer; } else if (isTransportError(msg)) { - processTransportFailure(msg); + // Failed to send response - transport has likely been removed + WarningLog (<< "Failed to send response to server transaction (transport was likely removed)." << *this); delete msg; + terminateServerTransaction(mId); + delete this; } else if (isAbandonServerTransaction(msg)) { @@ -1883,8 +2010,8 @@ TransactionState::processServerInvite(TransactionMessage* msg) { mMsgToRetransmit.clear(); // hey, we had a 1xx laying around! Turn it into a 500 and send. - assert(mNextTransmission->isResponse()); - assert(mNextTransmission->const_header(h_StatusLine).statusCode()/100==1); + resip_assert(mNextTransmission->isResponse()); + resip_assert(mNextTransmission->const_header(h_StatusLine).statusCode()/100==1); mNextTransmission->header(h_StatusLine).statusCode()=500; mNextTransmission->header(h_StatusLine).reason()="Server Error"; sendCurrentToWire(); @@ -1958,7 +2085,7 @@ TransactionState::processClientStale(TransactionMessage* msg) } else if(isResponse(msg, 200, 299)) { - assert(isFromWire(msg)); + resip_assert(isFromWire(msg)); sendToTU(msg); } else if(dynamic_cast(msg)) @@ -2017,7 +2144,7 @@ TransactionState::processServerStale(TransactionMessage* msg) { // .bwc. We should never fall into this block. There is code in process // that should prevent it. - assert(isFromWire(msg)); + resip_assert(isFromWire(msg)); InfoLog (<< "Passing ACK directly to TU: " << sip->brief()); sendToTU(msg); } @@ -2057,7 +2184,6 @@ TransactionState::processServerStale(TransactionMessage* msg) } } - void TransactionState::processNoDnsResults() { @@ -2078,7 +2204,7 @@ TransactionState::processNoDnsResults() if(mDnsResult) { InfoLog (<< "Ran out of dns entries for " << mDnsResult->target() << ". Send 503"); - assert(mDnsResult->available() == DnsResult::Finished); + resip_assert(mDnsResult->available() == DnsResult::Finished); oDataStream warnText(warning.text()); warnText << "No other DNS entries to try (" << mFailureReason << "," << mFailureSubCode << ")"; @@ -2146,8 +2272,12 @@ void TransactionState::processTransportFailure(TransactionMessage* msg) { TransportFailure* failure = dynamic_cast(msg); - assert(failure); - assert(mState!=Bogus); + resip_assert(failure); + resip_assert(mState!=Bogus); + + // We come here if the tcp connect timer expires, so we reset the flag incase we are + // going to try another DNS entry that is also TCP. + mTcpConnectTimerStarted = false; // Store failure reasons if (failure->getFailureReason() > mFailureReason) @@ -2164,7 +2294,7 @@ TransactionState::processTransportFailure(TransactionMessage* msg) { WarningLog (<< "Failed to deliver a CANCEL request"); StackLog (<< *this); - assert(mMethod==CANCEL); + resip_assert(mMethod==CANCEL); // In the case of a client-initiated CANCEL, we don't want to // try other transports in the case of transport error as the @@ -2190,8 +2320,7 @@ TransactionState::processTransportFailure(TransactionMessage* msg) else if(mDnsResult) { // .bwc. Greylist for 32s - // !bwc! TODO make this duration configurable. - mDnsResult->greylistLast(Timer::getTimeMs()+32000); + mDnsResult->greylistLast(Timer::getTimeMs() + DnsGreylistDurationMs); // .bwc. We should only try multiple dns results if we are originating a // request. Additionally, there are (potential) cases where it would not @@ -2249,7 +2378,7 @@ TransactionState::processTransportFailure(TransactionMessage* msg) if(shouldFailover) { InfoLog (<< "Try sending request to a different dns result"); - assert(mMethod!=CANCEL); + resip_assert(mMethod!=CANCEL); switch (mDnsResult->available()) { @@ -2264,7 +2393,7 @@ TransactionState::processTransportFailure(TransactionMessage* msg) case DnsResult::Pending: InfoLog(<< "We have a DNS query pending."); - mWaitingForDnsResult=true; + mPendingOperation=Dns; restoreOriginalContactAndVia(); mMsgToRetransmit.clear(); break; @@ -2277,7 +2406,7 @@ TransactionState::processTransportFailure(TransactionMessage* msg) case DnsResult::Destroyed: default: InfoLog (<< "Bad state: " << *this); - assert(0); + resip_assert(0); } } else @@ -2288,6 +2417,27 @@ TransactionState::processTransportFailure(TransactionMessage* msg) } } +void +TransactionState::processTcpConnectState(TransactionMessage* msg) +{ + TcpConnectState* tcpConnectState = dynamic_cast(msg); + resip_assert(tcpConnectState); + + if (tcpConnectState->getState() == TcpConnectState::ConnectStarted && + !mTcpConnectTimerStarted && Timer::TcpConnectTimeout != 0 && + (mState == Trying || mState == Calling)) + { + // Start Timer + mController.mTimers.add(Timer::TcpConnectTimer, mId, Timer::TcpConnectTimeout); + mTcpConnectTimerStarted = true; + } + else if (tcpConnectState->getState() == TcpConnectState::Connected && + (mState == Trying || mState == Calling)) + { + mTcpConnectTimerStarted = false; + } +} + // called by DnsResult void TransactionState::rewriteRequest(const Uri& rewrite) @@ -2300,7 +2450,7 @@ TransactionState::rewriteRequest(const Uri& rewrite) // queue, and move all the code below into a function that handles that // message. - assert(mNextTransmission->isRequest()); + resip_assert(mNextTransmission->isRequest()); if (mNextTransmission->const_header(h_RequestLine).uri() != rewrite) { InfoLog (<< "Rewriting request-uri to " << rewrite); @@ -2320,29 +2470,28 @@ TransactionState::handle(DnsResult* result) } void -TransactionState::handleSync(DnsResult* result) +TransactionState::handleSync(DnsResult* result) // !slg! it is strange that we pass the result in here, then more or less ignore it in the method { StackLog (<< *this << " got DNS result: " << *result); // .bwc. Were we expecting something from mDnsResult? - if (mWaitingForDnsResult) + if (mPendingOperation == Dns) { - assert(mDnsResult); + resip_assert(mDnsResult); switch (mDnsResult->available()) { case DnsResult::Available: - mWaitingForDnsResult=false; + mPendingOperation=None; mTarget = mDnsResult->next(); - assert( mTarget.transport==0 ); - // below allows TU to which transport we send on + // below allows TU to know which transport we send on // (The Via mechanism for setting transport doesn't work for TLS) - mTarget.transport = mNextTransmission->getDestination().transport; + mTarget.mTransportKey = mNextTransmission->getDestination().mTransportKey; processReliability(mTarget.getType()); sendCurrentToWire(); break; case DnsResult::Finished: - mWaitingForDnsResult=false; + mPendingOperation=None; processNoDnsResults(); break; @@ -2351,7 +2500,7 @@ TransactionState::handleSync(DnsResult* result) case DnsResult::Destroyed: default: - assert(0); + resip_assert(0); break; } } @@ -2451,13 +2600,13 @@ TransactionState::sendCurrentToWire() else if(mNextTransmission) // initial transmission; need to determine target { SipMessage* sip=mNextTransmission; - bool transmitted=false; + TransportSelector::TransmitState transmitState = TransportSelector::Unsent; if(isClient()) { if(mTarget.getType() != UNKNOWN_TRANSPORT) // mTarget is set, so just send. { - transmitted=mController.mTransportSelector.transmit( + transmitState=mController.mTransportSelector.transmit( sip, mTarget, mIsReliable ? 0 : &mMsgToRetransmit); @@ -2467,14 +2616,14 @@ TransactionState::sendCurrentToWire() if (sip->getDestination().mFlowKey) //...but sip->getDestination() will work { // ?bwc? Maybe we should be nice to the TU and do DNS in this case? - assert(sip->getDestination().getType() != UNKNOWN_TRANSPORT); + resip_assert(sip->getDestination().getType() != UNKNOWN_TRANSPORT); // .bwc. We have the FlowKey. This completely specifies our // Transport (and Connection, if applicable). No DNS required. DebugLog(<< "Sending to tuple: " << sip->getDestination()); mTarget = sip->getDestination(); processReliability(mTarget.getType()); - transmitted=mController.mTransportSelector.transmit( + transmitState=mController.mTransportSelector.transmit( sip, mTarget, mIsReliable ? 0 : &mMsgToRetransmit); @@ -2484,10 +2633,10 @@ TransactionState::sendCurrentToWire() if(mDnsResult == 0) // ... and we haven't started a DNS query yet. { StackLog (<< "sendToWire with no dns result: " << *this); - assert(sip->isRequest()); - assert(mMethod!=CANCEL); // .bwc. mTarget should be set in this case. + resip_assert(sip->isRequest()); + resip_assert(mMethod!=CANCEL); // .bwc. mTarget should be set in this case. mDnsResult = mController.mTransportSelector.createDnsResult(this); - mWaitingForDnsResult=true; + mPendingOperation=Dns; mController.mTransportSelector.dnsResolve(mDnsResult, sip); } else // ... but our DNS query isn't done yet. @@ -2509,9 +2658,9 @@ TransactionState::sendCurrentToWire() } else // server transaction { - assert(mDnsResult == 0); - assert(sip->exists(h_Vias)); - assert(!sip->const_header(h_Vias).empty()); + resip_assert(mDnsResult == 0); + resip_assert(sip->exists(h_Vias)); + resip_assert(!sip->const_header(h_Vias).empty()); // .bwc. Code that tweaks mResponseTarget based on stuff in the SipMessage. // ?bwc? Why? @@ -2522,9 +2671,9 @@ TransactionState::sendCurrentToWire() // mResponseTarget here? I don't think this has been thought out properly. Tuple target = simpleTupleForUri(sip->getForceTarget()); StackLog(<<"!ah! response with force target going to : "<method(); - if(sip->isResponse()) - { - mCurrentResponseCode = sip->const_header(h_StatusLine).statusCode(); - } - - // !bwc! If mNextTransmission is a non-ACK request, we need to save the - // initial request in case we need to send a simulated 408 or a 503 to - // the TU (at least, until we get a response back) - if(!mNextTransmission->isRequest() || mNextTransmission->method()==ACK) - { - delete mNextTransmission; - mNextTransmission=0; - } + onSendSuccess(); } } else { - assert(0); + resip_assert(0); + } +} + +void +TransactionState::onSendSuccess() +{ + SipMessage* sip=mNextTransmission; + + if(mController.mStack.statisticsManagerEnabled()) + { + mController.mStatsManager.sent(sip); + } + + mCurrentMethodType = sip->method(); + if(sip->isResponse()) + { + mCurrentResponseCode = sip->const_header(h_StatusLine).statusCode(); + } + + // !bwc! If mNextTransmission is a non-ACK request, we need to save the + // initial request in case we need to send a simulated 408 or a 503 to + // the TU (at least, until we get a response back) + if(!mNextTransmission->isRequest() || mNextTransmission->method()==ACK) + { + delete mNextTransmission; + mNextTransmission=0; } } @@ -2605,13 +2762,10 @@ TransactionState::sendToTU(TransactionMessage* msg) break; case 408: - if(sipMsg->getReceivedTransport() == 0 && - (mState == Trying || mState==Calling)) // only greylist if internally generated and we haven't received any responses yet + if(!sipMsg->isFromWire() && (mState == Trying || mState==Calling)) // only greylist if internally generated and we haven't received any responses yet { // greylist last target. - // ?bwc? How long do we greylist this for? Probably should make - // this configurable. TODO - mDnsResult->greylistLast(resip::Timer::getTimeMs() + 32000); + mDnsResult->greylistLast(resip::Timer::getTimeMs() + DnsGreylistDurationMs); } break; @@ -2629,7 +2783,7 @@ TransactionState::sendToTU(TransactionMessage* msg) { if(sipMsg) { - assert(sipMsg->isExternal()); + resip_assert(sipMsg->isExternal()); if(sipMsg->isRequest()) { // .bwc. This could be an initial request, or an ACK/200. @@ -2783,6 +2937,12 @@ TransactionState::isTransportError(TransactionMessage* msg) const return dynamic_cast(msg) != 0; } +bool +TransactionState::isTcpConnectState(TransactionMessage* msg) const +{ + return dynamic_cast(msg) != 0; +} + bool TransactionState::isAbandonServerTransaction(TransactionMessage* msg) const { @@ -2799,9 +2959,9 @@ TransactionState::isCancelClientTransaction(TransactionMessage* msg) const const Data& TransactionState::tid(SipMessage* sip) const { - assert(0); - assert (mMachine != Stateless || (mMachine == Stateless && !mId.empty())); - assert (mMachine == Stateless || (mMachine != Stateless && sip)); + resip_assert(0); + resip_assert (mMachine != Stateless || (mMachine == Stateless && !mId.empty())); + resip_assert (mMachine == Stateless || (mMachine != Stateless && sip)); return (mId.empty() && sip) ? sip->getTransactionId() : mId; } @@ -2844,7 +3004,7 @@ TransactionState::isClient() const case ServerStale: return false; default: - assert(0); + resip_assert(0); } return false; } diff --git a/src/libs/resiprocate/resip/stack/TransactionState.hxx b/src/libs/resiprocate/resip/stack/TransactionState.hxx index 2caa86a8..4b69f196 100644 --- a/src/libs/resiprocate/resip/stack/TransactionState.hxx +++ b/src/libs/resiprocate/resip/stack/TransactionState.hxx @@ -30,6 +30,9 @@ class TransactionState : public DnsHandler { public: RESIP_HeapCount(TransactionState); + + static UInt64 DnsGreylistDurationMs; // The amount of time to greylist a DNS entry for after receiving a transport error + static void process(TransactionController& controller, TransactionMessage* message); static void processTimer(TransactionController& controller, @@ -59,6 +62,12 @@ class TransactionState : public DnsHandler Bogus } State; + typedef enum + { + None, + Dns + } PendingOperation; + TransactionState(TransactionController& controller, Machine m, State s, @@ -79,6 +88,7 @@ class TransactionState : public DnsHandler void processClientStale(TransactionMessage* msg); void processServerStale(TransactionMessage* msg); void processTransportFailure(TransactionMessage* failure); + void processTcpConnectState(TransactionMessage* msg); void processNoDnsResults(); void processReliability(TransportType type); @@ -94,6 +104,7 @@ class TransactionState : public DnsHandler bool isFromTU(TransactionMessage* msg) const; bool isFromWire(TransactionMessage* msg) const; bool isTransportError(TransactionMessage* msg) const; + bool isTcpConnectState(TransactionMessage* msg) const; bool isSentReliable(TransactionMessage* msg) const; bool isSentUnreliable(TransactionMessage* msg) const; bool isReliabilityIndication(TransactionMessage* msg) const; @@ -103,6 +114,7 @@ class TransactionState : public DnsHandler void sendToTU(TransactionMessage* msg); static void sendToTU(TransactionUser* tu, TransactionController& controller, TransactionMessage* msg); void sendCurrentToWire(); + void onSendSuccess(); SipMessage* make100(SipMessage* request) const; void terminateClientTransaction(const Data& tid); void terminateServerTransaction(const Data& tid); @@ -139,6 +151,8 @@ class TransactionState : public DnsHandler Machine mMachine; State mState; bool mIsAbandoned; // TU doesn't care about this transaction anymore. + Tokens* mPendingCancelReasons; // Using a pointer to keep storage to a minimum when not needed + void setPendingCancelReasons(const Tokens* reasons); // Indicates that the message has been sent with a reliable protocol. Set // by the TransportSelector @@ -161,9 +175,9 @@ class TransactionState : public DnsHandler Tuple mResponseTarget; // used to reply to requests // used when the DnsResult moves to another transport on failure. Only - // used for outgoing stateful, so unique_ptr for space efficiency. - std::unique_ptr mOriginalContact; - std::unique_ptr mOriginalVia; + // used for outgoing stateful, so auto_ptr for space efficiency. + std::auto_ptr mOriginalContact; + std::auto_ptr mOriginalVia; const Data mId; const MethodTypes mMethod; @@ -174,12 +188,13 @@ class TransactionState : public DnsHandler unsigned int mCurrentResponseCode; bool mAckIsValid; - bool mWaitingForDnsResult; + PendingOperation mPendingOperation; TransactionUser* mTransactionUser; TransportFailure::FailureReason mFailureReason; int mFailureSubCode; + bool mTcpConnectTimerStarted; - static unsigned long StatelessIdCounter; + static UInt32 StatelessIdCounter; friend EncodeStream& operator<<(EncodeStream& strm, const TransactionState& state); friend class TransactionController; diff --git a/src/libs/resiprocate/resip/stack/TransactionUser.cxx b/src/libs/resiprocate/resip/stack/TransactionUser.cxx index ce30b49b..b19b4058 100644 --- a/src/libs/resiprocate/resip/stack/TransactionUser.cxx +++ b/src/libs/resiprocate/resip/stack/TransactionUser.cxx @@ -1,3 +1,4 @@ +#include "resip/stack/BasicDomainMatcher.hxx" #include "resip/stack/TransactionUser.hxx" #include "resip/stack/MessageFilterRule.hxx" #include "rutil/Logger.hxx" @@ -13,7 +14,7 @@ TransactionUser::TransactionUser(TransactionTermination t, mFifo(0, 0), mCongestionManager(0), mRuleList(), - mDomainList(), + mDomainMatcher(new BasicDomainMatcher()), mRegisteredForTransactionTermination(t == RegisterForTransactionTermination), mRegisteredForConnectionTermination(c == RegisterForConnectionTermination), mRegisteredForKeepAlivePongs(k == RegisterForKeepAlivePongs) @@ -34,7 +35,7 @@ TransactionUser::TransactionUser(MessageFilterRuleList &mfrl, mFifo(0, 0), mCongestionManager(0), mRuleList(mfrl), - mDomainList(), + mDomainMatcher(new BasicDomainMatcher()), mRegisteredForTransactionTermination(t == RegisterForTransactionTermination), mRegisteredForConnectionTermination(c == RegisterForConnectionTermination), mRegisteredForKeepAlivePongs(k == RegisterForKeepAlivePongs) @@ -76,33 +77,43 @@ TransactionUser::wouldAccept(TimeLimitFifo::DepthUsage usage) const bool TransactionUser::isForMe(const SipMessage& msg) const { - DebugLog (<< "Checking if " << msg.brief() << " is for me"); // do this for each MessageFilterRule for (MessageFilterRuleList::const_iterator i = mRuleList.begin() ; i != mRuleList.end() ; ++i) { - DebugLog (<< "Checking rule..."); + DebugLog(<< "TransactionUser::isForMe: TU=" << name() << ", Checking rule... : " << msg.brief()); if (i->matches(msg)) { - DebugLog (<< "Match!"); + DebugLog(<< "TransactionUser::isForMe: TU=" << name() << ", Match! : " << msg.brief()); return true; } } - DebugLog (<< "No matching rule found"); + DebugLog(<< "TransactionUser::isForMe: TU=" << name() << ", No matching rule found : " << msg.brief()); return false; } bool TransactionUser::isMyDomain(const Data& domain) const { - // Domain search should be case insensitive - search in lowercase only - return mDomainList.count(Data(domain).lowercase()) > 0; + return mDomainMatcher->isMyDomain(domain); } -void TransactionUser::addDomain(const Data& domain) +void +TransactionUser::addDomain(const Data& domain) { - // Domain search should be case insensitive - store in lowercase only - mDomainList.insert(Data(domain).lowercase()); + mDomainMatcher->addDomain(domain); +} + +void +TransactionUser::removeDomain(const Data& domain) +{ + mDomainMatcher->removeDomain(domain); +} + +void +TransactionUser::setDomainMatcher(SharedPtr domainMatcher) +{ + mDomainMatcher = domainMatcher; } EncodeStream& diff --git a/src/libs/resiprocate/resip/stack/TransactionUser.hxx b/src/libs/resiprocate/resip/stack/TransactionUser.hxx index e40a2bf7..f306b154 100644 --- a/src/libs/resiprocate/resip/stack/TransactionUser.hxx +++ b/src/libs/resiprocate/resip/stack/TransactionUser.hxx @@ -6,6 +6,7 @@ #include "rutil/TimeLimitFifo.hxx" #include "rutil/Data.hxx" #include "rutil/CongestionManager.hxx" +#include "resip/stack/DomainMatcher.hxx" #include "resip/stack/Message.hxx" #include "resip/stack/MessageFilterRule.hxx" @@ -71,9 +72,37 @@ class TransactionUser @note The comparison performed is case-sensitive; make sure you lower-case everything you put in here. @todo Make this case-insensitive. - */ + @warning This method is NOT thread-safe. mDomainList is accessed from both the + thread that queues to the TU (iff a DomainIsMe MessageFilterRule is used) + and from within the TU itself. The only way calling this is safe, is if you + can ensure both of these threads are not calling isMyDomain when you call + this method. For example an application that does NOT use a DomainIsMe + MessageFilterRule and that posts the addDomain call to the TU processing + thread for execution there, will be thread safe. This API is also safe to call + before any of the processing threads have been started. + */ void addDomain(const Data& domain); + /** + @brief Removes a domain from the set of domains that this TransactionUser is + responsible for. + @note This API will lowercase the domain when searching for the domain to + remove + @warning This method is NOT thread-safe. mDomainList is accessed from both the + thread that queues to the TU (iff a DomainIsMe MessageFilterRule is used) + and from within the TU itself. The only way calling this is safe, is if you + can ensure both of these threads are not calling isMyDomain when you call + this method. For example an application that does NOT use a DomainIsMe + MessageFilterRule and that posts the removeDomain call to the TU processing + thread (ie: DUMThread) for execution there, will be thread safe. + */ + void removeDomain(const Data& domain); + + /** + @brief Replaces the default DomainMatcher + */ + void setDomainMatcher(SharedPtr domainMatcher); + /** @brief Return the name of this TransactionUser. Used in encode(). @return The name of this TransactionUser, as a Data. @@ -136,6 +165,8 @@ class TransactionUser mCongestionManager->registerFifo(&mFifo); } } + + const TimeLimitFifo* getFifo() { return(&mFifo); } const virtual UInt16 getExpectedWait() const { @@ -228,8 +259,7 @@ class TransactionUser private: MessageFilterRuleList mRuleList; - typedef std::set DomainList; - DomainList mDomainList; + SharedPtr mDomainMatcher; bool mRegisteredForTransactionTermination; bool mRegisteredForConnectionTermination; bool mRegisteredForKeepAlivePongs; diff --git a/src/libs/resiprocate/resip/stack/TransactionUserMessage.cxx b/src/libs/resiprocate/resip/stack/TransactionUserMessage.cxx index 9823900e..bc3d4c22 100644 --- a/src/libs/resiprocate/resip/stack/TransactionUserMessage.cxx +++ b/src/libs/resiprocate/resip/stack/TransactionUserMessage.cxx @@ -6,7 +6,7 @@ TransactionUserMessage::TransactionUserMessage(Type type, TransactionUser* ptu) mType(type) { mTu = ptu; - assert(mTu); + resip_assert(mTu); } EncodeStream& @@ -24,14 +24,14 @@ TransactionUserMessage::encodeBrief(EncodeStream& str) const const Data& TransactionUserMessage::getTransactionId() const { - assert(0); + resip_assert(0); return Data::Empty; } bool TransactionUserMessage::isClientTransaction() const { - assert(0); + resip_assert(0); return false; } diff --git a/src/libs/resiprocate/resip/stack/Transport.cxx b/src/libs/resiprocate/resip/stack/Transport.cxx index 8dab9e05..f3d83fdf 100644 --- a/src/libs/resiprocate/resip/stack/Transport.cxx +++ b/src/libs/resiprocate/resip/stack/Transport.cxx @@ -38,8 +38,6 @@ Transport::Transport(Fifo& rxFifo, AfterSocketCreationFuncPtr socketFunc, Compression &compression) : mTuple(address), - mHasRecordRoute(false), - mKey(0), mCongestionManager(0), mStateMachineFifo(rxFifo, 8), mShuttingDown(false), @@ -48,8 +46,11 @@ Transport::Transport(Fifo& rxFifo, mCompression(compression), mTransportFlags(0) { +#ifdef USE_NETNS + // Needs to be implemented for NETNS + resip_assert(0); +#endif mInterface = Tuple::inet_ntop(mTuple); - mConnectionsDeleted = 0; } Transport::Transport(Fifo& rxFifo, @@ -59,11 +60,10 @@ Transport::Transport(Fifo& rxFifo, const Data& tlsDomain, AfterSocketCreationFuncPtr socketFunc, Compression &compression, - unsigned transportFlags) : + unsigned transportFlags, + const Data& netNs) : mInterface(intfc), - mTuple(intfc, portNum, version), - mHasRecordRoute(false), - mKey(0), + mTuple(intfc, portNum, version, UNKNOWN_TRANSPORT, Data::Empty, netNs), mCongestionManager(0), mStateMachineFifo(rxFifo,8), mShuttingDown(false), @@ -72,13 +72,17 @@ Transport::Transport(Fifo& rxFifo, mCompression(compression), mTransportFlags(transportFlags) { - mConnectionsDeleted = 0; } Transport::~Transport() { } +void +Transport::onReload() +{ +} + void Transport::error(int e) { @@ -224,11 +228,20 @@ Transport::fail(const Data& tid, TransportFailure::FailureReason reason, int sub } } -std::unique_ptr +void +Transport::setTcpConnectState(const Data& tid, TcpConnectState::State state) +{ + if (!tid.empty()) + { + mStateMachineFifo.add(new TcpConnectState(tid, state)); + } +} + +std::auto_ptr Transport::makeSendData( const Tuple& dest, const Data& d, const Data& tid, const Data &sigcompId) { - assert(dest.getPort() != -1); - std::unique_ptr data(new SendData(dest, d, tid, sigcompId)); + resip_assert(dest.getPort() != -1); + std::auto_ptr data(new SendData(dest, d, tid, sigcompId)); return data; } @@ -241,7 +254,7 @@ Transport::makeFailedResponse(const SipMessage& msg, const Tuple& dest = msg.getSource(); - std::unique_ptr errMsg(Helper::makeResponse(msg, + std::auto_ptr errMsg(Helper::makeResponse(msg, responseCode, warning ? warning : "Original request had no Vias")); @@ -252,20 +265,20 @@ Transport::makeFailedResponse(const SipMessage& msg, DataStream encodeStream(encoded); errMsg->encode(encodeStream); encodeStream.flush(); - assert(!encoded.empty()); + resip_assert(!encoded.empty()); InfoLog(<<"Sending response directly to " << dest << " : " << errMsg->brief() ); // Calculate compartment ID for outbound message Data remoteSigcompId; setRemoteSigcompId(*errMsg,remoteSigcompId); - send(std::unique_ptr(makeSendData(dest, encoded, Data::Empty, remoteSigcompId))); + send(std::auto_ptr(makeSendData(dest, encoded, Data::Empty, remoteSigcompId))); } -std::unique_ptr +std::auto_ptr Transport::make503(SipMessage& msg, UInt16 retryAfter) { - std::unique_ptr result; + std::auto_ptr result; if (msg.isResponse()) return result; try @@ -296,10 +309,10 @@ Transport::make503(SipMessage& msg, UInt16 retryAfter) return result; } -std::unique_ptr +std::auto_ptr Transport::make100(SipMessage& msg) { - std::unique_ptr result; + std::auto_ptr result; if (msg.isResponse()) return result; try @@ -371,7 +384,7 @@ Transport::stampReceived(SipMessage* message) { const Tuple& tuple = message->getSource(); Data received = Tuple::inet_ntop(tuple); - if(message->const_header(h_Vias).front().sentHost() != received) // only add if received address is different from sent-by in Via + if(message->const_header(h_Vias).front().sentHost() != received) // only add if received address is different from sent-by in Via { message->header(h_Vias).front().param(p_received) = received; } @@ -385,7 +398,6 @@ Transport::stampReceived(SipMessage* message) StackLog (<< endl << endl << *message); } - bool Transport::basicCheck(const SipMessage& msg) { @@ -433,11 +445,16 @@ Transport::callSocketFunc(Socket sock) } void -Transport::pushRxMsgUp(TransactionMessage* msg) +Transport::pushRxMsgUp(SipMessage* message) { - mStateMachineFifo.add(msg); -} + SipMessageLoggingHandler* handler = getSipMessageLoggingHandler(); + if(handler) + { + handler->inboundMessage(message->getSource(), message->getReceivedTransportTuple(), *message); + } + mStateMachineFifo.add(message); +} bool Transport::operator==(const Transport& rhs) const @@ -455,23 +472,6 @@ resip::operator<<(EncodeStream& strm, const resip::Transport& rhs) return strm; } -int -Transport::getConnectionsDeleted() const -{ - return mConnectionsDeleted; -} - -void -Transport::resetConnectionsDeleted() -{ - mConnectionsDeleted = 0; -} - -void Transport::increaseConnectionsDeleted() -{ - mConnectionsDeleted++; -} - /* ==================================================================== * The Vovida Software License, Version 1.0 * diff --git a/src/libs/resiprocate/resip/stack/Transport.hxx b/src/libs/resiprocate/resip/stack/Transport.hxx index 0ff6d0b7..d2639f25 100644 --- a/src/libs/resiprocate/resip/stack/Transport.hxx +++ b/src/libs/resiprocate/resip/stack/Transport.hxx @@ -6,11 +6,12 @@ #include "rutil/FdSetIOObserver.hxx" #include "rutil/ProducerFifoBuffer.hxx" #include "resip/stack/TransportFailure.hxx" +#include "resip/stack/TcpConnectState.hxx" #include "resip/stack/Tuple.hxx" #include "resip/stack/NameAddr.hxx" #include "resip/stack/Compression.hxx" #include "resip/stack/SendData.hxx" - +#include "rutil/SharedPtr.hxx" namespace resip { @@ -73,7 +74,21 @@ class Transport : public FdSetIOObserver { public: - + class SipMessageLoggingHandler + { + public: + virtual ~SipMessageLoggingHandler(){} + virtual void outboundMessage(const Tuple &source, const Tuple &destination, const SipMessage &msg) = 0; + // Note: retranmissions store already encoded messages, so callback doesn't send SipMessage it sends + // the encoded version of the SipMessage instead. If you need a SipMessage you will need to + // re-parse back into a SipMessage in the callback handler. + virtual void outboundRetransmit(const Tuple &source, const Tuple &destination, const SendData &data) {} + virtual void inboundMessage(const Tuple& source, const Tuple& destination, const SipMessage &msg) = 0; + }; + + void setSipMessageLoggingHandler(SharedPtr handler) { mSipMessageLoggingHandler = handler; } + SipMessageLoggingHandler* getSipMessageLoggingHandler() { return 0 != mSipMessageLoggingHandler.get() ? mSipMessageLoggingHandler.get() : 0; } + /** @brief General exception class for Transport. @@ -132,11 +147,13 @@ class Transport : public FdSetIOObserver const Data& tlsDomain = Data::Empty, AfterSocketCreationFuncPtr socketFunc = 0, Compression &compression = Compression::Disabled, - unsigned transportFlags = 0 - ); + unsigned transportFlags = 0, + const Data& netNs = Data::Empty); virtual ~Transport(); + virtual void onReload(); + /** @note Subclasses override this method by checking whether there are unprocessed messages on the TransactionMessage @@ -144,7 +161,7 @@ class Transport : public FdSetIOObserver */ virtual bool isFinished() const=0; - std::unique_ptr makeSendData( const Tuple& tuple, const Data& data, const Data& tid, const Data &sigcompId = Data::Empty); + std::auto_ptr makeSendData( const Tuple& tuple, const Data& data, const Data& tid, const Data &sigcompId = Data::Empty); /** @todo !bwc! What we do with a SendData is flexible. It might make a @@ -154,7 +171,7 @@ class Transport : public FdSetIOObserver @todo !bch! Should this be protected and not public? !bwc! TransportSelector uses this directly for retransmissions. */ - virtual void send(std::unique_ptr data)=0; + virtual void send(std::auto_ptr data)=0; /** Called when a writer is done adding messages to the TxFifo; this is @@ -212,6 +229,11 @@ class Transport : public FdSetIOObserver TransportFailure::FailureReason reason = TransportFailure::Failure, int subCode = 0); + /** + Posts a TcpConnectState to the TransactionMessage Fifo. + */ + void setTcpConnectState(const Data& tid, TcpConnectState::State state); + /** Generates a generic log for the platform specific socket error number. @@ -240,10 +262,13 @@ class Transport : public FdSetIOObserver const Tuple& getTuple() const { return mTuple; } /// @return This transport's TransportType. - virtual TransportType transport() const =0 ; + const TransportType transport() const { return mTuple.getType(); } virtual bool isReliable() const =0; virtual bool isDatagram() const =0; + /// @return net namespace in which Transport is bound + const Data& netNs() const { return(mTuple.getNetNs()); } + /** @return true here if the subclass has a specific contact value that it wishes the TransportSelector to use. @@ -263,10 +288,10 @@ class Transport : public FdSetIOObserver void makeFailedResponse(const SipMessage& msg, int responseCode = 400, const char * warning = 0); - std::unique_ptr make503(SipMessage& msg, + std::auto_ptr make503(SipMessage& msg, UInt16 retryAfter); - std::unique_ptr make100(SipMessage& msg); + std::auto_ptr make100(SipMessage& msg); void setRemoteSigcompId(SipMessage&msg, Data& id); // mark the received= and rport parameters if necessary static void stampReceived(SipMessage* request); @@ -312,6 +337,7 @@ class Transport : public FdSetIOObserver // !jf! should use the fifo to pass this in mShuttingDown = true; } + virtual bool isShuttingDown() { return mShuttingDown; } // also used by the TransportSelector. // requires that the two transports be @@ -321,6 +347,7 @@ class Transport : public FdSetIOObserver virtual unsigned int getFifoSize() const=0; void callSocketFunc(Socket sock); + virtual void invokeAfterSocketCreationFunc() const = 0; //used to invoke the after socket creation func immeidately for all existing sockets - can be used to modify QOS settings at runtime virtual void setCongestionManager(CongestionManager* manager) { @@ -336,40 +363,29 @@ class Transport : public FdSetIOObserver return CongestionManager::NORMAL; } + void flushStateMacFifo() + { + mStateMachineFifo.flush(); + } + UInt32 getExpectedWaitForIncoming() const { return (UInt32)mStateMachineFifo.getFifo().expectedWaitTimeMilliSec()/1000; } // called by Connection to deliver a received message - virtual void pushRxMsgUp(TransactionMessage* msg); + virtual void pushRxMsgUp(SipMessage* msg); // set the receive buffer length (SO_RCVBUF) virtual void setRcvBufLen(int buflen) { }; // make pure? - // Storing and retrieving transport specific record-route header - virtual void setRecordRoute(const NameAddr& recordRoute) { mRecordRoute = recordRoute; mHasRecordRoute = true; } - virtual bool hasRecordRoute() const { return mHasRecordRoute; } - virtual const NameAddr& getRecordRoute() const { assert(mHasRecordRoute); return mRecordRoute; } - - inline unsigned int getKey() const {return mKey;} - - int getConnectionsDeleted() const; - void resetConnectionsDeleted(); - void increaseConnectionsDeleted(); + inline unsigned int getKey() const {return mTuple.mTransportKey;} + inline void setKey(unsigned int pKey) { mTuple.mTransportKey = pKey;} // should only be called once after creation protected: - friend class TransportSelector; - inline void setKey(unsigned int pKey) { mKey = pKey;} Data mInterface; Tuple mTuple; - NameAddr mRecordRoute; - bool mHasRecordRoute; - unsigned int mKey; - - /** Number of connections delete in last processFdSet() call */ - int mConnectionsDeleted; CongestionManager* mCongestionManager; ProducerFifoBuffer mStateMachineFifo; // passed in @@ -381,6 +397,8 @@ class Transport : public FdSetIOObserver friend EncodeStream& operator<<(EncodeStream& strm, const Transport& rhs); Data mTlsDomain; + SharedPtr mSipMessageLoggingHandler; + protected: AfterSocketCreationFuncPtr mSocketFunc; Compression &mCompression; diff --git a/src/libs/resiprocate/resip/stack/TransportSelector.cxx b/src/libs/resiprocate/resip/stack/TransportSelector.cxx index 9224446d..4a3d5c48 100644 --- a/src/libs/resiprocate/resip/stack/TransportSelector.cxx +++ b/src/libs/resiprocate/resip/stack/TransportSelector.cxx @@ -26,6 +26,7 @@ #include "resip/stack/TcpBaseTransport.hxx" #include "resip/stack/TcpTransport.hxx" #include "resip/stack/UdpTransport.hxx" +#include "resip/stack/WsTransport.hxx" #include "resip/stack/Uri.hxx" #include "rutil/DataStream.hxx" @@ -36,7 +37,9 @@ #include "rutil/FdPoll.hxx" #include "rutil/WinLeakCheck.hxx" #include "rutil/dns/DnsStub.hxx" - +#ifdef USE_NETNS +# include "rutil/NetNs.hxx" +#endif #ifdef USE_SIGCOMP #include #include @@ -46,6 +49,7 @@ #include "resip/stack/ssl/DtlsTransport.hxx" #include "resip/stack/ssl/Security.hxx" #include "resip/stack/ssl/TlsTransport.hxx" +#include "resip/stack/ssl/WssTransport.hxx" #endif #ifdef WIN32 @@ -62,12 +66,10 @@ using namespace resip; #define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT -TransportSelector::TransportSelector(Fifo& fifo, Security* security, DnsStub& dnsStub, Compression &compression) : - mDns(dnsStub), +TransportSelector::TransportSelector(Fifo& fifo, Security* security, DnsStub& dnsStub, Compression &compression, bool useDnsVip) : + mDns(dnsStub, useDnsVip), mStateMacFifo(fifo), mSecurity(security), - mSocket( INVALID_SOCKET ), - mSocket6( INVALID_SOCKET ), mCompression(compression), mSigcompStack (0), mPollGrp(0), @@ -108,19 +110,33 @@ TransportSelector::~TransportSelector() mSharedProcessTransports.clear(); mHasOwnProcessTransports.clear(); mTypeToTransportMap.clear(); - while(!mTransports.empty()) + for(TransportKeyMap::iterator it = mTransports.begin(); it != mTransports.end(); it++) { - delete mTransports.back(); - mTransports.pop_back(); + delete it->second; } #ifdef USE_SIGCOMP delete mSigcompStack; #endif - if ( mSocket != INVALID_SOCKET ) - closeSocket( mSocket ); - if ( mSocket6 != INVALID_SOCKET ) - closeSocket( mSocket6 ); + for(HashMap::iterator socketIterator = mSockets.begin(); + socketIterator != mSockets.end(); socketIterator++) + { + if (socketIterator->second != INVALID_SOCKET) + { + closeSocket(socketIterator->second); + DebugLog(<< "Closing TransportSelector::mSocket[" << socketIterator->first << "]"); + } + } + + for(HashMap::iterator socketIterator = mSocket6s.begin(); + socketIterator != mSocket6s.end(); socketIterator++) + { + if (socketIterator->second != INVALID_SOCKET) + { + closeSocket(socketIterator->second); + DebugLog(<< "Closing TransportSelector::mSocket6[" << socketIterator->first << "]"); + } + } setPollGrp(0); } @@ -128,100 +144,80 @@ TransportSelector::~TransportSelector() void TransportSelector::shutdown() { - //!dcm! repeat shutdown template pattern in all loop over all transport functions, refactor to functor? - for (ExactTupleMap::iterator i=mExactTransports.begin(); i!=mExactTransports.end(); ++i) + for(TransportKeyMap::iterator it = mTransports.begin(); it != mTransports.end(); it++) { - i->second->shutdown(); - } - for (AnyInterfaceTupleMap::iterator i=mAnyInterfaceTransports.begin(); i!=mAnyInterfaceTransports.end(); ++i) - { - i->second->shutdown(); - } - for (TlsTransportMap::iterator i=mTlsTransports.begin(); i!=mTlsTransports.end(); ++i) - { - i->second->shutdown(); + it->second->shutdown(); } } bool TransportSelector::isFinished() const { - for (ExactTupleMap::const_iterator i=mExactTransports.begin(); i!=mExactTransports.end(); ++i) + for(TransportKeyMap::const_iterator it = mTransports.begin(); it != mTransports.end(); it++) { - if (!i->second->isFinished()) return false; - } - for (AnyInterfaceTupleMap::const_iterator i=mAnyInterfaceTransports.begin(); i!=mAnyInterfaceTransports.end(); ++i) - { - if (!i->second->isFinished()) return false; - } - for (TlsTransportMap::const_iterator i=mTlsTransports.begin(); i!=mTlsTransports.end(); ++i) - { - if (!i->second->isFinished()) return false; + if (!it->second->isFinished()) + { + return false; + } } return true; } void -TransportSelector::addTransport(std::unique_ptr autoTransport, - bool immediate) -{ - if(immediate) - { - addTransportInternal(std::move(autoTransport)); - } - else - { - mTransportsToAdd.add(autoTransport.release()); - } -} - -void -TransportSelector::addTransportInternal(std::unique_ptr autoTransport) +TransportSelector::addTransport(std::auto_ptr autoTransport, bool isStackRunning) { Transport* transport = autoTransport.release(); - mDns.addTransportType(transport->transport(), transport->ipVersion()); // !bwc! This is a multimap from TransportType/IpVersion to Transport*. // Make _extra_ sure that no garbage goes in here. if(transport->transport()==TCP) { - assert(dynamic_cast(transport)); + resip_assert(dynamic_cast(transport)); } #ifdef USE_SSL else if(transport->transport()==TLS) { - assert(dynamic_cast(transport)); + resip_assert(dynamic_cast(transport)); } #endif else if(transport->transport()==UDP) { - assert(dynamic_cast(transport)); + resip_assert(dynamic_cast(transport)); } #ifdef USE_DTLS #ifdef USE_SSL else if(transport->transport()==DTLS) { - assert(dynamic_cast(transport)); + resip_assert(dynamic_cast(transport)); } #endif +#endif + else if(transport->transport()==WS) + { + resip_assert(dynamic_cast(transport)); + } +#ifdef USE_SSL + else if(transport->transport()==WSS) + { + resip_assert(dynamic_cast(transport)); + } #endif else { - assert(0); + resip_assert(0); } Tuple tuple(transport->interfaceName(), transport->port(), - transport->ipVersion(), transport->transport()); - mTypeToTransportMap.insert(TypeToTransportMap::value_type(tuple,transport)); + transport->ipVersion(), transport->transport(), + Data::Empty, // Domain + transport->netNs()); + tuple.mTransportKey = transport->getKey(); - switch (transport->transport()) + if(!isSecure(transport->transport())) { - case UDP: - case TCP: + if(mExactTransports.find(tuple) == mExactTransports.end() && + mAnyInterfaceTransports.find(tuple) == mAnyInterfaceTransports.end()) { - assert(mExactTransports.find(tuple) == mExactTransports.end() && - mAnyInterfaceTransports.find(tuple) == mAnyInterfaceTransports.end()); - DebugLog (<< "Adding transport: " << tuple); // Store the transport in the ANY interface maps if the tuple specifies ANY @@ -240,17 +236,27 @@ TransportSelector::addTransportInternal(std::unique_ptr autoTransport mAnyPortTransports[tuple] = transport; } } - break; - case TLS: - case DTLS: + else { - TlsTransportKey key(transport->tlsDomain(),transport->transport(),transport->ipVersion()); - mTlsTransports[key]=transport; + WarningLog (<< "Can't add transport, overlapping properties with existing transport: " << tuple); + resip_assert(false); // should never get here - checked in SipStack first + return; + } + } + else + { + tuple.setTargetDomain(transport->tlsDomain()); + TlsTransportKey key(tuple); + if(mTlsTransports.find(key) == mTlsTransports.end()) + { + mTlsTransports[key] = transport; + } + else + { + WarningLog (<< "Can't add transport, overlapping properties with existing transport: " << tuple); + resip_assert(false); // should never get here - checked in SipStack first + return; } - break; - default: - assert(0); - break; } if (transport->shareStackProcessAndSelect()) @@ -259,7 +265,20 @@ TransportSelector::addTransportInternal(std::unique_ptr autoTransport { transport->setPollGrp(mPollGrp); } - mSharedProcessTransports.push_back(transport); + if(isStackRunning) + { + // When stack is running we need to add to mSharedProcessTransports from + // within TransportSelectorThread in order to be thread safe + mTransportsToAddRemove.add(transport); + } + else + { + // Stack isn't running yet - just add to mSharedProcess directly - this + // ensures the mSharedProcessTransports list is propulated when the stack + // starts to run. When in multi-threaded stack mode the TransportSelectorThread + // will assume ownership (FdPollGrp control) of all the transports using this list. + mSharedProcessTransports.push_back(transport); + } } else { @@ -267,8 +286,122 @@ TransportSelector::addTransportInternal(std::unique_ptr autoTransport mHasOwnProcessTransports.back()->startOwnProcessing(); } - mTransports.push_back(transport); - transport->setKey((unsigned int)mTransports.size()); + mTypeToTransportMap.insert(TypeToTransportMap::value_type(tuple,transport)); + mDns.addTransportType(transport->transport(), transport->ipVersion()); + mTransports[transport->getKey()] = transport; + + InfoLog(<< "TransportSelector::addTransport: added transport for tuple=" << tuple << ", key=" << transport->getKey()); +} + +void +TransportSelector::removeTransport(unsigned int transportKey) +{ + Transport* transportToRemove = 0; + + // Find transport in global map and remove it + // Note: it is important that this map is removed from before rebuildAnyPortTransportMaps is called, + // since rebuildAnyPortTransportMaps uses this map. + TransportKeyMap::iterator it = mTransports.find(transportKey); + if(it != mTransports.end()) + { + transportToRemove = it->second; + mTransports.erase(it); + } + + // If we found the transport - continue removal from other maps + if(transportToRemove) + { + // notify transport to shutdown + transportToRemove->shutdown(); + + if(!isSecure(transportToRemove->transport())) + { + // Ensure transport is removed from all containers + mExactTransports.erase(transportToRemove->getTuple()); + mAnyInterfaceTransports.erase(transportToRemove->getTuple()); + + // In the AnyPort maps 2 transports can end up overwriting each other in these maps - then when we remove one, there may be none left - even though we should have an + // entry. The rebuilt method will dig through all transports again and rebuild these maps. + rebuildAnyPortTransportMaps(); + } + else + { + Tuple tlsRemoveTuple = transportToRemove->getTuple(); + tlsRemoveTuple.setTargetDomain(transportToRemove->tlsDomain()); + TlsTransportKey tlsKey(tlsRemoveTuple); + mTlsTransports.erase(tlsKey); + } + + // mTypeToTransportMap is a multimap - make sure to delete only this instance by looking up transportKey, instead of using + // mTypeToTransportMap.erase(transportToRemove->getTuple()); which might end up deleting more than 1 transport + for (TypeToTransportMap::iterator itTypeToTransport = mTypeToTransportMap.begin(); itTypeToTransport != mTypeToTransportMap.end(); itTypeToTransport++) + { + if (itTypeToTransport->second->getKey() == transportKey) + { + mTypeToTransportMap.erase(itTypeToTransport); + break; + } + } + + // Remove transport types from Dns list of supported protocols + // Note: DNS tracks use counts so that we will only remove this transport type if this is the last of the type to be removed + mDns.removeTransportType(transportToRemove->transport(), transportToRemove->ipVersion()); + + if (transportToRemove->shareStackProcessAndSelect()) + { + // Note: We called shutdown above, therefor the TransportSelectorThread can tell this + // is a remove transpot request vs an addTransport request, by calling isShuttingDown(). + mTransportsToAddRemove.add(transportToRemove); // Need to add to mSharedProcessTransports from within TransportSelectorThread + // Note: Transport will be deleted from mTransportsToAddRemove handler (see checkTransportAddRemoveQueue) + } + else + { + for(TransportList::iterator it = mHasOwnProcessTransports.begin(); it != mHasOwnProcessTransports.end(); it++) + { + if((*it)->getKey() == transportKey) + { + mHasOwnProcessTransports.erase(it); + break; + } + } + + // Delete transport + delete transportToRemove; + } + } +} + +void +TransportSelector::rebuildAnyPortTransportMaps() +{ + // These maps may contain less transports than what exists in the mTransports map, due to the fact that multiple transports can + // have the same index. In these cases the last transport added that matches the custom map compare function is the only one that ends + // up in these maps. Therefor we cannot just simply remove items and expect transprot selection to work as expected. + // We will clear these maps here. Iterate through the master transport list and rebuild them back up. This isn't very efficient, + // but it only occurs when a transport is removed. + + mAnyPortTransports.clear(); + mAnyPortAnyInterfaceTransports.clear(); + + for (TransportKeyMap::iterator it = mTransports.begin(); it != mTransports.end(); it++) + { + if (!isSecure(it->second->transport())) + { + // Store the transport in the ANY interface maps if the tuple specifies ANY + // interface. Store the transport in the specific interface maps if the tuple + // specifies an interface. See TransportSelector::findTransport. + if (it->second->interfaceName().empty() || + it->second->getTuple().isAnyInterface() || + it->second->hasSpecificContact()) + { + mAnyPortAnyInterfaceTransports[it->second->getTuple()] = it->second; + } + else + { + mAnyPortTransports[it->second->getTuple()] = it->second; + } + } + } } void @@ -288,8 +421,7 @@ TransportSelector::setPollGrp(FdPollGrp *grp) mInterruptorHandle = mPollGrp->addPollItem(mSelectInterruptor->getReadSocket(), FPEM_Read, mSelectInterruptor.get()); } - for(TransportList::iterator t=mSharedProcessTransports.begin(); - t!=mSharedProcessTransports.end(); ++t) + for(TransportList::iterator t=mSharedProcessTransports.begin(); t!=mSharedProcessTransports.end(); ++t) { (*t)->setPollGrp(mPollGrp); } @@ -311,8 +443,7 @@ TransportSelector::createSelectInterruptor() void TransportSelector::buildFdSet(FdSet& fdset) { - for(TransportList::iterator it = mSharedProcessTransports.begin(); - it != mSharedProcessTransports.end(); it++) + for(TransportList::iterator it = mSharedProcessTransports.begin(); it != mSharedProcessTransports.end(); it++) { (*it)->buildFdSet(fdset); } @@ -325,10 +456,9 @@ TransportSelector::buildFdSet(FdSet& fdset) void TransportSelector::process(FdSet& fdset) { - checkTransportAddQueue(); + checkTransportAddRemoveQueue(); - for(TransportList::iterator it = mSharedProcessTransports.begin(); - it != mSharedProcessTransports.end(); it++) + for(TransportList::iterator it = mSharedProcessTransports.begin(); it != mSharedProcessTransports.end(); it++) { try { @@ -349,12 +479,10 @@ TransportSelector::process(FdSet& fdset) void TransportSelector::process() { - // This function will only be sufficient if these Transports are hooked into - // a FdPollGrp. - checkTransportAddQueue(); + // This function will only be sufficient if these Transports are hooked into a FdPollGrp. + checkTransportAddRemoveQueue(); - for(TransportList::iterator it = mSharedProcessTransports.begin(); - it != mSharedProcessTransports.end(); it++) + for(TransportList::iterator it = mSharedProcessTransports.begin(); it != mSharedProcessTransports.end(); it++) { try { @@ -368,21 +496,43 @@ TransportSelector::process() } void -TransportSelector::checkTransportAddQueue() +TransportSelector::checkTransportAddRemoveQueue() { - std::unique_ptr t(mTransportsToAdd.getNext(-1)); - while(t.get()) + // This method ensures we add/remove from/to the mSharedProcessTransports + // list from the TransportSelectorThread + + Transport* t(mTransportsToAddRemove.getNext(-1)); + while(t) { - addTransportInternal(std::move(t)); - t.reset(mTransportsToAdd.getNext(0)); + if(!t->isShuttingDown()) + { + // If not shutting down then this is an addTransport request + mSharedProcessTransports.push_back(t); + } + else + { + // If shutting down then this is a removeTransport request + for(TransportList::iterator it = mSharedProcessTransports.begin(); it != mSharedProcessTransports.end(); it++) + { + if((*it)->getKey() == t->getKey()) + { + mSharedProcessTransports.erase(it); + break; + } + } + + // Now delete the transport + delete t; + } + + t = mTransportsToAddRemove.getNext(-1); } } void TransportSelector::poke() { - for(TransportList::iterator it = mHasOwnProcessTransports.begin(); - it != mHasOwnProcessTransports.end(); it++) + for(TransportList::iterator it = mHasOwnProcessTransports.begin(); it != mHasOwnProcessTransports.end(); it++) { try { @@ -394,7 +544,7 @@ TransportSelector::poke() } } - if(mSelectInterruptor.get() && hasDataToSend()) + if(mSelectInterruptor.get() /* && hasDataToSend() */) // removed hasDataToSend call since it is not thread safe { mSelectInterruptor->handleProcessNotification(); } @@ -403,8 +553,7 @@ TransportSelector::poke() bool TransportSelector::hasDataToSend() const { - for(TransportList::const_iterator it = mSharedProcessTransports.begin(); - it != mSharedProcessTransports.end(); it++) + for(TransportList::const_iterator it = mSharedProcessTransports.begin(); it != mSharedProcessTransports.end(); it++) { if ((*it)->hasDataToSend()) { @@ -458,14 +607,15 @@ TransportSelector::dnsResolve(DnsResult* result, else if (msg->isResponse()) { ErrLog(<<"unimplemented response dns"); - assert(0); + resip_assert(0); } else { - assert(0); + resip_assert(0); } } +// FIXME: maybe this should move to rutil/TransportType? bool isDgramTransport (TransportType type) { static const bool unknown_transport = false; @@ -479,10 +629,12 @@ bool isDgramTransport (TransportType type) case TCP: case TLS: + case WS: + case WSS: return false; default: - assert(unknown_transport); + resip_assert(unknown_transport); return unknown_transport; // !kh! just to make it compile wo/warning. } } @@ -492,7 +644,7 @@ TransportSelector::getFirstInterface(bool is_v4, TransportType type) { // !kh! both getaddrinfo() and IPv6 are not supported by cygwin, yet. #ifdef __CYGWIN__ - assert(0); + resip_assert(0); return Tuple(); #else // !kh! @@ -550,17 +702,15 @@ TransportSelector::getFirstInterface(bool is_v4, TransportType type) /** - Check the msg's top Via header for a source host&port that indicates - a particular Transport. - Do NOT do this for a response, as it would allow malicious downstream - to insert bogus host in via header that we would then use. + Check the msg's top Via header for a source host&port that indicates a particular Transport. + Do NOT do this for a response, as it would allow malicious downstream to insert bogus host + in via header that we would then use. **/ Transport* -TransportSelector::findTransportByVia(SipMessage* msg, const Tuple& target, - Tuple& source) const +TransportSelector::findTransportByVia(SipMessage* msg, const Tuple& target, Tuple& source) const { - assert(msg->exists(h_Vias)); - assert(!msg->const_header(h_Vias).empty()); + resip_assert(msg->exists(h_Vias)); + resip_assert(!msg->const_header(h_Vias).empty()); const Via& via = msg->const_header(h_Vias).front(); if (via.sentHost().empty() && via.transport().empty()) @@ -570,14 +720,16 @@ TransportSelector::findTransportByVia(SipMessage* msg, const Tuple& target, // XXX: Is there better way to do below (without the copy)? source = Tuple(via.sentHost(), via.sentPort(), target.ipVersion(), - via.transport().empty() ? target.getType() : toTransportType(via.transport())); // Transport type is pre-populated in via, lock to it + via.transport().empty() ? target.getType() : toTransportType(via.transport()), // Transport type is pre-populated in via, lock to it + Data::Empty, target.getNetNs()); + DebugLog(<< "TransportSelector::findTransportByVia: source: " << source); if ( target.mFlowKey!=0 && (source.getPort()==0 || source.isAnyInterface()) ) { WarningLog(<< "Sending request with incomplete Via header and FlowKey." <<" This code no smart enough to pick the correct Transport." <<" Via=" << via); - assert(0); + resip_assert(0); } if ( source.isAnyInterface() ) { @@ -605,12 +757,12 @@ TransportSelector::findTransportByVia(SipMessage* msg, const Tuple& target, Tuple TransportSelector::determineSourceInterface(SipMessage* msg, const Tuple& target) const { - assert(msg->exists(h_Vias)); - assert(!msg->header(h_Vias).empty()); + resip_assert(msg->exists(h_Vias)); + resip_assert(!msg->header(h_Vias).empty()); const Via& via = msg->header(h_Vias).front(); // this case should be handled already for UDP and TCP targets - //assert( (!(msg->isRequest() && !via.sentHost().empty())) || (target.getType() == TLS || target.getType() == DTLS) ); + resip_assert((!(msg->isRequest() && !via.sentHost().empty())) || isSecure(target.getType())); if (1) { Tuple source(target); @@ -636,23 +788,39 @@ TransportSelector::determineSourceInterface(SipMessage* msg, const Tuple& target // this process will determine which interface the kernel would use to // send a packet to the target by making a connect call on a udp socket. Socket tmp = INVALID_SOCKET; + Data netNs = target.getNetNs(); + // One IPV4 and IPV6 socket per namespace. Even if we do not support netns, + // we still have the default namespace of "" (empty string). if (target.isV4()) { - if (mSocket == INVALID_SOCKET) + // If socket does not exist for namespace, create one + if (mSockets.find(netNs) == mSockets.end() || mSockets[netNs] == INVALID_SOCKET) { - mSocket = InternalTransport::socket(UDP, V4); // may throw +#ifdef USE_NETNS + NetNs::setNs(netNs); +#endif + mSockets[netNs] = InternalTransport::socket(UDP, V4); // may throw } - tmp = mSocket; + tmp = mSockets[netNs]; } else { - if (mSocket6 == INVALID_SOCKET) + // If socket does not exist for namespace, create one + if (mSocket6s.find(netNs) == mSocket6s.end() || mSocket6s[netNs] == INVALID_SOCKET) { - mSocket6 = InternalTransport::socket(UDP, V6); // may throw +#ifdef USE_NETNS + NetNs::setNs(netNs); +#endif + mSocket6s[netNs] = InternalTransport::socket(UDP, V6); // may throw } - tmp = mSocket6; + tmp = mSocket6s[netNs]; } +#ifdef USE_NETNS + // Not sure if connect has to be done in netns context or just the socket create + NetNs::setNs(netNs); +#endif + int ret = connect(tmp,&target.getSockaddr(), target.length()); if (ret < 0) { @@ -698,21 +866,21 @@ TransportSelector::determineSourceInterface(SipMessage* msg, const Tuple& target // fails. I'm not sure the stack can recover from this error condition. if (target.isV4()) { - ret = connect(mSocket, + ret = connect(mSockets[netNs], (struct sockaddr*)&mUnspecified.v4Address, sizeof(mUnspecified.v4Address)); } #ifdef USE_IPV6 else { - ret = connect(mSocket6, + ret = connect(mSocket6s[netNs], (struct sockaddr*)&mUnspecified6.v6Address, sizeof(mUnspecified6.v6Address)); } #else else { - assert(0); + resip_assert(0); } #endif @@ -755,10 +923,10 @@ TransportSelector::determineSourceInterface(SipMessage* msg, const Tuple& target // !jf! there may be an extra copy of a tuple here. can probably get rid of it // but there are some const issues. -bool +TransportSelector::TransmitState TransportSelector::transmit(SipMessage* msg, Tuple& target, SendData* sendData) { - assert(msg); + resip_assert(msg); if(msg->mIsDecorated) { @@ -788,7 +956,7 @@ TransportSelector::transmit(SipMessage* msg, Tuple& target, SendData* sendData) Alternatively, we might not have the transport to start with. However, given a connection id, we will be able to find the Connection we should use, we can get the Transport we want. If we have no connection - id, but we know we are using TLS or DTLS and have a tls hostname, we + id, but we know we are using TLS, DTLS or WSS and have a tls hostname, we can use the hostname to find the appropriate transport. If all else fails, we must resort to the connected UDP trick to fill out source, which in turn is used to look up a matching transport. @@ -811,8 +979,13 @@ TransportSelector::transmit(SipMessage* msg, Tuple& target, SendData* sendData) if ((transport = findTransportByDest(target)) != NULL) { source = transport->getTuple(); + DebugLog(<< "Found transport: " << source); } } + else + { + DebugLog(<< "Found transport: " << source); + } if(!transport && target.mFlowKey && target.onlyUseExistingConnection) { @@ -822,7 +995,7 @@ TransportSelector::transmit(SipMessage* msg, Tuple& target, SendData* sendData) } else if (transport)// .bwc. Here we use transport to find source. { - assert( source.getType()!=0 ); + resip_assert( source.getType()!=0 ); // .bwc. If the transport has an ambiguous interface, we need to //look a little closer. @@ -832,7 +1005,7 @@ TransportSelector::transmit(SipMessage* msg, Tuple& target, SendData* sendData) // .bwc. determineSourceInterface() can give us a port, if the TU // put one in the topmost Via. - assert(source.ipVersion()==temp.ipVersion() && + resip_assert(source.ipVersion()==temp.ipVersion() && source.getType()==temp.getType()); source=temp; @@ -850,6 +1023,7 @@ TransportSelector::transmit(SipMessage* msg, Tuple& target, SendData* sendData) { source = determineSourceInterface(msg, target); transport = findTransportBySource(source, msg); + DebugLog(<< "Found transport: " << source); // .bwc. determineSourceInterface might give us a port if(transport && source.getPort()==0) @@ -858,12 +1032,12 @@ TransportSelector::transmit(SipMessage* msg, Tuple& target, SendData* sendData) } } - target.transportKey=transport ? transport->getKey() : 0; + target.mTransportKey = transport ? transport->getKey() : 0; // .bwc. Topmost Via is only filled out in the request case. Also, if // we don't have a transport at this point, we're going to fail, // so don't bother doing the work. - if(target.transportKey) + if(target.mTransportKey) { Via& topVia(msg->header(h_Vias).front()); topVia.remove(p_maddr); // !jf! why do this? @@ -930,7 +1104,6 @@ TransportSelector::transmit(SipMessage* msg, Tuple& target, SendData* sendData) topVia.param(p_branch).setSigcompCompartment(remoteSigcompId); } } - } else if (msg->isResponse()) { @@ -939,56 +1112,55 @@ TransportSelector::transmit(SipMessage* msg, Tuple& target, SendData* sendData) // and this has been copied by TransactionState::sendToWire into transport transport=findTransportByDest(target); - // !bwc! May eventually remove this once we allow transports to be - // removed while running. - assert(transport); - - source = transport->getTuple(); - - // .bwc. If the transport has an ambiguous interface, we need to - //look a little closer. - if(source.isAnyInterface()) + // Transport used to receive the request, may have been removed. + if(transport) { - Tuple temp = source; - source = determineSourceInterface(msg,target); - assert(source.ipVersion()==temp.ipVersion() && - source.getType()==temp.getType()); + source = transport->getTuple(); + DebugLog(<< "Found transport: " << source); - /* determineSourceInterface might return an arbitrary port here, - so use the port specified in transport->port(). - */ - if(source.getPort()==0) + // .bwc. If the transport has an ambiguous interface, we need to + //look a little closer. + if(source.isAnyInterface()) { - source.setPort(transport->port()); - } - } - if (mCompression.isEnabled()) - { - // Figure out remote identifier (from Via header field). - Via& topVia(msg->header(h_Vias).front()); + Tuple temp = source; + source = determineSourceInterface(msg,target); + resip_assert(source.ipVersion()==temp.ipVersion() && + source.getType()==temp.getType()); - if(topVia.exists(p_comp) && - topVia.param(p_comp) == "sigcomp") - { - if (topVia.exists(p_sigcompId)) + /* determineSourceInterface might return an arbitrary port here, + so use the port specified in transport->port(). + */ + if(source.getPort()==0) { - remoteSigcompId = topVia.param(p_sigcompId); + source.setPort(transport->port()); } - else + } + if (mCompression.isEnabled()) + { + // Figure out remote identifier (from Via header field). + Via& topVia(msg->header(h_Vias).front()); + + if(topVia.exists(p_comp) && topVia.param(p_comp) == "sigcomp") { - // XXX rohc-sigcomp-sip-03 says "sent-by", - // but this should probably be "received" if present, - // and "sent-by" otherwise. - // XXX Also, the spec is ambiguous about whether - // to include the port in this identifier. - remoteSigcompId = topVia.sentHost(); + if (topVia.exists(p_sigcompId)) + { + remoteSigcompId = topVia.param(p_sigcompId); + } + else + { + // XXX rohc-sigcomp-sip-03 says "sent-by", but this should probably + // be "received" if present, and "sent-by" otherwise. + // XXX Also, the spec is ambiguous about whether to include the port + // in this identifier. + remoteSigcompId = topVia.sentHost(); + } } } } } else { - assert(0); + resip_assert(0); } // .bwc. At this point, source, transport, and target should be @@ -1033,8 +1205,7 @@ TransportSelector::transmit(SipMessage* msg, Tuple& target, SendData* sendData) if (!contact.exists(p_Instance) && !contact.uri().exists(p_sigcompId)) { - contact.uri().param(p_sigcompId) - = mCompression.getSigcompId(); + contact.uri().param(p_sigcompId) = mCompression.getSigcompId(); } } } @@ -1049,7 +1220,6 @@ TransportSelector::transmit(SipMessage* msg, Tuple& target, SendData* sendData) contact.uri().remove(p_addTransport); } } - } } @@ -1130,16 +1300,19 @@ TransportSelector::transmit(SipMessage* msg, Tuple& target, SendData* sendData) #endif } - target.transportKey=transport->getKey(); - - // !bwc! Deprecated. Stop doing this eventually. - target.transport=transport; + resip_assert(target.mTransportKey == transport->getKey()); // Call back anyone who wants to perform outbound decoration msg->callOutboundDecorators(source, target,remoteSigcompId); - std::unique_ptr send(new SendData(target, - resip::Data::Empty, + Transport::SipMessageLoggingHandler* handler = transport->getSipMessageLoggingHandler(); + if(handler) + { + handler->outboundMessage(source, target, *msg); + } + + std::auto_ptr send(new SendData(target, + resip::Data::Empty, msg->getTransactionId(), remoteSigcompId)); @@ -1154,7 +1327,7 @@ TransportSelector::transmit(SipMessage* msg, Tuple& target, SendData* sendData) // dynamic resizing.) mAvgBufferSize = (255*mAvgBufferSize + send->data.size()+128)/256; - assert(!send->data.empty()); + resip_assert(!send->data.empty()); DebugLog (<< "Transmitting to " << target << " tlsDomain=" << msg->getTlsDomain() << " via " << source @@ -1166,29 +1339,28 @@ TransportSelector::transmit(SipMessage* msg, Tuple& target, SendData* sendData) *sendData = *send; } - transport->send(std::move(send)); - return true; + transport->send(send); + return Sent; } else { InfoLog (<< "tid=" << msg->getTransactionId() << " failed to find a transport to " << target); mStateMacFifo.add(new TransportFailure(msg->getTransactionId(), transportFailureReason)); - return false; + return Unsent; } - } catch (Transport::Exception& ) { InfoLog (<< "tid=" << msg->getTransactionId() << " no route to target: " << target); mStateMacFifo.add(new TransportFailure(msg->getTransactionId(), TransportFailure::NoRoute)); - return false; + return Unsent; } } void TransportSelector::retransmit(const SendData& data) { - assert(data.destination.transportKey); + resip_assert(data.destination.mTransportKey); Transport* transport = findTransportByDest(data.destination); // !jf! The previous call to transmit may have blocked or failed (It seems to @@ -1217,7 +1389,13 @@ TransportSelector::retransmit(const SendData& data) if(transport) { // If this is not true, it means the transport has been removed. - transport->send(std::unique_ptr(data.clone())); + Transport::SipMessageLoggingHandler* handler = transport->getSipMessageLoggingHandler(); + if(handler) + { + handler->outboundRetransmit(transport->getTuple(), data.destination, data); + } + + transport->send(std::auto_ptr(data.clone())); } } @@ -1228,11 +1406,11 @@ TransportSelector::closeConnection(const Tuple& peer) if(t) { SendData* close=new SendData(peer, - resip::Data::Empty, - resip::Data::Empty, - resip::Data::Empty); + resip::Data::Empty, + resip::Data::Empty, + resip::Data::Empty); close->command = SendData::CloseConnection; - t->send(std::unique_ptr(close)); + t->send(std::auto_ptr(close)); } } @@ -1240,25 +1418,10 @@ unsigned int TransportSelector::sumTransportFifoSizes() const { unsigned int sum = 0; - - for (AnyPortTupleMap::const_iterator i = mAnyPortTransports.begin(); - i != mAnyPortTransports.end(); ++i) + for(TransportKeyMap::const_iterator it = mTransports.begin(); it != mTransports.end(); it++) { - sum += i->second->getFifoSize(); + sum += it->second->getFifoSize(); } - - for (AnyPortAnyInterfaceTupleMap::const_iterator i = mAnyPortAnyInterfaceTransports.begin(); - i != mAnyPortAnyInterfaceTransports.end(); ++i) - { - sum += i->second->getFifoSize(); - } - - for (TlsTransportMap::const_iterator i = mTlsTransports.begin(); - i != mTlsTransports.end(); ++i) - { - sum += i->second->getFifoSize(); - } - return sum; } @@ -1279,18 +1442,36 @@ TransportSelector::enableFlowTimer(const resip::Tuple& flow) resip::Data::Empty, resip::Data::Empty); enableFlowTimer->command = SendData::EnableFlowTimer; - t->send(std::unique_ptr(enableFlowTimer)); + t->send(std::auto_ptr(enableFlowTimer)); } } +void +TransportSelector::invokeAfterSocketCreationFunc(TransportType type) +{ + for (TransportKeyMap::iterator it = mTransports.begin(); it != mTransports.end(); it++) + { + if (type == UNKNOWN_TRANSPORT || type == it->second->transport()) + { + it->second->invokeAfterSocketCreationFunc(); + } + } + if (type == UNKNOWN_TRANSPORT) + { + // !slg! TODO - invoke for DNS? + //mDns. + } +} + Transport* TransportSelector::findTransportByDest(const Tuple& target) { - if(target.transportKey) + if(target.mTransportKey) { - if(target.transportKey <= mTransports.size()) + TransportKeyMap::iterator it = mTransports.find(target.mTransportKey); + if(it != mTransports.end()) { - return mTransports[target.transportKey-1]; + return it->second; } } else @@ -1305,7 +1486,6 @@ TransportSelector::findTransportByDest(const Tuple& target) { return range.first->second; } - return i->second; } } @@ -1335,9 +1515,13 @@ TransportSelector::findLoopbackTransportBySource(bool ignorePort, Tuple& search) //Compare only the first byte (the 127) if(i->first.isEqualWithMask(search,8,ignorePort)) { - search=i->first; - DebugLog(<<"Match!"); - return i->second; + // Not sure if this should go here or in Tuple::isEqualWithMask + if(i->first.getNetNs() == search.getNetNs()) + { + search=i->first; + DebugLog(<<"Match!"); + return i->second; + } } } #ifdef USE_IPV6 @@ -1348,7 +1532,7 @@ TransportSelector::findLoopbackTransportBySource(bool ignorePort, Tuple& search) #endif else { - assert(0); + resip_assert(0); } } @@ -1362,9 +1546,9 @@ TransportSelector::findTransportBySource(Tuple& search, const SipMessage* msg) c if(msg && !msg->getTlsDomain().empty() && - (search.getType()==TLS || search.getType()==DTLS)) + isSecure(search.getType())) { - // We should not be willing to attempt sending on a TLS/DTLS transport + // We should not be willing to attempt sending on a TLS/DTLS/WSS transport // that does not have the cert we're attempting to use, even if the // IP/port/proto match. If we have not specified which identity we want // to use, then proceed with the code below. @@ -1389,9 +1573,10 @@ TransportSelector::findTransportBySource(Tuple& search, const SipMessage* msg) c // 2. search for matching port on any loopback interface if (search.isLoopback()) { - Transport *trans=findLoopbackTransportBySource( /*ignorePort*/false, search); + Transport *trans = findLoopbackTransportBySource( /*ignorePort*/false, search); if (trans) { + DebugLog(<< "findLoopbackTransportBySource(" << search << ")"); return trans; } } @@ -1413,7 +1598,7 @@ TransportSelector::findTransportBySource(Tuple& search, const SipMessage* msg) c AnyPortTupleMap::const_iterator i = mAnyPortTransports.find(search); if (i != mAnyPortTransports.end()) { - DebugLog(<< "findTransport (any port, specific interface) => " << *(i->second)); + DebugLog(<< "findTransport (any port, specific interface) => " << *(i->second) << " key: " << (i->first) << " search: " << search); return i->second; } } @@ -1449,20 +1634,18 @@ TransportSelector::findTransportBySource(Tuple& search, const SipMessage* msg) c return 0; } - Transport* -TransportSelector::findTlsTransport(const Data& domainname,resip::TransportType type,resip::IpVersion version) const +TransportSelector::findTlsTransport(const Data& domainname, TransportType type, IpVersion version) const { - assert(type==TLS || type==DTLS); - DebugLog (<< "Searching for " << ((type==TLS) ? "TLS" : "DTLS") << " transport for domain='" + resip_assert(isSecure(type)); + DebugLog(<< "Searching for " << toData(type) << " transport for domain='" << domainname << "'" << " have " << mTlsTransports.size()); if (domainname == Data::Empty) { - for(TlsTransportMap::const_iterator i=mTlsTransports.begin(); - i!=mTlsTransports.end();++i) + for(TlsTransportMap::const_iterator i=mTlsTransports.begin(); i != mTlsTransports.end();++i) { - if(i->first.mType==type && i->first.mVersion==version) + if(i->first.mTuple.getType() == type && i->first.mTuple.ipVersion() == version) { DebugLog(<<"Found a default transport."); return i->second; @@ -1471,8 +1654,7 @@ TransportSelector::findTlsTransport(const Data& domainname,resip::TransportType } else { - TlsTransportKey key(domainname,type,version); - + TlsTransportKey key(domainname, type, version); TlsTransportMap::const_iterator i=mTlsTransports.find(key); if(i!=mTlsTransports.end()) @@ -1503,6 +1685,13 @@ void TransportSelector::unregisterMarkListener(MarkListener* listener) mDns.getMarkManager().unregisterMarkListener(listener); } +EncodeStream& +resip::operator<<(EncodeStream& ostrm, const TransportSelector::TlsTransportKey& tlsTransportKey) +{ + ostrm << tlsTransportKey.mTuple; + + return ostrm; +} /* ==================================================================== * The Vovida Software License, Version 1.0 diff --git a/src/libs/resiprocate/resip/stack/TransportSelector.hxx b/src/libs/resiprocate/resip/stack/TransportSelector.hxx index 2f5b9fb4..f0e86635 100644 --- a/src/libs/resiprocate/resip/stack/TransportSelector.hxx +++ b/src/libs/resiprocate/resip/stack/TransportSelector.hxx @@ -7,6 +7,7 @@ #include #include +#include #include "rutil/Data.hxx" #include "rutil/Fifo.hxx" @@ -48,21 +49,27 @@ Transport in the FdSet processing loop. If the Transport returns false for shareStackProcessAndSelect(), TransportSelector will call startOwnProcessing on Transport add. +Thread Safey Notes - the majority of the access to this class is expected to be from +the TransactionController Thread. The TransportSelectorThread itself is used +to provide cycles to the actual transports for sending data in their Fifo's and +receiving data from the wire. The mSharedProcessTransports list is one member that +is expected to be accessed from TransportSelector processing loop only , all other +members are accessed from the TransactionController processing loop. */ class TransportSelector { public: - TransportSelector(Fifo& fifo, Security* security, DnsStub& dnsStub, Compression &compression); + TransportSelector(Fifo& fifo, Security* security, DnsStub& dnsStub, Compression &compression, bool useDnsVip); virtual ~TransportSelector(); - /** - @retval true Some transport in the transport list has data to send - @retval false No transport in the transport list has data to send - */ - bool hasDataToSend() const; /** - Shuts down all transports. - */ + @retval true Some transport in the transport list has data to send + @retval false No transport in the transport list has data to send + Should only be called from TransportSelector processing loop. + */ + bool hasDataToSend() const; + + /// Shuts down all transports. void shutdown(); /// Returns true if all Transports have their buffers cleared, false otherwise. @@ -88,18 +95,26 @@ class TransportSelector /// Causes transport process loops to be interrupted if there is stuff in /// their transmit fifos. void poke(); - void addTransport( std::unique_ptr transport, bool immediate); + /// Add/Remove a transport + void addTransport(std::auto_ptr transport, bool isStackRunning); + void removeTransport(unsigned int transportKey); + + /// DNS Resolution DnsResult* createDnsResult(DnsHandler* handler); - void dnsResolve(DnsResult* result, SipMessage* msg); /** - Results in msg->resolve() being called to either + transmit results in msg->resolve() being called to either kick off dns resolution or to pick the next tuple and will cause the message to be encoded and via updated - */ - bool transmit( SipMessage* msg, Tuple& target, SendData* sendData=0 ); + */ + typedef enum + { + Unsent, + Sent + } TransmitState; + TransmitState transmit( SipMessage* msg, Tuple& target, SendData* sendData=0 ); /// Resend to the same transport as last time void retransmit(const SendData& msg); @@ -119,32 +134,75 @@ class TransportSelector void terminateFlow(const resip::Tuple& flow); void enableFlowTimer(const resip::Tuple& flow); + bool setUdpOnlyOnNumeric(bool value) + { + return mDns.setUdpOnlyOnNumeric(value); + } + + bool getUdpOnlyOnNumeric() const + { + return mDns.getUdpOnlyOnNumeric(); + } + void setCongestionManager(CongestionManager* manager) { - for(TransportList::iterator i=mSharedProcessTransports.begin(); - i!=mSharedProcessTransports.end();++i) + for(TransportKeyMap::iterator i=mTransports.begin(); + i!=mTransports.end();++i) { - (*i)->setCongestionManager(manager); - } - - for(TransportList::iterator i=mHasOwnProcessTransports.begin(); - i!=mHasOwnProcessTransports.end();++i) - { - (*i)->setCongestionManager(manager); + i->second->setCongestionManager(manager); } } + void invokeAfterSocketCreationFunc(TransportType type); + + /** + @internal - public only for stream operator access + */ + class TlsTransportKey + { + public: + TlsTransportKey(const resip::Tuple& tuple) : mTuple(tuple) {} + TlsTransportKey(const resip::Data& domainName, resip::TransportType type, resip::IpVersion version) : + mTuple(Data::Empty, 0, version, type, domainName) {} + TlsTransportKey(const TlsTransportKey& orig) { mTuple = orig.mTuple; } + ~TlsTransportKey(){} + + bool operator<(const TlsTransportKey& rhs) const + { + if(mTuple.getTargetDomain() < rhs.mTuple.getTargetDomain()) + { + return true; + } + else if(mTuple.getTargetDomain() == rhs.mTuple.getTargetDomain()) + { + if(mTuple.getType() < rhs.mTuple.getType()) + { + return true; + } + else if(mTuple.getType() == rhs.mTuple.getType()) + { + return mTuple.ipVersion() < rhs.mTuple.ipVersion(); + } + } + return false; + } + + resip::Tuple mTuple; + + private: + TlsTransportKey(); + }; + private: - void addTransportInternal( std::unique_ptr transport); - void checkTransportAddQueue(); + void checkTransportAddRemoveQueue(); Connection* findConnection(const Tuple& dest) const; Transport* findTransportBySource(Tuple& src, const SipMessage* msg) const; Transport* findLoopbackTransportBySource(bool ignorePort, Tuple& src) const; Transport* findTransportByDest(const Tuple& dest); - Transport* findTransportByVia(SipMessage* msg, const Tuple& dest, - Tuple& src) const; + Transport* findTransportByVia(SipMessage* msg, const Tuple& dest, Tuple& src) const; Transport* findTlsTransport(const Data& domain,TransportType type,IpVersion ipv) const; Tuple determineSourceInterface(SipMessage* msg, const Tuple& dest) const; + void rebuildAnyPortTransportMaps(void); DnsInterface mDns; Fifo& mStateMacFifo; @@ -166,70 +224,22 @@ class TransportSelector typedef std::map AnyPortAnyInterfaceTupleMap; AnyPortAnyInterfaceTupleMap mAnyPortAnyInterfaceTransports; - std::vector mTransports; // owns all Transports + typedef std::map TransportKeyMap; + TransportKeyMap mTransports; // owns all Transports - /** - @internal - */ - class TlsTransportKey - { - public: - TlsTransportKey(const resip::Data& domain, resip::TransportType type, resip::IpVersion version) - :mDomain(domain), - mType(type), - mVersion(version) - {} - - TlsTransportKey(const TlsTransportKey& orig) - { - mDomain=orig.mDomain; - mType=orig.mType; - mVersion=orig.mVersion; - } - - ~TlsTransportKey(){} - bool operator<(const TlsTransportKey& rhs) const - { - if(mDomain < rhs.mDomain) - { - return true; - } - else if(mDomain == rhs.mDomain) - { - if(mType < rhs.mType) - { - return true; - } - else if(mType == rhs.mType) - { - return mVersion < rhs.mVersion; - } - } - return false; - } - - resip::Data mDomain; - resip::TransportType mType; - resip::IpVersion mVersion; - - private: - TlsTransportKey(); - }; - typedef std::map TlsTransportMap ; - TlsTransportMap mTlsTransports; - typedef std::vector TransportList; - TransportList mSharedProcessTransports; + typedef std::list TransportList; + TransportList mSharedProcessTransports; // Warning - only access this from the TransportSelector process loop / thread TransportList mHasOwnProcessTransports; typedef std::multimap TypeToTransportMap; TypeToTransportMap mTypeToTransportMap; - // fake socket for connect() and route table lookups - mutable Socket mSocket; - mutable Socket mSocket6; + // fake socket(s) one for each netns, for connect() and route table lookups + mutable HashMap mSockets; + mutable HashMap mSocket6s; // An AF_UNSPEC addr_in for rapid unconnect GenericIPAddress mUnspecified; @@ -243,14 +253,17 @@ class TransportSelector FdPollGrp* mPollGrp; int mAvgBufferSize; - Fifo mTransportsToAdd; - std::unique_ptr mSelectInterruptor; + Fifo mTransportsToAddRemove; + std::auto_ptr mSelectInterruptor; FdPollItemHandle mInterruptorHandle; friend class TestTransportSelector; friend class SipStack; // for debug only }; +EncodeStream& +operator<<(EncodeStream& ostrm, const TransportSelector::TlsTransportKey& tlsTransportKey); + } #endif @@ -303,5 +316,6 @@ class TransportSelector * Inc. For more information on Vovida Networks, Inc., please see * . * - * vi: set shiftwidth=3 expandtab: */ + +// vim: softtabstop=3:shiftwidth=3:expandtab diff --git a/src/libs/resiprocate/resip/stack/TransportSelectorThread.hxx b/src/libs/resiprocate/resip/stack/TransportSelectorThread.hxx index a7c1b14c..c1139138 100644 --- a/src/libs/resiprocate/resip/stack/TransportSelectorThread.hxx +++ b/src/libs/resiprocate/resip/stack/TransportSelectorThread.hxx @@ -35,8 +35,7 @@ class TransportSelectorThread : public ThreadIf try { mSelector.process(); - if (mPollGrp.get()) - mPollGrp->waitAndProcess(25); + mPollGrp->waitAndProcess(25); } catch(BaseException& e) { @@ -47,7 +46,7 @@ class TransportSelectorThread : public ThreadIf protected: TransportSelector& mSelector; - std::unique_ptr mPollGrp; + std::auto_ptr mPollGrp; }; // class TransportSelectorThread diff --git a/src/libs/resiprocate/resip/stack/TransportThread.cxx b/src/libs/resiprocate/resip/stack/TransportThread.cxx index 4691ba72..5e98ea98 100644 --- a/src/libs/resiprocate/resip/stack/TransportThread.cxx +++ b/src/libs/resiprocate/resip/stack/TransportThread.cxx @@ -30,8 +30,7 @@ TransportThread::thread() try { mTransport.process(); - if (mPollGrp.get()) - mPollGrp->waitAndProcess(25); + mPollGrp->waitAndProcess(25); } catch(BaseException& e) { diff --git a/src/libs/resiprocate/resip/stack/TransportThread.hxx b/src/libs/resiprocate/resip/stack/TransportThread.hxx index 780327d7..8090b812 100644 --- a/src/libs/resiprocate/resip/stack/TransportThread.hxx +++ b/src/libs/resiprocate/resip/stack/TransportThread.hxx @@ -20,7 +20,7 @@ class TransportThread : public ThreadIf protected: Transport& mTransport; - std::unique_ptr mPollGrp; + std::auto_ptr mPollGrp; }; // class TransportThread } // namespace resip diff --git a/src/libs/resiprocate/resip/stack/TuIM.cxx b/src/libs/resiprocate/resip/stack/TuIM.cxx index 1c1a19c7..d8012d5d 100644 --- a/src/libs/resiprocate/resip/stack/TuIM.cxx +++ b/src/libs/resiprocate/resip/stack/TuIM.cxx @@ -14,7 +14,7 @@ suppport loading destination certificates from server */ -#include +#include "rutil/ResipAssert.h" #include #include "resip/stack/SipStack.hxx" @@ -78,9 +78,9 @@ TuIM::TuIM(SipStack* stack, mSubscriptionTimeSeconds(subscriptionTimeSeconds), mDefaultProtocol( UNKNOWN_TRANSPORT ) { - assert( mStack ); - assert(mCallback); - assert(mPidf); + resip_assert( mStack ); + resip_assert(mCallback); + resip_assert(mPidf); mPidf->setSimpleId( Random::getRandomHex(4) ); mPidf->setEntity(mAor); @@ -95,7 +95,7 @@ TuIM::haveCerts( bool sign, const Data& encryptFor ) #if defined( USE_SSL ) Security* sec = mStack->getSecurity(); - assert(sec); + resip_assert(sec); if ( sign ) { @@ -143,7 +143,7 @@ TuIM::sendPage(const Data& text, const Uri& dest, DeprecatedDialog* dialog = new DeprecatedDialog( NameAddr(mContact) ); - unique_ptr msg( dialog->makeInitialMessage(NameAddr(target),NameAddr(from)) ); + auto_ptr msg( dialog->makeInitialMessage(NameAddr(target),NameAddr(from)) ); Page page; page.text = text; @@ -163,7 +163,7 @@ TuIM::sendPage(const Data& text, const Uri& dest, if ( !encryptFor.empty() ) { Security* sec = mStack->getSecurity(); - assert(sec); + resip_assert(sec); Contents* old = body; old->header(h_ContentTransferEncoding) = msg->header(h_ContentTransferEncoding); @@ -184,7 +184,7 @@ TuIM::sendPage(const Data& text, const Uri& dest, if ( sign ) { Security* sec = mStack->getSecurity(); - assert(sec); + resip_assert(sec); Contents* old = body; old->header(h_ContentTransferEncoding) = msg->header(h_ContentTransferEncoding); @@ -272,7 +272,7 @@ TuIM::processSipFrag(SipMessage* msg) InfoLog(<< "Received message with body contents" ); - assert( contents ); + resip_assert( contents ); Mime mime = contents->getType(); DebugLog ( << "got body of type " << mime.type() << "/" << mime.subType() ); @@ -284,7 +284,7 @@ TuIM::processSipFrag(SipMessage* msg) if ( mBody ) { Security* sec = mStack->getSecurity(); - assert(sec); + resip_assert(sec); contents = sec->checkSignature( mBody, &signedBy, &sigStat ); @@ -313,7 +313,7 @@ TuIM::processSipFrag(SipMessage* msg) ++i) { Contents* c = *i; - assert( c ); + resip_assert( c ); InfoLog ( << "mixed has a " << c->getType() ); if ( c->getType() == Mime("application","sipfrag") ) @@ -358,7 +358,7 @@ TuIM::processSipFrag(SipMessage* msg) void TuIM::processSubscribeRequest(SipMessage* msg) { - assert( msg->header(h_RequestLine).getMethod() == SUBSCRIBE ); + resip_assert( msg->header(h_RequestLine).getMethod() == SUBSCRIBE ); CallId id = msg->header(h_CallId); processSipFrag( msg ); @@ -379,7 +379,7 @@ TuIM::processSubscribeRequest(SipMessage* msg) for ( SubscriberIterator i=mSubscribers.begin(); i != mSubscribers.end(); i++) { DeprecatedDialog* d = i->dialog; - assert( d ); + resip_assert( d ); if ( d->getCallId() == id ) { @@ -402,16 +402,16 @@ TuIM::processSubscribeRequest(SipMessage* msg) Uri from = msg->header(h_From).uri(); s.aor = from.getAorNoPort(); - assert( mCallback ); + resip_assert( mCallback ); s.authorized = mCallback->authorizeSubscription( from ); mSubscribers.push_back( s ); } - assert( dialog ); + resip_assert( dialog ); dialog->setExpirySeconds( expires ); - unique_ptr response( dialog->makeResponse( *msg, 200 )); + auto_ptr response( dialog->makeResponse( *msg, 200 )); response->header(h_Expires).value() = expires; response->header(h_Event).value() = Data("presence"); @@ -449,7 +449,7 @@ TuIM::processSubscribeRequest(SipMessage* msg) void TuIM::processRegisterRequest(SipMessage* msg) { - assert( msg->header(h_RequestLine).getMethod() == REGISTER ); + resip_assert( msg->header(h_RequestLine).getMethod() == REGISTER ); CallId id = msg->header(h_CallId); int expires = msg->header(h_Expires).value(); @@ -499,12 +499,12 @@ TuIM::processRegisterRequest(SipMessage* msg) void TuIM::processNotifyRequest(SipMessage* msg) { - assert( mCallback ); - assert( msg->header(h_RequestLine).getMethod() == NOTIFY ); + resip_assert( mCallback ); + resip_assert( msg->header(h_RequestLine).getMethod() == NOTIFY ); processSipFrag( msg ); - unique_ptr response( Helper::makeResponse( *msg, 200 )); + auto_ptr response( Helper::makeResponse( *msg, 200 )); mStack->send( *response ); Uri from = msg->header(h_From).uri(); @@ -558,7 +558,7 @@ TuIM::processNotifyRequest(SipMessage* msg) // notify callback if (changed) { - assert(mCallback); + resip_assert(mCallback); mCallback->presenceUpdate( from, open, note ); } } @@ -567,8 +567,8 @@ TuIM::processNotifyRequest(SipMessage* msg) void TuIM::processMessageRequest(SipMessage* msg) { - assert( msg ); - assert( msg->header(h_RequestLine).getMethod() == MESSAGE ); + resip_assert( msg ); + resip_assert( msg->header(h_RequestLine).getMethod() == MESSAGE ); NameAddr contact; contact.uri() = mContact; @@ -602,7 +602,7 @@ TuIM::processMessageRequest(SipMessage* msg) if ( mBody ) { Security* sec = mStack->getSecurity(); - assert(sec); + resip_assert(sec); contents = sec->checkSignature( mBody, &signedBy, &sigStat ); @@ -621,9 +621,9 @@ TuIM::processMessageRequest(SipMessage* msg) Pkcs7SignedContents* sBody = dynamic_cast(contents); if ( sBody ) { - assert( sBody ); + resip_assert( sBody ); Security* sec = mStack->getSecurity(); - assert(sec); + resip_assert(sec); contents = sec->decrypt( mAor.getAor(), sBody ); @@ -642,9 +642,9 @@ TuIM::processMessageRequest(SipMessage* msg) Pkcs7Contents* eBody = dynamic_cast(contents); if ( eBody ) { - assert( eBody ); + resip_assert( eBody ); Security* sec = mStack->getSecurity(); - assert(sec); + resip_assert(sec); contents = sec->decrypt( mAor.getAor(), eBody ); @@ -667,14 +667,14 @@ TuIM::processMessageRequest(SipMessage* msg) PlainContents* plain = dynamic_cast(contents); if ( plain ) { - assert( plain ); + resip_assert( plain ); const Data& text = plain->text(); DebugLog ( << "got message from with text of <" << text << ">" ); Uri from = msg->header(h_From).uri(); DebugLog ( << "got message from " << from ); - assert( mCallback ); + resip_assert( mCallback ); mCallback->receivedPage( text, from, signedBy, sigStat, encrypted ); return; } @@ -682,7 +682,7 @@ TuIM::processMessageRequest(SipMessage* msg) CpimContents* cpim = dynamic_cast(contents); if ( cpim ) { - assert( cpim ); + resip_assert( cpim ); const Data& text = cpim->text(); DebugLog ( << "got CPIM message from with text of <" << text << ">" ); @@ -690,7 +690,7 @@ TuIM::processMessageRequest(SipMessage* msg) Uri from = msg->header(h_From).uri(); DebugLog ( << "got message from " << from ); - assert( mCallback ); + resip_assert( mCallback ); mCallback->receivedPage( text, from, signedBy, sigStat, encrypted ); return; } @@ -708,7 +708,7 @@ TuIM::processMessageRequest(SipMessage* msg) ++i) { Contents* c = *i; - assert( c ); + resip_assert( c ); InfoLog ( << "mixed has a " << c->getType() ); if ( c->getType() == Mime("text","plain") ) @@ -718,14 +718,14 @@ TuIM::processMessageRequest(SipMessage* msg) PlainContents* plainBody = dynamic_cast(c); if ( plainBody ) { - assert( plainBody ); + resip_assert( plainBody ); const Data& text = plainBody->text(); DebugLog ( << "got message from with text of <" << text << ">" ); Uri from = msg->header(h_From).uri(); DebugLog ( << "got message from " << from ); - assert( mCallback ); + resip_assert( mCallback ); mCallback->receivedPage( text, from, signedBy, sigStat, encrypted ); return; } @@ -742,14 +742,14 @@ TuIM::processMessageRequest(SipMessage* msg) OctetContents* octets = dynamic_cast(contents); if (octets) { - assert( contents ); + resip_assert( contents ); const Data& text = octets->getBodyData(); DebugLog ( << "got message from with text of <" << text << ">" ); Uri from = msg->header(h_From).uri(); DebugLog ( << "got message from " << from ); - assert( mCallback ); + resip_assert( mCallback ); mCallback->receivedPage( text, from, signedBy, sigStat, encrypted ); return; } @@ -769,9 +769,9 @@ TuIM::processMessageRequest(SipMessage* msg) void TuIM::processResponse(SipMessage* msg) { - assert( msg->exists(h_CallId)); + resip_assert( msg->exists(h_CallId)); CallId id = msg->header(h_CallId); - assert( id.value() != Data::Empty ); + resip_assert( id.value() != Data::Empty ); processSipFrag( msg ); @@ -795,7 +795,7 @@ TuIM::processResponse(SipMessage* msg) for ( BuddyIterator i=mBuddies.begin(); i != mBuddies.end(); i++) { Buddy& buddy = *i; - assert( buddy.presDialog ); + resip_assert( buddy.presDialog ); InfoLog( << "check buddy id =" << buddy.presDialog->getCallId() ); if ( buddy.presDialog->getCallId() == id ) { @@ -808,7 +808,7 @@ TuIM::processResponse(SipMessage* msg) // see if it is a publish response for ( StateAgentIterator i=mStateAgents.begin(); i != mStateAgents.end(); i++) { - assert( i->dialog ); + resip_assert( i->dialog ); InfoLog( << "check publish id =" << i->dialog->getCallId() ); if ( i->dialog->getCallId() == id ) { @@ -822,7 +822,7 @@ TuIM::processResponse(SipMessage* msg) for ( SubscriberIterator i=mSubscribers.begin(); i != mSubscribers.end(); i++) { DeprecatedDialog* dialog = i->dialog; - assert( dialog ); + resip_assert( dialog ); InfoLog( << "check subscriber id =" << dialog->getCallId() ); if ( dialog->getCallId() == id ) { @@ -835,7 +835,7 @@ TuIM::processResponse(SipMessage* msg) // see if it is a page response for ( PageIterator i=mPages.begin(); i != mPages.end(); i++) { - assert( i->dialog ); + resip_assert( i->dialog ); InfoLog( << "check page id =" << i->dialog->getCallId() ); if ( i->dialog->getCallId() == id ) { @@ -897,7 +897,7 @@ TuIM::processRegisterResponse(SipMessage* msg) if ( number >= 300 ) { - assert( mCallback ); + resip_assert( mCallback ); mCallback->registrationFailed( to, number ); return; } @@ -985,7 +985,7 @@ TuIM::processPageResponse(SipMessage* msg, Page& page ) if ( number >= 400 ) { Uri dest = msg->header(h_To).uri(); - assert( mCallback ); + resip_assert( mCallback ); mCallback->sendPageFailed( dest,number ); } @@ -1040,7 +1040,7 @@ TuIM::processSubscribeResponse(SipMessage* msg, Buddy& buddy) expires = 15; } - assert( buddy.presDialog ); + resip_assert( buddy.presDialog ); buddy.presDialog->createDialogAsUAC( *msg ); buddy.mNextTimeToSubscribe = Timer::getRandomFutureTimeMs( expires*1000 ); @@ -1068,7 +1068,7 @@ TuIM::processSubscribeResponse(SipMessage* msg, Buddy& buddy) // take this buddy off line Uri to = msg->header(h_To).uri(); - assert( mCallback ); + resip_assert( mCallback ); bool changed = true; @@ -1101,7 +1101,7 @@ TuIM::processSubscribeResponse(SipMessage* msg, Buddy& buddy) void TuIM::process() { - assert( mStack ); + resip_assert( mStack ); UInt64 now = Timer::getTimeMs(); @@ -1110,7 +1110,7 @@ TuIM::process() { if ( mRegistrationDialog.isCreated() ) { - unique_ptr msg( mRegistrationDialog.makeRegister() ); + auto_ptr msg( mRegistrationDialog.makeRegister() ); msg->header(h_Expires).value() = mRegistrationTimeSeconds; setOutbound( *msg ); mStack->send( *msg ); @@ -1128,10 +1128,10 @@ TuIM::process() buddy.mNextTimeToSubscribe = Timer::getRandomFutureTimeMs( mSubscriptionTimeSeconds*1000 ); - assert( buddy.presDialog ); + resip_assert( buddy.presDialog ); if ( buddy.presDialog->isCreated() ) { - unique_ptr msg( buddy.presDialog->makeSubscribe() ); + auto_ptr msg( buddy.presDialog->makeSubscribe() ); msg->header(h_Event).value() = Data("presence");; msg->header(h_Accepts).push_back( Mime( "application","pidf+xml") ); @@ -1183,7 +1183,7 @@ TuIM::registerAor( const Uri& uri, const Data& password ) //contactName.uri() = mContact; //SipMessage* msg = Helper::makeRegister(aorName,aorName,contactName); - unique_ptr msg( mRegistrationDialog.makeInitialRegister(NameAddr(uri),NameAddr(uri)) ); + auto_ptr msg( mRegistrationDialog.makeInitialRegister(NameAddr(uri),NameAddr(uri)) ); msg->header(h_Expires).value() = mRegistrationTimeSeconds; msg->header(h_Contacts).front().param(p_expires) = mRegistrationTimeSeconds; @@ -1210,8 +1210,8 @@ TuIM::getNumBuddies() const const Uri TuIM::getBuddyUri(const int index) { - assert( index >= 0 ); - assert( index < getNumBuddies() ); + resip_assert( index >= 0 ); + resip_assert( index < getNumBuddies() ); return mBuddies[index].uri; } @@ -1220,8 +1220,8 @@ TuIM::getBuddyUri(const int index) const Data TuIM::getBuddyGroup(const int index) { - assert( index >= 0 ); - assert( index < getNumBuddies() ); + resip_assert( index >= 0 ); + resip_assert( index < getNumBuddies() ); return mBuddies[index].group; } @@ -1230,8 +1230,8 @@ TuIM::getBuddyGroup(const int index) bool TuIM::getBuddyStatus(const int index, Data* status) { - assert( index >= 0 ); - assert( index < getNumBuddies() ); + resip_assert( index >= 0 ); + resip_assert( index < getNumBuddies() ); if (status) { @@ -1248,7 +1248,7 @@ void TuIM::subscribeBuddy( Buddy& buddy ) { // subscribe to this budy - unique_ptr msg( buddy.presDialog->makeInitialSubscribe(NameAddr(buddy.uri),NameAddr(mAor)) ); + auto_ptr msg( buddy.presDialog->makeInitialSubscribe(NameAddr(buddy.uri),NameAddr(mAor)) ); msg->header(h_Event).value() = Data("presence");; msg->header(h_Accepts).push_back( Mime( "application","pidf+xml") ); @@ -1271,7 +1271,7 @@ TuIM::addBuddy( const Uri& uri, const Data& group ) buddy.status = Data::Empty; buddy.group = group; buddy.presDialog = new DeprecatedDialog( NameAddr(mContact) ); - assert( buddy.presDialog ); + resip_assert( buddy.presDialog ); subscribeBuddy( buddy ); @@ -1306,9 +1306,9 @@ TuIM::removeBuddy( const Uri& name) void TuIM::sendNotify(DeprecatedDialog* dialog) { - assert( dialog ); + resip_assert( dialog ); - unique_ptr msg( dialog->makeNotify() ); + auto_ptr msg( dialog->makeNotify() ); Pidf* pidf = new Pidf( *mPidf ); @@ -1330,9 +1330,9 @@ TuIM::sendNotify(DeprecatedDialog* dialog) void TuIM::sendPublish(StateAgent& sa) { - assert( sa.dialog ); + resip_assert( sa.dialog ); - unique_ptr msg( sa.dialog->makeInitialPublish(NameAddr(sa.uri),NameAddr(mAor)) ); + auto_ptr msg( sa.dialog->makeInitialPublish(NameAddr(sa.uri),NameAddr(mAor)) ); Pidf* pidf = new Pidf( *mPidf ); @@ -1357,13 +1357,13 @@ void TuIM::setMyPresence( const bool open, const Data& status, const Data& user ) { // TODO implement the pser user status (when user is not empty) - assert( mPidf ); + resip_assert( mPidf ); mPidf->setSimpleStatus( open, status, mContact.getAor() ); for ( SubscriberIterator i=mSubscribers.begin(); i != mSubscribers.end(); i++) { DeprecatedDialog* dialog = i->dialog; - assert( dialog ); + resip_assert( dialog ); sendNotify(dialog); } diff --git a/src/libs/resiprocate/resip/stack/TuSelector.cxx b/src/libs/resiprocate/resip/stack/TuSelector.cxx index f5b5c657..7af169a5 100644 --- a/src/libs/resiprocate/resip/stack/TuSelector.cxx +++ b/src/libs/resiprocate/resip/stack/TuSelector.cxx @@ -53,7 +53,7 @@ TuSelector::process() remove(msg->getTransactionUser()); break; default: - assert(0); + resip_assert(0); break; } delete msg; @@ -67,7 +67,7 @@ TuSelector::add(Message* msg, TimeLimitFifo::DepthUsage usage) { if (exists(msg->getTransactionUser())) { - DebugLog (<< "Send to TU: " << *(msg->getTransactionUser()) << " " << std::endl << std::endl << *msg); + DebugLog (<< "Send to " << *(msg->getTransactionUser()) << " " << std::endl << std::endl << *msg); msg->getTransactionUser()->postToTransactionUser(msg, usage); } else @@ -163,10 +163,17 @@ TuSelector::size() const } void -TuSelector::registerTransactionUser(TransactionUser& tu) +TuSelector::registerTransactionUser(TransactionUser& tu, const bool front) { mTuSelectorMode = true; - mTuList.push_back(Item(&tu)); + if(front) + { + mTuList.insert(mTuList.begin(), Item(&tu)); + } + else + { + mTuList.push_back(Item(&tu)); + } } void @@ -186,6 +193,7 @@ TuSelector::unregisterTransactionUser(TransactionUser& tu) TransactionUser* TuSelector::selectTransactionUser(const SipMessage& msg) { + DebugLog(<< "TuSelector::selectTransactionUser: Checking which TU message belongs to:" << std::endl << std::endl << msg); for(TuList::iterator it = mTuList.begin(); it != mTuList.end(); it++) { if (it->tu->isForMe(msg)) @@ -207,7 +215,7 @@ TuSelector::markShuttingDown(TransactionUser* tu) return; } } - assert(0); + resip_assert(0); } void @@ -223,7 +231,7 @@ TuSelector::remove(TransactionUser* tu) return; } } - assert(0); + resip_assert(0); } bool @@ -299,7 +307,7 @@ TuSelector::getRejectionBehavior(TransactionUser* tu) const return mCongestionManager->getRejectionBehavior(&mFallBackFifo); } -unsigned int +UInt32 TuSelector::getExpectedWait(TransactionUser* tu) const { if(tu) diff --git a/src/libs/resiprocate/resip/stack/TuSelector.hxx b/src/libs/resiprocate/resip/stack/TuSelector.hxx index 8a13d30d..24994c5d 100644 --- a/src/libs/resiprocate/resip/stack/TuSelector.hxx +++ b/src/libs/resiprocate/resip/stack/TuSelector.hxx @@ -31,7 +31,7 @@ class TuSelector TransactionUser* selectTransactionUser(const SipMessage& msg); bool haveTransactionUsers() const { return mTuSelectorMode; } - void registerTransactionUser(TransactionUser&); + void registerTransactionUser(TransactionUser&, const bool front = false); void requestTransactionUserShutdown(TransactionUser&); void unregisterTransactionUser(TransactionUser&); void process(); @@ -44,7 +44,7 @@ class TuSelector void setCongestionManager(CongestionManager* manager); CongestionManager::RejectionBehavior getRejectionBehavior(TransactionUser* tu) const; - unsigned int getExpectedWait(TransactionUser* tu) const; + UInt32 getExpectedWait(TransactionUser* tu) const; private: void remove(TransactionUser* tu); diff --git a/src/libs/resiprocate/resip/stack/Tuple.cxx b/src/libs/resiprocate/resip/stack/Tuple.cxx index 06876d48..f9dc0b01 100644 --- a/src/libs/resiprocate/resip/stack/Tuple.cxx +++ b/src/libs/resiprocate/resip/stack/Tuple.cxx @@ -8,7 +8,7 @@ #include #include #include -#include +#include "rutil/ResipAssert.h" #if !defined (WIN32) #include @@ -24,17 +24,18 @@ #include "rutil/HashMap.hxx" #include "rutil/MD5Stream.hxx" #include "rutil/Logger.hxx" -#include "resip/stack/Transport.hxx" - +#ifdef USE_NETNS +# include "rutil/NetNs.hxx" +#endif +using std::auto_ptr; using namespace resip; #define RESIPROCATE_SUBSYSTEM Subsystem::DNS Tuple::Tuple() : mFlowKey(0), - transportKey(0), - transport(0), + mTransportKey(0), onlyUseExistingConnection(false), mTransportType(UNKNOWN_TRANSPORT) { @@ -46,13 +47,12 @@ Tuple::Tuple() : Tuple::Tuple(const GenericIPAddress& genericAddress, TransportType type, const Data& targetDomain) : mFlowKey(0), - transportKey(0), - transport(0), + mTransportKey(0), onlyUseExistingConnection(false), mTransportType(type), mTargetDomain(targetDomain) { - setSockaddr(genericAddress); + setSockaddr(genericAddress); } @@ -60,13 +60,14 @@ Tuple::Tuple(const Data& printableAddr, int port, IpVersion ipVer, TransportType type, - const Data& targetDomain) : + const Data& targetDomain, + const Data& netNs) : mFlowKey(0), - transportKey(0), - transport(0), + mTransportKey(0), onlyUseExistingConnection(false), mTransportType(type), - mTargetDomain(targetDomain) + mTargetDomain(targetDomain), + mNetNs(netNs) { if (ipVer == V4) { @@ -98,7 +99,13 @@ Tuple::Tuple(const Data& printableAddr, DnsUtil::inet_pton( printableAddr, m_anonv6.sin6_addr); } #else - assert(0); + // avoid asserts since Tuples created via printableAddr can be created from items + // received from the wire or from configuration settings. Just create an IPV4 inaddr_any tuple. + //assert(0); + memset(&m_anonv4, 0, sizeof(m_anonv4)); + m_anonv4.sin_family = AF_INET; + m_anonv4.sin_port = htons(port); + m_anonv4.sin_addr.s_addr = htonl(INADDR_ANY); #endif } } @@ -106,13 +113,14 @@ Tuple::Tuple(const Data& printableAddr, Tuple::Tuple(const Data& printableAddr, int port, TransportType ptype, - const Data& targetDomain) : + const Data& targetDomain, + const Data& netNs) : mFlowKey(0), - transportKey(0), - transport(0), + mTransportKey(0), onlyUseExistingConnection(false), mTransportType(ptype), - mTargetDomain(targetDomain) + mTargetDomain(targetDomain), + mNetNs(netNs) { if (DnsUtil::isIpV4Address(printableAddr)) { @@ -122,29 +130,38 @@ Tuple::Tuple(const Data& printableAddr, m_anonv4.sin_family = AF_INET; m_anonv4.sin_port = htons(port); } - else - { #ifdef USE_IPV6 + else if(DnsUtil::isIpV6Address(printableAddr)) + { memset(&m_anonv6, 0, sizeof(m_anonv6)); DnsUtil::inet_pton( printableAddr, m_anonv6.sin6_addr); m_anonv6.sin6_family = AF_INET6; m_anonv6.sin6_port = htons(port); -#else - assert(0); + } #endif + else + { + // avoid asserts since Tuples created via printableAddr can be created from items + // received from the wire or from configuration settings. Just create an IPV4 inaddr_any tuple. + // assert(0); + memset(&m_anonv4, 0, sizeof(m_anonv4)); + m_anonv4.sin_family = AF_INET; + m_anonv4.sin_port = htons(port); + m_anonv4.sin_addr.s_addr = htonl(INADDR_ANY); } } Tuple::Tuple(const in_addr& ipv4, int port, TransportType ptype, - const Data& targetDomain) + const Data& targetDomain, + const Data& netNs) :mFlowKey(0), - transportKey(0), - transport(0), + mTransportKey(0), onlyUseExistingConnection(false), mTransportType(ptype), - mTargetDomain(targetDomain) + mTargetDomain(targetDomain), + mNetNs(netNs) { memset(&m_anonv4, 0, sizeof(sockaddr_in)); m_anonv4.sin_addr = ipv4; @@ -156,13 +173,14 @@ Tuple::Tuple(const in_addr& ipv4, Tuple::Tuple(const in6_addr& ipv6, int port, TransportType ptype, - const Data& targetDomaina) + const Data& targetDomaina, + const Data& netNs) :mFlowKey(0), - transportKey(0), - transport(0), + mTransportKey(0), onlyUseExistingConnection(false), mTransportType(ptype), - mTargetDomain(targetDomaina) + mTargetDomain(targetDomaina), + mNetNs(netNs) { memset(&m_anonv6, 0, sizeof(sockaddr_in6)); m_anonv6.sin6_addr = ipv6; @@ -175,8 +193,7 @@ Tuple::Tuple(const struct sockaddr& addr, TransportType ptype, const Data& targetDomain) : mFlowKey(0), - transportKey(0), - transport(0), + mTransportKey(0), onlyUseExistingConnection(false), mSockaddr(addr), mTransportType(ptype), @@ -194,7 +211,28 @@ Tuple::Tuple(const struct sockaddr& addr, #endif else { - assert(0); + resip_assert(0); + } +} + +void +Tuple::copySockaddrAnyPort(sockaddr *sa) +{ + memcpy(sa, &mSockaddr, length()); + // zero the port number + if (sa->sa_family == AF_INET) + { + ((sockaddr_in*)sa)->sin_port = 0; + } +#ifdef USE_IPV6 + else if (sa->sa_family == AF_INET6) + { + ((sockaddr_in6*)sa)->sin6_port = 0; + } +#endif + else + { + resip_assert(0); } } @@ -212,11 +250,19 @@ Tuple::setSockaddr(const GenericIPAddress& addr) } #else { - assert(0); + resip_assert(0); } #endif } +#ifdef USE_NETNS +# define TOKEN_SIZE 8 +# define TOKEN_IP_ADDRESS_OFFSET 4 +#else +# define TOKEN_SIZE 7 +# define TOKEN_IP_ADDRESS_OFFSET 3 +#endif + void Tuple::writeBinaryToken(const resip::Tuple& tuple, resip::Data& container, const Data& salt) { @@ -225,12 +271,12 @@ Tuple::writeBinaryToken(const resip::Tuple& tuple, resip::Data& container, const // bytes for V6, and 14 extra bytes for V4. // V6: sin6_len(1), sin6_flowinfo(4), flowId(4), onlyUseExistingConnection(1) // V4: sin_family(2 instead of 1), sin_zero(8), flowId(4), onlyUseExistingConnection(1) - UInt32 rawToken[7]; - memset(&rawToken, 0, 28); + UInt32 rawToken[TOKEN_SIZE]; + memset(&rawToken, 0, TOKEN_SIZE * 4); rawToken[0] = tuple.mFlowKey; - rawToken[1] = tuple.transportKey; + rawToken[1] = tuple.mTransportKey; // 0xXXXX0000 rawToken[2] += (tuple.getPort() << 16); @@ -244,26 +290,30 @@ Tuple::writeBinaryToken(const resip::Tuple& tuple, resip::Data& container, const rawToken[2] += 0x00000010; } +#ifdef USE_NETNS + rawToken[3] = NetNs::getNetNsId(tuple.getNetNs()); +#endif + #ifdef USE_IPV6 if(tuple.ipVersion()==V6) { // 0x0000000X rawToken[2] += 0x00000001; in6_addr address = reinterpret_cast(tuple.getSockaddr()).sin6_addr; - assert(sizeof(address)==16); - memcpy(&rawToken[3],&address,16); + resip_assert(sizeof(address)==16); + memcpy(&rawToken[TOKEN_IP_ADDRESS_OFFSET],&address,16); } else #endif { in_addr address = reinterpret_cast(tuple.getSockaddr()).sin_addr; - assert(sizeof(address)==4); - memcpy(&rawToken[3],&address,4); + resip_assert(sizeof(address)==4); + memcpy(&rawToken[TOKEN_IP_ADDRESS_OFFSET],&address,4); } container.clear(); - container.reserve(((tuple.ipVersion()==V6) ? 28 : 16) + (salt.empty() ? 0 : 32)); - container.append((char*)&rawToken[0],(tuple.ipVersion()==V6) ? 28 : 16); + container.reserve(((tuple.ipVersion()==V6) ? TOKEN_SIZE*4 : (TOKEN_SIZE-3)*4) + (salt.empty() ? 0 : 32)); + container.append((char*)&rawToken[0],(tuple.ipVersion()==V6) ? TOKEN_SIZE*4 : (TOKEN_SIZE-3)*4); if(!salt.empty()) { @@ -309,10 +359,10 @@ Tuple::makeTupleFromBinaryToken(const resip::Data& binaryFlowToken, const Data& UInt16 port= (rawToken[2] >> 16); // Now that we have the version we can do a more accurate check on the size - if(!((version==V4 && salt.empty() && binaryFlowToken.size()==16) || - (version==V4 && !salt.empty() && binaryFlowToken.size()==48) || - (version==V6 && salt.empty() && binaryFlowToken.size()==28) || - (version==V6 && !salt.empty() && binaryFlowToken.size()==60))) + if(!((version==V4 && salt.empty() && binaryFlowToken.size()==(TOKEN_SIZE-3)*4) || + (version==V4 && !salt.empty() && binaryFlowToken.size()==(TOKEN_SIZE-3)*4 + 32) || + (version==V6 && salt.empty() && binaryFlowToken.size()==TOKEN_SIZE*4) || + (version==V6 && !salt.empty() && binaryFlowToken.size()==TOKEN_SIZE*4 + 32))) { DebugLog(<<"Binary flow token is the wrong size for its IP version."); return Tuple(); @@ -321,7 +371,7 @@ Tuple::makeTupleFromBinaryToken(const resip::Data& binaryFlowToken, const Data& // If salt is specified, validate HMAC if(!salt.empty()) { - unsigned int tokenSizeLessHMAC = version == V4 ? 16 : 28; + unsigned int tokenSizeLessHMAC = version == V4 ? (TOKEN_SIZE-3)*4 : TOKEN_SIZE*4; Data flowTokenLessHMAC(Data::Share, binaryFlowToken.data(), tokenSizeLessHMAC); Data flowTokenHMAC(Data::Share, binaryFlowToken.data()+tokenSizeLessHMAC, 32); MD5Stream ms; @@ -333,28 +383,42 @@ Tuple::makeTupleFromBinaryToken(const resip::Data& binaryFlowToken, const Data& } } + Data netNs(""); +#ifdef USE_NETNS + int netNsId = rawToken[3]; + try + { + netNs = NetNs::getNetNsName(netNsId); + } + catch(NetNs::Exception e) + { + ErrLog(<< "Tuple binary token contained netns id: " << netNsId << "which does not exist." + << e); + } +#endif + if(version==V6) { #ifdef USE_IPV6 in6_addr address; - assert(sizeof(address)==16); - memcpy(&address,&rawToken[3],16); - Tuple result(address,port,type); + resip_assert(sizeof(address)==16); + memcpy(&address,&rawToken[TOKEN_IP_ADDRESS_OFFSET],16); + Tuple result(address, port, type, Data::Empty, netNs); #else - Tuple result(resip::Data::Empty, port, type); + Tuple result(resip::Data::Empty, port, type, Data::Empty, netNs); #endif result.mFlowKey=(FlowKey)mFlowKey; - result.transportKey = (TransportKey)transportKey; + result.mTransportKey = (TransportKey)transportKey; result.onlyUseExistingConnection=isRealFlow; return result; } in_addr address; - assert(sizeof(address)==4); - memcpy(&address,&rawToken[3],4); - Tuple result(address,port,type); + resip_assert(sizeof(address)==4); + memcpy(&address,&rawToken[TOKEN_IP_ADDRESS_OFFSET],4); + Tuple result(address, port, type, Data::Empty, netNs); result.mFlowKey=(FlowKey)mFlowKey; - result.transportKey = (TransportKey)transportKey; + result.mTransportKey = (TransportKey)transportKey; result.onlyUseExistingConnection=isRealFlow; return result; } @@ -394,7 +458,7 @@ Tuple::setPort(int port) #ifdef USE_IPV6 m_anonv6.sin6_port = htons(port); #else - assert(0); + resip_assert(0); #endif } } @@ -411,7 +475,7 @@ Tuple::getPort() const #ifdef USE_IPV6 return ntohs(m_anonv6.sin6_port); #else - assert(0); + resip_assert(0); #endif } @@ -458,7 +522,7 @@ Tuple::isLoopback() const } else { - assert(0); + resip_assert(0); } return false; @@ -506,7 +570,7 @@ Tuple::isPrivateAddress() const #endif else { - assert(0); + resip_assert(0); } return false; @@ -526,7 +590,7 @@ Tuple::length() const } #endif - assert(0); + resip_assert(0); return 0; } @@ -539,17 +603,19 @@ bool Tuple::operator==(const Tuple& rhs) const { return (m_anonv4.sin_port == rhs.m_anonv4.sin_port && mTransportType == rhs.mTransportType && - memcmp(&m_anonv4.sin_addr, &rhs.m_anonv4.sin_addr, sizeof(in_addr)) == 0); + memcmp(&m_anonv4.sin_addr, &rhs.m_anonv4.sin_addr, sizeof(in_addr)) == 0 && + rhs.mNetNs == mNetNs); } else // v6 { #ifdef USE_IPV6 return (m_anonv6.sin6_port == rhs.m_anonv6.sin6_port && mTransportType == rhs.mTransportType && - memcmp(&m_anonv6.sin6_addr, &rhs.m_anonv6.sin6_addr, sizeof(in6_addr)) == 0); + memcmp(&m_anonv6.sin6_addr, &rhs.m_anonv6.sin6_addr, sizeof(in6_addr)) == 0 && + rhs.mNetNs == mNetNs); #else - assert(0); - return false; + resip_assert(0); + return false; #endif } } @@ -572,6 +638,22 @@ Tuple::operator<(const Tuple& rhs) const { return false; } + +#ifdef USE_NETNS + // netns needs to be checked before port and address as the port/address + // comparison bails out in equal case. Ideally netns comparison should + // be last as its the most expensive comparison. For now putting it here + // for minimal code change + else if(mNetNs < rhs.mNetNs) + { + return(true); + } + else if(mNetNs > rhs.mNetNs) + { + return(false); + } +#endif + else if (mSockaddr.sa_family == AF_INET && rhs.mSockaddr.sa_family == AF_INET) { int c=memcmp(&m_anonv4.sin_addr, @@ -630,6 +712,7 @@ Tuple::operator<(const Tuple& rhs) const return false; } #endif + else { //assert(0); @@ -655,16 +738,31 @@ resip::operator<<(EncodeStream& ostrm, const Tuple& tuple) } else { - assert(0); + resip_assert(0); } ostrm << " " << Tuple::toData(tuple.mTransportType); - ostrm << " target domain="; - if (tuple.mTargetDomain.empty()) ostrm << "unspecified"; - else ostrm << tuple.mTargetDomain; + + if (!tuple.mTargetDomain.empty()) + { + ostrm << " targetDomain=" << tuple.mTargetDomain; + } - ostrm << " mFlowKey=" << tuple.mFlowKey - << " ]"; + if(tuple.mFlowKey != 0) + { + ostrm << " flowKey=" << tuple.mFlowKey; + } + + if(tuple.mTransportKey != 0) + { + ostrm << " transportKey=" << tuple.mTransportKey; + } + +#ifdef USE_NETNS + ostrm << " mNetNs=" << tuple.mNetNs; +#endif + + ostrm << " ]"; return ostrm; } @@ -680,6 +778,9 @@ Tuple::hash() const reinterpret_cast(mSockaddr); return size_t(Data(Data::Share, (const char *)&in6.sin6_addr.s6_addr, sizeof(in6.sin6_addr.s6_addr)).hash() + +#ifdef USE_NETNS + mNetNs.hash() + +#endif 5*in6.sin6_port + 25*mTransportType); } @@ -690,6 +791,9 @@ Tuple::hash() const reinterpret_cast(mSockaddr); return size_t(in4.sin_addr.s_addr + +#ifdef USE_NETNS + mNetNs.hash() + +#endif 5*in4.sin_port + 25*mTransportType); } @@ -755,8 +859,8 @@ Tuple::isEqualWithMask(const Tuple& compare, short mask, bool ignorePort, bool i if(ignorePort || addr1->sin6_port == addr2->sin6_port) { - unsigned long mask6part; - unsigned long temp; + UInt32 mask6part; + UInt32 temp; bool match=true; for(int i = 3; i >= 0; i--) { @@ -788,8 +892,8 @@ Tuple::isEqualWithMask(const Tuple& compare, short mask, bool ignorePort, bool i if((*((unsigned long*)&addr1->sin6_addr.__u6_addr.__u6_addr32[i]) & htonl(mask6part)) != (*((unsigned long*)&addr2->sin6_addr.__u6_addr.__u6_addr32[i]) & htonl(mask6part))) #else - if((*((unsigned long*)&addr1->sin6_addr.s6_addr16[i*2]) & htonl(mask6part)) != - (*((unsigned long*)&addr2->sin6_addr.s6_addr16[i*2]) & htonl(mask6part))) + if((*((UInt32*)&addr1->sin6_addr.s6_addr16[i*2]) & htonl(mask6part)) != + (*((UInt32*)&addr2->sin6_addr.s6_addr16[i*2]) & htonl(mask6part))) #endif { match=false; @@ -874,7 +978,9 @@ Tuple::AnyPortCompare::operator()(const Tuple& lhs, { return false; } - else if (lhs.mSockaddr.sa_family == AF_INET && rhs.mSockaddr.sa_family == AF_INET) + + // transport types equal, so compare addresses + if (lhs.mSockaddr.sa_family == AF_INET && rhs.mSockaddr.sa_family == AF_INET) { int c = memcmp(&lhs.m_anonv4.sin_addr, &rhs.m_anonv4.sin_addr, @@ -916,6 +1022,20 @@ Tuple::AnyPortCompare::operator()(const Tuple& lhs, return false; } #endif +#ifdef USE_NETNS + // transport type and addresses are equal, so compare netns + if(lhs.mNetNs < rhs.mNetNs) + { + //DebugLog(<< "AnyPortCompare netns less than (l=" << lhs.mNetNs << ", r=" << rhs.mNetNs); + return(true); + } + else if(rhs.mNetNs < lhs.mNetNs) + { + //DebugLog(<< "AnyPortCompare netns greater than (l=" << lhs.mNetNs << ", r=" << rhs.mNetNs); + return(false); + } + //DebugLog(<< "AnyPortCompare netns equal to (l=\"" << lhs.mNetNs << "\", r=\"" << rhs.mNetNs << "\""); +#endif return false; } @@ -945,7 +1065,7 @@ Tuple::toGenericIPAddress() const } #else { - assert(0); + resip_assert(0); return m_anonv4; //bogus } #endif diff --git a/src/libs/resiprocate/resip/stack/Tuple.hxx b/src/libs/resiprocate/resip/stack/Tuple.hxx index d49f3596..f087cdf0 100644 --- a/src/libs/resiprocate/resip/stack/Tuple.hxx +++ b/src/libs/resiprocate/resip/stack/Tuple.hxx @@ -5,6 +5,7 @@ #include "config.h" #endif +#include #include "rutil/Socket.hxx" #include "rutil/compat.hxx" @@ -24,13 +25,12 @@ namespace resip { struct GenericIPAddress; -class Transport; // WARNING!! // When you change this structure, make sure to update the hash function, -// operator== and operator< to be consistent with the new structure. For -// instance, the Connection* and Transport* change value in the Tuple over -// its lifetime so they must not be included in the hash or comparisons. +// operator== and operator< to be consistent with the new structure. Be +// careful not to include members that change value in the Tuple over +// its lifetime (they must not be included in the hash or comparisons). typedef unsigned long FlowKey; typedef unsigned long TransportKey; @@ -52,8 +52,6 @@ typedef unsigned long TransportKey; Also included are some comparator classes that can be used for containers of Tuple. - - */ class Tuple { @@ -70,17 +68,20 @@ class Tuple int port, IpVersion ipVer, TransportType type=UNKNOWN_TRANSPORT, - const Data& targetDomain = Data::Empty); + const Data& targetDomain = Data::Empty, + const Data& netNs = Data::Empty); Tuple(const Data& printableAddress, int port, TransportType type, - const Data& targetDomain = Data::Empty); + const Data& targetDomain = Data::Empty, + const Data& netNs = Data::Empty); Tuple(const in_addr& pipv4, int pport, TransportType ptype, - const Data& targetDomain = Data::Empty); + const Data& targetDomain = Data::Empty, + const Data& netNs = Data::Empty); Tuple(const sockaddr& addr, TransportType ptype, @@ -97,7 +98,8 @@ class Tuple Tuple(const in6_addr& pipv6, int pport, TransportType ptype, - const Data& targetDomain = Data::Empty); + const Data& targetDomain = Data::Empty, + const Data& netNs = Data::Empty); #endif /// @brief Retrieve a const binary representation of the socket address @@ -107,24 +109,26 @@ class Tuple /// @brief Retrieve the binary representation of the socket address for /// this tuple. sockaddr& getMutableSockaddr() { return mSockaddr; } + /// @brief Get a copy of the socket address including the interface and + /// not the port number + void copySockaddrAnyPort(sockaddr *sa); /// @brief Set the internal binary representation of the socket address /// from the GenericIPAddress. void setSockaddr(const GenericIPAddress &); TransportType getType() const { return mTransportType; } - void setType(TransportType type) { mTransportType = type ;} + void setType(TransportType type) { mTransportType = type; } void setPort(int port); int getPort() const; - inline FlowKey getFlowKey() const { return mFlowKey;} + inline FlowKey getFlowKey() const { return mFlowKey; } /// @deprecated use ipVersion() - /// @todo !dcm! -- should deprecate asap + /// @todo !dcm! -- should deprecate asap bool isV4() const; /// Returns V4 or V6 as appropriate. IpVersion ipVersion() const; - void setIpVersion(IpVersion version); /// @brief TRUE if this address is equal to the "INADDR_ANY" value for /// this address family. @@ -175,10 +179,8 @@ class Tuple /// (It is highly recommended that these ids are unique across all /// instances of a transport type) FlowKey mFlowKey; - TransportKey transportKey; + TransportKey mTransportKey; - // deprecate - Transport* transport; bool onlyUseExistingConnection; /// @brief compares this tuple with the one passed in for family, port @@ -240,7 +242,19 @@ class Tuple { return mTargetDomain; } - + + /// @brief Set the netns (network namespace) for this Tuple + void setNetNs(const Data& netNs) + { + mNetNs = netNs; + } + + /// @brief Get the netns for this Tuple + const Data& getNetNs() const + { + return(mNetNs); + } + /** @brief Creates a 32-bit hash based on the contents of this Tuple. */ @@ -256,11 +270,13 @@ private: // ?bwc? Is there a more standard preprocessor macro for this? sockaddr_in6 m_anonv6; #endif - char pad[28]; //< this make union same size if v6 is in or out + char pad[RESIP_MAX_SOCKADDR_SIZE]; //< this make union same size if v6 is in or out }; TransportType mTransportType; Data mTargetDomain; + Data mNetNs; ///< The network namespace to which the address and port are scoped + friend EncodeStream& operator<<(EncodeStream& strm, const Tuple& tuple); friend class DnsResult; }; diff --git a/src/libs/resiprocate/resip/stack/TupleMarkManager.cxx b/src/libs/resiprocate/resip/stack/TupleMarkManager.cxx index 80e23862..2a5a19c2 100644 --- a/src/libs/resiprocate/resip/stack/TupleMarkManager.cxx +++ b/src/libs/resiprocate/resip/stack/TupleMarkManager.cxx @@ -11,7 +11,6 @@ TupleMarkManager::MarkType TupleMarkManager::getMarkType(const Tuple& tuple) { ListEntry entry(tuple,0); - resip::Lock g(mListMutex); TupleList::iterator i=mList.find(entry); if(i!=mList.end()) @@ -39,7 +38,6 @@ void TupleMarkManager::mark(const Tuple& tuple,UInt64 expiry,MarkType mark) // .amr. Notify listeners first so they can change the entry if they want notifyListeners(tuple,expiry,mark); ListEntry entry(tuple,expiry); - resip::Lock g(mListMutex); mList[entry]=mark; } diff --git a/src/libs/resiprocate/resip/stack/TupleMarkManager.hxx b/src/libs/resiprocate/resip/stack/TupleMarkManager.hxx index 13692a25..e12e9fc7 100644 --- a/src/libs/resiprocate/resip/stack/TupleMarkManager.hxx +++ b/src/libs/resiprocate/resip/stack/TupleMarkManager.hxx @@ -50,9 +50,7 @@ class TupleMarkManager }; typedef std::map TupleList; - TupleList mList; - resip::Mutex mListMutex; typedef std::set Listeners; Listeners mListeners; diff --git a/src/libs/resiprocate/resip/stack/UdpTransport.cxx b/src/libs/resiprocate/resip/stack/UdpTransport.cxx index 0a2fd48f..0332894a 100644 --- a/src/libs/resiprocate/resip/stack/UdpTransport.cxx +++ b/src/libs/resiprocate/resip/stack/UdpTransport.cxx @@ -44,7 +44,7 @@ UdpTransport::UdpTransport(Fifo& fifo, mPollEventCnt = 0; mTxTryCnt = mTxMsgCnt = mTxFailCnt = 0; mRxTryCnt = mRxMsgCnt = mRxKeepaliveCnt = mRxTransactionCnt = 0; - mTuple.setType(transport()); + mTuple.setType(UDP); mFd = InternalTransport::socket(transport(), version); mTuple.mFlowKey=(FlowKey)mFd; bind(); // also makes it non-blocking @@ -120,8 +120,8 @@ UdpTransport::setPollGrp(FdPollGrp *grp) * Called after a message is added. Could try writing it now. */ void -UdpTransport::process() { - mStateMachineFifo.flush(); +UdpTransport::process() +{ if ( (mTransportFlags & RESIP_TRANSPORT_FLAG_TXNOW)!= 0 ) { processTxAll(); @@ -129,8 +129,13 @@ UdpTransport::process() { // shouldn't ever happen (with current code) // but in future we may throttle transmits } + if ( mPollGrp ) + { updateEvents(); + } + + mStateMachineFifo.flush(); } void @@ -140,14 +145,12 @@ UdpTransport::updateEvents() bool haveMsg = mTxFifoOutBuffer.messageAvailable(); if ( !mInWritable && haveMsg ) { - if (mPollGrp) - mPollGrp->modPollItem(mPollItemHandle, FPEM_Read|FPEM_Write); + mPollGrp->modPollItem(mPollItemHandle, FPEM_Read|FPEM_Write); mInWritable = true; } else if ( mInWritable && !haveMsg ) { - if (mPollGrp) - mPollGrp->modPollItem(mPollItemHandle, FPEM_Read); + mPollGrp->modPollItem(mPollItemHandle, FPEM_Read); mInWritable = false; } } @@ -159,7 +162,7 @@ UdpTransport::processPollEvent(FdPollEventMask mask) ++mPollEventCnt; if ( mask & FPEM_Error ) { - assert(0); + resip_assert(0); } if ( mask & FPEM_Write ) { @@ -170,6 +173,7 @@ UdpTransport::processPollEvent(FdPollEventMask mask) { processRxAll(); } + mStateMachineFifo.flush(); } /** @@ -200,7 +204,6 @@ UdpTransport::process(FdSet& fdset) // pull buffers to send out of TxFifo // receive datagrams from fd // preparse and stuff into RxFifo - if (fdset.readyToWrite(mFd)) { processTxAll(); @@ -228,19 +231,26 @@ UdpTransport::processTxAll() processTxOne(msg); // With UDP we don't need to worry about write blocking (I hope) if ( (mTransportFlags & RESIP_TRANSPORT_FLAG_TXALL)==0 ) + { break; + } } } void UdpTransport::processTxOne(SendData *data) { + resip_assert(data); + if(data->command != SendData::NoCommand) + { + // We don't handle any special SendData commands in the UDP transport yet. + return; + } ++mTxMsgCnt; - assert(data); - std::unique_ptr sendData(data); + std::auto_ptr sendData(data); //DebugLog (<< "Sent: " << sendData->data); //DebugLog (<< "Sending message on udp."); - assert( sendData->destination.getPort() != 0 ); + resip_assert( sendData->destination.getPort() != 0 ); const sockaddr& addr = sendData->destination.getSockaddr(); int expected; @@ -278,12 +288,6 @@ UdpTransport::processTxOne(SendData *data) sendData->data.data(), (int)sendData->data.size(), 0, // flags &addr, (int)sendData->destination.length()); - if (mTransportLogger && count != SOCKET_ERROR) - { - mTransportLogger->onSipMessage(TransportLogger::Flow_Sent, sendData->data.data(), - sendData->data.size(), &addr, sendData->destination.length()); - } - } if ( count == SOCKET_ERROR ) @@ -324,23 +328,29 @@ UdpTransport::processRxAll() Tuple sender(mTuple); int len = processRxRecv(buffer, sender); if ( len <= 0 ) + { break; + } ++mRxMsgCnt; if ( processRxParse(buffer, len, sender) ) { buffer = NULL; } - if ( (mTransportFlags & RESIP_TRANSPORT_FLAG_RXALL)==0 ) + if ( (mTransportFlags & RESIP_TRANSPORT_FLAG_RXALL) == 0 ) + { break; + } } if ( buffer && (mTransportFlags & RESIP_TRANSPORT_FLAG_KEEP_BUFFER)!=0 ) { - assert(mRxBuffer==NULL); + resip_assert(mRxBuffer==NULL); mRxBuffer = buffer; buffer = NULL; } if ( buffer ) + { delete[] buffer; + } } /* @@ -367,7 +377,8 @@ UdpTransport::processRxRecv(char*& buffer, Tuple& sender) buffer = MsgHeaderScanner::allocateBuffer(MaxBufferSize); } - for (;;) { + for (;;) + { // !jf! how do we tell if it discarded bytes // !ah! we use the len-1 trick :-( socklen_t slen = sender.length(); @@ -380,7 +391,7 @@ UdpTransport::processRxRecv(char*& buffer, Tuple& sender) if ( len == SOCKET_ERROR ) { int err = getErrno(); - if ( err != EWOULDBLOCK ) + if ( err != EAGAIN && err != EWOULDBLOCK ) // Treat EGAIN and EWOULDBLOCK as the same: http://stackoverflow.com/questions/7003234/which-systems-define-eagain-and-ewouldblock-as-different-values { error( err ); } @@ -450,12 +461,12 @@ UdpTransport::processRxParse(char *buffer, int len, Tuple& sender) else if(resp.hasMappedAddress) { #if defined(WIN32) - sin_addr.S_un.S_addr = htonl(resp.mappedAddress.ipv4.addr); + sin_addr.S_un.S_addr = htonl(resp.mappedAddress.ipv4.addr); #else - sin_addr.s_addr = htonl(resp.mappedAddress.ipv4.addr); + sin_addr.s_addr = htonl(resp.mappedAddress.ipv4.addr); #endif - mStunMappedAddress = Tuple(sin_addr,resp.mappedAddress.ipv4.port, UDP); - mStunSuccess = true; + mStunMappedAddress = Tuple(sin_addr,resp.mappedAddress.ipv4.port, UDP); + mStunSuccess = true; } } return false; @@ -520,53 +531,45 @@ UdpTransport::processRxParse(char *buffer, int len, Tuple& sender) // Attempt to decode SigComp message, if appropriate. if ((buffer[0] & 0xf8) == 0xf8) { - if (!mCompression.isEnabled()) - { - InfoLog(<< "Discarding unexpected SigComp Message"); - return false; - } + if (!mCompression.isEnabled()) + { + InfoLog(<< "Discarding unexpected SigComp Message"); + return false; + } #ifdef USE_SIGCOMP - char* newBuffer = MsgHeaderScanner::allocateBuffer(MaxBufferSize); - size_t uncompressedLength = - mSigcompStack->uncompressMessage(buffer, len, - newBuffer, MaxBufferSize, sc); + char* newBuffer = MsgHeaderScanner::allocateBuffer(MaxBufferSize); + size_t uncompressedLength = mSigcompStack->uncompressMessage(buffer, len, newBuffer, MaxBufferSize, sc); - DebugLog (<< "Uncompressed message from " - << len << " bytes to " - << uncompressedLength << " bytes"); + DebugLog (<< "Uncompressed message from " + << len << " bytes to " + << uncompressedLength << " bytes"); + osc::SigcompMessage *nack = mSigcompStack->getNack(); - osc::SigcompMessage *nack = mSigcompStack->getNack(); + if (nack) + { + mTxFifo.add(new SendData(tuple, + Data(nack->getDatagramMessage(), + nack->getDatagramLength()), + Data::Empty, + Data::Empty, + true)); + delete nack; + } - if (nack) - { - mTxFifo.add(new SendData(tuple, - Data(nack->getDatagramMessage(), - nack->getDatagramLength()), - Data::Empty, - Data::Empty, - true) - ); - delete nack; - } - - // delete[] buffer; NO: let caller do this if needed - origBufferConsumed = false; - buffer = newBuffer; - len = uncompressedLength; + // delete[] buffer; NO: let caller do this if needed + origBufferConsumed = false; + buffer = newBuffer; + len = uncompressedLength; #endif } buffer[len]=0; // null terminate the buffer string just to make debug easier and reduce errors - if (mTransportLogger) - { - mTransportLogger->onSipMessage(TransportLogger::Flow_Received, buffer, len, &sender.getSockaddr(), sender.length()); - } //DebugLog ( << "UDP Rcv : " << len << " b" ); //DebugLog ( << Data(buffer, len).escaped().c_str()); - SipMessage* message = new SipMessage(this); + SipMessage* message = new SipMessage(&mTuple); // set the received from information into the received= parameter in the // via @@ -574,11 +577,7 @@ UdpTransport::processRxParse(char *buffer, int len, Tuple& sender) // It is presumed that UDP Datagrams are arriving atomically and that // each one is a unique SIP message - // Save all the info where this message came from - sender.transport = this; - sender.transportKey = getKey(); - sender.mFlowKey=mTuple.mFlowKey; message->setSource(sender); //DebugLog (<< "Received from: " << sender); @@ -598,13 +597,13 @@ UdpTransport::processRxParse(char *buffer, int len, Tuple& sender) StackLog(<< Data(Data::Borrow, buffer, len)); if(mExternalUnknownDatagramHandler) { - unique_ptr datagram(new Data(buffer,len)); - (*mExternalUnknownDatagramHandler)(this,sender, std::move(datagram)); + auto_ptr datagram(new Data(buffer,len)); + (*mExternalUnknownDatagramHandler)(this,sender,datagram); } // Idea: consider backing buffer out of message and letting caller reuse it delete message; - message = nullptr; + message=0; return origBufferConsumed; } @@ -640,21 +639,21 @@ UdpTransport::processRxParse(char *buffer, int len, Tuple& sender) // .bwc. This handles all appropriate checking for whether // this is a response or an ACK. - std::unique_ptr tryLater(make503(*message, getExpectedWaitForIncoming()/1000)); + std::auto_ptr tryLater(make503(*message, getExpectedWaitForIncoming()/1000)); if(tryLater.get()) { - send(std::move(tryLater)); + send(tryLater); } - delete message; // dropping message due to congestion - message = nullptr; - return origBufferConsumed; + delete message; // dropping message due to congestion + message = 0; + return origBufferConsumed; } if (!basicCheck(*message)) { delete message; // cannot use it, so, punt on it... // basicCheck queued any response required - message = nullptr; + message = 0; return origBufferConsumed; } @@ -663,49 +662,46 @@ UdpTransport::processRxParse(char *buffer, int len, Tuple& sender) #ifdef USE_SIGCOMP if (mCompression.isEnabled() && sc) { - const Via &via = message->header(h_Vias).front(); - if (message->isRequest()) - { - // For requests, the compartment ID is read out of the - // top via header field; if not present, we use the - // TCP connection for identification purposes. - if (via.exists(p_sigcompId)) - { - Data compId = via.param(p_sigcompId); + const Via &via = message->header(h_Vias).front(); + if (message->isRequest()) + { + // For requests, the compartment ID is read out of the + // top via header field; if not present, we use the + // TCP connection for identification purposes. + if (via.exists(p_sigcompId)) + { + Data compId = via.param(p_sigcompId); + if(!compId.empty()) + { + // .bwc. Crash was happening here. Why was there an empty sigcomp id? + mSigcompStack->provideCompartmentId(sc, compId.data(), compId.size()); + } + } + else + { + mSigcompStack->provideCompartmentId(sc, this, sizeof(this)); + } + } + else + { + // For responses, the compartment ID is supposed to be + // the same as the compartment ID of the request. We + // *could* dig down into the transaction layer to try to + // figure this out, but that's a royal pain, and a rather + // severe layer violation. In practice, we're going to ferret + // the ID out of the the Via header field, which is where we + // squirreled it away when we sent this request in the first place. + // !bwc! This probably shouldn't be going out over the wire. + Data compId = via.param(p_branch).getSigcompCompartment(); if(!compId.empty()) { - // .bwc. Crash was happening here. Why was there an empty sigcomp - // id? - mSigcompStack->provideCompartmentId( - sc, compId.data(), compId.size()); + mSigcompStack->provideCompartmentId(sc, compId.data(), compId.size()); } - } - else - { - mSigcompStack->provideCompartmentId(sc, this, sizeof(this)); - } - } - else - { - // For responses, the compartment ID is supposed to be - // the same as the compartment ID of the request. We - // *could* dig down into the transaction layer to try to - // figure this out, but that's a royal pain, and a rather - // severe layer violation. In practice, we're going to ferret - // the ID out of the the Via header field, which is where we - // squirreled it away when we sent this request in the first place. - // !bwc! This probably shouldn't be going out over the wire. - Data compId = via.param(p_branch).getSigcompCompartment(); - if(!compId.empty()) - { - mSigcompStack->provideCompartmentId(sc, compId.data(), compId.size()); - } - } - + } } #endif - mStateMachineFifo.add(message); + pushRxMsgUp(message); ++mRxTransactionCnt; return origBufferConsumed; } diff --git a/src/libs/resiprocate/resip/stack/UdpTransport.hxx b/src/libs/resiprocate/resip/stack/UdpTransport.hxx index 4ad574bc..78e9ce70 100644 --- a/src/libs/resiprocate/resip/stack/UdpTransport.hxx +++ b/src/libs/resiprocate/resip/stack/UdpTransport.hxx @@ -25,7 +25,7 @@ public: * @param transport contains a pointer to the specific UdpTransport object that * received the unknown packet. * @param unknownDatagram contains the actual contents of unknown data received. */ - virtual void operator()(UdpTransport* transport, const Tuple& source, std::unique_ptr unknownDatagram) = 0; + virtual void operator()(UdpTransport* transport, const Tuple& source, std::auto_ptr unknownDatagram) = 0; }; /** @@ -63,10 +63,9 @@ public: const Data& interfaceObj, AfterSocketCreationFuncPtr socketFunc = 0, Compression &compression = Compression::Disabled, - unsigned transportFlags = 0); + unsigned transportFlags = 0); virtual ~UdpTransport(); - virtual TransportType transport() const { return UDP; } virtual bool isReliable() const { return false; } virtual bool isDatagram() const { return true; } diff --git a/src/libs/resiprocate/resip/stack/Uri.cxx b/src/libs/resiprocate/resip/stack/Uri.cxx index 6b5a7542..9f905b6b 100644 --- a/src/libs/resiprocate/resip/stack/Uri.cxx +++ b/src/libs/resiprocate/resip/stack/Uri.cxx @@ -71,7 +71,10 @@ Uri::Uri(const Uri& rhs, mUserParameters(rhs.mUserParameters), mPort(rhs.mPort), mPassword(rhs.mPassword), + mNetNs(rhs.mNetNs), + mPath(rhs.mPath), mHostCanonicalized(rhs.mHostCanonicalized), + mCanonicalHost(rhs.mCanonicalHost), mEmbeddedHeadersText(rhs.mEmbeddedHeadersText.get() ? new Data(*rhs.mEmbeddedHeadersText) : 0), mEmbeddedHeaders(rhs.mEmbeddedHeaders.get() ? new SipMessage(*rhs.mEmbeddedHeaders) : 0) {} @@ -85,7 +88,7 @@ Uri::~Uri() Uri Uri::fromTel(const Uri& tel, const Data& host) { - assert(tel.scheme() == Symbols::Tel); + resip_assert(tel.scheme() == Symbols::Tel); Uri u; u.scheme() = Symbols::Sip; @@ -168,7 +171,7 @@ Uri::fromTel(const Uri& tel, const Data& host) Uri Uri::fromTel(const Uri& tel, const Uri& hostUri) { - assert(tel.scheme() == Symbols::Tel); + resip_assert(tel.scheme() == Symbols::Tel); Uri u(hostUri); u.scheme() = Symbols::Sip; @@ -252,6 +255,12 @@ Uri::isEnumSearchable() const checkParsed(); int digits = 0; + if(mScheme != Symbols::Tel) + { + StackLog(<< "not a tel Uri"); + return false; + } + if(mUser.size() < 4) { StackLog(<< "user part of Uri empty or too short for E.164"); @@ -269,14 +278,18 @@ Uri::isEnumSearchable() const // count the digits (skip the leading `+') for(const char* i=user().begin() + 1; i!= user().end(); i++) { - if(isdigit(*i)) + if (isdigit(*i)) + { digits++; + } else - if(*i != '-') + { + if (*i != '-') { StackLog(<< "user part of Uri contains non-digit: " << *i); return false; // Only digits and '-' permitted } + } } if(digits > 15) { @@ -314,7 +327,6 @@ Uri::getEnumLookups(const std::vector& suffixes) const return results; } - bool Uri::hasEmbedded() const { @@ -330,8 +342,6 @@ Uri::removeEmbedded() mEmbeddedHeadersText.reset(); } - - Uri& Uri::operator=(const Uri& rhs) { @@ -340,11 +350,14 @@ Uri::operator=(const Uri& rhs) ParserCategory::operator=(rhs); mScheme = rhs.mScheme; mHost = rhs.mHost; - mHostCanonicalized=rhs.mHostCanonicalized; + mPath = rhs.mPath; + mHostCanonicalized = rhs.mHostCanonicalized; + mCanonicalHost = rhs.mCanonicalHost; mUser = rhs.mUser; mUserParameters = rhs.mUserParameters; mPort = rhs.mPort; mPassword = rhs.mPassword; + mNetNs = rhs.mNetNs; if (rhs.mEmbeddedHeaders.get() != 0) { mEmbeddedHeaders.reset(new SipMessage(*rhs.mEmbeddedHeaders)); @@ -409,24 +422,23 @@ Uri::operator==(const Uri& other) const if (DnsUtil::isIpV6Address(mHost) && DnsUtil::isIpV6Address(other.mHost)) { - // compare canonicalized IPV6 addresses // update canonicalized if host changed if (!mHostCanonicalized) { - mHost = DnsUtil::canonicalizeIpV6Address(mHost); + mCanonicalHost = DnsUtil::canonicalizeIpV6Address(mHost); mHostCanonicalized=true; } // update canonicalized if host changed if (!other.mHostCanonicalized) { - other.mHost = DnsUtil::canonicalizeIpV6Address(other.mHost); + other.mCanonicalHost = DnsUtil::canonicalizeIpV6Address(other.mHost); other.mHostCanonicalized=true; } - if (mHost != other.mHost) + if (mCanonicalHost != other.mCanonicalHost) { return false; } @@ -443,7 +455,9 @@ Uri::operator==(const Uri& other) const ((isEqualNoCase(mScheme, Symbols::Sip) || isEqualNoCase(mScheme, Symbols::Sips)) ? mUser == other.mUser : isEqualNoCase(mUser, other.mUser)) && isEqualNoCase(mUserParameters,other.mUserParameters) && mPassword == other.mPassword && - mPort == other.mPort) + mPort == other.mPort && + mNetNs == other.mNetNs && + mPath == mPath) { for (ParameterList::const_iterator it = mParameters.begin(); it != mParameters.end(); ++it) { @@ -485,8 +499,8 @@ Uri::operator==(const Uri& other) const // ?bwc? It looks like we're just assuming the dynamic_cast // will succeed everywhere else; why are we bothering to // assert()? - assert(dp1); - assert(dp2); + resip_assert(dp1); + resip_assert(dp2); } if (!(otherParam && isEqualNoCase(dynamic_cast(*it)->value(), @@ -696,11 +710,12 @@ Uri::operator<(const Uri& other) const { if(DnsUtil::isIpV6Address(mHost)) { - mHost = DnsUtil::canonicalizeIpV6Address(mHost); + mCanonicalHost = DnsUtil::canonicalizeIpV6Address(mHost); } else { - mHost.lowercase(); + mCanonicalHost = mHost; + mCanonicalHost.lowercase(); } mHostCanonicalized=true; } @@ -709,21 +724,22 @@ Uri::operator<(const Uri& other) const { if(DnsUtil::isIpV6Address(other.mHost)) { - other.mHost = DnsUtil::canonicalizeIpV6Address(other.mHost); + other.mCanonicalHost = DnsUtil::canonicalizeIpV6Address(other.mHost); } else { - other.mHost.lowercase(); + other.mCanonicalHost = other.mHost; + other.mCanonicalHost.lowercase(); } other.mHostCanonicalized=true; } - if (mHost < other.mHost) + if (mCanonicalHost < other.mCanonicalHost) { return true; } - if (mHost > other.mHost) + if (mCanonicalHost > other.mCanonicalHost) { return false; } @@ -741,11 +757,12 @@ Uri::aorEqual(const resip::Uri& rhs) const { if(DnsUtil::isIpV6Address(mHost)) { - mHost = DnsUtil::canonicalizeIpV6Address(mHost); + mCanonicalHost = DnsUtil::canonicalizeIpV6Address(mHost); } else { - mHost.lowercase(); + mCanonicalHost = mHost; + mCanonicalHost.lowercase(); } mHostCanonicalized=true; } @@ -754,17 +771,18 @@ Uri::aorEqual(const resip::Uri& rhs) const { if(DnsUtil::isIpV6Address(rhs.mHost)) { - rhs.mHost = DnsUtil::canonicalizeIpV6Address(rhs.mHost); + rhs.mCanonicalHost = DnsUtil::canonicalizeIpV6Address(rhs.mHost); } else { - rhs.mHost.lowercase(); + rhs.mCanonicalHost = rhs.mHost; + rhs.mCanonicalHost.lowercase(); } rhs.mHostCanonicalized=true; } - return (mUser==rhs.mUser) && (mHost==rhs.mHost) && (mPort==rhs.mPort) && - (isEqualNoCase(mScheme,rhs.mScheme)); + return (mUser == rhs.mUser) && (mCanonicalHost == rhs.mCanonicalHost) && (mPort == rhs.mPort) && + isEqualNoCase(mScheme, rhs.mScheme) && (mNetNs == rhs.mNetNs); } void @@ -775,18 +793,19 @@ Uri::getAorInternal(bool dropScheme, bool addPort, Data& aor) const addPort = addPort && mPort!=0; - bool hostIsIpV6Address = false; + bool hostIsIpV6Address = DnsUtil::isIpV6Address(mHost); if(!mHostCanonicalized) { - if (DnsUtil::isIpV6Address(mHost)) + if (hostIsIpV6Address) { - mHost = DnsUtil::canonicalizeIpV6Address(mHost); - hostIsIpV6Address = true; + mCanonicalHost = DnsUtil::canonicalizeIpV6Address(mHost); } else { - mHost.lowercase(); + mCanonicalHost = mHost; + mCanonicalHost.lowercase(); } + mHostCanonicalized = true; } // !bwc! Maybe reintroduce caching of aor. (Would use a bool instead of the @@ -794,7 +813,7 @@ Uri::getAorInternal(bool dropScheme, bool addPort, Data& aor) const // @:10000 aor.clear(); aor.reserve((dropScheme ? 0 : mScheme.size()+1) - + mUser.size() + mHost.size() + 7); + + mUser.size() + mCanonicalHost.size() + 7); if(!dropScheme) { aor += mScheme; @@ -811,7 +830,7 @@ Uri::getAorInternal(bool dropScheme, bool addPort, Data& aor) const #else aor += mUser; #endif - if(!mHost.empty()) + if(!mCanonicalHost.empty()) { aor += Symbols::AT_SIGN; } @@ -820,12 +839,12 @@ Uri::getAorInternal(bool dropScheme, bool addPort, Data& aor) const if(hostIsIpV6Address && addPort) { aor += Symbols::LS_BRACKET; - aor += mHost; + aor += mCanonicalHost; aor += Symbols::RS_BRACKET; } else { - aor += mHost; + aor += mCanonicalHost; } if(addPort) @@ -978,6 +997,21 @@ Uri::parse(ParseBuffer& pb) { pb.skipWhitespace(); const char* start = pb.position(); + + // Relative URLs (typically HTTP) start with a slash. These + // are seen when parsing the WebSocket handshake. + if (*pb.position() == Symbols::SLASH[0]) + { + mScheme.clear(); + pb.skipToOneOf("?;", ParseBuffer::Whitespace); + pb.data(mPath, start); + if (!pb.eof() && !ParseBuffer::oneOf(*pb.position(), ParseBuffer::Whitespace)) + { + parseParameters(pb); + } + return; + } + pb.skipToOneOf(":@"); pb.assertNotEof(); @@ -1056,6 +1090,11 @@ Uri::parse(ParseBuffer& pb) pb.reset(start); } + if (pb.eof()) + { + return; + } + mHostCanonicalized=false; static std::bitset<256> hostDelimiter(Data::toBitset("\r\n\t :;?>")); if (*start == '[') @@ -1063,10 +1102,8 @@ Uri::parse(ParseBuffer& pb) start = pb.skipChar(); pb.skipToChar(']'); pb.data(mHost, start); - // .bwc. We do not save this canonicalization, since we weren't doing so - // before. This may change soon. - Data canonicalizedHost=DnsUtil::canonicalizeIpV6Address(mHost); - if(canonicalizedHost.empty()) + mCanonicalHost = DnsUtil::canonicalizeIpV6Address(mHost); + if (mCanonicalHost.empty()) { // .bwc. So the V6 addy is garbage. throw ParseException("Unparsable V6 address (note, this might" @@ -1074,6 +1111,7 @@ Uri::parse(ParseBuffer& pb) " enabled)","Uri",__FILE__, __LINE__); } + mHostCanonicalized = true; pb.skipChar(); pb.skipToOneOf(hostDelimiter); } @@ -1136,7 +1174,12 @@ void Uri::setUriPasswordEncoding(unsigned char c, bool encode) EncodeStream& Uri::encodeParsed(EncodeStream& str) const { - str << mScheme << Symbols::COLON; + // Relative URIs may not have the scheme + if (!mScheme.empty()) + { + str << mScheme << Symbols::COLON; + } + if (!mUser.empty()) { #ifdef HANDLE_CHARACTER_ESCAPING @@ -1177,6 +1220,10 @@ Uri::encodeParsed(EncodeStream& str) const { str << Symbols::COLON << mPort; } + if (!mPath.empty()) + { + str << mPath; + } encodeParameters(str); encodeEmbeddedHeaders(str); @@ -1357,6 +1404,8 @@ defineParam(extension, "ext", DataParameter, "RFC 3966"); // Token is used when defineParam(sigcompId, "sigcomp-id", QuotedDataParameter, "RFC 5049"); defineParam(rinstance, "rinstance", DataParameter, "proprietary (resip)"); defineParam(addTransport, "addTransport", ExistsParameter, "RESIP INTERNAL"); +defineParam(wsSrcIp, "ws-src-ip", DataParameter, "RESIP INTERNAL (WebSocket)"); +defineParam(wsSrcPort, "ws-src-port", UInt32Parameter, "RESIP INTERNAL (WebSocket)"); #undef defineParam diff --git a/src/libs/resiprocate/resip/stack/Uri.hxx b/src/libs/resiprocate/resip/stack/Uri.hxx index dc8f6b99..1a0a839f 100644 --- a/src/libs/resiprocate/resip/stack/Uri.hxx +++ b/src/libs/resiprocate/resip/stack/Uri.hxx @@ -2,7 +2,7 @@ #define RESIP_URI_HXX #include -#include +#include "rutil/ResipAssert.h" #include "resip/stack/ParserCategory.hxx" #include "resip/stack/Token.hxx" @@ -45,6 +45,8 @@ class Uri : public ParserCategory const Data& userParameters() const {checkParsed(); return mUserParameters;} Data& opaque() {checkParsed(); return mHost;} const Data& opaque() const {checkParsed(); return mHost;} + Data& path() {checkParsed(); return mPath;} + const Data& path() const {checkParsed(); return mPath;} // Returns user@host[:port] (no scheme) Data getAor() const; @@ -145,6 +147,9 @@ class Uri : public ParserCategory Data& password() {checkParsed(); return mPassword;} const Data& password() const {checkParsed(); return mPassword;} + Data& netNs() {return(mNetNs);} + const Data& netNs() const {return(mNetNs);} + Data toString() const; /** Returns true if the uri can be converted into a string that can be @@ -248,24 +253,28 @@ class Uri : public ParserCategory defineParam(sigcompId, "sigcomp-id", QuotedDataParameter, "RFC 5049"); defineParam(rinstance, "rinstance", DataParameter, "proprietary (resip)"); defineParam(addTransport, "addTransport", ExistsParameter, "RESIP INTERNAL"); + defineParam(wsSrcIp, "ws-src-ip", DataParameter, "RESIP INTERNAL (WebSocket)"); + defineParam(wsSrcPort, "ws-src-port", UInt32Parameter, "RESIP INTERNAL (WebSocket)"); #undef defineParam protected: Data mScheme; - // .bwc. I don't like this. - mutable Data mHost; + Data mHost; Data mUser; Data mUserParameters; int mPort; Data mPassword; + Data mNetNs; ///< Net namespace name scoping host and port + Data mPath; void getAorInternal(bool dropScheme, bool addPort, Data& aor) const; mutable bool mHostCanonicalized; + mutable Data mCanonicalHost; ///< cache for IPv6 host comparison private: - std::unique_ptr mEmbeddedHeadersText; - std::unique_ptr mEmbeddedHeaders; + std::auto_ptr mEmbeddedHeadersText; + std::auto_ptr mEmbeddedHeaders; static ParameterTypes::Factory ParameterFactories[ParameterTypes::MAX_PARAMETER]; diff --git a/src/libs/resiprocate/resip/stack/ValueFifo.hxx b/src/libs/resiprocate/resip/stack/ValueFifo.hxx index 1897ccd4..96ca5b39 100644 --- a/src/libs/resiprocate/resip/stack/ValueFifo.hxx +++ b/src/libs/resiprocate/resip/stack/ValueFifo.hxx @@ -105,8 +105,8 @@ class ValueFifo : public resip::FifoStatsInterface myTimerSize--; } - assert (myFifoSize > 0); - assert (!myList.empty()); + resip_assert (myFifoSize > 0); + resip_assert (!myList.empty()); T firstMessage = myList.front(); diff --git a/src/libs/resiprocate/resip/stack/Via.cxx b/src/libs/resiprocate/resip/stack/Via.cxx index 00c09fbd..e5a6ad39 100644 --- a/src/libs/resiprocate/resip/stack/Via.cxx +++ b/src/libs/resiprocate/resip/stack/Via.cxx @@ -3,6 +3,7 @@ #endif #include "resip/stack/Via.hxx" +#include "resip/stack/InteropHelper.hxx" #include "rutil/DnsUtil.hxx" #include "rutil/Logger.hxx" #include "rutil/ParseBuffer.hxx" @@ -27,7 +28,10 @@ Via::Via() { // insert a branch in all Vias (default constructor) this->param(p_branch); - this->param(p_rport); // add the rport parameter by default as per rfc 3581 + if(InteropHelper::getRportEnabled()) + { + this->param(p_rport); // add the rport parameter by default as per rfc 3581 + } } Via::Via(const HeaderFieldValue& hfv, diff --git a/src/libs/resiprocate/resip/stack/Worker.hxx b/src/libs/resiprocate/resip/stack/Worker.hxx new file mode 100644 index 00000000..7b09dc46 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/Worker.hxx @@ -0,0 +1,74 @@ +#ifndef WORKER_HXX +#define WORKER_HXX 1 + +#include "resip/stack/ApplicationMessage.hxx" +#include "rutil/ResipAssert.h" + +namespace resip +{ + +class Worker +{ + public: + Worker(){}; + virtual ~Worker(){}; + + // called once when the thread is started + virtual void onStart() {}; + + // return true to queue to stack when complete, false when no response is required + virtual bool process(resip::ApplicationMessage* msg)=0; + virtual Worker* clone() const=0; +}; +} +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * . + * + */ diff --git a/src/libs/resiprocate/rutil/DigestStream.cxx b/src/libs/resiprocate/resip/stack/WorkerThread.cxx similarity index 59% rename from src/libs/resiprocate/rutil/DigestStream.cxx rename to src/libs/resiprocate/resip/stack/WorkerThread.cxx index 0e3e023f..bfc9dc57 100644 --- a/src/libs/resiprocate/rutil/DigestStream.cxx +++ b/src/libs/resiprocate/resip/stack/WorkerThread.cxx @@ -1,95 +1,66 @@ -#include "rutil/DigestStream.hxx" +#include "resip/stack/WorkerThread.hxx" -// Remove warning about 'this' use in initiator list - pointer is only stored -#if defined(WIN32) && !defined(__GNUC__) -#pragma warning( disable : 4355 ) // using this in base member initializer list -#endif +#include "resip/stack/SipStack.hxx" +#include "resip/stack/ApplicationMessage.hxx" +#include "rutil/Logger.hxx" -using namespace resip; +#define RESIPROCATE_SUBSYSTEM resip::Subsystem::SIP -DigestBuffer::DigestBuffer(const EVP_MD* digest) +namespace resip { - EVP_MD_CTX_init(&mContext); - EVP_DigestInit_ex(&mContext, digest, 0); - setp(mBuf, mBuf + sizeof(mBuf)); -} -DigestBuffer::~DigestBuffer() -{ - EVP_MD_CTX_cleanup(&mContext); -} - -int -DigestBuffer::sync() -{ - size_t len = pptr() - pbase(); - if (len > 0) - { - EVP_DigestUpdate(&mContext, reinterpret_cast (pbase()), len); - // reset the put buffer - setp(mBuf, mBuf + sizeof(mBuf)); - } - return 0; -} - -int -DigestBuffer::overflow(int c) -{ - sync(); - if (c != -1) - { - mBuf[0] = c; - pbump(1); - return c; - } - return 0; -} - -Data -DigestBuffer::getHex() -{ - unsigned char buf[EVP_MD_CTX_size(&mContext)]; - unsigned int len; - EVP_DigestFinal_ex(&mContext, buf, &len); - - Data digest(Data::Share, (const char*)buf, len); - return digest.hex(); -} - -Data -DigestBuffer::getBin() -{ - unsigned char buf[EVP_MD_CTX_size(&mContext)]; - unsigned int len; - EVP_DigestFinal_ex(&mContext, buf, &len); - - Data digest(Data::Share, (const char*)buf, len); - return digest; -} - -DigestStream::DigestStream(const EVP_MD* digest) - : DigestBuffer(digest), std::ostream(this) -{ -} - -DigestStream::~DigestStream() +WorkerThread::WorkerThread(Worker* worker, + resip::TimeLimitFifo& fifo, + resip::SipStack* stack): + mWorker(worker), + mFifo(fifo), + mStack(stack) {} -Data -DigestStream::getHex() +WorkerThread::~WorkerThread() { - flush(); - return DigestBuffer::getHex(); - //return mStreambuf.getHex(); + shutdown(); + join(); + delete mWorker; } -Data -DigestStream::getBin() +void +WorkerThread::thread() { - flush(); - return DigestBuffer::getBin(); + resip::ApplicationMessage* msg; + bool queueToStack; + if(mWorker && !isShutdown()) + { + mWorker->onStart(); + while(mWorker && !isShutdown()) + { + if( (msg=mFifo.getNext(100)) != 0 ) + { + queueToStack = mWorker->process(msg); + + if(queueToStack && mStack) + { + StackLog(<<"async work done, posting to stack"); + // Post to stack instead of directly to TU, since stack does + // some safety checks to ensure the TU still exists before posting + mStack->post(std::auto_ptr(msg)); + } + else + { + StackLog(<<"discarding a message"); + if(!mStack) + { + WarningLog(<<"mStack == 0"); + } + delete msg; + } + } + } + } } +}//namespace resip + /* ==================================================================== * The Vovida Software License, Version 1.0 * diff --git a/src/libs/resiprocate/resip/stack/FloatParameter.cxx b/src/libs/resiprocate/resip/stack/WorkerThread.hxx similarity index 67% rename from src/libs/resiprocate/resip/stack/FloatParameter.cxx rename to src/libs/resiprocate/resip/stack/WorkerThread.hxx index 63d471fe..a2c1418f 100644 --- a/src/libs/resiprocate/resip/stack/FloatParameter.cxx +++ b/src/libs/resiprocate/resip/stack/WorkerThread.hxx @@ -1,54 +1,32 @@ -#if defined(HAVE_CONFIG_H) -#include "config.h" -#endif +#ifndef WORKER_THREAD_HXX +#define WORKER_THREAD_HXX 1 -#include "resip/stack/FloatParameter.hxx" -#include "rutil/ParseException.hxx" -#include "resip/stack/Symbols.hxx" -#include "rutil/ParseBuffer.hxx" -#include "rutil/Logger.hxx" -#include "rutil/WinLeakCheck.hxx" +#include "rutil/ThreadIf.hxx" +#include "resip/stack/Worker.hxx" +#include "rutil/TimeLimitFifo.hxx" +#include "resip/stack/ApplicationMessage.hxx" -using namespace resip; -using namespace std; - -#define RESIPROCATE_SUBSYSTEM Subsystem::SIP - -FloatParameter::FloatParameter(ParameterTypes::Type type, - ParseBuffer& pb, - const char* terminators) - : Parameter(type), - mValue(0) +namespace resip { - pb.skipWhitespace(); - if (!pb.eof() && *pb.position() != '=') - { - throw ParseException("parameter constructor expected '='", "FloatParameter", __FILE__, __LINE__); - } - pb.skipChar(); - pb.skipWhitespace(); - - // .dlb. not zero terminated; no error detection - mValue = pb.floatVal(); -} +class SipStack; -FloatParameter::FloatParameter(ParameterTypes::Type type) - : Parameter(type), - mValue(0.0) -{} +class WorkerThread : public resip::ThreadIf +{ + + public: + WorkerThread(Worker* impl,resip::TimeLimitFifo& fifo,resip::SipStack* stack); + virtual ~WorkerThread(); + void thread(); -Parameter* -FloatParameter::clone() const -{ - return new FloatParameter(*this); -} - -EncodeStream& -FloatParameter::encode(ostream& stream) const -{ - return stream << getName() << Symbols::EQUALS << mValue; + protected: + Worker* mWorker; + resip::TimeLimitFifo& mFifo; + resip::SipStack* mStack; + +}; } +#endif /* ==================================================================== * The Vovida Software License, Version 1.0 diff --git a/src/libs/resiprocate/resip/stack/WsBaseTransport.cxx b/src/libs/resiprocate/resip/stack/WsBaseTransport.cxx new file mode 100644 index 00000000..e88ff60c --- /dev/null +++ b/src/libs/resiprocate/resip/stack/WsBaseTransport.cxx @@ -0,0 +1,65 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include +#include "rutil/compat.hxx" +#include "rutil/Data.hxx" +#include "rutil/Socket.hxx" +#include "rutil/Logger.hxx" +#include "resip/stack/WsBaseTransport.hxx" +#include "resip/stack/WsConnection.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +using namespace std; +using namespace resip; + +WsBaseTransport::WsBaseTransport(SharedPtr connectionValidator, SharedPtr cookieContextFactory) + : mConnectionValidator(connectionValidator), + mCookieContextFactory(cookieContextFactory) +{ +} + +WsBaseTransport::~WsBaseTransport() +{ +} + +/* ==================================================================== + * + * Copyright 2013 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/resip/stack/WsBaseTransport.hxx b/src/libs/resiprocate/resip/stack/WsBaseTransport.hxx new file mode 100644 index 00000000..5e2bd6c2 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/WsBaseTransport.hxx @@ -0,0 +1,66 @@ +#if !defined(RESIP_WSBASETRANSPORT_HXX) +#define RESIP_WSBASETRANSPORT_HXX + +#include "resip/stack/WsConnectionValidator.hxx" +#include "resip/stack/WsCookieContextFactory.hxx" +#include "rutil/SharedPtr.hxx" + +namespace resip +{ + +class WsBaseTransport +{ + public: + RESIP_HeapCount(WsBaseTransport); + WsBaseTransport(SharedPtr = SharedPtr(), SharedPtr = SharedPtr(new BasicWsCookieContextFactory())); + virtual ~WsBaseTransport(); + + SharedPtr cookieContextFactory() { return mCookieContextFactory; }; + + protected: + SharedPtr mConnectionValidator; + SharedPtr mCookieContextFactory; +}; + +} + + +#endif + +/* ==================================================================== + * + * Copyright 2013 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/resip/stack/WsConnection.cxx b/src/libs/resiprocate/resip/stack/WsConnection.cxx new file mode 100644 index 00000000..dec987b6 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/WsConnection.cxx @@ -0,0 +1,57 @@ +#include "rutil/Logger.hxx" +#include "rutil/Socket.hxx" +#include "resip/stack/TcpConnection.hxx" +#include "resip/stack/WsConnection.hxx" +#include "resip/stack/Tuple.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +WsConnection::WsConnection(Transport* transport, + const Tuple& who, Socket fd, + Compression &compression, + SharedPtr wsConnectionValidator, + bool isServer) + : TcpConnection(transport,who, fd, compression, isServer), WsConnectionBase(wsConnectionValidator) +{ + DebugLog (<< "Creating WS connection " << who << " on " << fd); +} + + +/* ==================================================================== + * BSD License + * + * Copyright (c) 2013 Catalin Constantin Usurelu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + */ diff --git a/src/libs/resiprocate/resip/stack/WsConnection.hxx b/src/libs/resiprocate/resip/stack/WsConnection.hxx new file mode 100644 index 00000000..94cff0c3 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/WsConnection.hxx @@ -0,0 +1,68 @@ +#ifndef RESIP_WsConnection_hxx +#define RESIP_WsConnection_hxx + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include "resip/stack/TcpConnection.hxx" +#include "resip/stack/WsConnectionBase.hxx" +#include "rutil/SharedPtr.hxx" + +namespace resip +{ + +class WsConnection : public TcpConnection, public WsConnectionBase +{ + public: + WsConnection(Transport* transport, + const Tuple& who, Socket fd, + Compression &compression, + SharedPtr wsConnectionValidator, + bool isServer); + + private: + /// No default c'tor + WsConnection(); +}; + +} +#endif + + +/* ==================================================================== + * BSD License + * + * Copyright (c) 2013 Catalin Constantin Usurelu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + */ diff --git a/src/libs/resiprocate/resip/stack/WsConnectionBase.cxx b/src/libs/resiprocate/resip/stack/WsConnectionBase.cxx new file mode 100644 index 00000000..92e5e23d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/WsConnectionBase.cxx @@ -0,0 +1,59 @@ +#include "resip/stack/WsConnectionBase.hxx" + +using namespace resip; + +WsConnectionBase::WsConnectionBase() + : mWsConnectionValidator(SharedPtr()) // null pointer +{ +} + +WsConnectionBase::WsConnectionBase(SharedPtr wsConnectionValidator) + : mWsConnectionValidator(wsConnectionValidator) +{ +} + +WsConnectionBase::~WsConnectionBase() +{ +} + +SharedPtr WsConnectionBase::connectionValidator() const +{ + return mWsConnectionValidator; +} + +/* ==================================================================== + * BSD License + * + * Copyright (c) 2013 Catalin Constantin Usurelu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + */ diff --git a/src/libs/resiprocate/resip/stack/WsConnectionBase.hxx b/src/libs/resiprocate/resip/stack/WsConnectionBase.hxx new file mode 100644 index 00000000..38de0097 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/WsConnectionBase.hxx @@ -0,0 +1,74 @@ +#ifndef RESIP_WsConnectionBase_hxx +#define RESIP_WsConnectionBase_hxx + +#include +#include +#include +#include "rutil/Data.hxx" +#include "rutil/SharedPtr.hxx" + +#include + +namespace resip +{ + +class WsConnectionBase +{ + public: + WsConnectionBase(); + WsConnectionBase(SharedPtr mWsConnectionValidator); + virtual ~WsConnectionBase(); + + void setCookies(CookieList& cookies) { mCookies = cookies; }; + const CookieList& getCookies() const { return mCookies; }; + SharedPtr getWsCookieContext() const { return mWsCookieContext; } + void setWsCookieContext(SharedPtr wsCookieContext) { mWsCookieContext = wsCookieContext; } + SharedPtr connectionValidator() const; + + private: + CookieList mCookies; + SharedPtr mWsCookieContext; + SharedPtr mWsConnectionValidator; +}; + +} + +#endif + +/* ==================================================================== + * BSD License + * + * Copyright (c) 2013 Catalin Constantin Usurelu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + */ + diff --git a/src/libs/resiprocate/resip/stack/WsConnectionValidator.hxx b/src/libs/resiprocate/resip/stack/WsConnectionValidator.hxx new file mode 100644 index 00000000..204865c8 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/WsConnectionValidator.hxx @@ -0,0 +1,54 @@ +#ifndef RESIP_WsConnectionValidator_hxx +#define RESIP_WsConnectionValidator_hxx + +#include "WsCookieContext.hxx" + +namespace resip +{ + +class WsConnectionValidator +{ + public: + virtual bool validateConnection(const WsCookieContext& wsCookieContext)=0; +}; + +} + +#endif + +/* ==================================================================== + * BSD License + * + * Copyright (c) 2013 Catalin Constantin Usurelu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + */ diff --git a/src/libs/resiprocate/resip/stack/WsCookieContext.cxx b/src/libs/resiprocate/resip/stack/WsCookieContext.cxx new file mode 100644 index 00000000..3a0590ad --- /dev/null +++ b/src/libs/resiprocate/resip/stack/WsCookieContext.cxx @@ -0,0 +1,159 @@ +#include "resip/stack/WsCookieContext.hxx" +#include "resip/stack/Transport.hxx" +#include "resip/stack/UnknownParameterType.hxx" +#include "rutil/Data.hxx" +#include "rutil/Logger.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +WsCookieContext::WsCookieContext() +{ +} + +WsCookieContext::WsCookieContext(const WsCookieContext& rhs) +{ + mWsSessionInfo = rhs.getWsSessionInfo(); + mWsSessionExtra = rhs.getWsSessionExtra(); + mWsSessionMAC = rhs.getWsSessionMAC(); + mWsFromUri = rhs.getWsFromUri(); + mWsDestUri = rhs.getWsDestUri(); + mExpiresTime = rhs.getExpiresTime(); +} + + +WsCookieContext& WsCookieContext::operator=(const WsCookieContext& rhs) +{ + if(this != &rhs) + { + mWsSessionInfo = rhs.getWsSessionInfo(); + mWsSessionExtra = rhs.getWsSessionExtra(); + mWsSessionMAC = rhs.getWsSessionMAC(); + mWsFromUri = rhs.getWsFromUri(); + mWsDestUri = rhs.getWsDestUri(); + mExpiresTime = rhs.getExpiresTime(); + } + return *this; +} + +WsCookieContext::WsCookieContext(const CookieList& cookieList, const Data& infoCookieName, const Data& extraCookieName, const Data& macCookieName, const Uri& requestUri) +{ + for (CookieList::const_iterator it = cookieList.begin(); it != cookieList.end(); ++it) + { + if ((*it).name() == infoCookieName) + { + mWsSessionInfo = (*it).value(); + } + else if ((*it).name() == extraCookieName) + { + mWsSessionExtra = (*it).value(); + } + else if ((*it).name() == macCookieName) + { + mWsSessionMAC = (*it).value(); + } + } + + // If present, parameters in the request URI override those in the cookies + UnknownParameterType pInfo(infoCookieName); + if(requestUri.exists(pInfo)) + { + mWsSessionInfo = requestUri.param(pInfo).urlDecoded(); + } + UnknownParameterType pExtra(extraCookieName); + if(requestUri.exists(pExtra)) + { + mWsSessionExtra = requestUri.param(pExtra).urlDecoded(); + } + UnknownParameterType pMac(macCookieName); + if(requestUri.exists(pMac)) + { + mWsSessionMAC = requestUri.param(pMac).urlDecoded(); + } + + if(mWsSessionInfo.empty()) + { + ErrLog(<<"Cookie " << infoCookieName << " missing or empty"); + throw Transport::Exception("Required cookie missing", __FILE__, __LINE__); + } + if(mWsSessionMAC.empty()) + { + ErrLog(<<"Cookie " << macCookieName << " missing or empty"); + throw Transport::Exception("Required cookie missing", __FILE__, __LINE__); + } + + ParseBuffer pb(mWsSessionInfo); + StackLog(<<"Checking Cookie scheme version"); + int contextVersion = pb.uInt32(); + if(contextVersion != RESIP_WS_COOKIE_CONTEXT_VERSION) + { + // Cookie created for another version of the code + ErrLog(<<"Expecting cookie version " << RESIP_WS_COOKIE_CONTEXT_VERSION << " but found " << contextVersion); + throw ParseException("Cookie version mismatch", pb.getContext(), __FILE__, __LINE__); + } + pb.skipToChar(':'); + pb.skipChar(':'); + + pb.skipToChar(':'); // skip the creation time + pb.skipChar(':'); + mExpiresTime = (time_t) pb.uInt64(); + + const char* anchor; + Data uriString; + + pb.skipToChar(':'); + pb.skipChar(':'); + anchor = pb.position(); + pb.skipToChar(':'); + pb.data(uriString, anchor); + mWsFromUri = Uri("sip:" + uriString); + + pb.skipChar(':'); + anchor = pb.position(); + pb.skipToChar(':'); + pb.data(uriString, anchor); + mWsDestUri = Uri("sip:" + uriString); +} + +WsCookieContext::~WsCookieContext() +{ +} + + +/* ==================================================================== + * BSD License + * + * Copyright (c) 2013 Catalin Constantin Usurelu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + */ diff --git a/src/libs/resiprocate/resip/stack/WsCookieContext.hxx b/src/libs/resiprocate/resip/stack/WsCookieContext.hxx new file mode 100644 index 00000000..59ea5313 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/WsCookieContext.hxx @@ -0,0 +1,78 @@ +#ifndef RESIP_WsCookieContext_hxx +#define RESIP_WsCookieContext_hxx + +#include "Cookie.hxx" +#include "rutil/Data.hxx" +#include "Uri.hxx" + +#define RESIP_WS_COOKIE_CONTEXT_VERSION 1 + +namespace resip +{ + +class WsCookieContext +{ + public: + WsCookieContext(); + WsCookieContext(const CookieList& cookieList, const Data& infoCookieName, const Data& extraCookieName, const Data& macCookieName, const Uri& requestUri); + WsCookieContext(const WsCookieContext& rhs); + ~WsCookieContext(); + + WsCookieContext& operator=(const WsCookieContext& rhs); + + Data getWsSessionInfo() const { return mWsSessionInfo; }; + Data getWsSessionExtra() const { return mWsSessionExtra; }; + Data getWsSessionMAC() const { return mWsSessionMAC; }; + Uri getWsFromUri() const { return mWsFromUri; }; + Uri getWsDestUri() const { return mWsDestUri; }; + time_t getExpiresTime() const { return mExpiresTime; }; + + private: + Data mWsSessionInfo; + Data mWsSessionExtra; + Data mWsSessionMAC; + Uri mWsFromUri; + Uri mWsDestUri; + time_t mExpiresTime; +}; + +} + +#endif + +/* ==================================================================== + * BSD License + * + * Copyright (c) 2013 Catalin Constantin Usurelu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + */ diff --git a/src/libs/resiprocate/resip/stack/WsCookieContextFactory.hxx b/src/libs/resiprocate/resip/stack/WsCookieContextFactory.hxx new file mode 100644 index 00000000..e2d54f59 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/WsCookieContextFactory.hxx @@ -0,0 +1,87 @@ +#ifndef RESIP_WsCookieContextFactory_hxx +#define RESIP_WsCookieContextFactory_hxx + +#include "rutil/SharedPtr.hxx" + +#include "Cookie.hxx" +#include "rutil/Data.hxx" +#include "Uri.hxx" +#include "WsCookieContext.hxx" + +namespace resip +{ + +class WsCookieContextFactory +{ + protected: + WsCookieContextFactory() {}; + virtual ~WsCookieContextFactory() {}; + + public: + virtual SharedPtr makeCookieContext(const CookieList& cookieList, const Uri& requestUri) = 0; +}; + +class BasicWsCookieContextFactory : public WsCookieContextFactory +{ + public: + BasicWsCookieContextFactory(const Data& infoCookieName = "", const Data& extraCookieName = "", const Data& macCookieName = "") + : mInfoCookieName(infoCookieName.empty() ? "WSSessionInfo" : infoCookieName), + mExtraCookieName(extraCookieName.empty() ? "WSSessionExtra": extraCookieName), + macCookieName(macCookieName.empty() ? "WSSessionMAC" : macCookieName) + { + }; + + virtual ~BasicWsCookieContextFactory() {}; + + SharedPtr makeCookieContext(const CookieList& cookieList, const Uri& requestUri) + { + SharedPtr ctx(new WsCookieContext(cookieList, mInfoCookieName, mExtraCookieName, macCookieName, requestUri)); + return ctx; + }; + + private: + Data mInfoCookieName; + Data mExtraCookieName; + Data macCookieName; +}; + +} + +#endif + +/* ==================================================================== + * BSD License + * + * Copyright (c) 2013 Daniel Pocock http://danielpocock.com All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + */ diff --git a/src/libs/resiprocate/resip/stack/WsDecorator.cxx b/src/libs/resiprocate/resip/stack/WsDecorator.cxx new file mode 100644 index 00000000..7b646f2f --- /dev/null +++ b/src/libs/resiprocate/resip/stack/WsDecorator.cxx @@ -0,0 +1,100 @@ +#include "WsDecorator.hxx" + +#include "SipMessage.hxx" +#include "Tuple.hxx" +#include "Transport.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace std; +using namespace resip; + +WsDecorator::WsDecorator() +{ +} + +WsDecorator::~WsDecorator() +{ +} + +void +WsDecorator::decorateMessage(resip::SipMessage &msg, const resip::Tuple &source, const resip::Tuple &destination, const resip::Data& sigcompId) +{ + const resip::Tuple& wsSource = msg.getSource(); + + if(wsSource.getType() == resip::WS) + { + if(msg.exists(resip::h_Contacts)) + { + resip::NameAddr& contact = msg.header(resip::h_Contacts).front(); + + if (isEqualNoCase(contact.uri().host(), resip::Data("df7jal23ls0d.invalid"))) + { + contact.uri().host() = resip::Tuple::inet_ntop(source); + contact.uri().port() = source.getPort(); + contact.uri().param(resip::p_transport) = resip::Tuple::toDataLower(source.getType()); + + contact.uri().param(resip::p_wsSrcIp) = resip::Tuple::inet_ntop(wsSource); + contact.uri().param(resip::p_wsSrcPort) = wsSource.getPort(); + } + } + + if(msg.exists(resip::h_Vias)) + { + resip::Via &via = msg.header(resip::h_Vias).back(); + if(isEqualNoCase(via.sentHost(), resip::Data("df7jal23ls0d.invalid"))) + { + via.sentHost() = resip::Tuple::inet_ntop(wsSource); + via.sentPort() = wsSource.getPort(); + via.transport() = "TCP"; // most servers get crazy if we send "WS" as transport + } + } + } +} + +void +WsDecorator::rollbackMessage(resip::SipMessage& msg) +{ +} + +MessageDecorator* WsDecorator::clone() const +{ + return new WsDecorator(*this); +} + +/* ==================================================================== + * + * Copyright 2012 Doubango Telecom. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/resip/stack/WsDecorator.hxx b/src/libs/resiprocate/resip/stack/WsDecorator.hxx new file mode 100644 index 00000000..e38e9249 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/WsDecorator.hxx @@ -0,0 +1,63 @@ +#ifndef WSDecorator_Include_Guard +#define WSDecorator_Include_Guard + +#include "MessageDecorator.hxx" +#include "Tuple.hxx" + +namespace resip +{ +class WsDecorator : public MessageDecorator +{ + public: + WsDecorator(); + virtual ~WsDecorator(); + + virtual void decorateMessage(SipMessage &msg, + const Tuple &source, + const Tuple &destination, + const Data& sigcompId) ; + virtual void rollbackMessage(SipMessage& msg); + virtual MessageDecorator* clone() const; +}; + +}// namespace resip + +#endif /* WSDecorator_Include_Guard */ + +/* ==================================================================== + * + * Copyright 2012 Doubango Telecom. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/resip/stack/WsFrameExtractor.cxx b/src/libs/resiprocate/resip/stack/WsFrameExtractor.cxx new file mode 100644 index 00000000..8bab31fa --- /dev/null +++ b/src/libs/resiprocate/resip/stack/WsFrameExtractor.cxx @@ -0,0 +1,289 @@ + +#include "rutil/Logger.hxx" +#include "resip/stack/WsFrameExtractor.hxx" +#include "rutil/WinLeakCheck.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + + +const int WsFrameExtractor::mMaxHeaderLen = 14; + +WsFrameExtractor::WsFrameExtractor(Data::size_type maxMessage) + : mMaxMessage(maxMessage), + mMessageSize(0), + mHaveHeader(false), + mHeaderLen(0) +{ + // we re-use this for multiple messages throughout + // the lifetime of this parser object + mWsHeader = new UInt8[mMaxHeaderLen]; +} + +WsFrameExtractor::~WsFrameExtractor() +{ + // FIXME - delete any objects left in the queues + delete [] mWsHeader; + + while(!mFrames.empty()) + { + delete [] mFrames.front()->data(); + delete mFrames.front(); + mFrames.pop(); + } + + while(!mMessages.empty()) + { + delete [] mMessages.front()->data(); + delete mMessages.front(); + mMessages.pop(); + } + +} + +std::auto_ptr +WsFrameExtractor::processBytes(UInt8 *input, Data::size_type len, bool& dropConnection) +{ + std::auto_ptr ret(0); + dropConnection = false; + Data::size_type pos = 0; + while(input != 0 && pos < len) + { + while(!mHaveHeader && pos < len) + { + StackLog(<<"Need a header, parsing bytes..."); + // Append bytes to the header buffer + int needed = parseHeader(); + if(mHeaderLen >= mMaxHeaderLen) + { + WarningLog(<<"WS Frame header too long"); + dropConnection = true; + return ret; + } + for( ; needed > 0 && pos < len; needed-- ) + { + mWsHeader[mHeaderLen++] = input[pos++]; + } + if(needed > 0) + { + StackLog(<<"Not enough bytes available to form a full header"); + return ret; + } + } + if(mHaveHeader) + { + StackLog(<<"have header, parsing payload data..."); + // Process input bytes to output buffer, unmasking if necessary + if(mMessageSize + mPayloadLength > mMaxMessage) + { + WarningLog(<<"WS frame header describes a payload size bigger than messageSizeMax, max = " << mMaxMessage + << ", dropping connection"); + dropConnection = true; + return ret; + } + + if(mPayload == 0) + { + StackLog(<<"starting new frame buffer"); + // Include an extra byte at the end for null terminator + mPayload = (UInt8*)new char[mPayloadLength + 1]; + mPayloadPos = 0; + } + + Data::size_type takeBytes = len - pos; + if(takeBytes > mPayloadLength - mPayloadPos) + { + takeBytes = mPayloadLength - mPayloadPos; + } + + if(mMasked) + { + Data::size_type endOffset = mPayloadPos + takeBytes; + for( ; mPayloadPos < endOffset; mPayloadPos++) + { + mPayload[mPayloadPos] = (input[pos++] ^ mWsMaskKey[(mPayloadPos & 3)]); + } + } + else + { + memmove(&mPayload[mPayloadPos], &input[pos], takeBytes); + pos += takeBytes; + mPayloadPos += takeBytes; + } + + if(mPayloadPos == mPayloadLength) + { + StackLog(<<"Got a whole frame, queueing it"); + mMessageSize += mPayloadLength; + Data *mFrame = new Data(Data::Borrow, (char *)mPayload, mPayloadLength, mPayloadLength + 1); + mFrames.push(mFrame); + mHaveHeader = false; + mHeaderLen = 0; + mPayload = 0; + if(mFinalFrame) + { + joinFrames(); + } + } + } + } + if(mMessages.empty()) + { + StackLog(<<"no full messages available in queue"); + return ret; + } + ret = std::auto_ptr(mMessages.front()); + mMessages.pop(); + StackLog(<<"returning a message, size = " << ret->size()); + return ret; +} + +int +WsFrameExtractor::parseHeader() +{ + if(mHeaderLen < 2) + { + StackLog(<< "Too short to contain ws data [0]"); + return (2 - mHeaderLen); + } + + UInt64 hdrPos = 2; + + mFinalFrame = (mWsHeader[0] >> 7) != 0; + mMasked = (mWsHeader[1] >> 7) != 0; + + if(mWsHeader[0] & 0x40 || mWsHeader[0] & 0x20 || mWsHeader[0] & 0x10) + { + WarningLog(<< "Unknown extension: " << ((mWsHeader[0] >> 4) & 0x07)); + // do not exit + } + + mPayloadLength = mWsHeader[1] & 0x7F; + if(mPayloadLength == 126) + { + if(mHeaderLen < 4) + { + StackLog(<< "Too short to contain ws data [1]"); + return (4 - mHeaderLen) + (mMasked ? 4 : 0); + } + mPayloadLength = (mWsHeader[hdrPos] << 8 | mWsHeader[hdrPos + 1]); + hdrPos += 2; + } + else if(mPayloadLength == 127) + { + if(mHeaderLen < 8) + { + StackLog(<< "Too short to contain ws data [2]"); + return (8 - mHeaderLen) + (mMasked ? 4 : 0); + } + mPayloadLength = (((UInt64)mWsHeader[hdrPos]) << 56 | ((UInt64)mWsHeader[hdrPos + 1]) << 48 | ((UInt64)mWsHeader[hdrPos + 2]) << 40 | ((UInt64)mWsHeader[hdrPos + 3]) << 32 | ((UInt64)mWsHeader[hdrPos + 4]) << 24 | ((UInt64)mWsHeader[hdrPos + 5]) << 16 | ((UInt64)mWsHeader[hdrPos + 6]) << 8 || ((UInt64)mWsHeader[hdrPos + 7])); + hdrPos += 8; + } + + if(mMasked) + { + if((mHeaderLen - hdrPos) < 4) + { + StackLog(<< "Too short to contain ws data [3]"); + return (int)((hdrPos + 4) - mHeaderLen); + } + mWsMaskKey[0] = mWsHeader[hdrPos]; + mWsMaskKey[1] = mWsHeader[hdrPos + 1]; + mWsMaskKey[2] = mWsHeader[hdrPos + 2]; + mWsMaskKey[3] = mWsHeader[hdrPos + 3]; + hdrPos += 4; + } + + StackLog(<< "successfully processed a WebSocket frame header, payload length = " << mPayloadLength + << ", masked = "<< mMasked << ", final frame = "<< mFinalFrame); + + mHaveHeader = true; + mPayload = 0; + return 0; +} + +void +WsFrameExtractor::joinFrames() +{ + StackLog(<<"trying to join frames"); + if(mFrames.empty()) + { + ErrLog(<<"No frames to join!"); + return; + } + + Data *msg = mFrames.front(); + mFrames.pop(); + if(!mFrames.empty()) + { + // must expand buffer because there are multiple frames + // can't use Data::reserve() to increase the buffer, because the + // ShareEnum will change to Take when expanded + char *_msg = (char *)msg->data(); + Data::size_type frameSize = msg->size(); + delete msg; + + // allow extra byte for null terminator + char *newBuf = new char [mMessageSize + 1]; + memcpy(newBuf, _msg, frameSize); + + msg = new Data(Data::Borrow, newBuf, frameSize, mMessageSize + 1); + } + while(!mFrames.empty()) + { + Data *mFrame = mFrames.front(); + mFrames.pop(); + msg->append(mFrame->data(), mFrame->size()); + delete [] mFrame->data(); + delete mFrame; + } + + // It is safe to cast because we used Borrow: + char *_msg = (char *)msg->data(); + // MsgHeaderScanner expects space for an extra byte at the end: + _msg[mMessageSize] = 0; + + mMessages.push(msg); + + // Ready to start examinging first frame of next message... + mMessageSize = 0; +} + +/* ==================================================================== + * + * Copyright 2013 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/resip/stack/WsFrameExtractor.hxx b/src/libs/resiprocate/resip/stack/WsFrameExtractor.hxx new file mode 100644 index 00000000..0e1a3715 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/WsFrameExtractor.hxx @@ -0,0 +1,90 @@ +#ifndef RESIP_WsFrameExtractor_hxx +#define RESIP_WsFrameExtractor_hxx + +#include +#include + +#include "rutil/compat.hxx" +#include "rutil/Data.hxx" + +namespace resip +{ + +class WsFrameExtractor +{ + public: + + WsFrameExtractor(Data::size_type maxMessage); + ~WsFrameExtractor(); + std::auto_ptr processBytes(UInt8 *input, Data::size_type len, bool& dropConnection); + + private: + + static const int mMaxHeaderLen; + + Data::size_type mMaxMessage; + + std::queue mFrames; + std::queue mMessages; + // for tracking the cumulative size of all full frames + // not yet assembled into a message: + Data::size_type mMessageSize; + + bool mHaveHeader; + int mHeaderLen; + UInt8 *mWsHeader; + + bool mFinalFrame; + bool mMasked; + UInt8 mWsMaskKey[4]; + Data::size_type mPayloadLength; + + UInt8 *mPayload; + Data::size_type mPayloadPos; + + int parseHeader(); + void joinFrames(); + +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright 2013 Daniel Pocock. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/resip/stack/WsTransport.cxx b/src/libs/resiprocate/resip/stack/WsTransport.cxx new file mode 100644 index 00000000..2960aa12 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/WsTransport.cxx @@ -0,0 +1,88 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include +#include "rutil/compat.hxx" +#include "rutil/Data.hxx" +#include "rutil/Socket.hxx" +#include "rutil/Logger.hxx" +#include "resip/stack/WsTransport.hxx" +#include "resip/stack/WsConnection.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +using namespace std; +using namespace resip; + +WsTransport::WsTransport(Fifo& fifo, int portNum, + IpVersion version, const Data& pinterface, + AfterSocketCreationFuncPtr socketFunc, + Compression &compression, + unsigned transportFlags, + SharedPtr connectionValidator, + SharedPtr cookieContextFactory) +: TcpBaseTransport(fifo, portNum, version, pinterface, socketFunc, compression, transportFlags), + WsBaseTransport(connectionValidator, cookieContextFactory) +{ + mTuple.setType(WS); + + init(); + + InfoLog (<< "Creating WS transport host=" << pinterface + << " port=" << mTuple.getPort() + << " ipv4=" << bool(version==V4) ); + + mTxFifo.setDescription("WsTransport::mTxFifo"); +} + +WsTransport::~WsTransport() +{ +} + +Connection* +WsTransport::createConnection(const Tuple& who, Socket fd, bool server) +{ + resip_assert(this); + Connection* conn = new WsConnection(this,who, fd, mCompression, mConnectionValidator, server); + return conn; +} + +/* ==================================================================== + * + * Copyright 2012 Doubango Telecom. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/resip/stack/WsTransport.hxx b/src/libs/resiprocate/resip/stack/WsTransport.hxx new file mode 100644 index 00000000..73aaeea8 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/WsTransport.hxx @@ -0,0 +1,78 @@ +#if !defined(RESIP_WSTRANSPORT_HXX) +#define RESIP_WSTRANSPORT_HXX + +#include "resip/stack/WsBaseTransport.hxx" +#include "resip/stack/WsConnectionValidator.hxx" +#include "resip/stack/WsCookieContextFactory.hxx" +#include "resip/stack/TcpBaseTransport.hxx" +#include "resip/stack/Compression.hxx" +#include "rutil/SharedPtr.hxx" + +namespace resip +{ + +class Connection; +class Message; +class Security; + +class WsTransport : public TcpBaseTransport, public WsBaseTransport +{ + public: + RESIP_HeapCount(WsTransport); + WsTransport(Fifo& fifo, + int portNum, + IpVersion version, + const Data& interfaceObj, + AfterSocketCreationFuncPtr socketFunc=0, + Compression &compression = Compression::Disabled, + unsigned transportFlags = 0, + SharedPtr = SharedPtr(), + SharedPtr = SharedPtr(new BasicWsCookieContextFactory())); + virtual ~WsTransport(); + + protected: + Connection* createConnection(const Tuple& who, Socket fd, bool server=false); +}; + +} + + +#endif + +/* ==================================================================== + * + * Copyright 2012 Doubango Telecom. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/resip/stack/XMLCursor.cxx b/src/libs/resiprocate/resip/stack/XMLCursor.cxx deleted file mode 100644 index ba9850b1..00000000 --- a/src/libs/resiprocate/resip/stack/XMLCursor.cxx +++ /dev/null @@ -1,680 +0,0 @@ -#if defined(HAVE_CONFIG_H) -#include "resip/stack/config.hxx" -#endif - -#include "resip/stack/XMLCursor.hxx" -#include "resip/stack/Symbols.hxx" -#include "rutil/Logger.hxx" -#include "rutil/WinLeakCheck.hxx" - -using namespace resip; -using namespace std; - -#define RESIPROCATE_SUBSYSTEM Subsystem::CONTENTS - -/** -Whitespace handling: -Are the following XML fragments equivalent? - -Strictly interpreted, the root of the first XML document has one -child while the root of the second XML doucment has three children. -The line breaks and spaces after the and before are -tagless children. - ----> - child content -<-- - vs. ----> - - child content - -<-- - -Treating whitespace as children is consistent with the spec but not usually -convenient. is used to -control whitespace handling. Supporting this switch is painful. For now, treat -whitespace as non-significant. -*/ - -static char BANG[] = "!"; -static char HYPHEN[] = "-"; -//http://www.w3.org/TR/1998/REC-xml-19980210 -static const Data COMMENT_START(""); - -// An alternative to stripping comments out in preparse -// is to deal with them in the parse; ignore when after non-leaf element -// put a leaf after a comment after a leaf in the first leaf's children -// getValue() needs to copy first leaf and all 'child' leaves to mValue -// -// has the advantage of allowing -// 1. lazier parsing -// 2. embedded wierdnesses like and -XMLCursor::XMLCursor(const ParseBuffer& pb) - : mRoot(0), - mCursor(0), - mAttributesSet(false) -{ - ParseBuffer lPb(pb); - - skipProlog(lPb); - const char* start = lPb.position(); - - lPb.skipToChars(COMMENT_START); - if (!lPb.eof()) - { - StackLog(<< "removing comments"); - lPb.reset(start); - mData.reserve(lPb.end() - lPb.start()); - - const char* anchor = start; - { - DataStream str(mData); - Data temp; - while (true) - { - lPb.skipToChars(COMMENT_START); - if (!lPb.eof()) - { - lPb.data(temp, anchor); - str << temp; - anchor = Node::skipComments(lPb); - } - else - { - lPb.data(temp, anchor); - str << temp; - break; - } - } - } - mRoot = new Node(ParseBuffer(mData.data(), mData.size())); - } - else - { - mRoot = new Node(ParseBuffer(start, pb.end() - start)); - } - mCursor = mRoot; - - if (mRoot->extractTag()) - { - InfoLog(<< "XML: empty element no a legal root"); - mRoot->mPb.fail(__FILE__, __LINE__); - } - - mTag = mRoot->mTag; - decodeName(mRoot->mTag); - - // check for # & and note -- make decode, decodeName do stuff if set - - // // no children - ParseBuffer pbtemp(mRoot->mPb); - pbtemp.skipToChar(Symbols::RA_QUOTE[0]); - pbtemp.skipChar(); - if (!WhitespaceSignificant) - { - pbtemp.skipWhitespace(); - } - if (*pbtemp.position() == Symbols::LA_QUOTE[0] && - *(pbtemp.position()+1) == Symbols::SLASH[0]) - { - pbtemp.skipChar(); - pbtemp.skipChar(); - if (strncmp(mRoot->mTag.data(), pbtemp.position(), mRoot->mTag.size()) == 0) - { - // no children ever - mRoot->mPb.reset(mRoot->mPb.end()); - return; - } - } -} - -XMLCursor::~XMLCursor() -{ - delete mRoot; -} - -static const Data QUESTION_RA_QUOTE("?>"); -void -XMLCursor::skipProlog(ParseBuffer& pb) -{ - //''? ''? S? '?> - - // !dlb! much more complicated than this.. can contain comments - const char* start = pb.position(); - pb.skipToChars(QUESTION_RA_QUOTE); - if(pb.eof()) - { - // No Prolog - pb.reset(start); - return; - } - pb.skipN(2); - pb.skipWhitespace(); -} - -void -XMLCursor::decode(Data& text) -{ -} - -void -XMLCursor::decodeName(Data& name) -{ -} - -void -XMLCursor::parseNextRootChild() -{ - // no next child to parse? - if (mRoot->mPb.eof()) - { - return; - } - - // next child already parsed? - if (mRoot->mNext != mRoot->mChildren.end()) - { - return; - } - - // skip self tag - if (mRoot->mPb.position() == mRoot->mPb.start()) - { - mRoot->mPb.skipToChar(Symbols::RA_QUOTE[0]); - mRoot->mPb.skipChar(); - } - - if (!WhitespaceSignificant) - { - mRoot->mPb.skipWhitespace(); - } - - // root end tag? - if (*mRoot->mPb.position() == Symbols::LA_QUOTE[0]) - { - ParseBuffer pb(mRoot->mPb.position(), - mRoot->mPb.end() - mRoot->mPb.position()); - pb.skipChar(); - if (!pb.eof() && *pb.position() == Symbols::SLASH[0]) - { - pb.skipChar(); - // CodeWarrior isn't helpful enough to pick the "obvious" operator definition - // so we add volatile here so CW is completely unconfused what to do. - // second note - MSVC 7.0 won't compile the volatile - tried the following to fix - const char* end = pb.position(); - if ( (const char*)pb.end() < end + mTag.size() ) - { - InfoLog(<< "XML: unexpected end"); - pb.fail(__FILE__, __LINE__); - } - - if (strncmp(mTag.data(), pb.position(), mRoot->mTag.size()) == 0) - { - mRoot->mPb.skipToEnd(); - return; - } - } - } - - // leaf? - if (*mRoot->mPb.position() != Symbols::LA_QUOTE[0]) - { - const char* anchor = mRoot->mPb.position(); - mRoot->mPb.skipToChar(Symbols::LA_QUOTE[0]); - Node* leaf = new Node(ParseBuffer(anchor, mRoot->mPb.position() - anchor)); - leaf->mIsLeaf = true; - mRoot->addChild(leaf); - } - else - { - Node* child = new Node(mRoot->mPb); - child->skipToEndTag(); - - // leave the parse buffer after the child - mRoot->mPb.reset(child->mPb.end()); - - mRoot->addChild(child); - } - - // mNext always points at cursored child - mRoot->mNext = mRoot->mChildren.end(); - mRoot->mNext--; -} - -bool -XMLCursor::nextSibling() -{ - if (atRoot()) - { - StackLog(<< "XMLCursor::nextSibling" << *this->mCursor << " <>"); - return false; - } - - StackLog(<< "XMLCursor::nextSibling" << *this->mCursor << " " << *this->mCursor->mParent); - if (mCursor->mParent == mRoot) - { - parseNextRootChild(); - } - - if (mCursor->mParent->mNext != mCursor->mParent->mChildren.end()) - { - mCursor = *((mCursor->mParent->mNext)++); - mAttributesSet = false; - return true; - } - else - { - return false; - } -} - -bool -XMLCursor::firstChild() -{ - if (atRoot() && - mRoot->mChildren.empty()) - { - parseNextRootChild(); - } - - if (mCursor->mChildren.empty()) - { - return false; - } - else - { - // mNext always points after cursored child - mCursor->mNext = mCursor->mChildren.begin(); - mCursor->mNext++; - mCursor = mCursor->mChildren.front(); - mAttributesSet = false; - return true; - } -} - -bool -XMLCursor::parent() -{ - if (atRoot()) - { - return false; - } - - mCursor = mCursor->mParent; - mAttributesSet = false; - return true; -} - -void -XMLCursor::reset() -{ - mCursor = mRoot; - mAttributesSet = false; -} - -bool -XMLCursor::atRoot() const -{ - return mCursor == mRoot; -} - -bool -XMLCursor::atLeaf() const -{ - return mCursor->mIsLeaf; -} - -const Data& -XMLCursor::getTag() const -{ - return mCursor->mTag; -} - -// -// -// -// -// -// -// -static const Data RA_QUOTE_SLASH(">/"); -const XMLCursor::AttributeMap& -XMLCursor::getAttributes() const -{ - if (!atLeaf() && - !mAttributesSet) - { - mAttributes.clear(); - mAttributesSet = true; - - ParseBuffer pb(mCursor->mPb); - pb.reset(mCursor->mPb.start()); - - Data attribute; - Data value; - - pb.skipToOneOf(ParseBuffer::Whitespace, RA_QUOTE_SLASH); - - while (!pb.eof() && - *pb.position() != Symbols::RA_QUOTE[0] && - *pb.position() != Symbols::SLASH[0]) - { - attribute.clear(); - value.clear(); - - const char* anchor = pb.skipWhitespace(); - pb.skipToOneOf(ParseBuffer::Whitespace, Symbols::EQUALS); - pb.data(attribute, anchor); - XMLCursor::decodeName(attribute); - - StackLog(<< "attribute: " << attribute); - - pb.skipWhitespace(); - pb.skipToChar(Symbols::EQUALS[0]); - pb.skipChar(); - pb.skipWhitespace(); - if (!pb.eof()) - { - const char quote = *pb.position(); - - StackLog(<< "quote is <" << quote << ">"); - - if (quote != Symbols::DOUBLE_QUOTE[0] && - quote != '\'') - { - InfoLog(<< "XML: badly quoted attribute value"); - pb.fail(__FILE__, __LINE__); - } - anchor = pb.skipChar(); - pb.skipToChar(quote); - pb.data(value, anchor); - XMLCursor::decode(value); - pb.skipChar(); - mAttributes[attribute] = value; - } - pb.skipWhitespace(); - } - } - - return mAttributes; -} - -const Data& -XMLCursor::getValue() const -{ - if (atLeaf()) - { - ParseBuffer pb(mCursor->mPb); - pb.skipToEnd(); - mValue = pb.data(pb.start()); - XMLCursor::decode(mValue); - } - else - { - mValue.clear(); - } - return mValue; -} - -EncodeStream& -XMLCursor::encode(EncodeStream& str, const AttributeMap& attrs) -{ - for(AttributeMap::const_iterator i = attrs.begin(); - i != attrs.end(); ++i) - { - if (i != attrs.begin()) - { - str << " "; - } - // !dlb! some sort of character encoding required here - str << i->first << "=\"" << i->second << "\""; - } - - return str; -} - -XMLCursor::Node::Node(const ParseBuffer& pb) - : mPb(pb.position(), pb.end() - pb.position()), - mParent(0), - mChildren(), - mNext(mChildren.begin()), - mIsLeaf(false) -{ - mPb.assertNotEof(); - StackLog(<< "XMLCursor::Node::Node" << *this); -} - -XMLCursor::Node::~Node() -{ - for (vector::iterator i = mChildren.begin(); - i != mChildren.end(); ++i) - { - delete *i; - } -} - -// start: -// -//^ -// end: -// -// ^ -static Data SLASH_RA_QUOTE("/>"); -bool -XMLCursor::Node::extractTag() -{ - ParseBuffer pb(mPb); - const char* anchor = pb.skipChar(); - pb.skipToOneOf(ParseBuffer::Whitespace, SLASH_RA_QUOTE); - pb.assertNotEof(); - pb.data(mTag, anchor); - - return !pb.eof() && *pb.position() == Symbols::SLASH[0]; -} - -void -XMLCursor::Node::addChild(Node* child) -{ - mChildren.push_back(child); - child->mParent = this; -} - -// -//^start -// ^child -// ^child -// ^end -// -// sdfsf sadfsf asdfdf sadfsdf -//^start -// ^child -// ^child sub -// ^child -void -XMLCursor::Node::skipToEndTag() -{ - extractTag(); - StackLog(<< "XMLCursor::Node::skipToEndTag(" << mTag << ")"); - //StackLog(<< "XMLCursor::Node::skipToEndTag(" << Data(mPb.position(), mPb.end() - mPb.position()) << ")"); - - // - mPb.skipToChar(Symbols::RA_QUOTE[0]); - if (*(mPb.position()-1) == Symbols::SLASH[0]) - { - mPb.skipChar(); - mPb = ParseBuffer(mPb.start(), mPb.position() - mPb.start()); - return; - } - - // ... ... - // ^ - mPb.skipChar(); - // ... ... - // ^ - while (true) - { - if (!WhitespaceSignificant) - { - mPb.skipWhitespace(); - } - - // Some text contents ...< - // ^ ^ - if (*mPb.position() != Symbols::LA_QUOTE[0]) - { - const char* anchor = mPb.position(); - mPb.skipToChar(Symbols::LA_QUOTE[0]); - Node* leaf = new Node(ParseBuffer(anchor, mPb.position() - anchor)); - leaf->mIsLeaf = true; - addChild(leaf); - } - - //<... - //^ - mPb.skipChar(); - //<... - // ^ - - // exit condition - // - if (*mPb.position() == Symbols::SLASH[0]) - { - mPb.skipChar(); - // CodeWarrior isn't helpful enough to pick the "obvious" operator definition - // so we add volatile here so CW is completely unconfused what to do. - // second note - MSVC 7.0 won't compile the volatile - tried the following to fix - const char* end = mPb.position(); - if ( (const char*)mPb.end() < end + mTag.size() ) - { - InfoLog(<< "XML: unexpected end"); - mPb.fail(__FILE__, __LINE__); - } - - if (strncmp(mTag.data(), mPb.position(), mTag.size()) == 0) - { - mPb.skipToChar(Symbols::RA_QUOTE[0]); - mPb.skipChar(); - mPb = ParseBuffer(mPb.start(), mPb.position() - mPb.start()); - return; - } - else - { - InfoLog(<< "Badly formed XML: unexpected endtag"); - mPb.fail(__FILE__, __LINE__); - } - } - - //... - // ^ - if (mPb.position() == mPb.start()) - { - InfoLog(<< "XML: badly formed element"); - mPb.fail(__FILE__, __LINE__); - } - - mPb.reset(mPb.position()-1); - //... - //^ - Node* child = new Node(mPb); - addChild(child); - child->skipToEndTag(); - mPb.reset(child->mPb.end()); - XMLCursor::decodeName(child->mTag); - StackLog(<< mTag << "(" << child->mTag << ")"); - } -} - -// -const char* -XMLCursor::Node::skipComments(ParseBuffer& pb) -{ - while (*pb.position() == Symbols::LA_QUOTE[0] && - *(pb.position()+1) == BANG[0] && - *(pb.position()+2) == HYPHEN[0] && - *(pb.position()+3) == HYPHEN[0]) - { - pb.skipToChars(COMMENT_END); - pb.skipChars(COMMENT_END); - pb.skipWhitespace(); - if(pb.eof()) - { - return pb.end(); - } - } - - return pb.position(); -} - -EncodeStream& -resip::operator<<(EncodeStream& str, const XMLCursor::Node& node) -{ - Data::size_type size = node.mPb.end() - node.mPb.start(); - - static const Data::size_type showSize(35); - - str << &node << "[" - << Data(node.mPb.start(), - min(showSize, size)) - << "]" << (size ? "" : "..."); - - return str; -} - -EncodeStream& -resip::operator<<(EncodeStream& str, const XMLCursor& cursor) -{ - str << "XMLCursor " << *cursor.mCursor; - return str; -} - -/* ==================================================================== - * The Vovida Software License, Version 1.0 - * - * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The names "VOCAL", "Vovida Open Communication Application Library", - * and "Vovida Open Communication Application Library (VOCAL)" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact vocal@vovida.org. - * - * 4. Products derived from this software may not be called "VOCAL", nor - * may "VOCAL" appear in their name, without prior written - * permission of Vovida Networks, Inc. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND - * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA - * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES - * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ==================================================================== - * - * This software consists of voluntary contributions made by Vovida - * Networks, Inc. and many individuals on behalf of Vovida Networks, - * Inc. For more information on Vovida Networks, Inc., please see - * . - * - */ diff --git a/src/libs/resiprocate/resip/stack/XMLCursor.hxx b/src/libs/resiprocate/resip/stack/XMLCursor.hxx deleted file mode 100644 index ac27d647..00000000 --- a/src/libs/resiprocate/resip/stack/XMLCursor.hxx +++ /dev/null @@ -1,250 +0,0 @@ -#if !defined(RESIP_XMLCURSOR_HXX) -#define RESIP_XMLCURSOR_HXX - -#include -#include - -#include "rutil/ParseBuffer.hxx" -#include "rutil/HashMap.hxx" - -namespace resip -{ - -/* -// XML tree traversal. -// XMLCursor starts at the root. -// The attributes and value of the cursor are those of the root. -// To descend to the first child of the root, call firstChild(). -// To traverse the children of root from root, call firstChild();nextSibling();nextSibling();... -// To descend into the first child of the current element, call firstChild. -// To return to the parent of the current element, call parent. -// The traversal state among the siblings of the parent is maintained. -// -// root -// / \ -// P1 P2 -// / \ / \ -// A1 A2 B1 B2 -// -// atRoot() == true; -// firstChild(); // P1 -// firstChild(); // A1 -// nextSibling(); // A2 -// parent(); // P1 -// nextSibling(); // P2 -// firstChild(); // B1 -// nextSibling(); // B2 -// parent(); // P2 -// nextSibling(); // false, stay at P2 -// parent(); // root -// nextSibling(); // false, stay at root -// parent(); // false, stay at root -// firstChild(); // P1 - -// E.g.: Depth first traversal -// -// void traverse(XMLCursor& c) -// { -// if (c.firstChild()) -// { -// traverse(c); -// c.parent(); -// } -// -// process(c); -// -// if (c.nextSibling()) -// { -// traverse(c); -// } -// } -// -// E.g.: Lexical Order traversal -// -// void -// traverse(XMLCursor& c, int i = 0) -// { -// for (int ii = 0; ii < i; ++ii) -// { -// cerr << " "; -// } - -// cerr << c.getTag(); -// if (c.atLeaf()) -// { -// cerr << "[" << c.getValue() << "]" << endl; -// } -// else -// { -// cerr << endl; -// } - -// if (c.firstChild()) -// { -// traverse(c, i+2); -// c.parent(); -// } - -// if (c.nextSibling()) -// { -// traverse(c, i+2); -// } -// } - -*/ - -class XMLCursor -{ - public: - // !dlb! should be determined by the document - // see http://www.w3.org/TR/1998/REC-xml-19980210#sec-white-space - enum {WhitespaceSignificant = false}; - - XMLCursor(const ParseBuffer& pb); - ~XMLCursor(); - - bool nextSibling(); - bool firstChild(); - bool parent(); - void reset(); - - bool atRoot() const; - bool atLeaf() const; - - const Data& getTag() const; - typedef HashMap AttributeMap; - const AttributeMap& getAttributes() const; - const Data& getValue() const; - - static EncodeStream& encode(EncodeStream& strm, const AttributeMap& attrs); - class Node; - - class AttributeValueEqual { - Data data_; - public: - AttributeValueEqual(const Data& data) : data_(data) {}; - bool operator()(const std::pair& data) { return data.second == data_; } - }; - - private: - static void skipProlog(ParseBuffer& pb); - static void decode(Data&); - static void decodeName(Data&); - - void parseNextRootChild(); - - - Node* mRoot; - Node* mCursor; - - //bool isEmpty; - - // store for undecoded root tag - Data mTag; - - // store for copy of input if commented - Data mData; - - // store date for decoding - mutable Data mValue; - // store attributes for reference - mutable AttributeMap mAttributes; - mutable bool mAttributesSet; - -public: - class Node - { - public: - Node(const ParseBuffer& pb); - ~Node(); - - void addChild(Node*); - // return true if - bool extractTag(); - void skipToEndTag(); - static const char* skipComments(ParseBuffer& pb); - - ParseBuffer mPb; - Node* mParent; - std::vector mChildren; - std::vector::const_iterator mNext; - - bool mIsLeaf; - Data mTag; - - private: - Node(const Node&); - Node& operator=(const Node&); - - friend EncodeStream& operator<<(EncodeStream& str, const XMLCursor& cursor); - // friend EncodeStream& operator<<(EncodeStream& str, const XMLCursor::Node& cursor); // this line won't compile in windows - }; - private: - friend EncodeStream& operator<<(EncodeStream&, const XMLCursor&); - friend EncodeStream& operator<<(EncodeStream&, const XMLCursor::Node&); - - // no value semantics - XMLCursor(const XMLCursor&); - XMLCursor& operator=(const XMLCursor&); - friend class Node; -}; - -EncodeStream& -operator<<(EncodeStream& str, const XMLCursor& cursor); - -EncodeStream& -operator<<(EncodeStream& str, const XMLCursor::Node& cursor); - -} - -#endif - -/* ==================================================================== - * The Vovida Software License, Version 1.0 - * - * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The names "VOCAL", "Vovida Open Communication Application Library", - * and "Vovida Open Communication Application Library (VOCAL)" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact vocal@vovida.org. - * - * 4. Products derived from this software may not be called "VOCAL", nor - * may "VOCAL" appear in their name, without prior written - * permission of Vovida Networks, Inc. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND - * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA - * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES - * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ==================================================================== - * - * This software consists of voluntary contributions made by Vovida - * Networks, Inc. and many individuals on behalf of Vovida Networks, - * Inc. For more information on Vovida Networks, Inc., please see - * . - * - */ diff --git a/src/libs/resiprocate/resip/stack/config.hxx.in b/src/libs/resiprocate/resip/stack/config.hxx.in deleted file mode 100644 index a17c1da1..00000000 --- a/src/libs/resiprocate/resip/stack/config.hxx.in +++ /dev/null @@ -1,116 +0,0 @@ -/* resiprocate/config.hxx.in. Generated from configure.ac by autoheader. */ - -/* Define to 1 if you have the header file. */ -#undef HAVE_DLFCN_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_NETINET_IN_H - -/* Has popt.h */ -#undef HAVE_POPT_H - -/* Define if you have POSIX threads libraries and header files. */ -#undef HAVE_PTHREAD - -/* Has socklen_t */ -#undef HAVE_SOCKLEN_T - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_INT_TYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_SOCKET_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_SOCKIO_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Use NewHeaderScanner instead of Preparser */ -#undef NEW_MSG_HEADER_SCANNER - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* Define to the necessary symbol if this constant uses a non-standard name on - your system. */ -#undef PTHREAD_CREATE_JOINABLE - -/* Data local size */ -#undef RESIP_DATA_LOCAL_SIZE - -/* The major version number of resip */ -#undef RESIP_MAJOR_VERSION - -/* The micro version number of resip */ -#undef RESIP_MICRO_VERSION - -/* The minor version number of resip */ -#undef RESIP_MINOR_VERSION - -/* set when debugging requested in MsgHeaderScanner */ -#undef RESIP_MSG_HEADER_SCANNER_DEBUG - -/* BaseException DebugLog Disposition */ -#undef RESIP_NO_EXCEPTION_DEBUG_LOGS - -/* The version number of resip */ -#undef RESIP_VERSION - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Select ARES Resolver */ -#undef USE_ARES - -/* Select IPv6 code */ -#undef USE_IPV6 - -/* Use OpenSSL */ -#undef USE_SSL - -/* Version number of package */ -#undef VERSION - -/* Needs BSD socklen_t */ -#undef _BSD_SOCKLEN_T_ diff --git a/src/libs/resiprocate/resip/stack/dayofweek.gperf b/src/libs/resiprocate/resip/stack/dayofweek.gperf deleted file mode 100644 index fdf69c9f..00000000 --- a/src/libs/resiprocate/resip/stack/dayofweek.gperf +++ /dev/null @@ -1,9 +0,0 @@ -struct days { const char *name; DayOfWeek type; }; -%% -Sun, DayOfWeek::Sun -Mon, DayOfWeek::Mon -Tue, DayOfWeek::Tue -Wed, DayOfWeek::Wed -Thu, DayOfWeek::Thu -Fri, DayOfWeek::Fri -Sat, DayOfWeek::Sat diff --git a/src/libs/resiprocate/resip/stack/gen/DayOfWeekHash.cxx b/src/libs/resiprocate/resip/stack/gen/DayOfWeekHash.cxx new file mode 100644 index 00000000..b2874479 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/gen/DayOfWeekHash.cxx @@ -0,0 +1,143 @@ +/* C++ code produced by gperf version 3.1 */ +/* Command-line: gperf -C -D -E -L C++ -t --key-positions='*' --compare-strncmp -Z DayOfWeekHash DayOfWeekHash.gperf */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 1 "DayOfWeekHash.gperf" + +#include +#include +#include "resip/stack/DateCategory.hxx" + +namespace resip +{ +#line 9 "DayOfWeekHash.gperf" +struct days { const char *name; DayOfWeek type; }; +/* maximum key range = 16, duplicates = 0 */ + +class DayOfWeekHash +{ +private: + static inline unsigned int hash (const char *str, size_t len); +public: + static const struct days *in_word_set (const char *str, size_t len); +}; + +inline unsigned int +DayOfWeekHash::hash (const char *str, size_t len) +{ + static const unsigned char asso_values[] = + { + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 2, 16, 16, 16, 16, 16, 16, 2, 16, 16, + 16, 16, 16, 0, 5, 16, 16, 2, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 0, 16, 16, + 0, 5, 16, 16, 0, 5, 16, 16, 16, 16, + 0, 0, 16, 16, 5, 16, 0, 5, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16 + }; + return asso_values[static_cast(str[2])] + asso_values[static_cast(str[1])] + asso_values[static_cast(str[0])]; +} + +const struct days * +DayOfWeekHash::in_word_set (const char *str, size_t len) +{ + enum + { + TOTAL_KEYWORDS = 7, + MIN_WORD_LENGTH = 3, + MAX_WORD_LENGTH = 3, + MIN_HASH_VALUE = 0, + MAX_HASH_VALUE = 15 + }; + + static const struct days wordlist[] = + { +#line 17 "DayOfWeekHash.gperf" + {"Sat", Sat}, +#line 12 "DayOfWeekHash.gperf" + {"Mon", Mon}, +#line 11 "DayOfWeekHash.gperf" + {"Sun", Sun}, +#line 14 "DayOfWeekHash.gperf" + {"Wed", Wed}, +#line 15 "DayOfWeekHash.gperf" + {"Thu", Thu}, +#line 16 "DayOfWeekHash.gperf" + {"Fri", Fri}, +#line 13 "DayOfWeekHash.gperf" + {"Tue", Tue} + }; + + static const signed char lookup[] = + { + 0, -1, 1, -1, -1, 2, -1, 3, -1, -1, 4, -1, 5, -1, + -1, 6 + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + unsigned int key = hash (str, len); + + if (key <= MAX_HASH_VALUE) + { + int index = lookup[key]; + + if (index >= 0) + { + const char *s = wordlist[index].name; + + if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') + return &wordlist[index]; + } + } + } + return 0; +} +#line 18 "DayOfWeekHash.gperf" + +} diff --git a/src/libs/resiprocate/resip/stack/HeaderHash.cxx b/src/libs/resiprocate/resip/stack/gen/HeaderHash.cxx similarity index 63% rename from src/libs/resiprocate/resip/stack/HeaderHash.cxx rename to src/libs/resiprocate/resip/stack/gen/HeaderHash.cxx index 8c2dfbbe..6bdd9f10 100644 --- a/src/libs/resiprocate/resip/stack/HeaderHash.cxx +++ b/src/libs/resiprocate/resip/stack/gen/HeaderHash.cxx @@ -1,5 +1,5 @@ -/* C++ code produced by gperf version 3.0.4 */ -/* Command-line: gperf -C -D -E -L C++ -t -k '*' --compare-strncmp --ignore-case -Z HeaderHash HeaderHash.gperf */ +/* C++ code produced by gperf version 3.1 */ +/* Command-line: gperf -C -D -E -L C++ -t --key-positions='*' --compare-strncmp --ignore-case -Z HeaderHash HeaderHash.gperf */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ @@ -25,7 +25,7 @@ && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) /* The character set is not based on ISO-646. */ -#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." #endif #line 1 "HeaderHash.gperf" @@ -39,7 +39,7 @@ namespace resip using namespace std; #line 10 "HeaderHash.gperf" struct headers { const char *name; Headers::Type type; }; -/* maximum key range = 430, duplicates = 0 */ +/* maximum key range = 438, duplicates = 0 */ #ifndef GPERF_DOWNCASE #define GPERF_DOWNCASE 1 @@ -69,7 +69,7 @@ static unsigned char gperf_downcase[256] = #ifndef GPERF_CASE_STRNCMP #define GPERF_CASE_STRNCMP 1 static int -gperf_case_strncmp (register const char *s1, register const char *s2, register unsigned int n) +gperf_case_strncmp (const char *s1, const char *s2, size_t n) { for (; n > 0;) { @@ -89,136 +89,148 @@ gperf_case_strncmp (register const char *s1, register const char *s2, register u class HeaderHash { private: - static inline unsigned int hash (const char *str, unsigned int len); + static inline unsigned int hash (const char *str, size_t len); public: - static const struct headers *in_word_set (const char *str, unsigned int len); + static const struct headers *in_word_set (const char *str, size_t len); }; inline unsigned int -HeaderHash::hash (register const char *str, register unsigned int len) +HeaderHash::hash (const char *str, size_t len) { static const unsigned short asso_values[] = { - 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, - 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, - 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, - 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, - 431, 431, 431, 431, 431, 0, 431, 431, 431, 431, - 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, - 431, 431, 431, 431, 431, 0, 55, 15, 0, 30, - 35, 10, 5, 25, 5, 70, 40, 75, 0, 5, - 0, 25, 10, 50, 0, 10, 45, 0, 60, 20, - 50, 431, 431, 431, 431, 431, 431, 0, 55, 15, - 0, 30, 35, 10, 5, 25, 5, 70, 40, 75, - 0, 5, 0, 25, 10, 50, 0, 10, 45, 0, - 60, 20, 50, 431, 431, 431, 431, 431, 431, 431, - 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, - 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, - 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, - 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, - 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, - 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, - 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, - 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, - 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, - 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, - 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, - 431, 431, 431, 431, 431, 431, 431, 431, 431, 431, - 431, 431, 431, 431, 431, 431 + 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 0, 439, 439, 439, 5, + 0, 439, 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 0, 65, 25, 0, 20, + 45, 5, 15, 30, 15, 80, 50, 40, 0, 5, + 0, 30, 15, 10, 0, 0, 70, 0, 110, 35, + 0, 439, 439, 439, 439, 439, 439, 0, 65, 25, + 0, 20, 45, 5, 15, 30, 15, 80, 50, 40, + 0, 5, 0, 30, 15, 10, 0, 0, 70, 0, + 110, 35, 0, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439, 439, 439, 439, 439, + 439, 439, 439, 439, 439, 439 }; - register int hval = len; + unsigned int hval = len; switch (hval) { default: - hval += asso_values[(unsigned char)str[24]]; + hval += asso_values[static_cast(str[28])]; + /*FALLTHROUGH*/ + case 28: + hval += asso_values[static_cast(str[27])]; + /*FALLTHROUGH*/ + case 27: + hval += asso_values[static_cast(str[26])]; + /*FALLTHROUGH*/ + case 26: + hval += asso_values[static_cast(str[25])]; + /*FALLTHROUGH*/ + case 25: + hval += asso_values[static_cast(str[24])]; /*FALLTHROUGH*/ case 24: - hval += asso_values[(unsigned char)str[23]]; + hval += asso_values[static_cast(str[23])]; /*FALLTHROUGH*/ case 23: - hval += asso_values[(unsigned char)str[22]]; + hval += asso_values[static_cast(str[22])]; /*FALLTHROUGH*/ case 22: - hval += asso_values[(unsigned char)str[21]]; + hval += asso_values[static_cast(str[21])]; /*FALLTHROUGH*/ case 21: - hval += asso_values[(unsigned char)str[20]]; + hval += asso_values[static_cast(str[20])]; /*FALLTHROUGH*/ case 20: - hval += asso_values[(unsigned char)str[19]]; + hval += asso_values[static_cast(str[19])]; /*FALLTHROUGH*/ case 19: - hval += asso_values[(unsigned char)str[18]]; + hval += asso_values[static_cast(str[18])]; /*FALLTHROUGH*/ case 18: - hval += asso_values[(unsigned char)str[17]]; + hval += asso_values[static_cast(str[17])]; /*FALLTHROUGH*/ case 17: - hval += asso_values[(unsigned char)str[16]]; + hval += asso_values[static_cast(str[16])]; /*FALLTHROUGH*/ case 16: - hval += asso_values[(unsigned char)str[15]]; + hval += asso_values[static_cast(str[15])]; /*FALLTHROUGH*/ case 15: - hval += asso_values[(unsigned char)str[14]]; + hval += asso_values[static_cast(str[14])]; /*FALLTHROUGH*/ case 14: - hval += asso_values[(unsigned char)str[13]]; + hval += asso_values[static_cast(str[13])]; /*FALLTHROUGH*/ case 13: - hval += asso_values[(unsigned char)str[12]]; + hval += asso_values[static_cast(str[12])]; /*FALLTHROUGH*/ case 12: - hval += asso_values[(unsigned char)str[11]]; + hval += asso_values[static_cast(str[11])]; /*FALLTHROUGH*/ case 11: - hval += asso_values[(unsigned char)str[10]]; + hval += asso_values[static_cast(str[10])]; /*FALLTHROUGH*/ case 10: - hval += asso_values[(unsigned char)str[9]]; + hval += asso_values[static_cast(str[9])]; /*FALLTHROUGH*/ case 9: - hval += asso_values[(unsigned char)str[8]]; + hval += asso_values[static_cast(str[8])]; /*FALLTHROUGH*/ case 8: - hval += asso_values[(unsigned char)str[7]]; + hval += asso_values[static_cast(str[7])]; /*FALLTHROUGH*/ case 7: - hval += asso_values[(unsigned char)str[6]]; + hval += asso_values[static_cast(str[6])]; /*FALLTHROUGH*/ case 6: - hval += asso_values[(unsigned char)str[5]]; + hval += asso_values[static_cast(str[5])]; /*FALLTHROUGH*/ case 5: - hval += asso_values[(unsigned char)str[4]]; + hval += asso_values[static_cast(str[4])]; /*FALLTHROUGH*/ case 4: - hval += asso_values[(unsigned char)str[3]]; + hval += asso_values[static_cast(str[3])]; /*FALLTHROUGH*/ case 3: - hval += asso_values[(unsigned char)str[2]]; + hval += asso_values[static_cast(str[2])]; /*FALLTHROUGH*/ case 2: - hval += asso_values[(unsigned char)str[1]]; + hval += asso_values[static_cast(str[1])]; /*FALLTHROUGH*/ case 1: - hval += asso_values[(unsigned char)str[0]]; + hval += asso_values[static_cast(str[0])]; break; } return hval; } const struct headers * -HeaderHash::in_word_set (register const char *str, register unsigned int len) +HeaderHash::in_word_set (const char *str, size_t len) { enum { - TOTAL_KEYWORDS = 101, + TOTAL_KEYWORDS = 113, MIN_WORD_LENGTH = 1, - MAX_WORD_LENGTH = 25, + MAX_WORD_LENGTH = 29, MIN_HASH_VALUE = 1, - MAX_HASH_VALUE = 430 + MAX_HASH_VALUE = 438 }; static const struct headers wordlist[] = @@ -229,263 +241,287 @@ HeaderHash::in_word_set (register const char *str, register unsigned int len) {"o", Headers::Event}, #line 36 "HeaderHash.gperf" {"to", Headers::To}, -#line 92 "HeaderHash.gperf" - {"path", Headers::Path}, +#line 18 "HeaderHash.gperf" + {"s", Headers::Subject}, #line 22 "HeaderHash.gperf" {"r", Headers::ReferTo}, -#line 16 "HeaderHash.gperf" - {"c", Headers::ContentType}, -#line 25 "HeaderHash.gperf" - {"y", Headers::Identity}, -#line 12 "HeaderHash.gperf" - {"i", Headers::CallID}, +#line 99 "HeaderHash.gperf" + {"path", Headers::Path}, #line 14 "HeaderHash.gperf" {"e", Headers::ContentEncoding}, #line 52 "HeaderHash.gperf" {"date", Headers::Date}, -#line 17 "HeaderHash.gperf" - {"f", Headers::From}, -#line 86 "HeaderHash.gperf" - {"join", Headers::Join}, -#line 15 "HeaderHash.gperf" - {"l", Headers::ContentLength}, -#line 29 "HeaderHash.gperf" - {"contact", Headers::Contact}, -#line 21 "HeaderHash.gperf" - {"v", Headers::Via}, -#line 18 "HeaderHash.gperf" - {"s", Headers::Subject}, -#line 76 "HeaderHash.gperf" - {"warning", Headers::Warning}, -#line 23 "HeaderHash.gperf" - {"b", Headers::ReferredBy}, -#line 34 "HeaderHash.gperf" - {"route", Headers::Route}, -#line 24 "HeaderHash.gperf" - {"x", Headers::SessionExpires}, -#line 83 "HeaderHash.gperf" - {"hide", Headers::UNKNOWN}, -#line 38 "HeaderHash.gperf" - {"accept", Headers::Accept}, -#line 19 "HeaderHash.gperf" - {"k", Headers::Supported}, -#line 37 "HeaderHash.gperf" - {"via", Headers::Via}, +#line 16 "HeaderHash.gperf" + {"c", Headers::ContentType}, +#line 12 "HeaderHash.gperf" + {"i", Headers::CallID}, +#line 64 "HeaderHash.gperf" + {"host", Headers::Host}, +#line 25 "HeaderHash.gperf" + {"y", Headers::Identity}, #line 13 "HeaderHash.gperf" {"m", Headers::Contact}, +#line 34 "HeaderHash.gperf" + {"route", Headers::Route}, +#line 17 "HeaderHash.gperf" + {"f", Headers::From}, +#line 15 "HeaderHash.gperf" + {"l", Headers::ContentLength}, +#line 93 "HeaderHash.gperf" + {"join", Headers::Join}, +#line 103 "HeaderHash.gperf" + {"reason", Headers::Reason}, +#line 83 "HeaderHash.gperf" + {"warning", Headers::Warning}, +#line 77 "HeaderHash.gperf" + {"supported", Headers::Supported}, +#line 81 "HeaderHash.gperf" + {"unsupported", Headers::Unsupported}, +#line 29 "HeaderHash.gperf" + {"contact", Headers::Contact}, +#line 23 "HeaderHash.gperf" + {"b", Headers::ReferredBy}, +#line 90 "HeaderHash.gperf" + {"hide", Headers::UNKNOWN}, +#line 21 "HeaderHash.gperf" + {"v", Headers::Via}, +#line 75 "HeaderHash.gperf" + {"sip-etag", Headers::SIPETag}, +#line 38 "HeaderHash.gperf" + {"accept", Headers::Accept}, +#line 110 "HeaderHash.gperf" + {"rseq", Headers::RSeq}, +#line 82 "HeaderHash.gperf" + {"user-agent", Headers::UserAgent}, +#line 19 "HeaderHash.gperf" + {"k", Headers::Supported}, +#line 27 "HeaderHash.gperf" + {"cseq", Headers::CSeq}, #line 47 "HeaderHash.gperf" {"content-id", Headers::ContentId}, +#line 63 "HeaderHash.gperf" + {"origin", Headers::Origin}, +#line 57 "HeaderHash.gperf" + {"organization", Headers::Organization}, +#line 37 "HeaderHash.gperf" + {"via", Headers::Via}, +#line 116 "HeaderHash.gperf" + {"min-se", Headers::MinSE}, +#line 124 "HeaderHash.gperf" + {"user-to-user", Headers::UserToUser}, +#line 32 "HeaderHash.gperf" + {"from", Headers::From}, #line 43 "HeaderHash.gperf" {"allow", Headers::Allow}, -#line 95 "HeaderHash.gperf" - {"rack", Headers::RAck}, -#line 96 "HeaderHash.gperf" - {"reason", Headers::Reason}, -#line 58 "HeaderHash.gperf" - {"priority", Headers::Priority}, -#line 84 "HeaderHash.gperf" - {"identity", Headers::Identity}, -#line 39 "HeaderHash.gperf" - {"accept-contact", Headers::AcceptContact}, -#line 82 "HeaderHash.gperf" +#line 24 "HeaderHash.gperf" + {"x", Headers::SessionExpires}, +#line 86 "HeaderHash.gperf" + {"authorization", Headers::Authorization}, +#line 89 "HeaderHash.gperf" {"event", Headers::Event}, #line 50 "HeaderHash.gperf" {"content-type", Headers::ContentType}, -#line 63 "HeaderHash.gperf" - {"reply-to", Headers::ReplyTo}, -#line 70 "HeaderHash.gperf" - {"supported", Headers::Supported}, -#line 81 "HeaderHash.gperf" - {"encryption", Headers::UNKNOWN}, -#line 103 "HeaderHash.gperf" - {"rseq", Headers::RSeq}, -#line 94 "HeaderHash.gperf" - {"privacy", Headers::Privacy}, -#line 68 "HeaderHash.gperf" - {"sip-etag", Headers::SIPETag}, -#line 27 "HeaderHash.gperf" - {"cseq", Headers::CSeq}, -#line 74 "HeaderHash.gperf" - {"unsupported", Headers::Unsupported}, -#line 28 "HeaderHash.gperf" - {"call-id", Headers::CallID}, -#line 97 "HeaderHash.gperf" - {"refer-to",Headers::ReferTo}, -#line 32 "HeaderHash.gperf" - {"from", Headers::From}, -#line 77 "HeaderHash.gperf" - {"www-authenticate",Headers::WWWAuthenticate}, -#line 62 "HeaderHash.gperf" - {"record-route", Headers::RecordRoute}, -#line 100 "HeaderHash.gperf" - {"reject-contact", Headers::RejectContact}, -#line 53 "HeaderHash.gperf" - {"error-info", Headers::ErrorInfo}, -#line 54 "HeaderHash.gperf" - {"in-reply-to", Headers::InReplyTo}, -#line 57 "HeaderHash.gperf" - {"organization", Headers::Organization}, -#line 93 "HeaderHash.gperf" - {"target-dialog", Headers::TargetDialog}, -#line 64 "HeaderHash.gperf" - {"require", Headers::Require}, #line 79 "HeaderHash.gperf" - {"authorization", Headers::Authorization}, -#line 30 "HeaderHash.gperf" - {"content-length", Headers::ContentLength}, -#line 75 "HeaderHash.gperf" - {"user-agent", Headers::UserAgent}, -#line 48 "HeaderHash.gperf" - {"content-encoding", Headers::ContentEncoding}, -#line 42 "HeaderHash.gperf" - {"alert-info",Headers::AlertInfo}, + {"answer-mode", Headers::AnswerMode}, +#line 91 "HeaderHash.gperf" + {"identity", Headers::Identity}, +#line 102 "HeaderHash.gperf" + {"rack", Headers::RAck}, +#line 84 "HeaderHash.gperf" + {"www-authenticate",Headers::WWWAuthenticate}, +#line 104 "HeaderHash.gperf" + {"refer-to",Headers::ReferTo}, +#line 69 "HeaderHash.gperf" + {"record-route", Headers::RecordRoute}, +#line 70 "HeaderHash.gperf" + {"reply-to", Headers::ReplyTo}, +#line 71 "HeaderHash.gperf" + {"require", Headers::Require}, #line 65 "HeaderHash.gperf" - {"retry-after", Headers::RetryAfter}, -#line 40 "HeaderHash.gperf" - {"accept-encoding", Headers::AcceptEncoding}, -#line 49 "HeaderHash.gperf" - {"content-language", Headers::ContentLanguage}, -#line 45 "HeaderHash.gperf" - {"call-info", Headers::CallInfo}, + {"priority", Headers::Priority}, +#line 39 "HeaderHash.gperf" + {"accept-contact", Headers::AcceptContact}, +#line 88 "HeaderHash.gperf" + {"encryption", Headers::UNKNOWN}, #line 35 "HeaderHash.gperf" {"subject", Headers::Subject}, +#line 100 "HeaderHash.gperf" + {"target-dialog", Headers::TargetDialog}, +#line 49 "HeaderHash.gperf" + {"content-language", Headers::ContentLanguage}, +#line 106 "HeaderHash.gperf" + {"replaces",Headers::Replaces}, +#line 78 "HeaderHash.gperf" + {"timestamp", Headers::Timestamp}, +#line 48 "HeaderHash.gperf" + {"content-encoding", Headers::ContentEncoding}, +#line 30 "HeaderHash.gperf" + {"content-length", Headers::ContentLength}, +#line 74 "HeaderHash.gperf" + {"server", Headers::Server}, +#line 53 "HeaderHash.gperf" + {"error-info", Headers::ErrorInfo}, +#line 95 "HeaderHash.gperf" + {"p-associated-uri", Headers::PAssociatedUri}, +#line 28 "HeaderHash.gperf" + {"call-id", Headers::CallID}, +#line 107 "HeaderHash.gperf" + {"reject-contact", Headers::RejectContact}, #line 41 "HeaderHash.gperf" {"accept-language", Headers::AcceptLanguage}, -#line 85 "HeaderHash.gperf" - {"identity-info", Headers::IdentityInfo}, -#line 67 "HeaderHash.gperf" - {"server", Headers::Server}, -#line 99 "HeaderHash.gperf" - {"replaces",Headers::Replaces}, -#line 109 "HeaderHash.gperf" - {"min-se", Headers::MinSE}, -#line 112 "HeaderHash.gperf" - {"history-info", Headers::HistoryInfo}, -#line 89 "HeaderHash.gperf" - {"p-called-party-id", Headers::PCalledPartyId}, -#line 44 "HeaderHash.gperf" - {"authentication-info", Headers::AuthenticationInfo}, +#line 54 "HeaderHash.gperf" + {"in-reply-to", Headers::InReplyTo}, +#line 40 "HeaderHash.gperf" + {"accept-encoding", Headers::AcceptEncoding}, +#line 62 "HeaderHash.gperf" + {"cookie", Headers::Cookie}, +#line 42 "HeaderHash.gperf" + {"alert-info",Headers::AlertInfo}, #line 72 "HeaderHash.gperf" - {"answer-mode", Headers::AnswerMode}, -#line 31 "HeaderHash.gperf" - {"expires", Headers::Expires}, -#line 111 "HeaderHash.gperf" - {"remote-party-id", Headers::RemotePartyId}, -#line 59 "HeaderHash.gperf" - {"proxy-authenticate", Headers::ProxyAuthenticate}, -#line 66 "HeaderHash.gperf" - {"flow-timer", Headers::FlowTimer}, -#line 88 "HeaderHash.gperf" - {"p-associated-uri", Headers::PAssociatedUri}, -#line 110 "HeaderHash.gperf" - {"refer-sub", Headers::ReferSub}, -#line 98 "HeaderHash.gperf" - {"referred-by",Headers::ReferredBy}, -#line 69 "HeaderHash.gperf" - {"sip-if-match", Headers::SIPIfMatch}, -#line 61 "HeaderHash.gperf" - {"proxy-require", Headers::ProxyRequire}, -#line 60 "HeaderHash.gperf" - {"proxy-authorization", Headers::ProxyAuthorization}, -#line 80 "HeaderHash.gperf" - {"allow-events", Headers::AllowEvents}, + {"retry-after", Headers::RetryAfter}, +#line 101 "HeaderHash.gperf" + {"privacy", Headers::Privacy}, #line 46 "HeaderHash.gperf" {"content-disposition", Headers::ContentDisposition}, +#line 118 "HeaderHash.gperf" + {"remote-party-id", Headers::RemotePartyId}, +#line 117 "HeaderHash.gperf" + {"refer-sub", Headers::ReferSub}, +#line 119 "HeaderHash.gperf" + {"history-info", Headers::HistoryInfo}, +#line 76 "HeaderHash.gperf" + {"sip-if-match", Headers::SIPIfMatch}, +#line 92 "HeaderHash.gperf" + {"identity-info", Headers::IdentityInfo}, +#line 94 "HeaderHash.gperf" + {"p-asserted-identity", Headers::PAssertedIdentity}, +#line 97 "HeaderHash.gperf" + {"p-media-authorization", Headers::PMediaAuthorization}, +#line 31 "HeaderHash.gperf" + {"expires", Headers::Expires}, +#line 45 "HeaderHash.gperf" + {"call-info", Headers::CallInfo}, +#line 73 "HeaderHash.gperf" + {"flow-timer", Headers::FlowTimer}, +#line 44 "HeaderHash.gperf" + {"authentication-info", Headers::AuthenticationInfo}, +#line 109 "HeaderHash.gperf" + {"response-key", Headers::UNKNOWN}, +#line 108 "HeaderHash.gperf" + {"request-disposition", Headers::RequestDisposition}, +#line 87 "HeaderHash.gperf" + {"allow-events", Headers::AllowEvents}, +#line 85 "HeaderHash.gperf" + {"subscription-state",Headers::SubscriptionState}, +#line 80 "HeaderHash.gperf" + {"priv-answer-mode", Headers::PrivAnswerMode}, +#line 96 "HeaderHash.gperf" + {"p-called-party-id", Headers::PCalledPartyId}, +#line 114 "HeaderHash.gperf" + {"service-route", Headers::ServiceRoute}, +#line 121 "HeaderHash.gperf" + {"p-charging-vector", Headers::PChargingVector}, #line 33 "HeaderHash.gperf" {"max-forwards", Headers::MaxForwards}, -#line 71 "HeaderHash.gperf" - {"timestamp", Headers::Timestamp}, -#line 107 "HeaderHash.gperf" - {"service-route", Headers::ServiceRoute}, -#line 91 "HeaderHash.gperf" - {"p-preferred-identity", Headers::PPreferredIdentity}, -#line 104 "HeaderHash.gperf" - {"security-client", Headers::SecurityClient}, -#line 90 "HeaderHash.gperf" - {"p-media-authorization", Headers::PMediaAuthorization}, -#line 87 "HeaderHash.gperf" - {"p-asserted-identity", Headers::PAssertedIdentity}, +#line 105 "HeaderHash.gperf" + {"referred-by",Headers::ReferredBy}, #line 51 "HeaderHash.gperf" {"content-transfer-encoding", Headers::ContentTransferEncoding}, -#line 73 "HeaderHash.gperf" - {"priv-answer-mode", Headers::PrivAnswerMode}, -#line 102 "HeaderHash.gperf" - {"response-key", Headers::UNKNOWN}, +#line 111 "HeaderHash.gperf" + {"security-client", Headers::SecurityClient}, +#line 67 "HeaderHash.gperf" + {"proxy-authorization", Headers::ProxyAuthorization}, +#line 98 "HeaderHash.gperf" + {"p-preferred-identity", Headers::PPreferredIdentity}, #line 55 "HeaderHash.gperf" {"min-expires", Headers::MinExpires}, -#line 106 "HeaderHash.gperf" - {"security-verify", Headers::SecurityVerify}, -#line 78 "HeaderHash.gperf" - {"subscription-state",Headers::SubscriptionState}, -#line 105 "HeaderHash.gperf" - {"security-server", Headers::SecurityServer}, -#line 101 "HeaderHash.gperf" - {"request-disposition", Headers::RequestDisposition}, #line 56 "HeaderHash.gperf" {"mime-version", Headers::MIMEVersion}, -#line 108 "HeaderHash.gperf" - {"session-expires", Headers::SessionExpires} +#line 66 "HeaderHash.gperf" + {"proxy-authenticate", Headers::ProxyAuthenticate}, +#line 112 "HeaderHash.gperf" + {"security-server", Headers::SecurityServer}, +#line 115 "HeaderHash.gperf" + {"session-expires", Headers::SessionExpires}, +#line 68 "HeaderHash.gperf" + {"proxy-require", Headers::ProxyRequire}, +#line 120 "HeaderHash.gperf" + {"p-access-network-info", Headers::PAccessNetworkInfo}, +#line 122 "HeaderHash.gperf" + {"p-charging-function-addresses", Headers::PChargingFunctionAddresses}, +#line 123 "HeaderHash.gperf" + {"p-visited-network-id", Headers::PVisitedNetworkID}, +#line 113 "HeaderHash.gperf" + {"security-verify", Headers::SecurityVerify}, +#line 61 "HeaderHash.gperf" + {"sec-websocket-accept", Headers::SecWebSocketAccept}, +#line 58 "HeaderHash.gperf" + {"sec-websocket-key", Headers::SecWebSocketKey}, +#line 60 "HeaderHash.gperf" + {"sec-websocket-key2", Headers::SecWebSocketKey2}, +#line 59 "HeaderHash.gperf" + {"sec-websocket-key1", Headers::SecWebSocketKey1} }; static const signed char lookup[] = { - -1, 0, -1, -1, -1, -1, 1, 2, -1, 3, - -1, 4, -1, -1, -1, -1, 5, -1, -1, -1, - -1, 6, -1, -1, -1, -1, 7, -1, -1, -1, - -1, 8, -1, -1, 9, -1, 10, -1, -1, 11, - -1, 12, 13, -1, -1, -1, 14, -1, -1, -1, - -1, 15, 16, -1, -1, -1, 17, -1, -1, -1, - 18, 19, -1, -1, 20, -1, 21, -1, -1, -1, - -1, 22, -1, 23, -1, -1, 24, -1, -1, -1, - -1, -1, -1, -1, -1, 25, -1, -1, -1, -1, - 26, -1, -1, -1, -1, -1, -1, -1, -1, 27, - -1, 28, -1, 29, -1, -1, -1, -1, 30, 31, - 32, -1, 33, 34, 35, 36, -1, -1, -1, 37, - -1, -1, 38, 39, 40, -1, 41, 42, 43, 44, - -1, 45, -1, -1, -1, -1, -1, 46, -1, 47, - 48, 49, 50, 51, -1, -1, -1, 52, 53, 54, - 55, 56, -1, -1, -1, 57, 58, -1, -1, -1, - 59, -1, -1, -1, -1, -1, 60, -1, -1, 61, - -1, -1, 62, -1, -1, 63, -1, -1, 64, -1, - -1, 65, -1, 66, -1, -1, 67, -1, -1, -1, - -1, -1, 68, -1, -1, -1, -1, 69, -1, 70, + -1, 0, -1, -1, -1, -1, 1, 2, -1, -1, + -1, 3, -1, -1, -1, -1, 4, -1, -1, 5, + -1, 6, -1, -1, 7, -1, 8, -1, -1, -1, + -1, 9, -1, -1, 10, -1, 11, -1, -1, -1, + -1, 12, -1, -1, -1, 13, 14, -1, -1, -1, + -1, 15, -1, -1, 16, -1, 17, 18, -1, 19, + -1, 20, 21, -1, -1, -1, 22, -1, -1, 23, + -1, 24, -1, 25, -1, -1, 26, -1, -1, 27, + 28, 29, -1, -1, -1, -1, -1, -1, -1, 30, + 31, 32, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 33, 34, -1, -1, 35, 36, -1, 37, + 38, 39, -1, 40, -1, 41, -1, 42, -1, -1, + -1, 43, -1, 44, 45, -1, 46, -1, 47, -1, + -1, -1, 48, 49, -1, -1, -1, 50, 51, 52, + 53, -1, 54, 55, -1, -1, 56, -1, 57, 58, + -1, 59, -1, -1, 60, -1, 61, -1, -1, -1, + 62, 63, 64, -1, 65, 66, 67, -1, -1, -1, + 68, 69, -1, -1, -1, 70, 71, -1, -1, -1, + -1, -1, 72, -1, -1, -1, -1, -1, -1, 73, + -1, -1, -1, -1, -1, 74, -1, -1, -1, 75, + -1, -1, 76, -1, -1, -1, -1, 77, 78, 79, + -1, 80, 81, -1, 82, 83, -1, -1, -1, -1, + -1, -1, -1, -1, 84, -1, -1, 85, -1, -1, + -1, -1, -1, -1, 86, -1, -1, 87, 88, -1, + -1, 89, 90, 91, -1, -1, -1, 92, -1, -1, + -1, -1, 93, -1, -1, -1, -1, -1, -1, -1, + -1, 94, -1, -1, -1, 95, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 96, -1, -1, -1, -1, + -1, -1, -1, -1, 97, 98, 99, -1, -1, -1, + -1, -1, 100, 101, -1, -1, -1, -1, -1, -1, + 102, -1, -1, -1, -1, 103, -1, -1, 104, -1, + -1, 105, -1, -1, 106, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 71, 72, -1, -1, -1, -1, -1, -1, -1, - 73, -1, -1, -1, -1, -1, -1, -1, 74, -1, - 75, -1, -1, -1, -1, -1, 76, -1, -1, 77, - -1, 78, 79, -1, -1, -1, -1, -1, 80, 81, - -1, -1, 82, -1, 83, -1, -1, 84, -1, -1, - -1, -1, -1, -1, 85, -1, -1, -1, -1, -1, - -1, -1, -1, 86, -1, 87, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 88, 89, -1, -1, 90, - -1, -1, -1, -1, -1, 91, 92, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 93, -1, -1, - -1, -1, -1, -1, -1, -1, 94, -1, -1, -1, + 107, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 95, -1, -1, 96, -1, -1, -1, -1, -1, -1, - 97, -1, -1, -1, -1, -1, -1, -1, -1, 98, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 99, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 108, -1, -1, -1, -1, + 109, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 100 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 110, 111, -1, -1, -1, -1, 112 }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) { - register int key = hash (str, len); + unsigned int key = hash (str, len); - if (key <= MAX_HASH_VALUE && key >= 0) + if (key <= MAX_HASH_VALUE) { - register int index = lookup[key]; + int index = lookup[key]; if (index >= 0) { - register const char *s = wordlist[index].name; + const char *s = wordlist[index].name; if ((((unsigned char)*str ^ (unsigned char)*s) & ~32) == 0 && !gperf_case_strncmp (str, s, len) && s[len] == '\0') return &wordlist[index]; @@ -494,6 +530,6 @@ HeaderHash::in_word_set (register const char *str, register unsigned int len) } return 0; } -#line 113 "HeaderHash.gperf" +#line 125 "HeaderHash.gperf" } diff --git a/src/libs/resiprocate/resip/stack/MethodHash.cxx b/src/libs/resiprocate/resip/stack/gen/MethodHash.cxx similarity index 81% rename from src/libs/resiprocate/resip/stack/MethodHash.cxx rename to src/libs/resiprocate/resip/stack/gen/MethodHash.cxx index 3006778a..82ae0003 100644 --- a/src/libs/resiprocate/resip/stack/MethodHash.cxx +++ b/src/libs/resiprocate/resip/stack/gen/MethodHash.cxx @@ -1,5 +1,5 @@ -/* C++ code produced by gperf version 3.0.4 */ -/* Command-line: gperf -C -D -E -L C++ -t -k '*' --compare-strncmp -Z MethodHash MethodHash.gperf */ +/* C++ code produced by gperf version 3.1 */ +/* Command-line: gperf -C -D -E -L C++ -t --key-positions='*' --compare-strncmp -Z MethodHash MethodHash.gperf */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ @@ -25,7 +25,7 @@ && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) /* The character set is not based on ISO-646. */ -#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." #endif #line 1 "MethodHash.gperf" @@ -43,13 +43,13 @@ struct methods { const char *name; MethodTypes type; }; class MethodHash { private: - static inline unsigned int hash (const char *str, unsigned int len); + static inline unsigned int hash (const char *str, size_t len); public: - static const struct methods *in_word_set (const char *str, unsigned int len); + static const struct methods *in_word_set (const char *str, size_t len); }; inline unsigned int -MethodHash::hash (register const char *str, register unsigned int len) +MethodHash::hash (const char *str, size_t len) { static const unsigned char asso_values[] = { @@ -80,43 +80,43 @@ MethodHash::hash (register const char *str, register unsigned int len) 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35 }; - register int hval = len; + unsigned int hval = len; switch (hval) { default: - hval += asso_values[(unsigned char)str[8]]; + hval += asso_values[static_cast(str[8])]; /*FALLTHROUGH*/ case 8: - hval += asso_values[(unsigned char)str[7]]; + hval += asso_values[static_cast(str[7])]; /*FALLTHROUGH*/ case 7: - hval += asso_values[(unsigned char)str[6]]; + hval += asso_values[static_cast(str[6])]; /*FALLTHROUGH*/ case 6: - hval += asso_values[(unsigned char)str[5]]; + hval += asso_values[static_cast(str[5])]; /*FALLTHROUGH*/ case 5: - hval += asso_values[(unsigned char)str[4]]; + hval += asso_values[static_cast(str[4])]; /*FALLTHROUGH*/ case 4: - hval += asso_values[(unsigned char)str[3]]; + hval += asso_values[static_cast(str[3])]; /*FALLTHROUGH*/ case 3: - hval += asso_values[(unsigned char)str[2]]; + hval += asso_values[static_cast(str[2])]; /*FALLTHROUGH*/ case 2: - hval += asso_values[(unsigned char)str[1]]; + hval += asso_values[static_cast(str[1])]; /*FALLTHROUGH*/ case 1: - hval += asso_values[(unsigned char)str[0]]; + hval += asso_values[static_cast(str[0])]; break; } return hval; } const struct methods * -MethodHash::in_word_set (register const char *str, register unsigned int len) +MethodHash::in_word_set (const char *str, size_t len) { enum { @@ -172,15 +172,15 @@ MethodHash::in_word_set (register const char *str, register unsigned int len) if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) { - register int key = hash (str, len); + unsigned int key = hash (str, len); - if (key <= MAX_HASH_VALUE && key >= 0) + if (key <= MAX_HASH_VALUE) { - register int index = lookup[key]; + int index = lookup[key]; if (index >= 0) { - register const char *s = wordlist[index].name; + const char *s = wordlist[index].name; if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') return &wordlist[index]; diff --git a/src/libs/resiprocate/resip/stack/gen/MonthHash.cxx b/src/libs/resiprocate/resip/stack/gen/MonthHash.cxx new file mode 100644 index 00000000..e10305ac --- /dev/null +++ b/src/libs/resiprocate/resip/stack/gen/MonthHash.cxx @@ -0,0 +1,154 @@ +/* C++ code produced by gperf version 3.1 */ +/* Command-line: gperf -C -D -E -L C++ -t --key-positions='*' --compare-strncmp -Z MonthHash MonthHash.gperf */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 1 "MonthHash.gperf" + +#include +#include +#include "resip/stack/DateCategory.hxx" + +namespace resip +{ +#line 9 "MonthHash.gperf" +struct months { const char *name; Month type; }; +/* maximum key range = 41, duplicates = 0 */ + +class MonthHash +{ +private: + static inline unsigned int hash (const char *str, size_t len); +public: + static const struct months *in_word_set (const char *str, size_t len); +}; + +inline unsigned int +MonthHash::hash (const char *str, size_t len) +{ + static const unsigned char asso_values[] = + { + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 10, 41, 41, 4, 41, + 4, 41, 41, 41, 0, 41, 41, 5, 15, 15, + 41, 41, 41, 15, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 5, 0, 10, + 41, 10, 41, 15, 41, 41, 41, 41, 4, 41, + 0, 15, 5, 41, 5, 41, 10, 0, 10, 41, + 41, 0, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41 + }; + return asso_values[static_cast(str[2])] + asso_values[static_cast(str[1])] + asso_values[static_cast(str[0])]; +} + +const struct months * +MonthHash::in_word_set (const char *str, size_t len) +{ + enum + { + TOTAL_KEYWORDS = 12, + MIN_WORD_LENGTH = 3, + MAX_WORD_LENGTH = 3, + MIN_HASH_VALUE = 0, + MAX_HASH_VALUE = 40 + }; + + static const struct months wordlist[] = + { +#line 16 "MonthHash.gperf" + {"Jun", Jun}, +#line 17 "MonthHash.gperf" + {"Jul", Jul}, +#line 11 "MonthHash.gperf" + {"Jan", Jan}, +#line 15 "MonthHash.gperf" + {"May", May}, +#line 12 "MonthHash.gperf" + {"Feb", Feb}, +#line 13 "MonthHash.gperf" + {"Mar", Mar}, +#line 14 "MonthHash.gperf" + {"Apr", Apr}, +#line 22 "MonthHash.gperf" + {"Dec", Dec}, +#line 18 "MonthHash.gperf" + {"Aug", Aug}, +#line 19 "MonthHash.gperf" + {"Sep", Sep}, +#line 20 "MonthHash.gperf" + {"Oct", Oct}, +#line 21 "MonthHash.gperf" + {"Nov", Nov} + }; + + static const signed char lookup[] = + { + 0, -1, -1, -1, 1, 2, -1, -1, -1, -1, 3, -1, -1, -1, + 4, 5, -1, -1, -1, -1, 6, -1, -1, -1, 7, 8, -1, -1, + -1, -1, 9, -1, -1, -1, -1, 10, -1, -1, -1, -1, 11 + }; + + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + unsigned int key = hash (str, len); + + if (key <= MAX_HASH_VALUE) + { + int index = lookup[key]; + + if (index >= 0) + { + const char *s = wordlist[index].name; + + if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0') + return &wordlist[index]; + } + } + } + return 0; +} +#line 23 "MonthHash.gperf" + +} diff --git a/src/libs/resiprocate/resip/stack/ParameterHash.cxx b/src/libs/resiprocate/resip/stack/gen/ParameterHash.cxx similarity index 60% rename from src/libs/resiprocate/resip/stack/ParameterHash.cxx rename to src/libs/resiprocate/resip/stack/gen/ParameterHash.cxx index a0225144..569c90a2 100644 --- a/src/libs/resiprocate/resip/stack/ParameterHash.cxx +++ b/src/libs/resiprocate/resip/stack/gen/ParameterHash.cxx @@ -1,5 +1,5 @@ -/* C++ code produced by gperf version 3.0.4 */ -/* Command-line: gperf -C -D -E -L C++ -t -k '*' --compare-strncmp --ignore-case -Z ParameterHash ParameterHash.gperf */ +/* C++ code produced by gperf version 3.1 */ +/* Command-line: gperf -C -D -E -L C++ -t --key-positions='*' --compare-strncmp --ignore-case -Z ParameterHash ParameterHash.gperf */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ @@ -25,7 +25,7 @@ && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) /* The character set is not based on ISO-646. */ -#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." #endif #line 1 "ParameterHash.gperf" @@ -37,7 +37,7 @@ namespace resip { using namespace std; #line 8 "ParameterHash.gperf" struct params { const char *name; ParameterTypes::Type type; }; -/* maximum key range = 266, duplicates = 0 */ +/* maximum key range = 511, duplicates = 0 */ #ifndef GPERF_DOWNCASE #define GPERF_DOWNCASE 1 @@ -67,7 +67,7 @@ static unsigned char gperf_downcase[256] = #ifndef GPERF_CASE_STRNCMP #define GPERF_CASE_STRNCMP 1 static int -gperf_case_strncmp (register const char *s1, register const char *s2, register unsigned int n) +gperf_case_strncmp (const char *s1, const char *s2, size_t n) { for (; n > 0;) { @@ -87,321 +87,400 @@ gperf_case_strncmp (register const char *s1, register const char *s2, register u class ParameterHash { private: - static inline unsigned int hash (const char *str, unsigned int len); + static inline unsigned int hash (const char *str, size_t len); public: - static const struct params *in_word_set (const char *str, unsigned int len); + static const struct params *in_word_set (const char *str, size_t len); }; inline unsigned int -ParameterHash::hash (register const char *str, register unsigned int len) +ParameterHash::hash (const char *str, size_t len) { static const unsigned short asso_values[] = { - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 0, 268, 40, 0, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 0, 25, 0, 15, 0, - 15, 35, 75, 10, 268, 10, 0, 25, 5, 5, - 5, 45, 0, 0, 0, 40, 85, 5, 65, 65, - 40, 268, 268, 268, 268, 268, 268, 0, 25, 0, - 15, 0, 15, 35, 75, 10, 268, 10, 0, 25, - 5, 5, 5, 45, 0, 0, 0, 40, 85, 5, - 65, 65, 40, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268, 268, 268, 268, 268, - 268, 268, 268, 268, 268, 268 + 513, 513, 513, 513, 513, 513, 513, 513, 513, 513, + 513, 513, 513, 513, 513, 513, 513, 513, 513, 513, + 513, 513, 513, 513, 513, 513, 513, 513, 513, 513, + 513, 513, 513, 513, 513, 513, 513, 513, 513, 513, + 513, 513, 513, 0, 513, 5, 0, 513, 513, 513, + 513, 0, 513, 513, 513, 513, 513, 513, 513, 513, + 513, 513, 513, 513, 513, 0, 85, 0, 25, 5, + 115, 45, 70, 0, 513, 0, 50, 25, 5, 0, + 5, 119, 0, 0, 0, 35, 100, 40, 125, 65, + 5, 513, 513, 513, 513, 513, 513, 0, 85, 0, + 25, 5, 115, 45, 70, 0, 513, 0, 50, 25, + 5, 0, 5, 119, 0, 0, 0, 35, 100, 40, + 125, 65, 5, 513, 513, 513, 513, 513, 513, 513, + 513, 513, 513, 513, 513, 513, 513, 513, 513, 513, + 513, 513, 513, 513, 513, 513, 513, 513, 513, 513, + 513, 513, 513, 513, 513, 513, 513, 513, 513, 513, + 513, 513, 513, 513, 513, 513, 513, 513, 513, 513, + 513, 513, 513, 513, 513, 513, 513, 513, 513, 513, + 513, 513, 513, 513, 513, 513, 513, 513, 513, 513, + 513, 513, 513, 513, 513, 513, 513, 513, 513, 513, + 513, 513, 513, 513, 513, 513, 513, 513, 513, 513, + 513, 513, 513, 513, 513, 513, 513, 513, 513, 513, + 513, 513, 513, 513, 513, 513, 513, 513, 513, 513, + 513, 513, 513, 513, 513, 513, 513, 513, 513, 513, + 513, 513, 513, 513, 513, 513, 513, 513, 513, 513, + 513, 513, 513, 513, 513, 513 }; - register int hval = len; + unsigned int hval = len; switch (hval) { default: - hval += asso_values[(unsigned char)str[12]]; + hval += asso_values[static_cast(str[17])]; + /*FALLTHROUGH*/ + case 17: + hval += asso_values[static_cast(str[16])]; + /*FALLTHROUGH*/ + case 16: + hval += asso_values[static_cast(str[15])]; + /*FALLTHROUGH*/ + case 15: + hval += asso_values[static_cast(str[14])]; + /*FALLTHROUGH*/ + case 14: + hval += asso_values[static_cast(str[13])]; + /*FALLTHROUGH*/ + case 13: + hval += asso_values[static_cast(str[12])]; /*FALLTHROUGH*/ case 12: - hval += asso_values[(unsigned char)str[11]]; + hval += asso_values[static_cast(str[11])]; /*FALLTHROUGH*/ case 11: - hval += asso_values[(unsigned char)str[10]]; + hval += asso_values[static_cast(str[10])]; /*FALLTHROUGH*/ case 10: - hval += asso_values[(unsigned char)str[9]]; + hval += asso_values[static_cast(str[9])]; /*FALLTHROUGH*/ case 9: - hval += asso_values[(unsigned char)str[8]]; + hval += asso_values[static_cast(str[8])]; /*FALLTHROUGH*/ case 8: - hval += asso_values[(unsigned char)str[7]]; + hval += asso_values[static_cast(str[7])]; /*FALLTHROUGH*/ case 7: - hval += asso_values[(unsigned char)str[6]]; + hval += asso_values[static_cast(str[6])]; /*FALLTHROUGH*/ case 6: - hval += asso_values[(unsigned char)str[5]]; + hval += asso_values[static_cast(str[5])]; /*FALLTHROUGH*/ case 5: - hval += asso_values[(unsigned char)str[4]]; + hval += asso_values[static_cast(str[4])]; /*FALLTHROUGH*/ case 4: - hval += asso_values[(unsigned char)str[3]]; + hval += asso_values[static_cast(str[3])]; /*FALLTHROUGH*/ case 3: - hval += asso_values[(unsigned char)str[2]]; + hval += asso_values[static_cast(str[2])]; /*FALLTHROUGH*/ case 2: - hval += asso_values[(unsigned char)str[1]]; + hval += asso_values[static_cast(str[1])]; /*FALLTHROUGH*/ case 1: - hval += asso_values[(unsigned char)str[0]]; + hval += asso_values[static_cast(str[0])]; break; } return hval; } const struct params * -ParameterHash::in_word_set (register const char *str, register unsigned int len) +ParameterHash::in_word_set (const char *str, size_t len) { enum { - TOTAL_KEYWORDS = 90, + TOTAL_KEYWORDS = 106, MIN_WORD_LENGTH = 1, - MAX_WORD_LENGTH = 13, + MAX_WORD_LENGTH = 18, MIN_HASH_VALUE = 2, - MAX_HASH_VALUE = 267 + MAX_HASH_VALUE = 512 }; static const struct params wordlist[] = { -#line 40 "ParameterHash.gperf" - {"lr", ParameterTypes::lr}, -#line 38 "ParameterHash.gperf" - {"ttl", ParameterTypes::ttl}, -#line 64 "ParameterHash.gperf" - {"stale", ParameterTypes::stale}, -#line 60 "ParameterHash.gperf" - {"nc", ParameterTypes::nc}, +#line 100 "ParameterHash.gperf" + {"rc", ParameterTypes::rc}, #line 23 "ParameterHash.gperf" {"actor", ParameterTypes::actor}, +#line 60 "ParameterHash.gperf" + {"nc", ParameterTypes::nc}, #line 83 "ParameterHash.gperf" {"site", ParameterTypes::site}, #line 54 "ParameterHash.gperf" {"rport", ParameterTypes::rport}, +#line 102 "ParameterHash.gperf" + {"np", ParameterTypes::np}, +#line 81 "ParameterHash.gperf" + {"size", ParameterTypes::size}, #line 71 "ParameterHash.gperf" {"reason", ParameterTypes::reason}, -#line 10 "ParameterHash.gperf" - {"data", ParameterTypes::data}, +#line 34 "ParameterHash.gperf" + {"transport", ParameterTypes::transport}, #line 59 "ParameterHash.gperf" {"nonce", ParameterTypes::nonce}, #line 56 "ParameterHash.gperf" {"cnonce", ParameterTypes::cnonce}, -#line 11 "ParameterHash.gperf" - {"control", ParameterTypes::control}, -#line 63 "ParameterHash.gperf" - {"response", ParameterTypes::response}, -#line 34 "ParameterHash.gperf" - {"transport", ParameterTypes::transport}, -#line 58 "ParameterHash.gperf" - {"id", ParameterTypes::id}, -#line 77 "ParameterHash.gperf" - {"protocol", ParameterTypes::protocol}, +#line 111 "ParameterHash.gperf" + {"content", ParameterTypes::content}, #line 52 "ParameterHash.gperf" {"rinstance", ParameterTypes::rinstance}, -#line 62 "ParameterHash.gperf" - {"realm", ParameterTypes::realm}, -#line 29 "ParameterHash.gperf" - {"ob", ParameterTypes::ob}, -#line 33 "ParameterHash.gperf" - {"name", ParameterTypes::name}, -#line 30 "ParameterHash.gperf" - {"gr", ParameterTypes::gr}, -#line 48 "ParameterHash.gperf" - {"tag", ParameterTypes::tag}, +#line 58 "ParameterHash.gperf" + {"id", ParameterTypes::id}, +#line 63 "ParameterHash.gperf" + {"response", ParameterTypes::response}, +#line 10 "ParameterHash.gperf" + {"data", ParameterTypes::data}, +#line 101 "ParameterHash.gperf" + {"mp", ParameterTypes::mp}, +#line 27 "ParameterHash.gperf" + {"+sip.instance", ParameterTypes::Instance}, #line 53 "ParameterHash.gperf" {"comp", ParameterTypes::comp}, -#line 97 "ParameterHash.gperf" - {"url", ParameterTypes::url}, +#line 69 "ParameterHash.gperf" + {"uri", ParameterTypes::uri}, +#line 33 "ParameterHash.gperf" + {"name", ParameterTypes::name}, +#line 110 "ParameterHash.gperf" + {"term-ioi", ParameterTypes::termIoi}, #line 35 "ParameterHash.gperf" {"user", ParameterTypes::user}, #line 25 "ParameterHash.gperf" {"cause", ParameterTypes::cause}, -#line 41 "ParameterHash.gperf" - {"q", ParameterTypes::q}, -#line 27 "ParameterHash.gperf" - {"+sip.instance", ParameterTypes::Instance}, -#line 85 "ParameterHash.gperf" - {"mode", ParameterTypes::mode}, -#line 91 "ParameterHash.gperf" - {"model", ParameterTypes::model}, -#line 18 "ParameterHash.gperf" - {"application", ParameterTypes::application}, -#line 69 "ParameterHash.gperf" - {"uri", ParameterTypes::uri}, -#line 81 "ParameterHash.gperf" - {"size", ParameterTypes::size}, -#line 99 "ParameterHash.gperf" - {"addtransport", ParameterTypes::addTransport}, -#line 68 "ParameterHash.gperf" - {"qop", ParameterTypes::qop}, -#line 39 "ParameterHash.gperf" - {"maddr", ParameterTypes::maddr}, -#line 13 "ParameterHash.gperf" - {"description", ParameterTypes::description}, -#line 42 "ParameterHash.gperf" - {"purpose", ParameterTypes::purpose}, -#line 76 "ParameterHash.gperf" - {"filename", ParameterTypes::filename}, -#line 57 "ParameterHash.gperf" - {"domain", ParameterTypes::domain}, -#line 36 "ParameterHash.gperf" - {"ext", ParameterTypes::extension}, -#line 24 "ParameterHash.gperf" - {"text", ParameterTypes::text}, -#line 82 "ParameterHash.gperf" - {"permission", ParameterTypes::permission}, -#line 21 "ParameterHash.gperf" - {"type", ParameterTypes::type}, -#line 78 "ParameterHash.gperf" - {"micalg", ParameterTypes::micalg}, -#line 22 "ParameterHash.gperf" - {"isfocus", ParameterTypes::isFocus}, -#line 65 "ParameterHash.gperf" - {"username", ParameterTypes::username}, #line 95 "ParameterHash.gperf" {"app-id", ParameterTypes::appId}, -#line 87 "ParameterHash.gperf" - {"charset", ParameterTypes::charset}, -#line 45 "ParameterHash.gperf" - {"duration", ParameterTypes::duration}, +#line 30 "ParameterHash.gperf" + {"gr", ParameterTypes::gr}, +#line 48 "ParameterHash.gperf" + {"tag", ParameterTypes::tag}, +#line 82 "ParameterHash.gperf" + {"permission", ParameterTypes::permission}, +#line 13 "ParameterHash.gperf" + {"description", ParameterTypes::description}, +#line 40 "ParameterHash.gperf" + {"lr", ParameterTypes::lr}, +#line 38 "ParameterHash.gperf" + {"ttl", ParameterTypes::ttl}, #line 43 "ParameterHash.gperf" {"to-tag", ParameterTypes::toTag}, -#line 46 "ParameterHash.gperf" - {"expires", ParameterTypes::expires}, -#line 86 "ParameterHash.gperf" - {"server", ParameterTypes::server}, -#line 72 "ParameterHash.gperf" - {"d-alg", ParameterTypes::dAlg}, -#line 14 "ParameterHash.gperf" - {"events", ParameterTypes::events}, -#line 94 "ParameterHash.gperf" - {"document", ParameterTypes::document}, -#line 67 "ParameterHash.gperf" - {"refresher", ParameterTypes::refresher}, -#line 26 "ParameterHash.gperf" - {"extensions", ParameterTypes::extensions}, -#line 61 "ParameterHash.gperf" - {"opaque", ParameterTypes::opaque}, -#line 51 "ParameterHash.gperf" - {"require", ParameterTypes::require}, +#line 42 "ParameterHash.gperf" + {"purpose", ParameterTypes::purpose}, +#line 109 "ParameterHash.gperf" + {"orig-ioi", ParameterTypes::origIoi}, +#line 85 "ParameterHash.gperf" + {"mode", ParameterTypes::mode}, +#line 64 "ParameterHash.gperf" + {"stale", ParameterTypes::stale}, +#line 57 "ParameterHash.gperf" + {"domain", ParameterTypes::domain}, +#line 11 "ParameterHash.gperf" + {"control", ParameterTypes::control}, +#line 77 "ParameterHash.gperf" + {"protocol", ParameterTypes::protocol}, +#line 114 "ParameterHash.gperf" + {"ws-src-ip", ParameterTypes::wsSrcIp}, +#line 115 "ParameterHash.gperf" + {"ws-src-port", ParameterTypes::wsSrcPort}, +#line 113 "ParameterHash.gperf" + {"addtransport", ParameterTypes::addTransport}, +#line 45 "ParameterHash.gperf" + {"duration", ParameterTypes::duration}, +#line 18 "ParameterHash.gperf" + {"application", ParameterTypes::application}, #line 15 "ParameterHash.gperf" {"priority", ParameterTypes::priority}, -#line 84 "ParameterHash.gperf" - {"directory", ParameterTypes::directory}, +#line 21 "ParameterHash.gperf" + {"type", ParameterTypes::type}, +#line 39 "ParameterHash.gperf" + {"maddr", ParameterTypes::maddr}, +#line 87 "ParameterHash.gperf" + {"charset", ParameterTypes::charset}, +#line 65 "ParameterHash.gperf" + {"username", ParameterTypes::username}, +#line 62 "ParameterHash.gperf" + {"realm", ParameterTypes::realm}, #line 28 "ParameterHash.gperf" {"reg-id", ParameterTypes::regid}, -#line 17 "ParameterHash.gperf" - {"schemes", ParameterTypes::schemes}, -#line 80 "ParameterHash.gperf" - {"expiration", ParameterTypes::expiration}, -#line 49 "ParameterHash.gperf" - {"branch", ParameterTypes::branch}, -#line 92 "ParameterHash.gperf" - {"version", ParameterTypes::version}, -#line 73 "ParameterHash.gperf" - {"d-qop", ParameterTypes::dQop}, -#line 90 "ParameterHash.gperf" - {"vendor", ParameterTypes::vendor}, -#line 96 "ParameterHash.gperf" - {"network-user", ParameterTypes::networkUser}, -#line 50 "ParameterHash.gperf" - {"received", ParameterTypes::received}, -#line 19 "ParameterHash.gperf" - {"video", ParameterTypes::video}, +#line 29 "ParameterHash.gperf" + {"ob", ParameterTypes::ob}, +#line 97 "ParameterHash.gperf" + {"url", ParameterTypes::url}, +#line 112 "ParameterHash.gperf" + {"encoding", ParameterTypes::encoding}, #line 88 "ParameterHash.gperf" {"access-type", ParameterTypes::accessType}, -#line 20 "ParameterHash.gperf" - {"language", ParameterTypes::language}, +#line 94 "ParameterHash.gperf" + {"document", ParameterTypes::document}, +#line 84 "ParameterHash.gperf" + {"directory", ParameterTypes::directory}, +#line 96 "ParameterHash.gperf" + {"network-user", ParameterTypes::networkUser}, +#line 91 "ParameterHash.gperf" + {"model", ParameterTypes::model}, +#line 17 "ParameterHash.gperf" + {"schemes", ParameterTypes::schemes}, +#line 104 "ParameterHash.gperf" + {"cgi-3gpp", ParameterTypes::cgi3gpp}, +#line 98 "ParameterHash.gperf" + {"sigcomp-id", ParameterTypes::sigcompId}, +#line 86 "ParameterHash.gperf" + {"server", ParameterTypes::server}, +#line 92 "ParameterHash.gperf" + {"version", ParameterTypes::version}, +#line 105 "ParameterHash.gperf" + {"ccf", ParameterTypes::ccf}, +#line 41 "ParameterHash.gperf" + {"q", ParameterTypes::q}, +#line 14 "ParameterHash.gperf" + {"events", ParameterTypes::events}, +#line 106 "ParameterHash.gperf" + {"ecf", ParameterTypes::ecf}, +#line 78 "ParameterHash.gperf" + {"micalg", ParameterTypes::micalg}, +#line 68 "ParameterHash.gperf" + {"qop", ParameterTypes::qop}, +#line 72 "ParameterHash.gperf" + {"d-alg", ParameterTypes::dAlg}, #line 37 "ParameterHash.gperf" {"method", ParameterTypes::method}, #line 16 "ParameterHash.gperf" {"methods", ParameterTypes::methods}, -#line 44 "ParameterHash.gperf" - {"from-tag", ParameterTypes::fromTag}, -#line 70 "ParameterHash.gperf" - {"retry-after", ParameterTypes::retryAfter}, +#line 36 "ParameterHash.gperf" + {"ext", ParameterTypes::extension}, +#line 24 "ParameterHash.gperf" + {"text", ParameterTypes::text}, +#line 19 "ParameterHash.gperf" + {"video", ParameterTypes::video}, #line 74 "ParameterHash.gperf" {"d-ver", ParameterTypes::dVer}, -#line 12 "ParameterHash.gperf" - {"mobility", ParameterTypes::mobility}, -#line 47 "ParameterHash.gperf" - {"handling", ParameterTypes::handling}, -#line 98 "ParameterHash.gperf" - {"sigcomp-id", ParameterTypes::sigcompId}, -#line 89 "ParameterHash.gperf" - {"profile-type", ParameterTypes::profileType}, -#line 55 "ParameterHash.gperf" - {"algorithm", ParameterTypes::algorithm}, -#line 79 "ParameterHash.gperf" - {"boundary", ParameterTypes::boundary}, +#line 90 "ParameterHash.gperf" + {"vendor", ParameterTypes::vendor}, +#line 108 "ParameterHash.gperf" + {"icid-generated-at", ParameterTypes::icidGeneratedAt}, #line 75 "ParameterHash.gperf" {"smime-type", ParameterTypes::smimeType}, -#line 66 "ParameterHash.gperf" - {"early-only", ParameterTypes::earlyOnly}, +#line 46 "ParameterHash.gperf" + {"expires", ParameterTypes::expires}, +#line 50 "ParameterHash.gperf" + {"received", ParameterTypes::received}, +#line 80 "ParameterHash.gperf" + {"expiration", ParameterTypes::expiration}, +#line 26 "ParameterHash.gperf" + {"extensions", ParameterTypes::extensions}, +#line 22 "ParameterHash.gperf" + {"isfocus", ParameterTypes::isFocus}, +#line 73 "ParameterHash.gperf" + {"d-qop", ParameterTypes::dQop}, #line 32 "ParameterHash.gperf" {"temp-gruu", ParameterTypes::tempGruu}, +#line 99 "ParameterHash.gperf" + {"index", ParameterTypes::index}, +#line 49 "ParameterHash.gperf" + {"branch", ParameterTypes::branch}, +#line 61 "ParameterHash.gperf" + {"opaque", ParameterTypes::opaque}, +#line 51 "ParameterHash.gperf" + {"require", ParameterTypes::require}, +#line 20 "ParameterHash.gperf" + {"language", ParameterTypes::language}, +#line 44 "ParameterHash.gperf" + {"from-tag", ParameterTypes::fromTag}, +#line 55 "ParameterHash.gperf" + {"algorithm", ParameterTypes::algorithm}, +#line 70 "ParameterHash.gperf" + {"retry-after", ParameterTypes::retryAfter}, +#line 47 "ParameterHash.gperf" + {"handling", ParameterTypes::handling}, +#line 67 "ParameterHash.gperf" + {"refresher", ParameterTypes::refresher}, +#line 76 "ParameterHash.gperf" + {"filename", ParameterTypes::filename}, +#line 79 "ParameterHash.gperf" + {"boundary", ParameterTypes::boundary}, +#line 107 "ParameterHash.gperf" + {"icid-value", ParameterTypes::icidValue}, +#line 12 "ParameterHash.gperf" + {"mobility", ParameterTypes::mobility}, #line 31 "ParameterHash.gperf" {"pub-gruu", ParameterTypes::pubGruu}, +#line 66 "ParameterHash.gperf" + {"early-only", ParameterTypes::earlyOnly}, +#line 103 "ParameterHash.gperf" + {"utran-cell-id-3gpp", ParameterTypes::utranCellId3gpp}, +#line 89 "ParameterHash.gperf" + {"profile-type", ParameterTypes::profileType}, #line 93 "ParameterHash.gperf" {"effective-by", ParameterTypes::effectiveBy} }; static const signed char lookup[] = { - -1, -1, 0, 1, -1, 2, -1, 3, -1, -1, 4, -1, -1, -1, - 5, 6, 7, -1, -1, 8, 9, 10, 11, 12, 13, -1, -1, 14, - 15, 16, 17, -1, 18, -1, 19, -1, -1, 20, 21, 22, -1, -1, - -1, 23, 24, 25, 26, -1, 27, 28, 29, 30, -1, 31, 32, -1, - -1, 33, 34, -1, 35, 36, 37, 38, -1, -1, 39, -1, 40, 41, - 42, -1, -1, -1, 43, -1, 44, 45, 46, -1, -1, 47, 48, 49, - -1, -1, 50, 51, -1, -1, -1, 52, -1, -1, -1, 53, 54, -1, - 55, 56, 57, 58, 59, 60, 61, -1, 62, 63, -1, -1, 64, 65, - 66, -1, -1, 67, 68, 69, 70, -1, 71, 72, -1, 73, -1, -1, - 74, 75, 76, -1, -1, 77, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 78, -1, -1, 79, -1, -1, -1, -1, 80, - -1, 81, -1, 82, -1, 83, -1, -1, -1, 84, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 85, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 86, -1, -1, -1, 87, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 88, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 89 + -1, -1, 0, -1, -1, 1, -1, 2, -1, 3, + 4, -1, 5, -1, 6, -1, 7, -1, -1, 8, + 9, 10, 11, -1, 12, -1, -1, 13, 14, 15, + -1, -1, 16, 17, 18, -1, -1, -1, 19, 20, + -1, -1, -1, 21, 22, 23, 24, 25, 26, -1, + 27, 28, 29, 30, -1, -1, 31, 32, 33, 34, + 35, 36, 37, 38, 39, -1, 40, -1, -1, -1, + -1, -1, 41, 42, -1, -1, 43, -1, 44, 45, + 46, -1, 47, 48, -1, 49, 50, 51, 52, -1, + -1, -1, -1, 53, -1, -1, 54, -1, -1, -1, + -1, -1, -1, 55, 56, -1, -1, 57, -1, -1, + 58, -1, 59, 60, -1, 61, 62, 63, 64, -1, + 65, 66, -1, 67, -1, -1, 68, 69, -1, -1, + 70, 71, 72, 73, 74, 75, -1, -1, -1, -1, + 76, 77, 78, -1, -1, 79, -1, 80, 81, -1, + 82, -1, -1, -1, -1, 83, -1, 84, -1, 85, + -1, -1, -1, -1, 86, 87, 88, -1, -1, -1, + 89, 90, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 91, -1, -1, -1, -1, 92, 93, + -1, -1, -1, -1, -1, -1, 94, -1, 95, 96, + -1, -1, -1, 97, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 98, -1, -1, -1, -1, -1, -1, + 99, -1, -1, 100, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 101, -1, 102, -1, -1, 103, -1, + -1, -1, -1, -1, -1, -1, -1, 104, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 105 }; if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) { - register int key = hash (str, len); + unsigned int key = hash (str, len); - if (key <= MAX_HASH_VALUE && key >= 0) + if (key <= MAX_HASH_VALUE) { - register int index = lookup[key]; + int index = lookup[key]; if (index >= 0) { - register const char *s = wordlist[index].name; + const char *s = wordlist[index].name; if ((((unsigned char)*str ^ (unsigned char)*s) & ~32) == 0 && !gperf_case_strncmp (str, s, len) && s[len] == '\0') return &wordlist[index]; @@ -410,6 +489,6 @@ ParameterHash::in_word_set (register const char *str, register unsigned int len) } return 0; } -#line 100 "ParameterHash.gperf" +#line 116 "ParameterHash.gperf" } diff --git a/src/libs/resiprocate/resip/stack/gperf_w32.bat b/src/libs/resiprocate/resip/stack/gperf_w32.bat index 0aebd727..a0b3d97b 100644 --- a/src/libs/resiprocate/resip/stack/gperf_w32.bat +++ b/src/libs/resiprocate/resip/stack/gperf_w32.bat @@ -1,14 +1,17 @@ -@echo off -echo WARNING - use of this batch file is only recommended for advanced users. -echo It is used to automate the first step required in creating the -echo GPERF HASH files for resiprocate on windows. -echo. -echo Note - Ensure gperf.exe is present in the path or resip/stack directory -echo before continuing -echo. -pause -gperf -C -D -E -L C++ -t -k "*" --compare-strncmp -Z MethodHash MethodHash.gperf > MethodHash.cxx -gperf -C -D -E -L C++ -t -k "*" --compare-strncmp --ignore-case -Z HeaderHash HeaderHash.gperf > HeaderHash.cxx -gperf -C -D -E -L C++ -t -k "*" --compare-strncmp --ignore-case -Z ParameterHash ParameterHash.gperf > ParameterHash.cxx -echo MethodHash.cxx, HeaderHash.cxx and ParameterHash.cxx have been created using gperf. -pause +@echo off +echo WARNING - use of this batch file is only recommended for advanced users. +echo It is used to automate the first step required in creating the +echo GPERF HASH files for resiprocate on windows. +echo. +echo Note - Ensure gperf.exe is present in the path or resip/stack directory +echo before continuing +echo. +pause +if not exist gen mkdir gen +gperf -C -D -E -L C++ -t --key-positions="*" --compare-strncmp -Z DayOfWeekHash DayOfWeekHash.gperf > gen\DayOfWeekHash.cxx +gperf -C -D -E -L C++ -t --key-positions="*" --compare-strncmp -Z MonthHash MonthHash.gperf > gen\MonthHash.cxx +gperf -C -D -E -L C++ -t --key-positions="*" --compare-strncmp -Z MethodHash MethodHash.gperf > gen\MethodHash.cxx +gperf -C -D -E -L C++ -t --key-positions="*" --compare-strncmp --ignore-case -Z HeaderHash HeaderHash.gperf > gen\HeaderHash.cxx +gperf -C -D -E -L C++ -t --key-positions="*" --compare-strncmp --ignore-case -Z ParameterHash ParameterHash.gperf > gen\ParameterHash.cxx +echo DayOfWeekHash.cxx, MonthHash.cxx, MethodHash.cxx, HeaderHash.cxx and ParameterHash.cxx have been created using gperf. +pause diff --git a/src/libs/resiprocate/resip/stack/makeCert.cxx b/src/libs/resiprocate/resip/stack/makeCert.cxx deleted file mode 100644 index 9b685571..00000000 --- a/src/libs/resiprocate/resip/stack/makeCert.cxx +++ /dev/null @@ -1,177 +0,0 @@ - -#if defined(HAVE_CONFIG_H) - #include "config.h" -#endif - -#if defined(USE_SSL) -#include -#include -#include -#include -#include -#include "resip/stack/X509Contents.hxx" -#include "resip/stack/Pkcs8Contents.hxx" -#include "resip/stack/MultipartMixedContents.hxx" -#include "resip/stack/Uri.hxx" -#include "rutil/Random.hxx" - -using namespace resip; - -int makeSelfCert(X509** selfcert, EVP_PKEY* privkey); - -int main() -{ - int err; - Uri aor; - Data passphrase; - RSA *rsa = NULL; - EVP_PKEY *privkey = NULL; - X509 *selfcert = NULL; - BUF_MEM *bptr = NULL; - - // initilization: are these needed? -// CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); -// bio_err=BIO_new_fp(stderr, BIO_NOCLOSE); - - Random::initialize(); - - rsa = RSA_generate_key(1024, RSA_F4, NULL, NULL); - assert(rsa); // couldn't make key pair - - EVP_PKEY_assign_RSA(privkey, rsa); - assert(privkey); - - selfcert = X509_new(); - err = makeSelfCert(&selfcert, privkey); - assert(!err); // couldn't make cert - - unsigned char* buffer = NULL; - int len = i2d_X509(selfcert, &buffer); // if buffer is NULL, openssl - // assigns memory for buffer - assert(buffer); - Data derData((char *) buffer, len); - X509Contents *certpart = new X509Contents( derData ); - assert(certpart); - - // make an in-memory BIO [ see BIO_s_mem(3) ] - BIO *mbio = BIO_new(BIO_s_mem()); - - // encrypt the the private key with the passphrase and put it in the BIO in DER format - i2d_PKCS8PrivateKey_bio( mbio, privkey, EVP_des_ede3_cbc(), - (char *) passphrase.data(), - passphrase.size(), NULL, NULL); - - // dump the BIO into a Contents - BIO_get_mem_ptr(mbio, &bptr); - Pkcs8Contents *keypart = new Pkcs8Contents(Data(bptr->data, bptr->length)); - assert(keypart); - BIO_free(mbio); - - MultipartMixedContents *certsbody = new MultipartMixedContents; - certsbody->parts().push_back(certpart); - certsbody->parts().push_back(keypart); - assert(certsbody); -} - - -int makeSelfCert(X509 **cert, EVP_PKEY *privkey) // should include a Uri type at the end of the function call -{ - int serial; - assert(sizeof(int)==4); - const long duration = 60*60*24*30; // make cert valid for 30 days - X509* selfcert = NULL; - X509_NAME *subject = NULL; - X509_EXTENSION *ext = NULL; - - Data domain("example.org"); - Data userAtDomain("user@example.org"); - - // Setup the subjectAltName structure here with sip:, im:, and pres: URIs - // TODO: - - selfcert = *cert; - - X509_set_version(selfcert, 2L); // set version to X509v3 (starts from 0) - - // RAND_bytes((char *) serial , 4); - //serial = 1; - serial = Random::getRandom(); // get an int worth of randomness - ASN1_INTEGER_set(X509_get_serialNumber(selfcert),serial); - - X509_NAME_add_entry_by_txt( subject, "O", MBSTRING_UTF8, (unsigned char *) domain.data(), domain.size(), -1, 0); - X509_NAME_add_entry_by_txt( subject, "CN", MBSTRING_UTF8, (unsigned char *) userAtDomain.data(), userAtDomain.size(), -1, 0); - - X509_set_issuer_name(selfcert, subject); - X509_set_subject_name(selfcert, subject); - - X509_gmtime_adj(X509_get_notBefore(selfcert),0); - X509_gmtime_adj(X509_get_notAfter(selfcert), duration); - - X509_set_pubkey(selfcert, privkey); - - // need to fiddle with this to make this work with lists of IA5 URIs and UTF8 - //ext = X509V3_EXT_conf_nid( NULL , NULL , NID_subject_alt_name, subjectAltNameStr.cstr() ); - //X509_add_ext( selfcert, ext, -1); - //X509_EXTENSION_free(ext); - - ext = X509V3_EXT_conf_nid(NULL, NULL, NID_basic_constraints, "CA:FALSE"); - X509_add_ext( selfcert, ext, -1); - X509_EXTENSION_free(ext); - - // add extensions NID_subject_key_identifier and NID_authority_key_identifier - - X509_sign(selfcert, privkey, EVP_sha1()); - - return true; -} -#endif - -/* ==================================================================== - * The Vovida Software License, Version 1.0 - * - * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The names "VOCAL", "Vovida Open Communication Application Library", - * and "Vovida Open Communication Application Library (VOCAL)" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact vocal@vovida.org. - * - * 4. Products derived from this software may not be called "VOCAL", nor - * may "VOCAL" appear in their name, without prior written - * permission of Vovida Networks, Inc. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND - * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA - * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES - * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * ==================================================================== - * - * This software consists of voluntary contributions made by Vovida - * Networks, Inc. and many individuals on behalf of Vovida Networks, - * Inc. For more information on Vovida Networks, Inc., please see - * . - * - */ diff --git a/src/libs/resiprocate/resip/stack/month.gperf b/src/libs/resiprocate/resip/stack/month.gperf deleted file mode 100644 index 333f071c..00000000 --- a/src/libs/resiprocate/resip/stack/month.gperf +++ /dev/null @@ -1,14 +0,0 @@ -struct months { const char *name; Month type; }; -%% -Jan, Month::Jan -Feb, Month::Feb -Mar, Month::Mar -Apr, Month::Apr -May, Month::May -Jun, Month::Jun -Jul, Month::Jul -Aug, Month::Aug -Sep, Month::Sep -Oct, Month::Oct -Nov, Month::Nov -Dec, Month::Dec diff --git a/src/libs/resiprocate/resip/stack/resiprocate.pro b/src/libs/resiprocate/resip/stack/resiprocate.pro deleted file mode 100644 index 89137fe7..00000000 --- a/src/libs/resiprocate/resip/stack/resiprocate.pro +++ /dev/null @@ -1,310 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2010-11-29T21:54:39 -# -#------------------------------------------------- - -QT -= core gui - -TARGET = resiprocate -TEMPLATE = lib -CONFIG += staticlib -INCLUDEPATH += ../../ ../../contrib/ares ../../../contrib/ares -DEFINES += USE_ARES USE_IPV6 _WIN32_WINNT=0x0501 - -win32 { - DESTDIR = ../../../../Libs/compiled/win -} - -SOURCES += \ - CallId.cxx \ - BranchParameter.cxx \ - BasicNonceHelper.cxx \ - Auth.cxx \ - ApplicationSip.cxx \ - ApiCheck.cxx \ - Aor.cxx \ - Compression.cxx \ - DateCategory.cxx \ - DataParameter.cxx \ - CSeqCategory.cxx \ - CpimContents.cxx \ - ContentsFactoryBase.cxx \ - Contents.cxx \ - ConnectionManager.cxx \ - ConnectionBase.cxx \ - Connection.cxx \ - DnsResult.cxx \ - DnsInterface.cxx \ - DeprecatedDialog.cxx \ - ExternalBodyContents.cxx \ - ExtensionParameter.cxx \ - ExtensionHeader.cxx \ - ExpiresCategory.cxx \ - ExistsParameter.cxx \ - ExistsOrDataParameter.cxx \ - Embedded.cxx \ - DtlsMessage.cxx \ - GenericUri.cxx \ - GenericContents.cxx \ - FloatParameter.cxx \ - LazyParser.cxx \ - KeepAliveMessage.cxx \ - InvalidContents.cxx \ - InterruptableStackThread.cxx \ - InteropHelper.cxx \ - InternalTransport.cxx \ - IntegerParameter.cxx \ - IntegerCategory.cxx \ - Helper.cxx \ - HeaderTypes.cxx \ - Headers.cxx \ - HeaderHash.cxx \ - HeaderFieldValueList.cxx \ - HeaderFieldValue.cxx \ - SecurityAttributes.cxx \ - SdpContents.cxx \ - RportParameter.cxx \ - Rlmi.cxx \ - RequestLine.cxx \ - RAckCategory.cxx \ - QValueParameter.cxx \ - QValue.cxx \ - QuotedDataParameter.cxx \ - PrivacyCategory.cxx \ - PlainContents.cxx \ - Pkcs8Contents.cxx \ - Pkcs7Contents.cxx \ - Pidf.cxx \ - ParserContainerBase.cxx \ - ParserCategory.cxx \ - ParserCategories.cxx \ - ParameterTypes.cxx \ - ParameterHash.cxx \ - Parameter.cxx \ - OctetContents.cxx \ - NonceHelper.cxx \ - NameAddr.cxx \ - MultipartSignedContents.cxx \ - MultipartRelatedContents.cxx \ - MultipartMixedContents.cxx \ - MultipartAlternativeContents.cxx \ - MsgHeaderScanner.cxx \ - Mime.cxx \ - MethodTypes.cxx \ - MethodHash.cxx \ - MessageWaitingContents.cxx \ - MessageFilterRule.cxx \ - Message.cxx \ - XMLCursor.cxx \ - X509Contents.cxx \ - WarningCategory.cxx \ - Via.cxx \ - Uri.cxx \ - UnknownParameter.cxx \ - UInt32Parameter.cxx \ - UInt32Category.cxx \ - UdpTransport.cxx \ - TuSelector.cxx \ - TupleMarkManager.cxx \ - Tuple.cxx \ - TuIM.cxx \ - TransportSelector.cxx \ - TransportFailure.cxx \ - Transport.cxx \ - TransactionUserMessage.cxx \ - TransactionUser.cxx \ - TransactionState.cxx \ - TransactionMap.cxx \ - TransactionController.cxx \ - Token.cxx \ - TimerQueue.cxx \ - TimerMessage.cxx \ - TimeAccumulate.cxx \ - TcpTransport.cxx \ - TcpConnection.cxx \ - TcpBaseTransport.cxx \ - Symbols.cxx \ - StringCategory.cxx \ - StatusLine.cxx \ - StatisticsMessage.cxx \ - StatisticsManager.cxx \ - StatisticsHandler.cxx \ - StatelessHandler.cxx \ - StackThread.cxx \ - SipStack.cxx \ - SipMessage.cxx \ - SipFrag.cxx \ - SERNonceHelper.cxx \ - SelectInterruptor.cxx \ - ssl/TlsTransport.cxx \ - ssl/TlsConnection.cxx \ - ssl/Security.cxx \ - ssl/DtlsTransport.cxx - -win32 { - SOURCES += ssl/WinSecurity.cxx -} - -HEADERS += \ - CancelClientInviteTransaction.hxx \ - CancelableTimerQueue.hxx \ - CallId.hxx \ - BranchParameter.hxx \ - BasicNonceHelper.hxx \ - Auth.hxx \ - ApplicationSip.hxx \ - ApplicationMessage.hxx \ - ApiCheckList.hxx \ - ApiCheck.hxx \ - Aor.hxx \ - AbandonServerTransaction.hxx \ - Compression.hxx \ - DateCategory.hxx \ - DataParameter.hxx \ - CSeqCategory.hxx \ - CpimContents.hxx \ - ContentsFactoryBase.hxx \ - ContentsFactory.hxx \ - Contents.hxx \ - ConnectionTerminated.hxx \ - ConnectionManager.hxx \ - ConnectionBase.hxx \ - Connection.hxx \ - DnsResult.hxx \ - DnsInterface.hxx \ - DeprecatedDialog.hxx \ - ExternalBodyContents.hxx \ - ExtensionParameter.hxx \ - ExtensionHeader.hxx \ - ExpiresCategory.hxx \ - ExistsParameter.hxx \ - ExistsOrDataParameter.hxx \ - Embedded.hxx \ - DtlsMessage.hxx \ - GenericUri.hxx \ - GenericContents.hxx \ - FloatParameter.hxx \ - LazyParser.hxx \ - KeepAliveMessage.hxx \ - InvalidContents.hxx \ - InterruptableStackThread.hxx \ - InteropHelper.hxx \ - InternalTransport.hxx \ - IntegerParameter.hxx \ - IntegerCategory.hxx \ - Helper.hxx \ - HeaderTypes.hxx \ - Headers.hxx \ - HeaderHash.hxx \ - HeaderFieldValueList.hxx \ - HeaderFieldValue.hxx \ - SecurityTypes.hxx \ - SecurityAttributes.hxx \ - SdpContents.hxx \ - RportParameter.hxx \ - Rlmi.hxx \ - RequestLine.hxx \ - RAckCategory.hxx \ - QValueParameter.hxx \ - QValue.hxx \ - QuotedDataParameter.hxx \ - PrivacyCategory.hxx \ - PlainContents.hxx \ - Pkcs8Contents.hxx \ - Pkcs7Contents.hxx \ - Pidf.hxx \ - ParserContainerBase.hxx \ - ParserContainer.hxx \ - ParserCategory.hxx \ - ParserCategories.hxx \ - ParameterTypes.hxx \ - ParameterTypeEnums.hxx \ - parametersA.gperf \ - ParameterHash.hxx \ - Parameter.hxx \ - OctetContents.hxx \ - NonceHelper.hxx \ - NameAddr.hxx \ - MultipartSignedContents.hxx \ - MultipartRelatedContents.hxx \ - MultipartMixedContents.hxx \ - MultipartAlternativeContents.hxx \ - MsgHeaderScanner.hxx \ - Mime.hxx \ - MethodTypes.hxx \ - MethodHash.hxx \ - MessageWaitingContents.hxx \ - MessageFilterRule.hxx \ - MessageDecorator.hxx \ - Message.hxx \ - MarkListener.hxx \ - XMLCursor.hxx \ - X509Contents.hxx \ - WarningCategory.hxx \ - Via.hxx \ - ValueFifo.hxx \ - Uri.hxx \ - UnknownParameterType.hxx \ - UnknownParameter.hxx \ - UnknownHeaderType.hxx \ - UInt32Parameter.hxx \ - UInt32Category.hxx \ - UdpTransport.hxx \ - TuSelector.hxx \ - TupleMarkManager.hxx \ - Tuple.hxx \ - TuIM.hxx \ - TransportSelector.hxx \ - TransportFailure.hxx \ - Transport.hxx \ - TransactionUserMessage.hxx \ - TransactionUser.hxx \ - TransactionTerminated.hxx \ - TransactionState.hxx \ - TransactionMessage.hxx \ - TransactionMap.hxx \ - TransactionController.hxx \ - Token.hxx \ - TimerQueue.hxx \ - TimerMessage.hxx \ - TimeAccumulate.hxx \ - TcpTransport.hxx \ - TcpConnection.hxx \ - TcpBaseTransport.hxx \ - Symbols.hxx \ - StringCategory.hxx \ - StatusLine.hxx \ - StatisticsMessage.hxx \ - StatisticsManager.hxx \ - StatisticsHandler.hxx \ - StatelessHandler.hxx \ - StackThread.hxx \ - SipStack.hxx \ - SipMessage.hxx \ - SipFrag.hxx \ - ShutdownMessage.hxx \ - SERNonceHelper.hxx \ - SendData.hxx \ - SelectInterruptor.hxx \ - ssl/TlsTransport.hxx \ - ssl/TlsConnection.hxx \ - ssl/Security.hxx \ - ssl/DtlsTransport.hxx - -win32 { - HEADERS += ssl/WinSecurity.hxx -} - -unix:!symbian { - maemo5 { - target.path = /opt/usr/lib - } else { - target.path = /usr/local/lib - } - INSTALLS += target -} - -OTHER_FILES += - - diff --git a/src/libs/resiprocate/resip/stack/resiprocate_10_0.vcxproj.filters b/src/libs/resiprocate/resip/stack/resiprocate_10_0.vcxproj.filters deleted file mode 100644 index 4517fd7c..00000000 --- a/src/libs/resiprocate/resip/stack/resiprocate_10_0.vcxproj.filters +++ /dev/null @@ -1,856 +0,0 @@ - - - - - {7670bbf8-7277-4dba-b6f5-bb726a96b4e6} - - - {11690c26-b5eb-442d-b7fb-5fb97ce10cf0} - h;hpp;hxx;hm;inl;inc - - - {4d95e332-af7e-4e86-9bd4-3c03fc017b97} - cpp;c;cxx;def;odl;idl;hpj;bat;asm - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - GPerfFiles - - - GPerfFiles - - - GPerfFiles - - - \ No newline at end of file diff --git a/src/libs/resiprocate/resip/stack/resiprocate_9_0.vcxproj b/src/libs/resiprocate/resip/stack/resiprocate_12_0.vcxproj.filters similarity index 52% rename from src/libs/resiprocate/resip/stack/resiprocate_9_0.vcxproj rename to src/libs/resiprocate/resip/stack/resiprocate_12_0.vcxproj.filters index 87d2ecd2..6531c9da 100644 --- a/src/libs/resiprocate/resip/stack/resiprocate_9_0.vcxproj +++ b/src/libs/resiprocate/resip/stack/resiprocate_12_0.vcxproj.filters @@ -1,179 +1,17 @@  - - - - Debug - Win32 - - - Release - Win32 - - - SSL-Debug - Win32 - - - SSL-Release - Win32 - + + + + {7670bbf8-7277-4dba-b6f5-bb726a96b4e6} + gperf + - - resiprocate - {2A8BE839-6466-4001-B224-8F1C3168D04A} - resiprocate - Win32Proj - - - - StaticLibrary - v120 - false - MultiByte - - - StaticLibrary - v120 - false - MultiByte - - - StaticLibrary - v120 - false - MultiByte - - - StaticLibrary - v120 - false - NotSet - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>12.0.21005.1 - - - $(SolutionDir)\output\$(Platform)\$(Configuration)\$(ProjectName)\ - $(SolutionDir)\intermediate\$(Platform)\$(Configuration)\$(ProjectName)\ - - - $(SolutionDir)\output\$(Platform)\$(Configuration)\$(ProjectName)\ - $(SolutionDir)\intermediate\$(Platform)\$(Configuration)\$(ProjectName)\ - - - $(Configuration)\ - SSL-Debug\ - - - SSL-Release\ - SSL-Release\ - - - - /Zm300 /MP %(AdditionalOptions) - Disabled - $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;LEAK_CHECK;USE_SSL;%(PreprocessorDefinitions) - false - EnableFastChecks - MultiThreadedDebugDLL - true - true - - Level3 - ProgramDatabase - - - $(OutDir)resiprocate.lib - - - - - /Zm300 /MP %(AdditionalOptions) - MaxSpeed - OnlyExplicitInline - Speed - true - $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions) - true - false - MultiThreadedDLL - false - true - true - - Level3 - - - - $(OutDir)resiprocate.lib - - - - - /Zm300 /MP %(AdditionalOptions) - Disabled - $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../../openssl/include;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;LEAK_CHECK;USE_SSL;USE_ARES;USE_IPV6;USE_DTLS;%(PreprocessorDefinitions) - false - EnableFastChecks - MultiThreadedDebugDLL - true - - Level3 - EditAndContinue - - - $(OutDir)resiprocate.lib - - - - - /Zm300 /MP %(AdditionalOptions) - MaxSpeed - OnlyExplicitInline - false - $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../../openssl/include;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;USE_SSL;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) - true - false - MultiThreadedDLL - true - true - - Level3 - ProgramDatabase - - - $(OutDir)resiprocate.lib - - + @@ -183,23 +21,23 @@ + + - - true - true - + + @@ -207,7 +45,6 @@ - @@ -222,9 +59,9 @@ - + @@ -234,7 +71,6 @@ - @@ -252,12 +88,10 @@ - - true - true - + + @@ -275,15 +109,11 @@ - - true - true - - - true - true - + + + + @@ -304,23 +134,43 @@ - - true - true - + + + + + + + + + + + + + + + + + + + + + + + + @@ -329,6 +179,7 @@ + @@ -337,14 +188,15 @@ + - + @@ -367,6 +219,7 @@ + @@ -398,6 +251,7 @@ + @@ -408,6 +262,7 @@ + @@ -424,13 +279,14 @@ - + + @@ -459,15 +315,37 @@ + + + + + + + + + + + - + + + + + + + + + - - - + + GPerfFiles + + + GPerfFiles + + + GPerfFiles + - - - - \ No newline at end of file + diff --git a/src/libs/resiprocate/resip/stack/resiprocate_10_0.vcxproj b/src/libs/resiprocate/resip/stack/resiprocate_14_0.vcxproj similarity index 67% rename from src/libs/resiprocate/resip/stack/resiprocate_10_0.vcxproj rename to src/libs/resiprocate/resip/stack/resiprocate_14_0.vcxproj index 9175e59d..5e1e8b77 100644 --- a/src/libs/resiprocate/resip/stack/resiprocate_10_0.vcxproj +++ b/src/libs/resiprocate/resip/stack/resiprocate_14_0.vcxproj @@ -17,6 +17,14 @@ Release x64 + + SSL-Debug-MT + Win32 + + + SSL-Debug-MT + x64 + SSL-Debug Win32 @@ -25,6 +33,14 @@ SSL-Debug x64 + + SSL-Release-MT + Win32 + + + SSL-Release-MT + x64 + SSL-Release Win32 @@ -47,24 +63,48 @@ MultiByte v140 + + StaticLibrary + false + MultiByte + v140 + StaticLibrary false MultiByte v140 + + StaticLibrary + false + MultiByte + v140 + StaticLibrary false MultiByte v140 + + StaticLibrary + false + MultiByte + v140 + StaticLibrary false MultiByte v140 + + StaticLibrary + false + MultiByte + v140 + StaticLibrary false @@ -96,18 +136,34 @@ + + + + + + + + + + + + + + + + @@ -127,22 +183,30 @@ <_ProjectFileVersion>10.0.21006.1 - Debug\ - Debug\ - Debug\ - Debug\ - Release\ - Release\ - Release\ - Release\ - SSL-Debug\ - SSL-Debug\ - SSL-Debug\ - SSL-Debug\ - SSL-Release\ - SSL-Release\ - SSL-Release\ - SSL-Release\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ AllRules.ruleset AllRules.ruleset @@ -156,24 +220,36 @@ AllRules.ruleset + AllRules.ruleset AllRules.ruleset + AllRules.ruleset + + + + AllRules.ruleset + AllRules.ruleset AllRules.ruleset + AllRules.ruleset + + + + /Zm300 %(AdditionalOptions) Disabled $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions) + WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL @@ -193,7 +269,7 @@ /Zm300 %(AdditionalOptions) Disabled $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions) + WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL true @@ -215,7 +291,7 @@ Speed true $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) + WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) true MultiThreadedDLL false @@ -239,7 +315,7 @@ Speed true $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) + WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) true MultiThreadedDLL false @@ -260,7 +336,7 @@ /Zm300 %(AdditionalOptions) Disabled $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;_LIB;LEAK_CHECK;USE_SSL;USE_ARES;USE_IPV6;USE_DTLS;NO_IPHLPAPI;%(PreprocessorDefinitions) + WIN32;_DEBUG;_LIB;LEAK_CHECK;USE_SSL;USE_ARES;USE_IPV6;USE_DTLS;NO_IPHLPAPI;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL @@ -274,12 +350,31 @@ $(OutDir)$(TargetName)$(TargetExt) + + + /Zm300 %(AdditionalOptions) + Disabled + $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;LEAK_CHECK;USE_SSL;USE_ARES;USE_IPV6;USE_DTLS;NO_IPHLPAPI;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + + + Level3 + EditAndContinue + + + $(OutDir)$(TargetName)$(TargetExt) + + /Zm300 %(AdditionalOptions) Disabled - $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;_LIB;LEAK_CHECK;USE_SSL;USE_ARES;USE_IPV6;USE_DTLS;NO_IPHLPAPI;%(PreprocessorDefinitions) + $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../contrib/opensslx64/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;LEAK_CHECK;USE_SSL;USE_ARES;USE_IPV6;USE_DTLS;NO_IPHLPAPI;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL true @@ -292,6 +387,24 @@ $(OutDir)$(TargetName)$(TargetExt) + + + /Zm300 %(AdditionalOptions) + Disabled + $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../contrib/opensslx64/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;LEAK_CHECK;USE_SSL;USE_ARES;USE_IPV6;USE_DTLS;NO_IPHLPAPI;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + /Zm300 %(AdditionalOptions) @@ -299,10 +412,33 @@ OnlyExplicitInline true $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;_LIB;USE_SSL;USE_ARES;USE_IPV6;NO_IPHLPAPI;%(PreprocessorDefinitions) + WIN32;NDEBUG;_LIB;USE_SSL;USE_ARES;USE_IPV6;NO_IPHLPAPI;%(PreprocessorDefinitions) true MultiThreadedDLL - true + + + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + /Zm300 %(AdditionalOptions) + MaxSpeed + OnlyExplicitInline + true + $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;USE_SSL;USE_ARES;USE_IPV6;NO_IPHLPAPI;%(PreprocessorDefinitions) + true + MultiThreaded + + true @@ -319,8 +455,8 @@ MaxSpeed OnlyExplicitInline true - $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;_LIB;USE_SSL;USE_ARES;USE_IPV6;NO_IPHLPAPI;%(PreprocessorDefinitions) + $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../contrib/opensslx64/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;USE_SSL;USE_ARES;USE_IPV6;NO_IPHLPAPI;%(PreprocessorDefinitions) true MultiThreadedDLL true @@ -334,11 +470,33 @@ $(OutDir)$(TargetName)$(TargetExt) + + + /Zm300 %(AdditionalOptions) + MaxSpeed + OnlyExplicitInline + true + $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../contrib/opensslx64/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;USE_SSL;USE_ARES;USE_IPV6;NO_IPHLPAPI;%(PreprocessorDefinitions) + true + MultiThreaded + true + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + @@ -348,14 +506,20 @@ + + + + + + true true @@ -367,6 +531,7 @@ + @@ -374,10 +539,11 @@ - + + @@ -389,9 +555,10 @@ - + + @@ -401,7 +568,7 @@ - + @@ -427,9 +594,28 @@ + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + @@ -440,6 +626,7 @@ + @@ -457,6 +644,7 @@ true + @@ -483,15 +671,25 @@ true true + + + + + + + + + + @@ -505,23 +703,32 @@ + + + + + + + + + @@ -533,6 +740,7 @@ + @@ -584,9 +792,13 @@ + + + + @@ -598,15 +810,16 @@ + - + @@ -635,6 +848,17 @@ + + + + + + + + + + + @@ -643,12 +867,6 @@ - - - {3d0e5ceb-93dc-4fdb-918b-d08fa369e106} - false - - diff --git a/src/libs/resiprocate/resip/stack/resiprocate_14_0.vcxproj.filters b/src/libs/resiprocate/resip/stack/resiprocate_14_0.vcxproj.filters new file mode 100644 index 00000000..cc790193 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/resiprocate_14_0.vcxproj.filters @@ -0,0 +1,351 @@ + + + + + {7670bbf8-7277-4dba-b6f5-bb726a96b4e6} + gperf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GPerfFiles + + + GPerfFiles + + + GPerfFiles + + + \ No newline at end of file diff --git a/src/libs/resiprocate/resip/stack/resiprocate_15_0.vcxproj b/src/libs/resiprocate/resip/stack/resiprocate_15_0.vcxproj new file mode 100644 index 00000000..9f47e81d --- /dev/null +++ b/src/libs/resiprocate/resip/stack/resiprocate_15_0.vcxproj @@ -0,0 +1,874 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + SSL-Debug-MT + Win32 + + + SSL-Debug-MT + x64 + + + SSL-Debug + Win32 + + + SSL-Debug + x64 + + + SSL-Release-MT + Win32 + + + SSL-Release-MT + x64 + + + SSL-Release + Win32 + + + SSL-Release + x64 + + + + resiprocate + {2A8BE839-6466-4001-B224-8F1C3168D04A} + resiprocate + Win32Proj + 10.0.17134.0 + + + + StaticLibrary + false + MultiByte + v141 + + + StaticLibrary + false + MultiByte + v141 + + + StaticLibrary + false + MultiByte + v141 + + + StaticLibrary + false + MultiByte + v141 + + + StaticLibrary + false + MultiByte + v141 + + + StaticLibrary + false + MultiByte + v141 + + + StaticLibrary + false + MultiByte + v141 + + + StaticLibrary + false + MultiByte + v141 + + + StaticLibrary + false + MultiByte + v141 + + + StaticLibrary + false + MultiByte + v141 + + + StaticLibrary + false + MultiByte + v141 + + + StaticLibrary + false + MultiByte + v141 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.21006.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + + + + + + /Zm300 %(AdditionalOptions) + Disabled + $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + /Zm300 %(AdditionalOptions) + Disabled + $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + true + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + /Zm300 %(AdditionalOptions) + MaxSpeed + OnlyExplicitInline + Speed + true + $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + + + Level3 + + + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + /Zm300 %(AdditionalOptions) + MaxSpeed + OnlyExplicitInline + Speed + true + $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) + true + MultiThreadedDLL + false + true + true + + + Level3 + + + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + /Zm300 %(AdditionalOptions) + Disabled + $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;LEAK_CHECK;USE_SSL;USE_ARES;USE_IPV6;USE_DTLS;NO_IPHLPAPI;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + + + Level3 + EditAndContinue + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + /Zm300 %(AdditionalOptions) + Disabled + $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;LEAK_CHECK;USE_SSL;USE_ARES;USE_IPV6;USE_DTLS;NO_IPHLPAPI;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + + + Level3 + EditAndContinue + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + /Zm300 %(AdditionalOptions) + Disabled + $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../contrib/opensslx64/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;LEAK_CHECK;USE_SSL;USE_ARES;USE_IPV6;USE_DTLS;NO_IPHLPAPI;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + /Zm300 %(AdditionalOptions) + Disabled + $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../contrib/opensslx64/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;LEAK_CHECK;USE_SSL;USE_ARES;USE_IPV6;USE_DTLS;NO_IPHLPAPI;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + /Zm300 %(AdditionalOptions) + MaxSpeed + OnlyExplicitInline + true + $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;USE_SSL;USE_ARES;USE_IPV6;NO_IPHLPAPI;%(PreprocessorDefinitions) + true + MultiThreadedDLL + + + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + /Zm300 %(AdditionalOptions) + MaxSpeed + OnlyExplicitInline + true + $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../contrib/openssl/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;USE_SSL;USE_ARES;USE_IPV6;NO_IPHLPAPI;%(PreprocessorDefinitions) + true + MultiThreaded + + + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + /Zm300 %(AdditionalOptions) + MaxSpeed + OnlyExplicitInline + true + $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../contrib/opensslx64/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;USE_SSL;USE_ARES;USE_IPV6;NO_IPHLPAPI;%(PreprocessorDefinitions) + true + MultiThreadedDLL + true + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + /Zm300 %(AdditionalOptions) + MaxSpeed + OnlyExplicitInline + true + $(ProjectDir)../../contrib/ares;$(ProjectDir)../;$(ProjectDir)../../;$(ProjectDir)../../contrib/opensslx64/include;$(ProjectDir)../../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;USE_SSL;USE_ARES;USE_IPV6;NO_IPHLPAPI;%(PreprocessorDefinitions) + true + MultiThreaded + true + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + true + true + + + + + + + + + true + true + true + true + + + true + true + true + true + + + true + true + true + true + + + + + + + + + + + + + + + + + + true + true + true + true + + + true + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + true + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/libs/resiprocate/resip/stack/resiprocate_15_0.vcxproj.filters b/src/libs/resiprocate/resip/stack/resiprocate_15_0.vcxproj.filters new file mode 100644 index 00000000..cc790193 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/resiprocate_15_0.vcxproj.filters @@ -0,0 +1,351 @@ + + + + + {7670bbf8-7277-4dba-b6f5-bb726a96b4e6} + gperf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + GPerfFiles + + + GPerfFiles + + + GPerfFiles + + + \ No newline at end of file diff --git a/src/libs/resiprocate/resip/stack/resiprocate_7_1.vcproj b/src/libs/resiprocate/resip/stack/resiprocate_7_1.vcproj deleted file mode 100644 index b45ea17c..00000000 --- a/src/libs/resiprocate/resip/stack/resiprocate_7_1.vcproj +++ /dev/null @@ -1,1125 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/libs/resiprocate/resip/stack/resiprocate_8_0.vcproj b/src/libs/resiprocate/resip/stack/resiprocate_8_0.vcproj deleted file mode 100644 index 0f6c7367..00000000 --- a/src/libs/resiprocate/resip/stack/resiprocate_8_0.vcproj +++ /dev/null @@ -1,1490 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/libs/resiprocate/resip/stack/resiprocate_9_0.vcproj b/src/libs/resiprocate/resip/stack/resiprocate_9_0.vcproj deleted file mode 100644 index 9c6e8447..00000000 --- a/src/libs/resiprocate/resip/stack/resiprocate_9_0.vcproj +++ /dev/null @@ -1,1509 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/libs/resiprocate/resip/stack/resiprocate_9_0.vcxproj.filters b/src/libs/resiprocate/resip/stack/resiprocate_9_0.vcxproj.filters deleted file mode 100644 index 6d6858e6..00000000 --- a/src/libs/resiprocate/resip/stack/resiprocate_9_0.vcxproj.filters +++ /dev/null @@ -1,853 +0,0 @@ - - - - - {5105422a-a87a-4074-87f1-a17e44415a29} - cpp;c;cxx;def;odl;idl;hpj;bat;asm - - - {0df38903-f4ad-4501-9d85-5207452e4073} - h;hpp;hxx;hm;inl;inc - - - {b1841523-a7a0-4f2d-a95b-594f4358e036} - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - GPerfFiles - - - GPerfFiles - - - GPerfFiles - - - \ No newline at end of file diff --git a/src/libs/resiprocate/resip/stack/resiprocate_9_0.vcxproj.user b/src/libs/resiprocate/resip/stack/resiprocate_9_0.vcxproj.user deleted file mode 100644 index abe8dd89..00000000 --- a/src/libs/resiprocate/resip/stack/resiprocate_9_0.vcxproj.user +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/libs/resiprocate/resip/stack/ssl/DtlsTransport.cxx b/src/libs/resiprocate/resip/stack/ssl/DtlsTransport.cxx index 47785a55..3e70ee31 100644 --- a/src/libs/resiprocate/resip/stack/ssl/DtlsTransport.cxx +++ b/src/libs/resiprocate/resip/stack/ssl/DtlsTransport.cxx @@ -50,7 +50,10 @@ #include "rutil/WinLeakCheck.hxx" +#include +#if !defined(LIBRESSL_VERSION_NUMBER) #include +#endif #include #include #include @@ -67,6 +70,23 @@ #define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) + +static void SSL_set0_rbio(SSL *s, BIO *rbio) +{ + BIO_free_all(s->rbio); + s->rbio = rbio; +} + +#if !defined(LIBRESSL_VERSION_NUMBER) +static void BIO_up_ref(BIO *a) +{ + CRYPTO_add(&a->references, 1, CRYPTO_LOCK_BIO); +} +#endif + +#endif + using namespace std; using namespace resip; @@ -80,13 +100,20 @@ DtlsTransport::DtlsTransport(Fifo& fifo, Security& security, const Data& sipDomain, AfterSocketCreationFuncPtr socketFunc, - Compression& compression) - : UdpTransport( fifo, portNum, version, - StunDisabled, interfaceObj, socketFunc, compression ), + Compression& compression, + const Data& certificateFilename, + const Data& privateKeyFilename, + const Data& privateKeyPassPhrase) + : UdpTransport( fifo, portNum, version, StunDisabled, interfaceObj, socketFunc, compression ), mTimer( mHandshakePending ), mSecurity( &security ), mDomain(sipDomain) { + // Note on AfterSocketCreateFuncPtr: because this class uses UdpTransport the bind operation + // is called in the UdpTransport constructor and the transport type passed to AfterSocketCreationFuncPtr + // will end up being UDP and not DTLS. TODO - this should be fixed. Creating a UdpBaseTransport is one + // solution that would align with the TCP flavour of transports. + setTlsDomain(sipDomain); InfoLog ( << "Creating DTLS transport host=" << interfaceObj << " port=" << mTuple.getPort() @@ -94,15 +121,15 @@ DtlsTransport::DtlsTransport(Fifo& fifo, mTxFifo.setDescription("DtlsTransport::mTxFifo"); - mTuple.setType( transport() ); + mTuple.setType( DTLS ); - mClientCtx = mSecurity->createDomainCtx(DTLSv1_client_method(), Data::Empty) ; - mServerCtx = mSecurity->createDomainCtx(DTLSv1_server_method(), sipDomain) ; - assert( mClientCtx ) ; - assert( mServerCtx ) ; + mClientCtx = mSecurity->createDomainCtx(DTLSv1_client_method(), Data::Empty, certificateFilename, privateKeyFilename, privateKeyPassPhrase) ; + mServerCtx = mSecurity->createDomainCtx(DTLSv1_server_method(), sipDomain, certificateFilename, privateKeyFilename, privateKeyPassPhrase) ; + resip_assert( mClientCtx ) ; + resip_assert( mServerCtx ) ; mDummyBio = BIO_new( BIO_s_mem() ) ; - assert( mDummyBio ) ; + resip_assert( mDummyBio ) ; mSendData = NULL ; @@ -161,7 +188,7 @@ DtlsTransport::_read( FdSet& fdset ) if ( len == SOCKET_ERROR ) { int err = getErrno() ; - if ( err != EWOULDBLOCK ) + if ( err != EAGAIN && err != EWOULDBLOCK ) // Treat EGAIN and EWOULDBLOCK as the same: http://stackoverflow.com/questions/7003234/which-systems-define-eagain-and-ewouldblock-as-different-values { error( err ) ; } @@ -170,14 +197,15 @@ DtlsTransport::_read( FdSet& fdset ) if (len == 0 || len == SOCKET_ERROR) { delete [] buffer ; - buffer = 0 ; + delete [] pt; return ; } if ( len + 1 >= UdpTransport::MaxBufferSize ) { InfoLog (<<"Datagram exceeded max length "<rbio = rbio ; + SSL_set0_rbio( ssl, rbio ); len = SSL_read( ssl, pt, UdpTransport::MaxBufferSize ) ; int err = SSL_get_error( ssl, len ) ; /* done with the rbio */ - BIO_free( ssl->rbio ) ; - ssl->rbio = mDummyBio ; + SSL_set0_rbio( ssl, mDummyBio ); delete [] buffer ; buffer = 0 ; @@ -282,10 +309,14 @@ DtlsTransport::_read( FdSet& fdset ) } if ( len <= 0 ) + { return ; + } if ( SSL_in_init( ssl ) ) + { mTimer.add( ssl, DtlsReceiveTimeout ) ; + } #ifdef USE_SIGCOMP osc::StateChanges *sc = 0; @@ -330,7 +361,7 @@ DtlsTransport::_read( FdSet& fdset ) #endif } - SipMessage* message = new SipMessage(this); + SipMessage* message = new SipMessage(&mTuple); // set the received from information into the received= parameter in the // via @@ -339,7 +370,6 @@ DtlsTransport::_read( FdSet& fdset ) // each one is a unique SIP message // Save all the info where this message came from - tuple.transport = this ; message->setSource( tuple ) ; //DebugLog (<< "Received from: " << tuple); @@ -424,7 +454,7 @@ DtlsTransport::_read( FdSet& fdset ) } #endif - mStateMachineFifo.add( message ) ; + pushRxMsgUp(message); } void DtlsTransport::_write( FdSet& fdset ) @@ -442,8 +472,8 @@ void DtlsTransport::_write( FdSet& fdset ) //DebugLog (<< "Sent: " << sendData->data); //DebugLog (<< "Sending message on udp."); - assert( &(*sendData) ); - assert( sendData->destination.getPort() != 0 ); + resip_assert( &(*sendData) ); + resip_assert( sendData->destination.getPort() != 0 ); sockaddr peer = sendData->destination.getSockaddr(); @@ -453,7 +483,7 @@ void DtlsTransport::_write( FdSet& fdset ) if ( ssl == NULL ) { ssl = SSL_new( mClientCtx ) ; - assert( ssl ) ; + resip_assert( ssl ) ; InfoLog( << "DTLS handshake starting (client mode)" ); @@ -461,7 +491,7 @@ void DtlsTransport::_write( FdSet& fdset ) SSL_set_connect_state( ssl ) ; wBio = BIO_new_dgram( (int)mFd, BIO_NOCLOSE ) ; - assert( wBio ) ; + resip_assert( wBio ) ; BIO_dgram_set_peer( wBio, &peer) ; @@ -685,7 +715,7 @@ DtlsTransport::_cleanupConnectionState( SSL *ssl, struct sockaddr_in peer ) * SSL_free decrements the ref-count for mDummyBio by 1, so * add 1 to the ref-count to make sure it does not get free'd */ - CRYPTO_add(&mDummyBio->references, 1, CRYPTO_LOCK_BIO); + BIO_up_ref(mDummyBio); SSL_shutdown(ssl); SSL_free(ssl) ; mDtlsConnections.erase(peer) ; @@ -695,7 +725,7 @@ void DtlsTransport::_mapDebug( const char *where, const char *action, SSL *ssl ) { fprintf( stderr, "%s: %s\t%p\n", where, action, ssl ) ; - fprintf( stderr, "map sizet = %d\n", mDtlsConnections.size() ) ; + fprintf( stderr, "map sizet = %d\n", (unsigned int)mDtlsConnections.size() ) ; } void diff --git a/src/libs/resiprocate/resip/stack/ssl/DtlsTransport.hxx b/src/libs/resiprocate/resip/stack/ssl/DtlsTransport.hxx index e4924f0f..0d2f8098 100644 --- a/src/libs/resiprocate/resip/stack/ssl/DtlsTransport.hxx +++ b/src/libs/resiprocate/resip/stack/ssl/DtlsTransport.hxx @@ -43,7 +43,7 @@ class DtlsMessage; class DtlsTransport : public UdpTransport { -#if defined(__INTEL_COMPILER ) || (defined(WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1310)) // !slg! not sure if this works on __INTEL_COMPILER +#if defined(__INTEL_COMPILER ) || (defined(WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1310) && (_MSC_VER < 1900)) // !slg! not sure if this works on __INTEL_COMPILER struct sockaddr_in_hash_compare { enum { bucket_size = 4, min_buckets = 8 }; @@ -124,20 +124,22 @@ class DtlsTransport : public UdpTransport Security& security, const Data& sipDomain, AfterSocketCreationFuncPtr socketFunc = 0, - Compression &compression = Compression::Disabled); + Compression &compression = Compression::Disabled, + const Data& certificateFilename = "", + const Data& privateKeyFilename = "", + const Data& privateKeyPassPhrase = ""); virtual ~DtlsTransport(); void process(FdSet& fdset); bool isReliable() const { return false; } bool isDatagram() const { return true; } - TransportType transport() const { return DTLS; } virtual void buildFdSet( FdSet& fdset); static const unsigned long DtlsReceiveTimeout = 250000 ; private: -#if defined(__INTEL_COMPILER ) || (defined(WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1310)) +#if defined(__INTEL_COMPILER ) || (defined(WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1310) && (_MSC_VER < 1900)) typedef HashMap DtlsConnectionMap; diff --git a/src/libs/resiprocate/resip/stack/ssl/Security.cxx b/src/libs/resiprocate/resip/stack/ssl/Security.cxx index 1e08f096..e1828a4f 100644 --- a/src/libs/resiprocate/resip/stack/ssl/Security.cxx +++ b/src/libs/resiprocate/resip/stack/ssl/Security.cxx @@ -8,6 +8,7 @@ #include #include +#include #include "resip/stack/Contents.hxx" #include "resip/stack/MultipartSignedContents.hxx" @@ -16,6 +17,7 @@ #include "resip/stack/SecurityAttributes.hxx" #include "resip/stack/Transport.hxx" #include "resip/stack/SipMessage.hxx" +#include "rutil/ResipAssert.h" #include "rutil/BaseException.hxx" #include "rutil/DataStream.hxx" #include "rutil/Logger.hxx" @@ -31,15 +33,20 @@ #if !defined(WIN32) #include #include -#if !defined(TARGET_ANDROID) -# include +#if defined(__ANDROID__) +#include +#else +#include #endif #include #include #endif #include +#include +#if !defined(LIBRESSL_VERSION_NUMBER) #include +#endif #include #include #include @@ -50,6 +57,15 @@ #include #include +#if OPENSSL_VERSION_NUMBER < 0x10100000L + +inline const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x) +{ + return ASN1_STRING_data(const_cast< ASN1_STRING* >(x)); +} + +#endif // OPENSSL_VERSION_NUMBER < 0x10100000L + using namespace resip; using namespace std; @@ -77,68 +93,12 @@ pemTypePrefixes( Security::PEMType pType ) default: { ErrLog( << "Some unkonw pem type prefix requested" << (int)(pType) ); - assert(0); + resip_assert(0); } } return unknownKey; } -static Data -readIntoData(const Data& filename) -{ - DebugLog( << "Trying to read file " << filename ); - - ifstream is; - is.open(filename.c_str(), ios::binary ); - if ( !is.is_open() ) - { - ErrLog( << "Could not open file " << filename << " for read"); - throw BaseSecurity::Exception("Could not read file ", - __FILE__,__LINE__); - } - - assert(is.is_open()); - - int length = 0; - - // get length of file: -#if !defined(__MSL_CPP__) || (__MSL_CPP_ >= 0x00012000) - is.seekg (0, ios::end); - length = (int)is.tellg(); - is.seekg (0, ios::beg); -#else - // this is a work around for a bug in CodeWarrior 9's implementation of seekg. - // http://groups.google.ca/group/comp.sys.mac.programmer.codewarrior/browse_frm/thread/a4279eb75f3bd55a - FILE * tmpFile = fopen(filename.c_str(), "r+b"); - assert(tmpFile != NULL); - fseek(tmpFile, 0, SEEK_END); - length = ftell(tmpFile); - fseek(tmpFile, 0, SEEK_SET); -#endif // __MWERKS__ - - // tellg/tell will return -1 if the stream is bad - if (length == -1) - { - ErrLog( << "Could not seek into file " << filename); - throw BaseSecurity::Exception("Could not seek into file ", - __FILE__,__LINE__); - } - - // !jf! +1 is a workaround for a bug in Data::c_str() that adds the 0 without - // resizing. - char* buffer = new char [length+1]; - - // read data as a block: - is.read (buffer,length); - - Data target(Data::Take, buffer, length); - - is.close(); - - return target; -} - - static Data getAor(const Data& filename, const Security::PEMType &pemType ) { @@ -146,12 +106,14 @@ getAor(const Data& filename, const Security::PEMType &pemType ) return filename.substr(prefix.size(), filename.size() - prefix.size() - PEM.size()); } +extern "C" +{ -int +static int verifyCallback(int iInCode, X509_STORE_CTX *pInStore) { - char cBuf1[500]; - char cBuf2[500]; + char cBuf1[257]; + char cBuf2[501]; X509 *pErrCert; int iErr = 0; int iDepth = 0; @@ -162,20 +124,40 @@ verifyCallback(int iInCode, X509_STORE_CTX *pInStore) if (NULL != pErrCert) X509_NAME_oneline(X509_get_subject_name(pErrCert),cBuf1,256); - sprintf(cBuf2,", depth=%d %s\n",iDepth,cBuf1); + snprintf(cBuf2, 500, ", depth=%d %s\n", iDepth, cBuf1); if(!iInCode) - ErrLog(<< "Error when verifying server's chain of certificates: " << X509_verify_cert_error_string(pInStore->error) << cBuf2 ); - return 1; + { + ErrLog(<< "Error when verifying peer's chain of certificates: " << X509_verify_cert_error_string(X509_STORE_CTX_get_error(pInStore)) << cBuf2 ); + DebugLog(<<"additional validation checks may have failed but only one is ever logged - please check peer certificate carefully"); + } + return iInCode; } +} // .amr. RFC 5922 mandates exact match only on certificates, so this is the default, but RFC 2459 and RFC 3261 don't prevent wildcards, so enable if you want that mode. bool BaseSecurity::mAllowWildcardCertificates = false; -BaseSecurity::CipherList BaseSecurity::ExportableSuite("!SSLv2:aRSA+AES:aDSS+AES:@STRENGTH:aRSA+3DES:aDSS+3DES:aRSA+RC4+MEDIUM:aDSS+RC4+MEDIUM:aRSA+DES:aDSS+DES:aRSA+RC4:aDSS+RC4"); -BaseSecurity::CipherList BaseSecurity::StrongestSuite("!SSLv2:aRSA+AES:aDSS+AES:@STRENGTH:aRSA+3DES:aDSS+3DES"); +BaseSecurity::CipherList BaseSecurity::ExportableSuite("HIGH:RC4-SHA:-COMPLEMENTOFDEFAULT"); +BaseSecurity::CipherList BaseSecurity::StrongestSuite("HIGH:-COMPLEMENTOFDEFAULT"); -Security::Security(const CipherList& cipherSuite) : BaseSecurity(cipherSuite) +/** + * Note: + * + * When SSLv23 mode is selected and the options flags SSL_OP_NO_SSLv2 + * and SSL_OP_NO_SSLv3 are set, SSLv23_method() will allow a dynamic + * choice of TLS v1.0, v1.1 or v1.2 on each connection. + * + * If SSL_OP_NO_SSLv3 is removed (by an application changing the value + * of BaseSecurity::OpenSSLCTXSetOptions before instantiating + * resip::Security) then using SSLv23_method() will allow a dynamic + * choice of SSL v3.0 or any of the TLS versions on each connection. + */ +long BaseSecurity::OpenSSLCTXSetOptions = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3; +long BaseSecurity::OpenSSLCTXClearOptions = 0; + +Security::Security(const CipherList& cipherSuite, const Data& defaultPrivateKeyPassPhrase, const Data& dHParamsFilename) : + BaseSecurity(cipherSuite, defaultPrivateKeyPassPhrase, dHParamsFilename) { #ifdef WIN32 mPath = "C:\\sipCerts\\"; @@ -189,13 +171,12 @@ Security::Security(const CipherList& cipherSuite) : BaseSecurity(cipherSuite) #endif } -Security::Security(const Data& directory, const CipherList& cipherSuite) : - BaseSecurity(cipherSuite), +Security::Security(const Data& directory, const CipherList& cipherSuite, const Data& defaultPrivateKeyPassPhrase, const Data& dHParamsFilename) : + BaseSecurity(cipherSuite, defaultPrivateKeyPassPhrase, dHParamsFilename), mPath(directory) { - // since the preloader won't work otherwise and VERY difficult to figure - // out. - if ( !mPath.postfix(Symbols::SLASH)) + // since the preloader won't work otherwise and VERY difficult to figure out. + if (!mPath.empty() && !mPath.postfix(Symbols::SLASH)) { mPath += Symbols::SLASH; } @@ -218,9 +199,87 @@ Security::addCAFile(const Data& caFile) mCAFiles.push_back(caFile); } +void +Security::loadCADirectory(const Data& _dir) +{ + FileSystem::Directory dir(_dir); + FileSystem::Directory::iterator it(dir); + for (; it != dir.end(); ++it) + { + try + { + if (!it.is_directory()) // This can throw! + { + Data name = *it; + Data fileName = _dir + name; + loadCAFile(fileName); + } + } + catch (Exception& e) + { + ErrLog(<< "loadCADirectory: Some problem reading " << *it << ": " << e); + } + catch (...) + { + ErrLog(<< "loadCADirectory: Some problem reading " << *it); + } + } +} + +void +Security::loadCAFile(const Data& _file) +{ + try + { + addRootCertPEM(Data::fromFile(_file)); + InfoLog(<<"Successfully loaded " << _file); + } + catch (Exception& e) + { + ErrLog(<< "loadCAFile: Some problem reading " << _file << ": " << e); + } + catch (...) + { + ErrLog(<< "loadCAFile: Some problem reading " << _file); + } +} + void Security::preload() { + int count = 0; +#ifndef WIN32 + // We only do this for UNIX platforms at present + // If no other source of trusted roots exists, + // and if mPath is a file, check if it is a root certificate + // or a collection of root certificates + struct stat s; + Data fileName(mPath); + if(fileName.postfix("/")) + { + fileName.truncate(fileName.size() - 1); + } + if(fileName.size() > 0) + { + StackLog(<<"calling stat() for " << fileName); + if(stat(fileName.c_str(), &s) < 0) + { + ErrLog(<<"Error calling stat() for " << fileName.c_str() + << ": " << strerror(errno)); + } + else + { + if(!S_ISDIR(s.st_mode)) + { + WarningLog(<<"mPath argument is a file rather than a directory, " + "treating mPath as a file of trusted root certificates"); + loadCAFile(fileName); + count++; + } + } + } +#endif + FileSystem::Directory dir(mPath); FileSystem::Directory::iterator it(dir); for (; it != dir.end(); ++it) @@ -237,34 +296,28 @@ Security::preload() { if (name.prefix(pemTypePrefixes(UserCert))) { - addCertPEM( UserCert, getAor(name, UserCert), readIntoData(fileName), false ); + addCertPEM( UserCert, getAor(name, UserCert), Data::fromFile(fileName), false ); } else if (name.prefix(pemTypePrefixes(UserPrivateKey))) { - addPrivateKeyPEM( UserPrivateKey, getAor(name, UserPrivateKey), readIntoData(fileName), false); + addPrivateKeyPEM( UserPrivateKey, getAor(name, UserPrivateKey), Data::fromFile(fileName), false); } else if (name.prefix(pemTypePrefixes(DomainCert))) { - addCertPEM( DomainCert, getAor(name, DomainCert), readIntoData(fileName), false); + addCertPEM( DomainCert, getAor(name, DomainCert), Data::fromFile(fileName), false); } else if (name.prefix(pemTypePrefixes(DomainPrivateKey))) { - addPrivateKeyPEM( DomainPrivateKey, getAor(name, DomainPrivateKey), readIntoData(fileName), false); + addPrivateKeyPEM( DomainPrivateKey, getAor(name, DomainPrivateKey), Data::fromFile(fileName), false); } else if (name.prefix(pemTypePrefixes(RootCert))) { - addRootCertPEM(readIntoData(fileName)); + addRootCertPEM(Data::fromFile(fileName)); } else { DebugLog(<< "PEM file " << name << " does not have appropriate resip prefix, skipping..."); - // Try to load as root cert PEM - try - { - addRootCertPEM(readIntoData(fileName)); - } - catch (Exception& e) - {} + attemptedToLoad = false; } } catch (Exception& e) @@ -279,57 +332,61 @@ Security::preload() if(attemptedToLoad) { InfoLog(<<"Successfully loaded " << fileName ); + count++; } } } + InfoLog(<<"Files loaded by prefix: " << count); + + if(count == 0 && mCADirectories.empty() && mCAFiles.empty() && mPath.size() > 0) + { + // If no other source of trusted roots exists, + // assume mPath was meant to be in mCADirectories + WarningLog(<<"No root certificates found using legacy prefixes, " + "treating mPath as a normal directory of root certs"); + loadCADirectory(mPath); + } + std::list::iterator it_d = mCADirectories.begin(); for (; it_d != mCADirectories.end(); ++it_d) { - const Data _dir = *it_d; - FileSystem::Directory dir(_dir); - FileSystem::Directory::iterator it(dir); - for (; it != dir.end(); ++it) - { - if(!it.is_directory()) - { - Data name = *it; - Data fileName = _dir + name; - addCAFile(fileName); - } - } + loadCADirectory(*it_d); } + std::list::iterator it_f = mCAFiles.begin(); for (; it_f != mCAFiles.end(); ++it_f) { - const Data _file = *it_f; - try - { - addRootCertPEM(readIntoData(_file)); - InfoLog(<<"Successfully loaded " << _file); - } - catch (Exception& e) - { - ErrLog(<< "Some problem reading " << _file << ": " << e); - } - catch (...) - { - ErrLog(<< "Some problem reading " << _file); - } + loadCAFile(*it_f); + } +} + +// Generic password callback to copy over provided userdata/password +int pem_passwd_cb(char *buf, int size, int rwflag, void *password) +{ + if(password) + { + strncpy(buf, (char *)(password), size); + buf[size - 1] = '\0'; + return (int)strlen(buf); + } + else + { + return 0; } } SSL_CTX* -Security::createDomainCtx(const SSL_METHOD* method, const Data& domain) +Security::createDomainCtx(const SSL_METHOD* method, const Data& domain, const Data& certificateFilename, const Data& privateKeyFilename, const Data& privateKeyPassPhrase) { #if (OPENSSL_VERSION_NUMBER >= 0x1000000fL ) SSL_CTX* ctx = SSL_CTX_new(method); #else SSL_CTX* ctx = SSL_CTX_new((SSL_METHOD*)method); #endif - assert(ctx); + resip_assert(ctx); X509_STORE* x509Store = X509_STORE_new(); - assert(x509Store); + resip_assert(x509Store); // Load root certs into store X509List::iterator it; @@ -339,17 +396,50 @@ Security::createDomainCtx(const SSL_METHOD* method, const Data& domain) } SSL_CTX_set_cert_store(ctx, x509Store); + updateDomainCtx(ctx, domain, certificateFilename, privateKeyFilename, privateKeyPassPhrase); + + SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE, verifyCallback); + SSL_CTX_set_cipher_list(ctx, mCipherList.cipherList().c_str()); + setDHParams(ctx); + SSL_CTX_set_options(ctx, BaseSecurity::OpenSSLCTXSetOptions); + SSL_CTX_clear_options(ctx, BaseSecurity::OpenSSLCTXClearOptions); + + return ctx; +} + +void +Security::updateDomainCtx(SSL_CTX* ctx, const Data& domain, const Data& certificateFilename, const Data& privateKeyFilename, const Data& privateKeyPassPhrase) +{ // Load domain cert chain and private key if(!domain.empty()) { - Data certFilename(mPath + pemTypePrefixes(DomainCert) + domain + PEM); + // Set Private Key PassPhrase + SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_cb); + if(!privateKeyPassPhrase.empty()) + { + SSL_CTX_set_default_passwd_cb_userdata(ctx, (void*)privateKeyPassPhrase.c_str()); + } + Data certFilename(certificateFilename.empty() ? mPath + pemTypePrefixes(DomainCert) + domain + PEM : certificateFilename); if(SSL_CTX_use_certificate_chain_file(ctx, certFilename.c_str()) != 1) { ErrLog (<< "Error reading domain chain file " << certFilename); SSL_CTX_free(ctx); throw BaseSecurity::Exception("Failed opening PEM chain file", __FILE__,__LINE__); } - Data keyFilename(mPath + pemTypePrefixes(DomainPrivateKey) + domain + PEM); + + // Check if we have the domain cert in the main storage yet - needed for Identity header calculations + if(mDomainCerts.find(domain) == mDomainCerts.end()) + { + // Add to storage + addCertPEM( DomainCert, domain, Data::fromFile(certFilename), false); + InfoLog(<< "Security::updateDomainCtx: Successfully loaded domain cert and added to Security storage, domain=" << domain << ", filename=" << certFilename); + } + else + { + InfoLog(<< "Security::updateDomainCtx: Successfully loaded domain cert, domain=" << domain << ", filename=" << certFilename); + } + + Data keyFilename(privateKeyFilename.empty() ? mPath + pemTypePrefixes(DomainPrivateKey) + domain + PEM : privateKeyFilename); if(SSL_CTX_use_PrivateKey_file(ctx, keyFilename.c_str(), SSL_FILETYPE_PEM) != 1) { ErrLog (<< "Error reading domain private key file " << keyFilename); @@ -362,12 +452,19 @@ Security::createDomainCtx(const SSL_METHOD* method, const Data& domain) SSL_CTX_free(ctx); throw BaseSecurity::Exception("Invalid domain private key", __FILE__,__LINE__); } + + // Check if we have the domain cert in the main storage yet - needed for Identity header calculations + if(mDomainPrivateKeys.find(domain) == mDomainPrivateKeys.end()) + { + // Add to storage + addPrivateKeyPEM( DomainPrivateKey, domain, Data::fromFile(keyFilename), false, privateKeyPassPhrase); + InfoLog(<< "Security::updateDomainCtx: Successfully loaded domain private key and added to Security storage, domain=" << domain << ", filename=" << keyFilename); + } + else + { + InfoLog(<< "Security::updateDomainCtx: Successfully loaded domain private key, domain=" << domain << ", filename=" << keyFilename); + } } - - SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE, verifyCallback); - SSL_CTX_set_cipher_list(ctx, mCipherList.cipherList().c_str()); - - return ctx; } void @@ -377,10 +474,9 @@ Security::onReadPEM(const Data& name, PEMType type, Data& buffer) const InfoLog (<< "Reading PEM file " << filename << " into " << name); // .dlb. extra copy - buffer = readIntoData(filename); + buffer = Data::fromFile(filename); } - void Security::onWritePEM(const Data& name, PEMType type, const Data& buffer) const { @@ -403,15 +499,13 @@ Security::onWritePEM(const Data& name, PEMType type, const Data& buffer) const } } - void Security::onRemovePEM(const Data& name, PEMType type) const { - assert(0); + resip_assert(0); // TODO - should delete file } - void BaseSecurity::addCertDER (PEMType type, const Data& key, @@ -441,7 +535,6 @@ BaseSecurity::addCertDER (PEMType type, addCertX509(type,key,cert,write); } - void BaseSecurity::addCertPEM (PEMType type, const Data& name, @@ -461,20 +554,26 @@ BaseSecurity::addCertPEM (PEMType type, ErrLog(<< "Could not create BIO buffer from '" << certPEM << "'"); throw Exception("Could not create BIO buffer", __FILE__,__LINE__); } - cert = PEM_read_bio_X509(in,0,0,0); - if (cert == NULL) + while(!BIO_eof(in)) { - ErrLog( << "Could not load X509 cert from '" << certPEM << "'" ); - BIO_free(in); - throw Exception("Could not load X509 cert from BIO buffer", __FILE__,__LINE__); - } + cert = PEM_read_bio_X509(in,0,0,0); + if (cert == NULL) + { + ErrLog( << "Could not load X509 cert from '" << certPEM << "'" ); + BIO_free(in); + throw Exception("Could not load X509 cert from BIO buffer", __FILE__,__LINE__); + } - addCertX509(type,name,cert,write); + addCertX509(type,name,cert,write); + if(type != RootCert) + { + break; + } + } BIO_free(in); } - void BaseSecurity::addCertX509(PEMType type, const Data& key, X509* cert, bool write) { @@ -499,7 +598,7 @@ BaseSecurity::addCertX509(PEMType type, const Data& key, X509* cert, bool write) break; default: { - assert(0); + resip_assert(0); } } @@ -510,7 +609,7 @@ BaseSecurity::addCertX509(PEMType type, const Data& key, X509* cert, bool write) if(!out) { ErrLog(<< "Failed to create BIO: this cert will not be added."); - assert(0); + resip_assert(0); return; } @@ -519,7 +618,7 @@ BaseSecurity::addCertX509(PEMType type, const Data& key, X509* cert, bool write) int ret = PEM_write_bio_X509(out, cert); if(!ret) { - assert(0); + resip_assert(0); throw Exception("PEM_write_bio_X509 failed: this cert will not be " "added.", __FILE__,__LINE__); } @@ -530,13 +629,13 @@ BaseSecurity::addCertX509(PEMType type, const Data& key, X509* cert, bool write) size_t len = BIO_get_mem_data(out,&p); if(!p || !len) { - assert(0); + resip_assert(0); throw Exception("BIO_get_mem_data failed: this cert will not be " "added.", __FILE__,__LINE__); } - Data buf(Data::Borrow, p, len); + Data buf(Data::Borrow, p, (Data::size_type)len); - //this->onWritePEM(key, type, buf); + this->onWritePEM(key, type, buf); } catch(Exception& e) { @@ -552,11 +651,10 @@ BaseSecurity::addCertX509(PEMType type, const Data& key, X509* cert, bool write) } } - bool BaseSecurity::hasCert (PEMType type, const Data& aor) const { - assert( !aor.empty() ); + resip_assert( !aor.empty() ); const X509Map& certs = (type == DomainCert ? mDomainCerts : mUserCerts); X509Map::const_iterator where = certs.find(aor); @@ -565,8 +663,6 @@ BaseSecurity::hasCert (PEMType type, const Data& aor) const return true; } - return false; - /* try { Data certPEM; @@ -589,17 +685,15 @@ BaseSecurity::hasCert (PEMType type, const Data& aor) const return false; } - assert( certs.find(aor) != certs.end() ); + resip_assert( certs.find(aor) != certs.end() ); return true; - */ } - void BaseSecurity::removeCert (PEMType type, const Data& aor) { - assert( !aor.empty() ); + resip_assert( !aor.empty() ); X509Map& certs = (type == DomainCert ? mDomainCerts : mUserCerts); X509Map::iterator iter = certs.find(aor); @@ -611,14 +705,13 @@ BaseSecurity::removeCert (PEMType type, const Data& aor) onRemovePEM(aor, type); } - assert( certs.find(aor) == certs.end() ); + resip_assert( certs.find(aor) == certs.end() ); } - Data BaseSecurity::getCertDER (PEMType type, const Data& key) const { - assert( !key.empty() ); + resip_assert( !key.empty() ); if (hasCert(type, key) == false) { @@ -633,7 +726,7 @@ BaseSecurity::getCertDER (PEMType type, const Data& key) const // not supposed to happen, // hasCert() should have inserted a value into certs // or we should have throwed. - assert(0); + resip_assert(0); } //assert(0); // the code following this has no hope of working @@ -645,7 +738,7 @@ BaseSecurity::getCertDER (PEMType type, const Data& key) const // !kh! // Although len == 0 is not an error, I am not sure what quite to do. // Asserting for now. - assert(len != 0); + resip_assert(len != 0); if(len < 0) { ErrLog(<< "Could encode certificate of '" << key << "' to DER form"); @@ -656,7 +749,6 @@ BaseSecurity::getCertDER (PEMType type, const Data& key) const return certDER; } - void BaseSecurity::addPrivateKeyPKEY(PEMType type, const Data& name, @@ -668,11 +760,11 @@ BaseSecurity::addPrivateKeyPKEY(PEMType type, /* // make a copy of the the key - assert( EVP_PKEY_type(pKey->type) == EVP_PKEY_RSA ); + resip_assert( EVP_PKEY_type(pKey->type) == EVP_PKEY_RSA ); RSA* rsa = EVP_PKEY_get1_RSA(pKey); - assert( rsa ); + resip_assert( rsa ); EVP_PKEY* nKey = EVP_PKEY_new(); - assert( nKey ); + resip_assert( nKey ); EVP_PKEY_set1_RSA(nKey, rsa); */ @@ -698,12 +790,12 @@ BaseSecurity::addPrivateKeyPKEY(PEMType type, if(!bio) { ErrLog(<< "BIO_new failed: cannot add private key."); - assert(0); + resip_assert(0); } try { - assert( EVP_des_ede3_cbc() ); + resip_assert( EVP_des_ede3_cbc() ); const EVP_CIPHER* cipher = EVP_des_ede3_cbc(); if (kstr == NULL ) { @@ -720,7 +812,7 @@ BaseSecurity::addPrivateKeyPKEY(PEMType type, #endif if(!ret) { - assert(0); + resip_assert(0); throw Exception("PEM_write_bio_PKCS8PrivateKey failed: cannot add" " private key.", __FILE__, __LINE__); } @@ -730,11 +822,11 @@ BaseSecurity::addPrivateKeyPKEY(PEMType type, size_t len = BIO_get_mem_data(bio,&p); if(!p || !len) { - assert(0); + resip_assert(0); throw Exception("BIO_get_mem_data failed: cannot add" " private key.", __FILE__, __LINE__); } - Data pem(Data::Borrow, p, len); + Data pem(Data::Borrow, p, (Data::size_type)len); onWritePEM(name, type, pem ); } catch(Exception& e) @@ -751,14 +843,14 @@ BaseSecurity::addPrivateKeyPKEY(PEMType type, } } - void BaseSecurity::addPrivateKeyDER( PEMType type, const Data& name, const Data& privateKeyDER, - bool write ) + bool write, + const Data& privateKeyPassPhrase) { - assert( !name.empty() ); + resip_assert( !name.empty() ); if( privateKeyDER.empty() ) { ErrLog(<< name << " is empty. Skipping."); @@ -766,13 +858,27 @@ BaseSecurity::addPrivateKeyDER( PEMType type, } char* passPhrase = 0; - if (type != DomainPrivateKey) + if (privateKeyPassPhrase.empty()) { - PassPhraseMap::const_iterator iter = mUserPassPhrases.find(name); - if(iter != mUserPassPhrases.end()) + if (type == UserPrivateKey) { - passPhrase = const_cast(iter->second.c_str()); + PassPhraseMap::const_iterator iter = mUserPassPhrases.find(name); + if(iter != mUserPassPhrases.end()) + { + passPhrase = const_cast(iter->second.c_str()); + } } + else + { + if(!mDefaultPrivateKeyPassPhrase.empty()) + { + passPhrase = const_cast(mDefaultPrivateKeyPassPhrase.c_str()); + } + } + } + else + { + passPhrase = const_cast(privateKeyPassPhrase.c_str()); } BIO* in = BIO_new_mem_buf(const_cast(privateKeyDER.c_str()), -1); @@ -784,7 +890,6 @@ BaseSecurity::addPrivateKeyDER( PEMType type, try { - EVP_PKEY* privateKey; if (d2i_PKCS8PrivateKey_bio(in, &privateKey, 0, passPhrase) == 0) { @@ -804,14 +909,14 @@ BaseSecurity::addPrivateKeyDER( PEMType type, BIO_free(in); } - void BaseSecurity::addPrivateKeyPEM( PEMType type, const Data& name, const Data& privateKeyPEM, - bool write ) + bool write, + const Data& privateKeyPassPhrase) { - assert( !name.empty() ); + resip_assert( !name.empty() ); if( privateKeyPEM.empty() ) { ErrLog(<< name << " is empty. Skipping."); @@ -828,19 +933,43 @@ BaseSecurity::addPrivateKeyPEM( PEMType type, char* passPhrase = 0; try { - if (type == UserPrivateKey) + if (privateKeyPassPhrase.empty()) { - PassPhraseMap::const_iterator iter = mUserPassPhrases.find(name); - if(iter != mUserPassPhrases.end()) + if (type == UserPrivateKey) { - passPhrase = const_cast(iter->second.c_str()); + PassPhraseMap::const_iterator iter = mUserPassPhrases.find(name); + if(iter != mUserPassPhrases.end()) + { + passPhrase = const_cast(iter->second.c_str()); + } } + else + { + if(!mDefaultPrivateKeyPassPhrase.empty()) + { + passPhrase = const_cast(mDefaultPrivateKeyPassPhrase.c_str()); + } + } + } + else + { + passPhrase = const_cast(privateKeyPassPhrase.c_str()); } EVP_PKEY* privateKey=0; - if ( ( privateKey = PEM_read_bio_PrivateKey(in, NULL, 0, passPhrase)) == NULL) + if ( ( privateKey = PEM_read_bio_PrivateKey(in, NULL, pem_passwd_cb, passPhrase)) == NULL) { - ErrLog(<< "Could not read private key from <" << privateKeyPEM << ">" ); + char buffer[120]; + unsigned long err = ERR_get_error(); + ERR_error_string(err, buffer); + if(ERR_GET_LIB(err) == ERR_LIB_EVP && ERR_GET_FUNC(err) == EVP_F_EVP_DECRYPTFINAL_EX && ERR_GET_REASON(err) == EVP_R_BAD_DECRYPT) + { + ErrLog(<< "Could not read private key (error=" << buffer << ") - likely incorrect password provided, may load correctly when transports are added with appropriate password"); + } + else + { + ErrLog(<< "Could not read private key (error=" << buffer << ") from <" << privateKeyPEM << ">" ); + } throw Exception("Could not read private key ", __FILE__,__LINE__); } @@ -856,12 +985,11 @@ BaseSecurity::addPrivateKeyPEM( PEMType type, BIO_free(in); } - bool BaseSecurity::hasPrivateKey( PEMType type, const Data& key ) const { - assert( !key.empty() ); + resip_assert( !key.empty() ); const PrivateKeyMap& privateKeys = (type == DomainPrivateKey ? mDomainPrivateKeys : mUserPrivateKeys); @@ -893,12 +1021,11 @@ BaseSecurity::hasPrivateKey( PEMType type, return true; } - Data BaseSecurity::getPrivateKeyPEM( PEMType type, const Data& key) const { - assert( !key.empty() ); + resip_assert( !key.empty() ); if ( !hasPrivateKey(type, key) ) { @@ -919,20 +1046,20 @@ BaseSecurity::getPrivateKeyPEM( PEMType type, } } - assert(0); // TODO - following code has no hope of working + resip_assert(0); // TODO - following code has no hope of working // !kh! // creates a read/write BIO buffer. BIO *out = BIO_new(BIO_s_mem()); - assert(out); + resip_assert(out); EVP_PKEY* pk = where->second; - assert(pk); + resip_assert(pk); // write pk to out using key phrase p, with no cipher. int ret = PEM_write_bio_PrivateKey(out, pk, 0, 0, 0, 0, p); // paraters // are in the wrong order (void)ret; - assert(ret == 1); + resip_assert(ret == 1); // get content in BIO buffer to our buffer. // hand our buffer to a Data object. @@ -946,12 +1073,11 @@ BaseSecurity::getPrivateKeyPEM( PEMType type, return retVal; } - Data BaseSecurity::getPrivateKeyDER( PEMType type, const Data& key) const { - assert( !key.empty() ); + resip_assert( !key.empty() ); if ( !hasPrivateKey(type, key) ) { @@ -972,19 +1098,19 @@ BaseSecurity::getPrivateKeyDER( PEMType type, } } - assert(0); // TODO - following code has no hope of working + resip_assert(0); // TODO - following code has no hope of working // !kh! // creates a read/write BIO buffer. BIO *out = BIO_new(BIO_s_mem()); - assert(out); + resip_assert(out); EVP_PKEY* pk = where->second; - assert(pk); + resip_assert(pk); // write pk to out using key phrase p, with no cipher. int ret = i2d_PKCS8PrivateKey_bio(out, pk, 0, 0, 0, 0, p); (void)ret; - assert(ret == 1); + resip_assert(ret == 1); // get content in BIO buffer to our buffer. // hand our buffer to a Data object. @@ -998,15 +1124,14 @@ BaseSecurity::getPrivateKeyDER( PEMType type, return retVal; } - void BaseSecurity::removePrivateKey(PEMType type, const Data& key) { - assert( !key.empty() ); + resip_assert( !key.empty() ); PrivateKeyMap& privateKeys = (type == DomainPrivateKey ? mDomainPrivateKeys : mUserPrivateKeys); - assert( !key.empty() ); + resip_assert( !key.empty() ); PrivateKeyMap::iterator iter = privateKeys.find(key); if (iter != privateKeys.end()) { @@ -1023,12 +1148,13 @@ Security::Exception::Exception(const Data& msg, const Data& file, const int line { } - -BaseSecurity::BaseSecurity (const CipherList& cipherSuite) : +BaseSecurity::BaseSecurity (const CipherList& cipherSuite, const Data& defaultPrivateKeyPassPhrase, const Data& dHParamsFilename) : mTlsCtx(0), mSslCtx(0), mCipherList(cipherSuite), - mRootTlsCerts(0), + mDefaultPrivateKeyPassPhrase(defaultPrivateKeyPassPhrase), + mDHParamsFilename(dHParamsFilename), + mRootTlsCerts(0), mRootSslCerts(0) { DebugLog(<< "BaseSecurity::BaseSecurity"); @@ -1038,7 +1164,7 @@ BaseSecurity::BaseSecurity (const CipherList& cipherSuite) : mRootTlsCerts = X509_STORE_new(); mRootSslCerts = X509_STORE_new(); - assert(mRootTlsCerts && mRootSslCerts); + resip_assert(mRootTlsCerts && mRootSslCerts); mTlsCtx = SSL_CTX_new( TLSv1_method() ); if (!mTlsCtx) @@ -1051,19 +1177,27 @@ BaseSecurity::BaseSecurity (const CipherList& cipherSuite) : ErrLog(<< "OpenSSL error stack: " << errBuf); } } - assert(mTlsCtx); + resip_assert(mTlsCtx); + SSL_CTX_set_default_passwd_cb(mTlsCtx, pem_passwd_cb); SSL_CTX_set_cert_store(mTlsCtx, mRootTlsCerts); SSL_CTX_set_verify(mTlsCtx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE, verifyCallback); ret = SSL_CTX_set_cipher_list(mTlsCtx, cipherSuite.cipherList().c_str()); - assert(ret); + resip_assert(ret); + setDHParams(mTlsCtx); + SSL_CTX_set_options(mTlsCtx, BaseSecurity::OpenSSLCTXSetOptions); + SSL_CTX_clear_options(mTlsCtx, BaseSecurity::OpenSSLCTXClearOptions); mSslCtx = SSL_CTX_new( SSLv23_method() ); - assert(mSslCtx); + resip_assert(mSslCtx); + SSL_CTX_set_default_passwd_cb(mSslCtx, pem_passwd_cb); SSL_CTX_set_cert_store(mSslCtx, mRootSslCerts); SSL_CTX_set_verify(mSslCtx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE, verifyCallback); ret = SSL_CTX_set_cipher_list(mSslCtx,cipherSuite.cipherList().c_str()); - assert(ret); + resip_assert(ret); + setDHParams(mSslCtx); + SSL_CTX_set_options(mSslCtx, BaseSecurity::OpenSSLCTXSetOptions); + SSL_CTX_clear_options(mSslCtx, BaseSecurity::OpenSSLCTXClearOptions); } @@ -1112,32 +1246,29 @@ BaseSecurity::~BaseSecurity () } - void BaseSecurity::initialize () { Timer::getTimeMs(); // initalize time offsets } - Security::CertificateInfoContainer BaseSecurity::getRootCertDescriptions() const { // !kh! // need to be implemented. - assert(0); // TODO + resip_assert(0); // TODO return CertificateInfoContainer(); } - void BaseSecurity::addRootCertPEM(const Data& x509PEMEncodedRootCerts) { - assert( mRootTlsCerts && mRootSslCerts ); + resip_assert( mRootTlsCerts && mRootSslCerts ); #if 1 addCertPEM(RootCert,Data::Empty,x509PEMEncodedRootCerts,false); #else - assert( !x509PEMEncodedRootCerts.empty() ); + resip_assert( !x509PEMEncodedRootCerts.empty() ); static X509_LOOKUP_METHOD x509_pemstring_lookup = { @@ -1158,7 +1289,7 @@ BaseSecurity::addRootCertPEM(const Data& x509PEMEncodedRootCerts) mRootCerts = X509_STORE_new(); } - assert( mRootCerts ); + resip_assert( mRootCerts ); X509_LOOKUP* lookup = X509_STORE_add_lookup(mRootCerts, &x509_pemstring_lookup); @@ -1171,21 +1302,19 @@ BaseSecurity::addRootCertPEM(const Data& x509PEMEncodedRootCerts) #endif } - void BaseSecurity::addDomainCertPEM(const Data& domainName, const Data& certPEM) { - addCertPEM(DomainCert, domainName, certPEM, true); + addCertPEM(DomainCert, domainName, certPEM, false); } void BaseSecurity::addDomainCertDER(const Data& domainName, const Data& certDER) { - addCertDER(DomainCert, domainName, certDER, true); + addCertDER(DomainCert, domainName, certDER, false); } - bool BaseSecurity::hasDomainCert(const Data& domainName) const { @@ -1199,28 +1328,24 @@ BaseSecurity::removeDomainCert(const Data& domainName) return removeCert(DomainCert, domainName); } - Data BaseSecurity::getDomainCertDER(const Data& domainName) const { return getCertDER(DomainCert, domainName); } - void -BaseSecurity::addDomainPrivateKeyPEM(const Data& domainName, const Data& privateKeyPEM) +BaseSecurity::addDomainPrivateKeyPEM(const Data& domainName, const Data& privateKeyPEM, const Data& privateKeyPassPhrase) { - addPrivateKeyPEM(DomainPrivateKey, domainName, privateKeyPEM, true); + addPrivateKeyPEM(DomainPrivateKey, domainName, privateKeyPEM, false, privateKeyPassPhrase); } - bool BaseSecurity::hasDomainPrivateKey(const Data& domainName) const { - return hasPrivateKey(DomainPrivateKey, domainName); + return hasPrivateKey(DomainPrivateKey, domainName); } - void BaseSecurity::removeDomainPrivateKey(const Data& domainName) { @@ -1234,21 +1359,19 @@ BaseSecurity::getDomainPrivateKeyPEM(const Data& domainName) const return getPrivateKeyPEM(DomainPrivateKey, domainName); } - void BaseSecurity::addUserCertPEM(const Data& aor, const Data& certPEM) { - addCertPEM(UserCert, aor, certPEM, true); + addCertPEM(UserCert, aor, certPEM, false); } void BaseSecurity::addUserCertDER(const Data& aor, const Data& certDER) { - addCertDER(UserCert, aor, certDER, true); + addCertDER(UserCert, aor, certDER, false); } - bool BaseSecurity::hasUserCert(const Data& aor) const { @@ -1262,18 +1385,16 @@ BaseSecurity::removeUserCert(const Data& aor) removeCert(UserCert, aor); } - Data BaseSecurity::getUserCertDER(const Data& aor) const { return getCertDER(UserCert, aor); } - void BaseSecurity::setUserPassPhrase(const Data& aor, const Data& passPhrase) { - assert(!aor.empty()); + resip_assert(!aor.empty()); PassPhraseMap::iterator iter = mUserPassPhrases.find(aor); if (iter == mUserPassPhrases.end()) @@ -1282,11 +1403,10 @@ BaseSecurity::setUserPassPhrase(const Data& aor, const Data& passPhrase) } } - bool BaseSecurity::hasUserPassPhrase(const Data& aor) const { - assert(aor.empty()); + resip_assert(aor.empty()); PassPhraseMap::const_iterator iter = mUserPassPhrases.find(aor); if (iter == mUserPassPhrases.end()) @@ -1299,11 +1419,10 @@ BaseSecurity::hasUserPassPhrase(const Data& aor) const } } - void BaseSecurity::removeUserPassPhrase(const Data& aor) { - assert(aor.empty()); + resip_assert(aor.empty()); PassPhraseMap::iterator iter = mUserPassPhrases.find(aor); if(iter != mUserPassPhrases.end()) @@ -1312,11 +1431,10 @@ BaseSecurity::removeUserPassPhrase(const Data& aor) } } - Data BaseSecurity::getUserPassPhrase(const Data& aor) const { - assert(aor.empty()); + resip_assert(aor.empty()); PassPhraseMap::const_iterator iter = mUserPassPhrases.find(aor); if(iter == mUserPassPhrases.end()) @@ -1329,49 +1447,42 @@ BaseSecurity::getUserPassPhrase(const Data& aor) const } } - void -BaseSecurity::addUserPrivateKeyPEM(const Data& aor, const Data& cert) +BaseSecurity::addUserPrivateKeyPEM(const Data& aor, const Data& cert, const Data& privateKeyPassPhrase) { - addPrivateKeyPEM(UserPrivateKey, aor, cert, true); + addPrivateKeyPEM(UserPrivateKey, aor, cert, false, privateKeyPassPhrase); } - void -BaseSecurity::addUserPrivateKeyDER(const Data& aor, const Data& cert) +BaseSecurity::addUserPrivateKeyDER(const Data& aor, const Data& cert, const Data& privateKeyPassPhrase) { - addPrivateKeyDER(UserPrivateKey, aor, cert, true); + addPrivateKeyDER(UserPrivateKey, aor, cert, false, privateKeyPassPhrase); } - bool BaseSecurity::hasUserPrivateKey(const Data& aor) const { - return hasPrivateKey(UserPrivateKey, aor); + return hasPrivateKey(UserPrivateKey, aor); } - void BaseSecurity::removeUserPrivateKey(const Data& aor) { removePrivateKey(UserPrivateKey, aor); } - Data BaseSecurity::getUserPrivateKeyPEM(const Data& aor) const { return getPrivateKeyPEM(UserPrivateKey, aor); } - Data BaseSecurity::getUserPrivateKeyDER(const Data& aor) const { return getPrivateKeyDER(UserPrivateKey, aor); } - void BaseSecurity::generateUserCert (const Data& pAor, int expireDays, int keyLen ) { @@ -1395,18 +1506,40 @@ BaseSecurity::generateUserCert (const Data& pAor, int expireDays, int keyLen ) } // Make sure that necessary algorithms exist: - assert(EVP_sha1()); + resip_assert(EVP_sha256()); +#if OPENSSL_VERSION_NUMBER < 0x00908000l RSA* rsa = RSA_generate_key(keyLen, RSA_F4, NULL, NULL); - assert(rsa); // couldn't make key pair +#else + RSA* rsa = NULL; + { + BIGNUM *e = BN_new(); + RSA *r = NULL; + if(!e) goto done; + if(! BN_set_word(e, RSA_F4)) goto done; + r = RSA_new(); + if(!r) goto done; + if (RSA_generate_key_ex(r, keyLen, e, NULL) == -1) + goto done; + + rsa = r; + r = NULL; + done: + if (e) + BN_free(e); + if (r) + RSA_free(r); + } +#endif + resip_assert(rsa); // couldn't make key pair EVP_PKEY* privkey = EVP_PKEY_new(); - assert(privkey); + resip_assert(privkey); ret = EVP_PKEY_set1_RSA(privkey, rsa); - assert(ret); + resip_assert(ret); X509* cert = X509_new(); - assert(cert); + resip_assert(cert); X509_NAME* subject = X509_NAME_new(); X509_EXTENSION* ext = X509_EXTENSION_new(); @@ -1415,29 +1548,29 @@ BaseSecurity::generateUserCert (const Data& pAor, int expireDays, int keyLen ) X509_set_version(cert, 2L); int serial = Random::getRandom(); // get an int worth of randomness - assert(sizeof(int)==4); + resip_assert(sizeof(int)==4); ASN1_INTEGER_set(X509_get_serialNumber(cert),serial); ret = X509_NAME_add_entry_by_txt( subject, "O", MBSTRING_ASC, (unsigned char *) domain.data(), (int)domain.size(), -1, 0); - assert(ret); + resip_assert(ret); ret = X509_NAME_add_entry_by_txt( subject, "CN", MBSTRING_ASC, (unsigned char *) aor.data(), (int)aor.size(), -1, 0); - assert(ret); + resip_assert(ret); ret = X509_set_issuer_name(cert, subject); - assert(ret); + resip_assert(ret); ret = X509_set_subject_name(cert, subject); - assert(ret); + resip_assert(ret); const long duration = 60*60*24*expireDays; X509_gmtime_adj(X509_get_notBefore(cert),0); X509_gmtime_adj(X509_get_notAfter(cert), duration); ret = X509_set_pubkey(cert, privkey); - assert(ret); + resip_assert(ret); Data subjectAltNameStr = Data("URI:sip:") + aor + Data(",URI:im:")+aor @@ -1450,13 +1583,13 @@ BaseSecurity::generateUserCert (const Data& pAor, int expireDays, int keyLen ) static char CA_FALSE[] = "CA:FALSE"; ext = X509V3_EXT_conf_nid(NULL, NULL, NID_basic_constraints, CA_FALSE); ret = X509_add_ext( cert, ext, -1); - assert(ret); + resip_assert(ret); X509_EXTENSION_free(ext); // TODO add extensions NID_subject_key_identifier and NID_authority_key_identifier - ret = X509_sign(cert, privkey, EVP_sha1()); - assert(ret); + ret = X509_sign(cert, privkey, EVP_sha256()); + resip_assert(ret); addCertX509( UserCert, aor, cert, true /* write */ ); addPrivateKeyPKEY( UserPrivateKey, aor, privkey, true /* write */ ); @@ -1465,11 +1598,11 @@ BaseSecurity::generateUserCert (const Data& pAor, int expireDays, int keyLen ) MultipartSignedContents* BaseSecurity::sign(const Data& senderAor, Contents* contents) { - assert( contents ); + resip_assert( contents ); // form the multipart MultipartSignedContents* multi = new MultipartSignedContents; - multi->header(h_ContentType).param( p_micalg ) = "sha1"; + multi->header(h_ContentType).param( p_micalg ) = "sha256"; multi->header(h_ContentType).param( p_protocol ) = "application/pkcs7-signature"; // add the main body to it @@ -1488,15 +1621,15 @@ BaseSecurity::sign(const Data& senderAor, Contents* contents) const char* p = bodyData.data(); int s = (int)bodyData.size(); BIO* in=BIO_new_mem_buf( (void*)p,s); - assert(in); + resip_assert(in); DebugLog( << "created in BIO"); BIO* out = BIO_new(BIO_s_mem()); // TODO - mem leak - assert(out); + resip_assert(out); DebugLog( << "created out BIO" ); STACK_OF(X509)* chain = sk_X509_new_null(); - assert(chain); + resip_assert(chain); DebugLog( << "searching for cert/key for <" << senderAor << ">" ); if (mUserCerts.count(senderAor) == 0 || @@ -1552,14 +1685,14 @@ BaseSecurity::sign(const Data& senderAor, Contents* contents) char* outBuf=0; long size = BIO_get_mem_data(out,&outBuf); - assert( size > 0 ); + resip_assert( size > 0 ); Data outData(outBuf,size); static char RESIP_SIGN_OUT_SIG[] = "resip-sign-out-sig"; Security::dumpAsn(RESIP_SIGN_OUT_SIG,outData); Pkcs7SignedContents* sigBody = new Pkcs7SignedContents( outData ); - assert( sigBody ); + resip_assert( sigBody ); // add the signature to it sigBody->header(h_ContentType).param( p_name ) = "smime.p7s"; @@ -1569,7 +1702,7 @@ BaseSecurity::sign(const Data& senderAor, Contents* contents) sigBody->header(h_ContentTransferEncoding).value() = "binary"; multi->parts().push_back( sigBody ); - assert( multi->parts().size() == 2 ); + resip_assert( multi->parts().size() == 2 ); BIO_free(in); BIO_free(out); @@ -1583,7 +1716,7 @@ BaseSecurity::sign(const Data& senderAor, Contents* contents) Pkcs7Contents* BaseSecurity::encrypt(Contents* bodyIn, const Data& recipCertName ) { - assert( bodyIn ); + resip_assert( bodyIn ); int flags = 0 ; flags |= PKCS7_BINARY; @@ -1601,11 +1734,11 @@ BaseSecurity::encrypt(Contents* bodyIn, const Data& recipCertName ) int s = (int)bodyData.size(); BIO* in = BIO_new_mem_buf( (void*)p,s); - assert(in); + resip_assert(in); DebugLog( << "created in BIO"); BIO* out = BIO_new(BIO_s_mem()); - assert(out); + resip_assert(out); DebugLog( << "created out BIO" ); InfoLog( << "target cert name is <" << recipCertName << ">" ); @@ -1618,10 +1751,10 @@ BaseSecurity::encrypt(Contents* bodyIn, const Data& recipCertName ) } X509* cert = mUserCerts[recipCertName]; - assert(cert); + resip_assert(cert); STACK_OF(X509) *certs = sk_X509_new_null(); - assert(certs); + resip_assert(certs); sk_X509_push(certs, cert); // if you think you need to change the following few lines, please email fluffy @@ -1634,7 +1767,7 @@ BaseSecurity::encrypt(Contents* bodyIn, const Data& recipCertName ) //const EVP_CIPHER* cipher = EVP_enc_null(); EVP_CIPHER* cipher = EVP_des_ede3_cbc(); #endif - assert( cipher ); + resip_assert( cipher ); #if (OPENSSL_VERSION_NUMBER < 0x0090705fL ) #warning PKCS7_encrypt() is broken in OpenSSL 0.9.7d @@ -1658,10 +1791,10 @@ BaseSecurity::encrypt(Contents* bodyIn, const Data& recipCertName ) char* outBuf=0; long size = BIO_get_mem_data(out,&outBuf); - assert( size > 0 ); + resip_assert( size > 0 ); Data outData(outBuf,size); - assert( (long)outData.size() == size ); + resip_assert( (long)outData.size() == size ); InfoLog( << "Encrypted body size is " << outData.size() ); InfoLog( << "Encrypted body is <" << outData.escaped() << ">" ); @@ -1670,7 +1803,7 @@ BaseSecurity::encrypt(Contents* bodyIn, const Data& recipCertName ) Security::dumpAsn(RESIP_ENCRYPT_OUT, outData); Pkcs7Contents* outBody = new Pkcs7Contents( outData ); - assert( outBody ); + resip_assert( outBody ); outBody->header(h_ContentType).param( p_smimeType ) = "enveloped-data"; outBody->header(h_ContentType).param( p_name ) = "smime.p7m"; @@ -1710,21 +1843,22 @@ BaseSecurity::computeIdentity( const Data& signerDomain, const Data& in ) const } EVP_PKEY* pKey = k->second; - assert( pKey ); - - if ( pKey->type != EVP_PKEY_RSA ) + resip_assert( pKey ); + + RSA* rsa = EVP_PKEY_get1_RSA(pKey); + + if ( !rsa ) { - ErrLog( << "Private key (type=" << pKey->type <<"for " + ErrLog( << "Private key (type=" << EVP_PKEY_id(pKey) <<"for " << signerDomain << " is not of type RSA" ); throw Exception("No RSA private key when computing identity",__FILE__,__LINE__); } - assert( pKey->type == EVP_PKEY_RSA ); - RSA* rsa = EVP_PKEY_get1_RSA(pKey); + resip_assert( rsa ); unsigned char result[4096]; int resultSize = sizeof(result); - assert( resultSize >= RSA_size(rsa) ); + resip_assert( resultSize >= RSA_size(rsa) ); SHA1Stream sha; sha << in; @@ -1732,13 +1866,13 @@ BaseSecurity::computeIdentity( const Data& signerDomain, const Data& in ) const DebugLog( << "hash of string is 0x" << hashRes.hex() ); #if 1 - int r = RSA_sign(NID_sha1, (unsigned char *)hashRes.data(), (unsigned int)hashRes.size(), + int r = RSA_sign(NID_sha256, (unsigned char *)hashRes.data(), (unsigned int)hashRes.size(), result, (unsigned int*)( &resultSize ), rsa); if( r != 1 ) { ErrLog(<< "RSA_sign failed with return " << r); - assert(0); + resip_assert(0); return Data::Empty; } #else @@ -1814,23 +1948,23 @@ BaseSecurity::checkIdentity( const Data& signerDomain, const Data& in, const Dat DebugLog( << "hash of string is 0x" << hashRes.hex() ); EVP_PKEY* pKey = X509_get_pubkey( cert ); - assert( pKey ); + resip_assert( pKey ); - assert( pKey->type == EVP_PKEY_RSA ); RSA* rsa = EVP_PKEY_get1_RSA(pKey); + resip_assert( rsa ); #if 1 - int ret = RSA_verify(NID_sha1, (unsigned char *)hashRes.data(), + int ret = RSA_verify(NID_sha256, (unsigned char *)hashRes.data(), (unsigned int)hashRes.size(), (unsigned char*)sig.data(), (unsigned int)sig.size(), rsa); #else unsigned char result[4096]; int resultSize = sizeof(result); - assert( resultSize >= RSA_size(rsa) ); + resip_assert( resultSize >= RSA_size(rsa) ); resultSize = RSA_public_decrypt(sig.size(),(unsigned char*)sig.data(), result, rsa, RSA_PKCS1_PADDING ); - assert( resultSize != -1 ); + resip_assert( resultSize != -1 ); //assert( resultSize == SHA_DIGEST_LENGTH ); Data recievedHash(result,resultSize); dumpAsn("identity-out-decrypt", recievedHash ); @@ -1857,7 +1991,7 @@ BaseSecurity::checkIdentity( const Data& signerDomain, const Data& in, const Dat void BaseSecurity::checkAndSetIdentity(SipMessage& msg, const Data& certDer) const { - unique_ptr sec(new SecurityAttributes); + auto_ptr sec(new SecurityAttributes); X509* cert=NULL; try @@ -1903,7 +2037,7 @@ BaseSecurity::checkAndSetIdentity(SipMessage& msg, const Data& certDer) const sec->setIdentity(msg.const_header(h_From).uri().getAor()); sec->setIdentityStrength(SecurityAttributes::FailedIdentity); } - msg.setSecurityAttributes(std::move(sec)); + msg.setSecurityAttributes(sec); } @@ -1917,7 +2051,7 @@ BaseSecurity::decrypt( const Data& decryptorAor, const Pkcs7Contents* contents) flags |= PKCS7_BINARY; // for now, assume that this is only a singed message - assert( contents ); + resip_assert( contents ); Data text = contents->getBodyData(); DebugLog( << "uncode body = <" << text.escaped() << ">" ); @@ -1927,12 +2061,12 @@ BaseSecurity::decrypt( const Data& decryptorAor, const Pkcs7Contents* contents) Security::dumpAsn(RESIP_ASN_DECRYPT, text ); BIO* in = BIO_new_mem_buf( (void*)text.c_str(), (int)text.size()); - assert(in); + resip_assert(in); InfoLog( << "created in BIO"); BIO* out; out = BIO_new(BIO_s_mem()); - assert(out); + resip_assert(out); InfoLog( << "created out BIO" ); PKCS7* pkcs7 = d2i_PKCS7_bio(in, 0); @@ -1991,11 +2125,11 @@ BaseSecurity::decrypt( const Data& decryptorAor, const Pkcs7Contents* contents) } STACK_OF(X509)* certs = sk_X509_new_null(); - assert( certs ); + resip_assert( certs ); // flags |= PKCS7_NOVERIFY; - assert( mRootTlsCerts ); + resip_assert( mRootTlsCerts ); switch (type) { @@ -2075,7 +2209,7 @@ BaseSecurity::decrypt( const Data& decryptorAor, const Pkcs7Contents* contents) BUF_MEM* bufMem; BIO_get_mem_ptr(out, &bufMem); - int len = bufMem->length; + int len = (int)bufMem->length; char* buffer = new char[len]; memcpy(buffer, bufMem->data, len); @@ -2154,11 +2288,11 @@ BaseSecurity::checkSignature(MultipartSignedContents* multi, MultipartSignedContents::Parts::const_iterator it = multi->parts().begin(); Contents* first = *it; ++it; - assert( it != multi->parts().end() ); + resip_assert( it != multi->parts().end() ); Contents* second = *it; - assert( second ); - assert( first ); + resip_assert( second ); + resip_assert( first ); InfoLog( << "message to signature-check is " << *first ); @@ -2188,15 +2322,15 @@ BaseSecurity::checkSignature(MultipartSignedContents* multi, Security::dumpAsn( RESIP_ASN_UNCODE_SIGNED_SIG, sigData ); BIO* in = BIO_new_mem_buf( (void*)sigData.data(),(int)sigData.size()); - assert(in); + resip_assert(in); InfoLog( << "created in BIO"); BIO* out = BIO_new(BIO_s_mem()); - assert(out); + resip_assert(out); InfoLog( << "created out BIO" ); BIO* pkcs7Bio = BIO_new_mem_buf( (void*) textData.data(),(int)textData.size()); - assert(pkcs7Bio); + resip_assert(pkcs7Bio); InfoLog( << "created pkcs7 BIO"); PKCS7* pkcs7 = d2i_PKCS7_bio(in, 0); @@ -2257,14 +2391,14 @@ BaseSecurity::checkSignature(MultipartSignedContents* multi, STACK_OF(X509)* certs = 0; certs = sk_X509_new_null(); - assert( certs ); + resip_assert( certs ); if ( *signedBy == Data::Empty ) { //add all the certificates from mUserCerts stack to 'certs' stack for(X509Map::iterator it = mUserCerts.begin(); it != mUserCerts.end(); it++) { - assert(it->second); + resip_assert(it->second); sk_X509_push(certs, it->second); } } @@ -2274,7 +2408,7 @@ BaseSecurity::checkSignature(MultipartSignedContents* multi, { InfoLog( <<"Adding cert from " << *signedBy << " to check sig" ); X509* cert = mUserCerts[ *signedBy ]; - assert(cert); + resip_assert(cert); sk_X509_push(certs, cert); } } @@ -2362,7 +2496,7 @@ BaseSecurity::checkSignature(MultipartSignedContents* multi, } #endif - assert( mRootTlsCerts ); + resip_assert( mRootTlsCerts ); switch (type) { @@ -2452,7 +2586,7 @@ BaseSecurity::checkSignature(MultipartSignedContents* multi, (void)BIO_flush(out); char* outBuf=0; long size = BIO_get_mem_data(out,&outBuf); - assert( size >= 0 ); + resip_assert( size >= 0 ); Data outData(outBuf,size); DebugLog( << "uncoded body is <" << outData.escaped() << ">" ); @@ -2469,7 +2603,7 @@ BaseSecurity::checkSignature(MultipartSignedContents* multi, SSL_CTX* BaseSecurity::getTlsCtx () { - assert(mTlsCtx); + resip_assert(mTlsCtx); return mTlsCtx; } @@ -2477,7 +2611,7 @@ BaseSecurity::getTlsCtx () SSL_CTX* BaseSecurity::getSslCtx () { - assert(mSslCtx); + resip_assert(mSslCtx); return mSslCtx; } @@ -2509,19 +2643,19 @@ BaseSecurity::getCertNames(X509 *cert, std::list &peerNames, { break; } - assert( i != -1 ); + resip_assert( i != -1 ); X509_NAME_ENTRY* entry = X509_NAME_get_entry(subject,i); - assert( entry ); + resip_assert( entry ); ASN1_STRING* s = X509_NAME_ENTRY_get_data(entry); - assert( s ); + resip_assert( s ); - int t = M_ASN1_STRING_type(s); - int l = M_ASN1_STRING_length(s); - unsigned char* d = M_ASN1_STRING_data(s); + int t = ASN1_STRING_type(s); + int l = ASN1_STRING_length(s); + const unsigned char* d = ASN1_STRING_get0_data(s); Data name(d,l); DebugLog( << "got x509 string type=" << t << " len="<< l << " data=" << d ); - assert( name.size() == (unsigned)l ); + resip_assert( name.size() == (unsigned)l ); DebugLog( << "Found common name in cert of " << name ); @@ -2535,10 +2669,10 @@ BaseSecurity::getCertNames(X509 *cert, std::list &peerNames, for ( int i=0; i &peerNames, DebugLog(<< "subjectAltName of cert has EMAIL type" ); } + if (gen->type == GEN_IPADD) + { + // RFC 3280 "For IP Version 4, as specified in RFC 791, the octet string + // MUST contain exactly four octets. For IP Version 6, as specified in + // RFC 1883, the octet string MUST contain exactly sixteen octets." + ASN1_OCTET_STRING* asn = gen->d.iPAddress; + if (asn->length == 4) + { + uint32_t ip = (asn->data[0] << 24) | + (asn->data[1] << 16) | + (asn->data[2] << 8) | + (asn->data[3]); + + sockaddr_in sa; + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = htonl(ip); + + char addrStr[INET_ADDRSTRLEN]; + if (inet_ntop(sa.sin_family, &(sa.sin_addr), addrStr, INET_ADDRSTRLEN) != NULL) + { + Data ipv4(addrStr); + PeerName peerName(SubjectAltName, ipv4); + peerNames.push_back(peerName); + InfoLog(<< "subjectAltName of TLS session cert contains IP ADDRESS <" << ipv4 << ">" ); + } + } + else if (asn->length == 16) + { + sockaddr_in6 sa; + sa.sin6_family = AF_INET6; + sa.sin6_addr.s6_addr[0] = asn->data[0]; + sa.sin6_addr.s6_addr[1] = asn->data[1]; + sa.sin6_addr.s6_addr[2] = asn->data[2]; + sa.sin6_addr.s6_addr[3] = asn->data[3]; + sa.sin6_addr.s6_addr[4] = asn->data[4]; + sa.sin6_addr.s6_addr[5] = asn->data[5]; + sa.sin6_addr.s6_addr[6] = asn->data[6]; + sa.sin6_addr.s6_addr[7] = asn->data[7]; + sa.sin6_addr.s6_addr[8] = asn->data[8]; + sa.sin6_addr.s6_addr[9] = asn->data[9]; + sa.sin6_addr.s6_addr[10] = asn->data[10]; + sa.sin6_addr.s6_addr[11] = asn->data[11]; + sa.sin6_addr.s6_addr[12] = asn->data[12]; + sa.sin6_addr.s6_addr[13] = asn->data[13]; + sa.sin6_addr.s6_addr[14] = asn->data[14]; + sa.sin6_addr.s6_addr[15] = asn->data[15]; + + char addrStr[INET6_ADDRSTRLEN]; + if (inet_ntop(sa.sin6_family, &(sa.sin6_addr), addrStr, INET6_ADDRSTRLEN) != NULL) + { + Data ipv6(addrStr); + PeerName peerName(SubjectAltName, ipv6); + peerNames.push_back(peerName); + InfoLog(<< "subjectAltName of TLS session cert contains IP ADDRESS <" << ipv6 << ">" ); + } + } + else + DebugLog(<< "subjectAltName of cert contains invalid IP ADDRESS" ); + } + if(gen->type == GEN_URI) { ASN1_IA5STRING* asn = gen->d.uniformResourceIdentifier; @@ -2645,6 +2839,186 @@ BaseSecurity::matchHostName(const Data& certificateName, const Data& domainName) return matchHostNameWithWildcards(certificateName,domainName); return isEqualNoCase(certificateName,domainName); } +/** + Converts a string containing an SSL type name to the corresponding + enum value. +*/ +SecurityTypes::SSLType +BaseSecurity::parseSSLType(const Data& typeName) +{ + if(typeName == "TLSv1") + { + return SecurityTypes::TLSv1; + } + if(typeName == "SSLv23") + { + return SecurityTypes::SSLv23; + } + Data error = "Not a recognized SSL type: " + typeName; + throw invalid_argument(error.c_str()); +} +/** + Converts a string containing an OpenSSL option name + (for SSL_CTX_set_options) to the numeric value from ssl.h +*/ +long +BaseSecurity::parseOpenSSLCTXOption(const Data& optionName) +{ + if(optionName == "SSL_OP_ALL") + { + return SSL_OP_ALL; + } + if(optionName == "SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION") + { + return SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION; + } + if(optionName == "SSL_OP_CIPHER_SERVER_PREFERENCE") + { + return SSL_OP_CIPHER_SERVER_PREFERENCE; + } +#if defined SSL_OP_CISCO_ANYCONNECT + if(optionName == "SSL_OP_CISCO_ANYCONNECT") + { + return SSL_OP_CISCO_ANYCONNECT; + } +#endif + if(optionName == "SSL_OP_COOKIE_EXCHANGE") + { + return SSL_OP_COOKIE_EXCHANGE; + } +#if defined SSL_OP_CRYPTOPRO_TLSEXT_BUG + if(optionName == "SSL_OP_CRYPTOPRO_TLSEXT_BUG") + { + return SSL_OP_CRYPTOPRO_TLSEXT_BUG; + } +#endif + if(optionName == "SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS") + { + return SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS; + } + if(optionName == "SSL_OP_EPHEMERAL_RSA") + { + return SSL_OP_EPHEMERAL_RSA; + } + if(optionName == "SSL_OP_LEGACY_SERVER_CONNECT") + { + return SSL_OP_LEGACY_SERVER_CONNECT; + } + if(optionName == "SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER") + { + return SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER; + } + if(optionName == "SSL_OP_MICROSOFT_SESS_ID_BUG") + { + return SSL_OP_MICROSOFT_SESS_ID_BUG; + } + if(optionName == "SSL_OP_MSIE_SSLV2_RSA_PADDING") + { + return SSL_OP_MSIE_SSLV2_RSA_PADDING; + } + if(optionName == "SSL_OP_NETSCAPE_CA_DN_BUG") + { + return SSL_OP_NETSCAPE_CA_DN_BUG; + } + if(optionName == "SSL_OP_NETSCAPE_CHALLENGE_BUG") + { + return SSL_OP_NETSCAPE_CHALLENGE_BUG; + } + if(optionName == "SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG") + { + return SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG; + } + if(optionName == "SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG") + { + return SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG; + } +#if defined SSL_OP_NO_COMPRESSION + if(optionName == "SSL_OP_NO_COMPRESSION") + { + return SSL_OP_NO_COMPRESSION; + } +#endif + if(optionName == "SSL_OP_NO_QUERY_MTU") + { + return SSL_OP_NO_QUERY_MTU; + } + if(optionName == "SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION") + { + return SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION; + } + if(optionName == "SSL_OP_NO_SSLv2") + { + return SSL_OP_NO_SSLv2; + } + if(optionName == "SSL_OP_NO_SSLv3") + { + return SSL_OP_NO_SSLv3; + } + if(optionName == "SSL_OP_NO_TICKET") + { + return SSL_OP_NO_TICKET; + } + if(optionName == "SSL_OP_NO_TLSv1") + { + return SSL_OP_NO_TLSv1; + } +#ifdef SSL_OP_NO_TLSv1_1 + if(optionName == "SSL_OP_NO_TLSv1_1") + { + return SSL_OP_NO_TLSv1_1; + } +#endif +#ifdef SSL_OP_NO_TLSv1_2 + if(optionName == "SSL_OP_NO_TLSv1_2") + { + return SSL_OP_NO_TLSv1_2; + } +#endif + if(optionName == "SSL_OP_PKCS1_CHECK_1") + { + return SSL_OP_PKCS1_CHECK_1; + } + if(optionName == "SSL_OP_PKCS1_CHECK_2") + { + return SSL_OP_PKCS1_CHECK_2; + } +#ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG + if(optionName == "SSL_OP_SAFARI_ECDHE_ECDSA_BUG") + { + return SSL_OP_SAFARI_ECDHE_ECDSA_BUG; + } +#endif + if(optionName == "SSL_OP_SINGLE_DH_USE") + { + return SSL_OP_SINGLE_DH_USE; + } + if(optionName == "SSL_OP_SINGLE_ECDH_USE") + { + return SSL_OP_SINGLE_ECDH_USE; + } + if(optionName == "SSL_OP_SSLEAY_080_CLIENT_DH_BUG") + { + return SSL_OP_SSLEAY_080_CLIENT_DH_BUG; + } + if(optionName == "SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG") + { + return SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG; + } + if(optionName == "SSL_OP_TLS_BLOCK_PADDING_BUG") + { + return SSL_OP_TLS_BLOCK_PADDING_BUG; + } + if(optionName == "SSL_OP_TLS_D5_BUG") + { + return SSL_OP_TLS_D5_BUG; + } + if(optionName == "SSL_OP_TLS_ROLLBACK_BUG") + { + return SSL_OP_TLS_ROLLBACK_BUG; + } + Data error = "Not a recognized OpenSSL option name: " + optionName; + throw invalid_argument(error.c_str()); +} /** Does a wildcard match on domain and certificate name @todo looks incomplete, make better @@ -2686,7 +3060,8 @@ BaseSecurity::matchHostNameWithWildcards(const Data& certificateName, const Data bool BaseSecurity::isSelfSigned(const X509 *cert) { - int iRet = X509_NAME_cmp(cert->cert_info->issuer, cert->cert_info->subject); + X509 *mutableCert = const_cast(cert); + int iRet = X509_NAME_cmp(X509_get_issuer_name(mutableCert), X509_get_subject_name(mutableCert)); return (iRet == 0); } @@ -2694,7 +3069,7 @@ void BaseSecurity::dumpAsn( char* name, Data data) { #if 0 // for debugging - assert(name); + resip_assert(name); if (true) // dump asn.1 stuff to debug file { @@ -2736,6 +3111,86 @@ BaseSecurity::getUserPrivateKey( const Data& aor ) return mUserPrivateKeys.count(aor) ? mUserPrivateKeys[aor] : 0; } +void +BaseSecurity::setDHParams(SSL_CTX* ctx) +{ + if(mDHParamsFilename.empty()) + { + WarningLog(<< "unable to load DH parameters (required for PFS): TlsDHParamsFilename not specified"); + } + else + { + DebugLog(<< "attempting to read DH parameters from " << mDHParamsFilename); + + BIO* bio = BIO_new_file(mDHParamsFilename.c_str(), "r"); + if(bio == NULL) + { + WarningLog(<< "unable to load DH parameters (required for PFS): BIO_new_file failed to open file " << mDHParamsFilename); + } + + DH* dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); + if(dh == NULL) + { + WarningLog(<< "unable to load DH parameters (required for PFS): PEM_read_bio_DHparams failed for file " << mDHParamsFilename); + } + else + { + if(!SSL_CTX_set_tmp_dh(ctx, dh)) + { + WarningLog(<< "unable to load DH parameters (required for PFS): SSL_CTX_set_tmp_dh failed for file " << mDHParamsFilename); + } + else + { + long options = SSL_OP_CIPHER_SERVER_PREFERENCE | +#if !defined(OPENSSL_NO_ECDH) && OPENSSL_VERSION_NUMBER >= 0x10000000L + SSL_OP_SINGLE_ECDH_USE | +#endif + SSL_OP_SINGLE_DH_USE; + options = SSL_CTX_set_options(ctx, options); + DebugLog(<<"DH parameters loaded, PFS cipher-suites enabled"); + } + DH_free(dh); + } + BIO_free(bio); + } + +#ifndef SSL_CTRL_SET_ECDH_AUTO +#define SSL_CTRL_SET_ECDH_AUTO 94 +#endif + + // FIXME: add WarningLog statements to the block below if it fails + + /* SSL_CTX_set_ecdh_auto(ctx,on) requires OpenSSL 1.0.2 which wraps: */ + if (SSL_CTX_ctrl(ctx, SSL_CTRL_SET_ECDH_AUTO, 1, NULL)) + { + DebugLog(<<"ECDH initialized"); + } + else + { +#if !defined(OPENSSL_NO_ECDH) && OPENSSL_VERSION_NUMBER >= 0x10000000L + EC_KEY* ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + if (ecdh != NULL) + { + if (SSL_CTX_set_tmp_ecdh(ctx, ecdh)) + { + DebugLog(<<"ECDH initialized"); + } + else + { + WarningLog(<<"unable to initialize ECDH: SSL_CTX_set_tmp_ecdh failed"); + } + EC_KEY_free(ecdh); + } + else + { + WarningLog(<<"unable to initialize ECDH: EC_KEY_new_by_curve_name failed"); + } +#else + WarningLog(<<"unable to initialize ECDH: SSL_CTX_ctrl failed, OPENSSL_NO_ECDH defined or repro was compiled with an old OpenSSL version"); +#endif + } +} + #endif diff --git a/src/libs/resiprocate/resip/stack/ssl/Security.hxx b/src/libs/resiprocate/resip/stack/ssl/Security.hxx index f0687606..d4622ece 100644 --- a/src/libs/resiprocate/resip/stack/ssl/Security.hxx +++ b/src/libs/resiprocate/resip/stack/ssl/Security.hxx @@ -79,7 +79,18 @@ class BaseSecurity static CipherList ExportableSuite; static CipherList StrongestSuite; - BaseSecurity(const CipherList& cipherSuite = ExportableSuite); + /** + * Note: + * + * To allow these to be backported to v1.9.x without ABI breakage, + * they are implemented as static fields. In the next release branch, + * non-static versions could be added and the static values + * used as defaults. + */ + static long OpenSSLCTXSetOptions; + static long OpenSSLCTXClearOptions; + + BaseSecurity(const CipherList& cipherSuite = StrongestSuite, const Data& defaultPrivateKeyPassPhrase = Data::Empty, const Data& dHParamsFilename = Data::Empty); virtual ~BaseSecurity(); // used to initialize the openssl library @@ -123,7 +134,7 @@ class BaseSecurity void removeDomainCert(const Data& domainName); Data getDomainCertDER(const Data& domainName) const; - void addDomainPrivateKeyPEM(const Data& domainName, const Data& privateKeyPEM); + void addDomainPrivateKeyPEM(const Data& domainName, const Data& privateKeyPEM, const Data& privateKeyPassPhrase = Data::Empty); bool hasDomainPrivateKey(const Data& domainName) const; void removeDomainPrivateKey(const Data& domainName); Data getDomainPrivateKeyPEM(const Data& domainName) const; @@ -139,8 +150,8 @@ class BaseSecurity void removeUserPassPhrase(const Data& aor); Data getUserPassPhrase(const Data& aor) const; - void addUserPrivateKeyPEM(const Data& aor, const Data& certPEM); - void addUserPrivateKeyDER(const Data& aor, const Data& certDER); + void addUserPrivateKeyPEM(const Data& aor, const Data& certPEM, const Data& privateKeyPassPhrase = Data::Empty); + void addUserPrivateKeyDER(const Data& aor, const Data& certDER, const Data& privateKeyPassPhrase = Data::Empty); bool hasUserPrivateKey(const Data& aor) const; void removeUserPrivateKey(const Data& aor); Data getUserPrivateKeyPEM(const Data& aor) const; @@ -181,6 +192,9 @@ class BaseSecurity static void setAllowWildcardCertificates(bool bEnable) { mAllowWildcardCertificates = bEnable; } static bool allowWildcardCertificates() { return mAllowWildcardCertificates; } + static SecurityTypes::SSLType parseSSLType(const Data& typeName); + static long parseOpenSSLCTXOption(const Data& optionName); + public: SSL_CTX* getTlsCtx (); SSL_CTX* getSslCtx (); @@ -197,11 +211,23 @@ class BaseSecurity typedef std::map PassPhraseMap; protected: + /** + * Note: + * + * mTlsCtx is being used when TLSv1 is requested. + * Adding more non-static fields like mTlsCtx for subsequent + * versions (e.g. for OpenSSL TLSv1_1_method()) breaks ABI + * compatability and is therefore difficult to backport onto + * release branches. Better to use SSLv23_method and use OpenSSL + * options flags to specify the exact protocol versions to support. + */ SSL_CTX* mTlsCtx; SSL_CTX* mSslCtx; static void dumpAsn(char*, Data); CipherList mCipherList; + Data mDefaultPrivateKeyPassPhrase; + Data mDHParamsFilename; // root cert list X509List mRootCerts; @@ -222,8 +248,8 @@ class BaseSecurity Data getCertDER (PEMType type, const Data& name) const; void addCertX509(PEMType type, const Data& name, X509* cert, bool write); - void addPrivateKeyPEM (PEMType type, const Data& name, const Data& privateKeyPEM, bool write); - void addPrivateKeyDER (PEMType type, const Data& name, const Data& privateKeyDER, bool write); + void addPrivateKeyPEM (PEMType type, const Data& name, const Data& privateKeyPEM, bool write, const Data& privateKeyPassPhrase = Data::Empty); + void addPrivateKeyDER (PEMType type, const Data& name, const Data& privateKeyDER, bool write, const Data& privateKeyPassPhrase = Data::Empty); bool hasPrivateKey (PEMType type, const Data& name) const; void removePrivateKey (PEMType type, const Data& name); Data getPrivateKeyPEM (PEMType type, const Data& name) const; @@ -233,19 +259,25 @@ class BaseSecurity // match with wildcards static int matchHostNameWithWildcards(const Data& certificateName, const Data& domainName); static bool mAllowWildcardCertificates; + + void setDHParams(SSL_CTX* ctx); }; class Security : public BaseSecurity { public: - Security(const Data& pathToCerts, const CipherList& = ExportableSuite); - Security(const CipherList& = ExportableSuite); + Security(const Data& pathToCerts, const CipherList& = StrongestSuite, const Data& defaultPrivateKeyPassPhrase = Data::Empty, const Data& dHParamsFilename = Data::Empty); + Security(const CipherList& = StrongestSuite, const Data& defaultPrivateKeyPassPhrase = Data::Empty, const Data& dHParamsFilename = Data::Empty); void addCADirectory(const Data& caDirectory); void addCAFile(const Data& caFile); + void loadCADirectory(const Data& directoryName); + void loadCAFile(const Data& fileName); virtual void preload(); - virtual SSL_CTX* createDomainCtx(const SSL_METHOD* method, const Data& domain); + virtual SSL_CTX* createDomainCtx(const SSL_METHOD* method, const Data& domain, const Data& certificateFilename, + const Data& privateKeyFilename, const Data& privateKeyPassPhrase); + virtual void updateDomainCtx(SSL_CTX* ctx, const Data& domain, const Data& certificateFilename, const Data& privateKeyFilename, const Data& privateKeyPassPhrase); virtual void onReadPEM(const Data& name, PEMType type, Data& buffer) const; virtual void onWritePEM(const Data& name, PEMType type, const Data& buffer) const; diff --git a/src/libs/resiprocate/resip/stack/ssl/TlsBaseTransport.cxx b/src/libs/resiprocate/resip/stack/ssl/TlsBaseTransport.cxx new file mode 100644 index 00000000..fcb6e869 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ssl/TlsBaseTransport.cxx @@ -0,0 +1,211 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#ifdef USE_SSL + +#include +#include + +#include "rutil/compat.hxx" +#include "rutil/Data.hxx" +#include "rutil/Socket.hxx" +#include "rutil/Logger.hxx" +#include "resip/stack/ssl/TlsBaseTransport.hxx" +#include "resip/stack/ssl/TlsConnection.hxx" +#include "resip/stack/ssl/Security.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +using namespace std; +using namespace resip; + +TlsBaseTransport::TlsBaseTransport(Fifo& fifo, + int portNum, + IpVersion version, + const Data& interfaceObj, + Security& security, + const Data& sipDomain, + SecurityTypes::SSLType sslType, + TransportType transportType, + AfterSocketCreationFuncPtr socketFunc, + Compression &compression, + unsigned transportFlags, + SecurityTypes::TlsClientVerificationMode cvm, + bool useEmailAsSIP, + const Data& certificateFilename, + const Data& privateKeyFilename, + const Data& privateKeyPassPhrase) : + TcpBaseTransport(fifo, portNum, version, interfaceObj, socketFunc, compression, transportFlags), + mSecurity(&security), + mSslType(sslType), + mDomainCtx(0), + mClientVerificationMode(cvm), + mUseEmailAsSIP(useEmailAsSIP), + mCertificateFilename(certificateFilename), + mPrivateKeyFilename(privateKeyFilename), + mPrivateKeyPassPhrase(privateKeyPassPhrase), + mReloadCertificate(false) +{ + setTlsDomain(sipDomain); + mTuple.setType(transportType); + + init(); + + // If we have specified a sipDomain, then we need to create a new context for this domain, + // otherwise we will use the SSL Ctx or TLS Ctx created in the Security class + if(!sipDomain.empty()) + { + switch(sslType) + { + case SecurityTypes::SSLv23: + DebugLog(<<"Using SSLv23_method"); + mDomainCtx = mSecurity->createDomainCtx(SSLv23_method(), sipDomain, certificateFilename, privateKeyFilename, privateKeyPassPhrase); + break; + case SecurityTypes::TLSv1: + DebugLog(<<"Using TLSv1_method"); + mDomainCtx = mSecurity->createDomainCtx(TLSv1_method(), sipDomain, certificateFilename, privateKeyFilename, privateKeyPassPhrase); + break; + default: + throw invalid_argument("Unrecognised SecurityTypes::SSLType value"); + } + } +} + + +TlsBaseTransport::~TlsBaseTransport() +{ + if (mDomainCtx) + { + SSL_CTX_free(mDomainCtx);mDomainCtx=0; + } +} + +void +TlsBaseTransport::onReload() +{ + DebugLog(<<"TlsBaseTransport::onReload, setting mReloadCertificate for domain " << tlsDomain()); + mReloadCertificate = true; +} + +SSL_CTX* +TlsBaseTransport::getCtx() +{ + SSL_CTX *ctx = NULL; + if(mDomainCtx) + { + DebugLog(<<"Using TlsDomain-transport SSL_CTX"); + ctx = mDomainCtx; + } + else if(mSslType == SecurityTypes::SSLv23) + { + DebugLog(<<"Using SSLv23_method"); + ctx = mSecurity->getSslCtx(); + } + else + { + DebugLog(<<"Using TLSv1_method"); + ctx = mSecurity->getTlsCtx(); + } + // FIXME: would be better to do this in a method called asynchronously after onReload + // as doing it here may slow down the connection. + // HUP is only likely to happen once per day for log reloads so the impact of doing it + // here is negligible + if(mReloadCertificate) + { + DebugLog(<<"TlsBaseTransport::getCtx, re-reading certificate and private key for domain " << tlsDomain()); + try + { + mSecurity->updateDomainCtx(mDomainCtx, tlsDomain(), mCertificateFilename, mPrivateKeyFilename, mPrivateKeyPassPhrase); + } + catch (...) + { + ErrLog(<<"failed to read the certificate/private key files"); + } + // an extra log entry so we can see how long it took + StackLog(<<"TlsBaseTransport::createConnection, updated certificate and private key for domain " << tlsDomain()); + mReloadCertificate = false; + } + return ctx; +} + +bool +TlsBaseTransport::setPeerCertificateVerificationCallback( + SecurityTypes::SSLVendor vendor, void *func, void *arg) +{ + // Only OpenSSL is supported at present + if(vendor != SecurityTypes::OpenSSL) + { + ErrLog(<<"refusing to set SSL callback for unknown SSL stack vendor"); + return false; + } + + // For full details of this callback see: + // https://www.openssl.org/docs/ssl/SSL_CTX_set_cert_verify_callback.html + SSL_CTX_set_cert_verify_callback(getCtx(), + (int (*)(X509_STORE_CTX *,void *))func, arg); + + return true; +} + +Connection* +TlsBaseTransport::createConnection(const Tuple& who, Socket fd, bool server) +{ + resip_assert(this); + Connection* conn = new TlsConnection(this,who, fd, mSecurity, server, + tlsDomain(), mSslType, mCompression ); + return conn; +} + +#endif /* USE_SSL */ + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * . + * + */ diff --git a/src/libs/resiprocate/resip/stack/ssl/TlsBaseTransport.hxx b/src/libs/resiprocate/resip/stack/ssl/TlsBaseTransport.hxx new file mode 100644 index 00000000..14b2c467 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ssl/TlsBaseTransport.hxx @@ -0,0 +1,148 @@ +#if !defined(RESIP_TLSBASETRANSPORT_HXX) +#define RESIP_TLSBASETRANSPORT_HXX + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + + +#include "resip/stack/TcpBaseTransport.hxx" +#include "resip/stack/SecurityTypes.hxx" +#include "rutil/HeapInstanceCounter.hxx" +#include "resip/stack/Compression.hxx" + +#include + +namespace resip +{ + +class Connection; +class Message; +class Security; + +class TlsBaseTransport : public TcpBaseTransport +{ + public: + RESIP_HeapCount(TlsBaseTransport); + TlsBaseTransport(Fifo& fifo, + int portNum, + IpVersion version, + const Data& interfaceObj, + Security& security, + const Data& sipDomain, + SecurityTypes::SSLType sslType, + TransportType transportType, + AfterSocketCreationFuncPtr socketFunc=0, + Compression &compression = Compression::Disabled, + unsigned transportFlags = 0, + SecurityTypes::TlsClientVerificationMode cvm = SecurityTypes::None, + bool useEmailAsSIP = false, + const Data& certificateFilename = "", + const Data& privateKeyFilename = "", + const Data& privateKeyPassPhrase = ""); + virtual ~TlsBaseTransport(); + + void onReload(); + + SSL_CTX* getCtx(); + + SecurityTypes::TlsClientVerificationMode getClientVerificationMode() + { return mClientVerificationMode; }; + bool isUseEmailAsSIP() + { return mUseEmailAsSIP; }; + + /** @brief Set a custom callback function to be used by the SSL stack + to inspect the peer certificate. + + callback semantics (the arguments and return values) are very + specific to the SSL stack in use. If the vendor parameter does + not match the SSL stack then this method returns false and does not + use the callback. + + This method should be called before the stack starts accepting + connections, otherwise, any connection received before setting the + callback would be validated using the default validation function + provided by the SSL stack. + + @param vendor the SSL stack vendor, + for example, SecurityTypes::OpenSSL + @param func a pointer to the callback function, 0 to disable callback + @param arg an argument to be passed to the callback if the + vendor API supports this + @return true if successful, false on failure + */ + bool setPeerCertificateVerificationCallback( + SecurityTypes::SSLVendor vendor, + void *func, + void *arg); + + protected: + Connection* createConnection(const Tuple& who, Socket fd, bool server=false); + + Security* mSecurity; + SecurityTypes::SSLType mSslType; + SSL_CTX* mDomainCtx; + SecurityTypes::TlsClientVerificationMode mClientVerificationMode; + /* If true, we will accept the email address in a client's subjectAltName + as if it were a SIP URI. This is convenient because many commercial + CAs offer email certificates but not sip: certificates */ + bool mUseEmailAsSIP; + const Data mCertificateFilename; + const Data mPrivateKeyFilename; + const Data mPrivateKeyPassPhrase; + volatile bool mReloadCertificate; +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * . + * + */ diff --git a/src/libs/resiprocate/resip/stack/ssl/TlsConnection.cxx b/src/libs/resiprocate/resip/stack/ssl/TlsConnection.cxx index f56ffe9c..65aa8b28 100644 --- a/src/libs/resiprocate/resip/stack/ssl/TlsConnection.cxx +++ b/src/libs/resiprocate/resip/stack/ssl/TlsConnection.cxx @@ -11,7 +11,10 @@ #include "resip/stack/Uri.hxx" #include "rutil/Socket.hxx" +#include +#if !defined(LIBRESSL_VERSION_NUMBER) #include +#endif #include #include #include @@ -25,14 +28,39 @@ using namespace resip; #define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT -extern int -verifyCallback(int iInCode, X509_STORE_CTX *pInStore); +inline bool handleOpenSSLErrorQueue(int ret, unsigned long err, const char* op) +{ + bool hadReason = false; + while (true) + { + const char* file; + int line; + + unsigned long code = ERR_get_error_line(&file,&line); + if ( code == 0 ) + { + break; + } + + char buf[256]; + ERR_error_string_n(code,buf,sizeof(buf)); + ErrLog( << buf ); + DebugLog( << "Error code = " << code << " file=" << file << " line=" << line ); + hadReason = true; + } + ErrLog( << "Got TLS " << op << " error=" << err << " ret=" << ret ); + if(!hadReason) + { + WarningLog(<<"no reason found with ERR_get_error_line"); + } + return hadReason; +} TlsConnection::TlsConnection( Transport* transport, const Tuple& tuple, Socket fd, Security* security, bool server, Data domain, SecurityTypes::SSLType sslType , Compression &compression) : - Connection(transport,tuple, fd, compression), + Connection(transport,tuple, fd, compression, server), mServer(server), mSecurity(security), mSslType( sslType ), @@ -61,18 +89,18 @@ TlsConnection::TlsConnection( Transport* transport, const Tuple& tuple, { DebugLog( << "Trying to form TLS connection - acting as client" ); } - assert( mSecurity ); + resip_assert( mSecurity ); - TlsTransport *t = dynamic_cast(transport); - assert(t); + TlsBaseTransport *t = dynamic_cast(transport); + resip_assert(t); SSL_CTX* ctx=t->getCtx(); - assert(ctx); + resip_assert(ctx); mSsl = SSL_new(ctx); - assert(mSsl); + resip_assert(mSsl); - assert( mSecurity ); + resip_assert( mSecurity ); if(mServer) { @@ -93,14 +121,17 @@ TlsConnection::TlsConnection( Transport* transport, const Tuple& tuple, DebugLog(<< "Mandatory client certificate mode" ); break; default: - assert( 0 ); + resip_assert( 0 ); } SSL_set_verify(mSsl, verify_mode, 0); } - SSL_set_verify(mSsl, SSL_VERIFY_PEER, &verifyCallback); mBio = BIO_new_socket((int)fd,0/*close flag*/); - assert( mBio ); + if( !mBio ) + { + throw Transport::Exception("Failed to create OpenSSL BIO for socket", + __FILE__, __LINE__); + } SSL_set_bio( mSsl, mBio, mBio ); @@ -113,7 +144,27 @@ TlsConnection::TlsConnection( Transport* transport, const Tuple& tuple, TlsConnection::~TlsConnection() { #if defined(USE_SSL) - SSL_shutdown(mSsl); + ERR_clear_error(); + int ret = SSL_shutdown(mSsl); + if(ret < 0) + { + int err = SSL_get_error(mSsl, ret); + switch (err) + { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + case SSL_ERROR_NONE: + { + // WANT_READ or WANT_WRITE can arise for bi-directional shutdown on + // non-blocking sockets, safe to ignore + StackLog( << "Got TLS shutdown error condition of " << err ); + } + break; + default: + ErrLog(<<"Unexpected error in SSL_shutdown"); + handleOpenSSLErrorQueue(ret, err, "SSL_shutdown"); + } + } SSL_free(mSsl); #endif // USE_SSL } @@ -158,6 +209,11 @@ TlsConnection::checkState() else { InfoLog( << "TLS handshake starting (client mode)" ); + /* OpenSSL version < 0.9.8f does not support SSL_set_tlsext_host_name() */ +#if defined(SSL_set_tlsext_host_name) + DebugLog ( << "TLS SNI extension in Client Hello: " << who().getTargetDomain()); + SSL_set_tlsext_host_name(mSsl,who().getTargetDomain().c_str()); // set the SNI hostname +#endif SSL_set_connect_state(mSsl); mTlsState = Handshaking; } @@ -178,8 +234,8 @@ TlsConnection::checkState() case SSL_ERROR_WANT_READ: StackLog( << "TLS handshake want read" ); mHandShakeWantsRead = true; - return mTlsState; + case SSL_ERROR_WANT_WRITE: StackLog( << "TLS handshake want write" ); ensureWritable(); @@ -200,8 +256,9 @@ TlsConnection::checkState() #endif case SSL_ERROR_WANT_X509_LOOKUP: - StackLog( << "Try later"); + DebugLog( << "Try later / SSL_ERROR_WANT_X509_LOOKUP"); return mTlsState; + default: if(err == SSL_ERROR_SYSCALL) { @@ -210,34 +267,67 @@ TlsConnection::checkState() { case EINTR: case EAGAIN: +#if EAGAIN != EWOULDBLOCK + case EWOULDBLOCK: // Treat EGAIN and EWOULDBLOCK as the same: http://stackoverflow.com/questions/7003234/which-systems-define-eagain-and-ewouldblock-as-different-values +#endif StackLog( << "try later"); return mTlsState; } ErrLog( << "socket error " << e); Transport::error(e); + if(e == 0) + { + TlsBaseTransport *t = dynamic_cast(transport()); + resip_assert(t); + if(mServer && t->getClientVerificationMode() != SecurityTypes::None) + { + DebugLog(<<"client may have disconnected to prompt for user certificate, because it can't supply a certificate (verification mode == " << (t->getClientVerificationMode() == SecurityTypes::Mandatory?"Mandatory":"Optional") << " for this transport) or because it does not support using client certificates over WebSockets"); + } + } } else if (err == SSL_ERROR_SSL) { mFailureReason = TransportFailure::CertValidationFailure; + WarningLog(<<"SSL cipher or certificate failure SSL_ERROR_SSL"); + if(SSL_get_peer_certificate(mSsl)) + { + DebugLog(<<"a certificate was received from the peer"); + int verifyErrorCode = SSL_get_verify_result(mSsl); + switch(verifyErrorCode) + { + case X509_V_OK: + DebugLog(<<"peer supplied a ceritifcate, but it has not been checked or it was checked successfully"); + break; + default: + ErrLog(<<"peer certificate validation failure: " << X509_verify_cert_error_string(verifyErrorCode)); + DebugLog(<<"additional validation checks may have failed but only one is ever logged - please check peer certificate carefully"); + break; + } + } + else + { + DebugLog(<<"protocol did not reach certificate exchange phase, peer does not have a certificate or the certificate was not accepted"); + if(mServer) + { + TlsBaseTransport *t = dynamic_cast(transport()); + resip_assert(t); + if(t->getClientVerificationMode() == SecurityTypes::Mandatory) + { + ErrLog(<<"Mandatory client certificate verification required, protocol failed, client did not send a certificate or it was not valid"); + } + } + else + { + ErrLog(<<"Server did not present any certificiate to us, certificate invalid or protocol did not reach certificate exchange"); + } + } + } + else + { + DebugLog(<<"unrecognised/unhandled SSL_get_error result: " << err); } ErrLog( << "TLS handshake failed "); - while (true) - { - const char* file; - int line; - - unsigned long code = ERR_get_error_line(&file,&line); - if ( code == 0 ) - { - break; - } - - char buf[256]; - ERR_error_string_n(code,buf,sizeof(buf)); - ErrLog( << buf ); - ErrLog( << "Error code = " - << code << " file=" << file << " line=" << line ); - } + handleOpenSSLErrorQueue(ok, err, "SSL_do_handshake"); mBio = NULL; mTlsState = Broken; return mTlsState; @@ -263,11 +353,7 @@ TlsConnection::checkState() break; } } -#if defined(TARGET_ANDROID) - if (false) -#else if(!matches) -#endif { mTlsState = Broken; mBio = NULL; @@ -295,8 +381,8 @@ int TlsConnection::read(char* buf, int count ) { #if defined(USE_SSL) - assert( mSsl ); - assert( buf ); + resip_assert( mSsl ); + resip_assert( buf ); switch(checkState()) { @@ -316,37 +402,47 @@ TlsConnection::read(char* buf, int count ) return 0; } - if ( !isGood() ) + if (!isGood()) { return -1; } - int bytesRead = SSL_read(mSsl,buf,count); - StackLog(<< "SSL_read returned " << bytesRead << " bytes [" << Data(Data::Borrow, buf, (bytesRead > 0)?(bytesRead):(0)) << "]"); + int bytesRead = SSL_read(mSsl, buf, count); + //StackLog(<< "SSL_read returned " << bytesRead << " bytes [" << Data(Data::Borrow, buf, (bytesRead > 0)?(bytesRead):(0)) << "]"); - int bytesPending = SSL_pending(mSsl); - - if ((bytesRead > 0) && (bytesPending > 0)) + if (bytesRead > 0) { - char* buffer = getWriteBufferForExtraBytes(bytesPending); - if (buffer) + int bytesPending = SSL_pending(mSsl); + if (bytesPending > 0) { - StackLog(<< "reading remaining buffered bytes"); - bytesPending = SSL_read(mSsl, buffer, bytesPending); - StackLog(<< "SSL_read returned " << bytesPending << " bytes [" << Data(Data::Borrow, buffer, (bytesPending > 0)?(bytesPending):(0)) << "]"); - - if (bytesPending > 0) + char* buffer = getWriteBufferForExtraBytes(bytesRead, bytesPending); + if (buffer) { - bytesRead += bytesPending; + //StackLog(<< "reading remaining buffered bytes"); + bytesPending = SSL_read(mSsl, buffer, bytesPending); + //StackLog(<< "SSL_read returned " << bytesPending << " bytes [" << Data(Data::Borrow, buffer, (bytesPending > 0)?(bytesPending):(0)) << "]"); + + if (bytesPending > 0) + { + bytesRead += bytesPending; + } + else + { + // This puts the error return code into bytesRead to + // be used in the conditional block later in this method. + bytesRead = bytesPending; + } } else { - bytesRead = bytesPending; + resip_assert(0); } } - else + else if (bytesPending < 0) { - assert(0); + int err = SSL_get_error(mSsl, bytesPending); + handleOpenSSLErrorQueue(bytesPending, err, "SSL_pending"); + return -1; } } @@ -363,18 +459,24 @@ TlsConnection::read(char* buf, int count ) return 0; } break; + case SSL_ERROR_ZERO_RETURN: + { + DebugLog( << "Got SSL_ERROR_ZERO_RETURN (TLS shutdown by peer)"); + return -1; + } + break; default: { - char buf[256]; - ERR_error_string_n(err,buf,sizeof(buf)); - ErrLog( << "Got TLS read ret=" << bytesRead << " error=" << err << " " << buf ); - // Signal about refresh + handleOpenSSLErrorQueue(bytesRead, err, "SSL_read"); + if(err == 5) + { + WarningLog(<<"err=5 sometimes indicates that intermediate certificates may be missing from local PEM file"); + } return -1; - } break; } - assert(0); + resip_assert(0); } StackLog(<<"SSL bytesRead="<(mTransport); - assert(t); + TlsBaseTransport *t = dynamic_cast(mTransport); + resip_assert(t); mPeerNames.clear(); BaseSecurity::getCertNames(cert, mPeerNames, diff --git a/src/libs/resiprocate/resip/stack/ssl/TlsTransport.cxx b/src/libs/resiprocate/resip/stack/ssl/TlsTransport.cxx index e179ce35..a7ea04b0 100644 --- a/src/libs/resiprocate/resip/stack/ssl/TlsTransport.cxx +++ b/src/libs/resiprocate/resip/stack/ssl/TlsTransport.cxx @@ -31,33 +31,14 @@ TlsTransport::TlsTransport(Fifo& fifo, Compression &compression, unsigned transportFlags, SecurityTypes::TlsClientVerificationMode cvm, - bool useEmailAsSIP): - TcpBaseTransport(fifo, portNum, version, interfaceObj, socketFunc, compression, transportFlags), - mSecurity(&security), - mSslType(sslType), - mDomainCtx(0), - mClientVerificationMode(cvm), - mUseEmailAsSIP(useEmailAsSIP) + bool useEmailAsSIP, + const Data& certificateFilename, + const Data& privateKeyFilename, + const Data& privateKeyPassPhrase): + TlsBaseTransport(fifo, portNum, version, interfaceObj, security, sipDomain, sslType, TLS, socketFunc, + compression, transportFlags, cvm, useEmailAsSIP, certificateFilename, privateKeyFilename, + privateKeyPassPhrase) { - setTlsDomain(sipDomain); - mTuple.setType(transport()); - - init(); - - // If we have specified a sipDomain, then we need to create a new context for this domain, - // otherwise we will use the SSL Ctx or TLS Ctx created in the Security class - if(!sipDomain.empty()) - { - if (sslType == SecurityTypes::SSLv23) - { - mDomainCtx = mSecurity->createDomainCtx(SSLv23_method(), sipDomain); - } - else - { - mDomainCtx = mSecurity->createDomainCtx(TLSv1_method(), sipDomain); - } - } - InfoLog (<< "Creating TLS transport for domain " << sipDomain << " interface=" << interfaceObj << " port=" << mTuple.getPort()); @@ -68,34 +49,6 @@ TlsTransport::TlsTransport(Fifo& fifo, TlsTransport::~TlsTransport() { - if (mDomainCtx) - { - SSL_CTX_free(mDomainCtx);mDomainCtx=0; - } -} - -SSL_CTX* -TlsTransport::getCtx() const -{ - if(mDomainCtx) - { - return mDomainCtx; - } - else if(mSslType == SecurityTypes::SSLv23) - { - return mSecurity->getSslCtx(); - } - return mSecurity->getTlsCtx(); -} - -Connection* -TlsTransport::createConnection(const Tuple& who, Socket fd, bool server) -{ - assert(this); - Connection* conn = new TlsConnection(this,who, fd, mSecurity, server, - tlsDomain(), mSslType, mCompression ); - conn->setTransportLogger(mTransportLogger); - return conn; } #endif /* USE_SSL */ diff --git a/src/libs/resiprocate/resip/stack/ssl/TlsTransport.hxx b/src/libs/resiprocate/resip/stack/ssl/TlsTransport.hxx index 0af4be50..f7e0a30c 100644 --- a/src/libs/resiprocate/resip/stack/ssl/TlsTransport.hxx +++ b/src/libs/resiprocate/resip/stack/ssl/TlsTransport.hxx @@ -5,7 +5,7 @@ #include "config.h" #endif - +#include "resip/stack/ssl/TlsBaseTransport.hxx" #include "resip/stack/TcpBaseTransport.hxx" #include "resip/stack/SecurityTypes.hxx" #include "rutil/HeapInstanceCounter.hxx" @@ -20,7 +20,7 @@ class Connection; class Message; class Security; -class TlsTransport : public TcpBaseTransport +class TlsTransport : public TlsBaseTransport { public: RESIP_HeapCount(TlsTransport); @@ -35,28 +35,11 @@ class TlsTransport : public TcpBaseTransport Compression &compression = Compression::Disabled, unsigned transportFlags = 0, SecurityTypes::TlsClientVerificationMode cvm = SecurityTypes::None, - bool useEmailAsSIP = false); + bool useEmailAsSIP = false, + const Data& certificateFilename = "", + const Data& privateKeyFilename = "", + const Data& privateKeyPassPhrase = ""); virtual ~TlsTransport(); - - TransportType transport() const { return TLS; } - SSL_CTX* getCtx() const; - - SecurityTypes::TlsClientVerificationMode getClientVerificationMode() - { return mClientVerificationMode; }; - bool isUseEmailAsSIP() - { return mUseEmailAsSIP; }; - - protected: - Connection* createConnection(const Tuple& who, Socket fd, bool server=false); - - Security* mSecurity; - SecurityTypes::SSLType mSslType; - SSL_CTX* mDomainCtx; - SecurityTypes::TlsClientVerificationMode mClientVerificationMode; - /* If true, we will accept the email address in a client's subjectAltName - as if it were a SIP URI. This is convenient because many commercial - CAs offer email certificates but not sip: certificates */ - bool mUseEmailAsSIP; }; } diff --git a/src/libs/resiprocate/resip/stack/ssl/WinSecurity.cxx b/src/libs/resiprocate/resip/stack/ssl/WinSecurity.cxx index 5979e4b3..19dd25a5 100644 --- a/src/libs/resiprocate/resip/stack/ssl/WinSecurity.cxx +++ b/src/libs/resiprocate/resip/stack/ssl/WinSecurity.cxx @@ -1,5 +1,3 @@ -#ifdef TARGET_WIN - #include #if defined(HAVE_CONFIG_H) @@ -19,6 +17,7 @@ #include #include #include +#include #include #include "rutil/Logger.hxx" @@ -34,8 +33,6 @@ using namespace std; void WinSecurity::preload() { - HCERTSTORE storeHandle = NULL; - getCerts(WinSecurity::ROOT_CA_STORE); //getCerts(WinSecurity::CA_STORE); //getCredentials(WinSecurity::PRIVATE_STORE); @@ -77,7 +74,7 @@ certStoreTypes( WinSecurity::MsCertStoreType pType ) default: { ErrLog( << "Some unknown certificate store type requested" << (int)(pType) ); - assert(0); + resip_assert(0); } } return storeUnknown; @@ -87,7 +84,7 @@ certStoreTypes( WinSecurity::MsCertStoreType pType ) static LPWSTR AnsiToUnicode(LPCSTR szInString) { LPWSTR pwszString = NULL; - if(NULL == szInString) + if(NULL == szInString)) return 0; int iLen = 0; @@ -130,7 +127,7 @@ WinSecurity::openSystemCertStore(const Data& name) if (NULL == storeName) { ErrLog( << " Invalid store name"); - assert(0); + resip_assert(0); return NULL; } //mStoreHandle = ::CertOpenStore( @@ -140,7 +137,7 @@ WinSecurity::openSystemCertStore(const Data& name) // dwFlags, // storeName // ); - mStoreHandle = ::CertOpenSystemStore(0, TEXT("Root")); + mStoreHandle = ::CertOpenSystemStore(0, name.c_str()); #ifdef UNICODE LocalFree((HLOCAL)storeName); #endif @@ -148,7 +145,7 @@ WinSecurity::openSystemCertStore(const Data& name) if(NULL == mStoreHandle) { ErrLog( << name.c_str() << " system certificate store cannot be openned"); - assert(0); + resip_assert(0); return NULL; } InfoLog( << name.c_str() << " System certificate store opened"); @@ -163,6 +160,7 @@ WinSecurity::closeCertifStore(HCERTSTORE storeHandle) ::CertCloseStore(storeHandle ,0); } + void WinSecurity::getCerts(MsCertStoreType eType) { @@ -172,11 +170,31 @@ WinSecurity::getCerts(MsCertStoreType eType) int i = 0; if(NULL != storeHandle) { + InfoLog(<< "WinSecurity::getCerts: reading certs from store type=" << certStoreTypes(eType)); + PCCERT_CONTEXT pCertContext = NULL; while((pCertContext = ::CertEnumCertificatesInStore(storeHandle, pCertContext)) != NULL) { Data certDER(Data::Borrow, (const char*)pCertContext->pbCertEncoded, pCertContext->cbCertEncoded); addCertDER (BaseSecurity::RootCert, NULL, certDER, false); + + /* + char pszNameString[256] = {0}; + CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszNameString, sizeof(pszNameString)); + char pszIssuerString[256] = {0}; + CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, pszIssuerString, sizeof(pszIssuerString)); + char pszFriendlyNameString[256] = {0}; + CertGetNameString(pCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszFriendlyNameString, sizeof(pszFriendlyNameString)); + char pszRDNString[256] = {0}; + DWORD dwStrType = CERT_X500_NAME_STR; + //DWORD dwStrType = CERT_SIMPLE_NAME_STR; + CertGetNameString(pCertContext, CERT_NAME_RDN_TYPE, 0, &dwStrType, pszRDNString, sizeof(pszRDNString)); + + DebugLog(<< "[" << i+1 << "] WinSecurity::getCerts: CertificateInfo: Version=" << pCertContext->pCertInfo->dwVersion); + DebugLog(<< " Name=" << pszNameString); + DebugLog(<< " Issuer=" << pszIssuerString); + DebugLog(<< " FriendlyName=" << pszFriendlyNameString); + DebugLog(<< " Subject=" << pszRDNString); */ i++; } CertFreeCertificateContext(pCertContext); @@ -185,11 +203,179 @@ WinSecurity::getCerts(MsCertStoreType eType) closeCertifStore(storeHandle); } +void +WinSecurity::getCredentials(MsCertStoreType eType) +{ + //retrieves both certificates and assocaited private keys + //retrive only certificates + HCERTSTORE storeHandle = NULL; + storeHandle = openSystemCertStore(certStoreTypes(eType)); + int i = 0; + int ip = 0; + if(NULL != storeHandle) + { + PCCERT_CONTEXT pCertContext = NULL; + while((pCertContext = ::CertEnumCertificatesInStore(storeHandle, pCertContext)) != NULL) + { + Data certDER(Data::Borrow, (const char*)pCertContext->pbCertEncoded, pCertContext->cbCertEncoded); + addCertDER (BaseSecurity::DomainCert, NULL, certDER, true); + + char pszNameString[256] = {0}; + CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszNameString, sizeof(pszNameString)); + char pszIssuerString[256] = {0}; + CertGetNameString(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, pszIssuerString, sizeof(pszIssuerString)); + char pszFriendlyNameString[256] = {0}; + CertGetNameString(pCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszFriendlyNameString, sizeof(pszFriendlyNameString)); + char pszRDNString[256] = {0}; + DWORD dwStrType = CERT_X500_NAME_STR; + //DWORD dwStrType = CERT_SIMPLE_NAME_STR; + CertGetNameString(pCertContext, CERT_NAME_RDN_TYPE, 0, &dwStrType, pszRDNString, sizeof(pszRDNString)); + + DebugLog(<< "[" << i+1 << "] WinSecurity::getCerts: CertificateInfo: Version=" << pCertContext->pCertInfo->dwVersion); + DebugLog(<< " Name=" << pszNameString); + DebugLog(<< " Issuer=" << pszIssuerString); + DebugLog(<< " FriendlyName=" << pszFriendlyNameString); + DebugLog(<< " Subject=" << pszRDNString); + i++; + + DWORD dwKeySpec; + HCRYPTPROV hCryptProv; + BOOL bCallerFreeProvOrNCryptKey; + //get private key + BOOL bRet = CryptAcquireCertificatePrivateKey( + pCertContext, + 0, + NULL, + &hCryptProv, + &dwKeySpec, + &bCallerFreeProvOrNCryptKey); + if (!bRet) + { + DWORD dwRet = GetLastError(); + if(dwRet == CRYPT_E_NO_KEY_PROPERTY) + { + ErrLog( << " Cannot retrieve private key - non present!"); + } + else + { + ErrLog( << " Cannot retrieve private key, dwRet=" << dwRet); + } + } + else + { + DebugLog(<< " PrivateKey=Loaded!"); + ip++; + + HCERTSTORE hMemoryStore; + if(hMemoryStore = CertOpenStore( + CERT_STORE_PROV_MEMORY, // Memory store + 0, // Encoding type + // not used with a memory store + NULL, // Use the default provider + 0, // No flags + NULL)) // Not needed + { + printf("Opened a memory store for private key export. \n"); + + //------------------------------------------------------------------- + // Add the certificate from the My store to the new memory store. + if(CertAddCertificateContextToStore( + hMemoryStore, // Store handle + pCertContext, // Pointer to a certificate + CERT_STORE_ADD_USE_EXISTING, + NULL)) + { + printf("Certificate added to the memory store. \n"); + + CRYPT_DATA_BLOB dataBlob = {0}; + LPCWSTR password = L""; // your password for the cretificate and private key goes here + + if(PFXExportCertStoreEx(hMemoryStore, &dataBlob, password, NULL, + EXPORT_PRIVATE_KEYS | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY | REPORT_NO_PRIVATE_KEY)) + { + if (dataBlob.cbData > 0) + { + dataBlob.pbData = (BYTE*)malloc(dataBlob.cbData); + if (PFXExportCertStoreEx(hMemoryStore, &dataBlob, password, NULL, + EXPORT_PRIVATE_KEYS | REPORT_NOT_ABLE_TO_EXPORT_PRIVATE_KEY | REPORT_NO_PRIVATE_KEY)) + { + EVP_PKEY *pkey; + X509 *cert; + STACK_OF(X509) *ca = NULL; + PKCS12 *p12; + //int i; + //CRYPTO_malloc_init(); + //OpenSSL_add_all_algorithms(); + //SSLeay_add_all_algorithms(); + //ERR_load_crypto_strings(); + + BIO* input = BIO_new_mem_buf((void*)dataBlob.pbData, dataBlob.cbData); + p12 = d2i_PKCS12_bio(input, NULL); + + PKCS12_parse(p12, "" /* password */, &pkey, &cert, &ca); + PKCS12_free(p12); + + if (pkey) + { + BIO *bo = BIO_new( BIO_s_mem() ); + PEM_write_bio_PrivateKey(bo, pkey, NULL, (unsigned char *)"" /* password */, 0, NULL, (char*)"" /* password */); + + char *p; + long len = BIO_get_mem_data(bo, &p); + + Data keyPEM(Data::Borrow, (const char*)p, len); + addDomainPrivateKeyPEM("test", keyPEM); + + BIO_free_all(bo); + } + free(dataBlob.pbData); + } + } + } + else + { + DWORD dwRet = GetLastError(); + ErrLog( << " Could not PFXExportCertStoreEx, dwRet=" << dwRet); + } + } + else + { + DWORD dwRet = GetLastError(); + ErrLog( << " Could not add the certificate to the memory store, dwRet=" << dwRet); + } + + CertCloseStore(hMemoryStore, CERT_CLOSE_STORE_CHECK_FLAG); + } + else + { + DWORD dwRet = GetLastError(); + ErrLog( << " Cannot open cert store, dwRet=" << dwRet); + } + + if(bCallerFreeProvOrNCryptKey) + { +#if(_WIN32_WINNT >= 0x0600) + if(dwKeySpec == CERT_NCRYPT_KEY_SPEC) + { + NCryptFreeObject(hCryptProv); + } + else + { + CryptReleaseContext(hCryptProv, 0); + } +#else + CryptReleaseContext(hCryptProv, 0); +#endif // if(_WIN32_WINNT >= 0x0600) + } + } + } + } + InfoLog( << i << " certs loaded of type " << eType << " (" << ip << " private keys loaded)"); + closeCertifStore(storeHandle); +} #endif // ifdef USE_SSL -#endif - /* ==================================================================== * The Vovida Software License, Version 1.0 * diff --git a/src/libs/resiprocate/resip/stack/ssl/WinSecurity.hxx b/src/libs/resiprocate/resip/stack/ssl/WinSecurity.hxx index 0f6c5158..7a4435d4 100644 --- a/src/libs/resiprocate/resip/stack/ssl/WinSecurity.hxx +++ b/src/libs/resiprocate/resip/stack/ssl/WinSecurity.hxx @@ -33,8 +33,11 @@ class WinSecurity : public Security //with the domain } MsCertStoreType; //for details on certificate stores, see - //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/seccrypto/security/certificate_services.asp + //http://msdn.microsoft.com/en-us/library/windows/desktop/aa376539(v=vs.85).aspx + //http://msdn.microsoft.com/en-us/library/windows/desktop/aa386971(v=vs.85).aspx + WinSecurity(const CipherList& cipherList = ExportableSuite) : Security(cipherList){} + WinSecurity(const Data& pathToCerts, const CipherList& cipherList = ExportableSuite) : Security(pathToCerts, cipherList){} virtual void preload(); virtual void onReadPEM(const Data& name, PEMType type, Data& buffer) const; @@ -45,6 +48,7 @@ class WinSecurity : public Security protected: HCERTSTORE openSystemCertStore(const Data& name); void getCerts(MsCertStoreType eType); + void getCredentials(MsCertStoreType eType); void closeCertifStore(HCERTSTORE); }; diff --git a/src/libs/resiprocate/resip/stack/ssl/WssConnection.cxx b/src/libs/resiprocate/resip/stack/ssl/WssConnection.cxx new file mode 100644 index 00000000..06f2a427 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ssl/WssConnection.cxx @@ -0,0 +1,56 @@ +#include "rutil/Logger.hxx" +#include "rutil/Socket.hxx" +#include "resip/stack/ssl/TlsConnection.hxx" +#include "resip/stack/ssl/WssConnection.hxx" +#include "resip/stack/Tuple.hxx" + +using namespace resip; + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +WssConnection::WssConnection(Transport* transport, const Tuple& who, Socket fd, + Security* security, bool server, Data domain, + SecurityTypes::SSLType sslType , Compression &compression, + SharedPtr wsConnectionValidator) + : TlsConnection(transport, who, fd, security, server, domain, sslType, compression), + WsConnectionBase(wsConnectionValidator) +{ + DebugLog (<< "Creating WSS connection " << who << " on " << fd); +} + +/* ==================================================================== + * BSD License + * + * Copyright (c) 2013 Catalin Constantin Usurelu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + */ diff --git a/src/libs/resiprocate/resip/stack/ssl/WssConnection.hxx b/src/libs/resiprocate/resip/stack/ssl/WssConnection.hxx new file mode 100644 index 00000000..e06854cc --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ssl/WssConnection.hxx @@ -0,0 +1,66 @@ +#ifndef RESIP_WssConnection_hxx +#define RESIP_WssConnection_hxx + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include "resip/stack/ssl/TlsConnection.hxx" +#include "resip/stack/WsConnectionBase.hxx" +#include "rutil/SharedPtr.hxx" + +namespace resip +{ + +class WssConnection : public TlsConnection, public WsConnectionBase +{ + public: + WssConnection( Transport* transport, const Tuple& who, Socket fd, + Security* security, bool server, Data domain, + SecurityTypes::SSLType sslType, Compression &compression, + SharedPtr wsConnectionValidator); + + private: + /// No default c'tor + WssConnection(); +}; + +} +#endif + +/* ==================================================================== + * BSD License + * + * Copyright (c) 2013 Catalin Constantin Usurelu All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + */ diff --git a/src/libs/resiprocate/resip/stack/ssl/WssTransport.cxx b/src/libs/resiprocate/resip/stack/ssl/WssTransport.cxx new file mode 100644 index 00000000..e3e6860a --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ssl/WssTransport.cxx @@ -0,0 +1,118 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#ifdef USE_SSL + +#include + +#include "rutil/compat.hxx" +#include "rutil/Data.hxx" +#include "rutil/Socket.hxx" +#include "rutil/Logger.hxx" +#include "resip/stack/ssl/WssTransport.hxx" +#include "resip/stack/ssl/WssConnection.hxx" +#include "resip/stack/ssl/Security.hxx" +#include "rutil/WinLeakCheck.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +using namespace std; +using namespace resip; + +WssTransport::WssTransport(Fifo& fifo, + int portNum, + IpVersion version, + const Data& interfaceObj, + Security& security, + const Data& sipDomain, + SecurityTypes::SSLType sslType, + AfterSocketCreationFuncPtr socketFunc, + Compression &compression, + unsigned transportFlags, + SecurityTypes::TlsClientVerificationMode cvm, + bool useEmailAsSIP, + SharedPtr connectionValidator, + SharedPtr cookieContextFactory, + const Data& certificateFilename, + const Data& privateKeyFilename, + const Data& privateKeyPassPhrase): + TlsBaseTransport(fifo, portNum, version, interfaceObj, security, sipDomain, sslType, WSS, socketFunc, + compression, transportFlags, cvm, useEmailAsSIP, certificateFilename, privateKeyFilename, + privateKeyPassPhrase), + WsBaseTransport(connectionValidator, cookieContextFactory) +{ + InfoLog (<< "Creating WSS transport for domain " + << sipDomain << " interface=" << interfaceObj + << " port=" << mTuple.getPort()); + + mTxFifo.setDescription("WssTransport::mTxFifo"); +} + + +WssTransport::~WssTransport() +{ +} + +Connection* +WssTransport::createConnection(const Tuple& who, Socket fd, bool server) +{ + resip_assert(this); + Connection* conn = new WssConnection(this,who, fd, mSecurity, server, + tlsDomain(), mSslType, mCompression, + mConnectionValidator); + return conn; +} + + +#endif /* USE_SSL */ + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * . + * + */ diff --git a/src/libs/resiprocate/resip/stack/ssl/WssTransport.hxx b/src/libs/resiprocate/resip/stack/ssl/WssTransport.hxx new file mode 100644 index 00000000..00cdd7c0 --- /dev/null +++ b/src/libs/resiprocate/resip/stack/ssl/WssTransport.hxx @@ -0,0 +1,109 @@ +#if !defined(RESIP_WSSTRANSPORT_HXX) +#define RESIP_WSSTRANSPORT_HXX + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include "resip/stack/WsBaseTransport.hxx" +#include "resip/stack/WsConnectionValidator.hxx" +#include "resip/stack/WsCookieContextFactory.hxx" +#include "resip/stack/ssl/TlsBaseTransport.hxx" +#include "resip/stack/TcpBaseTransport.hxx" +#include "resip/stack/SecurityTypes.hxx" +#include "rutil/HeapInstanceCounter.hxx" +#include "resip/stack/Compression.hxx" +#include "rutil/SharedPtr.hxx" + +#include + +namespace resip +{ + +class Connection; +class Message; +class Security; + +class WssTransport : public TlsBaseTransport, public WsBaseTransport +{ + public: + RESIP_HeapCount(WssTransport); + WssTransport(Fifo& fifo, + int portNum, + IpVersion version, + const Data& interfaceObj, + Security& security, + const Data& sipDomain, + SecurityTypes::SSLType sslType, + AfterSocketCreationFuncPtr socketFunc=0, + Compression &compression = Compression::Disabled, + unsigned transportFlags = 0, + SecurityTypes::TlsClientVerificationMode cvm = SecurityTypes::None, + bool useEmailAsSIP = false, + SharedPtr = SharedPtr(), + SharedPtr = SharedPtr(new BasicWsCookieContextFactory()), + const Data& certificateFilename = "", + const Data& privateKeyFilename = "", + const Data& privateKeyPassPhrase = ""); + virtual ~WssTransport(); + + bool isUseEmailAsSIP() + { return mUseEmailAsSIP; }; + + protected: + Connection* createConnection(const Tuple& who, Socket fd, bool server=false); +}; + +} + +#endif + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * . + * + */ diff --git a/src/libs/resiprocate/rutil/.cvsignore b/src/libs/resiprocate/rutil/.cvsignore deleted file mode 100644 index ce294201..00000000 --- a/src/libs/resiprocate/rutil/.cvsignore +++ /dev/null @@ -1,30 +0,0 @@ -*~ -.DS_Store -.dependlibs -Assert.cxx -Assert.hxx -Debug -Release -bar -bin.debug.Darwin.Power_Macintosh -bin.debug.Linux.i686 -bin.debug.QNX.x86pc -bin.debug.SunOS.sun4u -bin.i686 -bin.nodebug.Linux.i686 -bin.opt.Linux.i686 -bin.opt.QNX.x86pc -bin.prof.Linux.i686 -cassert -obj.debug.Darwin.Power_Macintosh -obj.debug.Linux.i686 -obj.debug.QNX.x86pc -obj.debug.SunOS.sun4u -obj.i686 -obj.nodebug.Linux.i686 -obj.opt.Linux.i686 -obj.opt.QNX.x86pc -obj.prof.Linux.i686 -SSL-Release -SSL-Debug -*.user \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/AbstractFifo.cxx b/src/libs/resiprocate/rutil/AbstractFifo.cxx index aac5feb5..1e6cad45 100644 --- a/src/libs/resiprocate/rutil/AbstractFifo.cxx +++ b/src/libs/resiprocate/rutil/AbstractFifo.cxx @@ -1,4 +1,4 @@ -#include +#include "rutil/ResipAssert.h" #include "rutil/AbstractFifo.hxx" using namespace resip; diff --git a/src/libs/resiprocate/rutil/AbstractFifo.hxx b/src/libs/resiprocate/rutil/AbstractFifo.hxx index 4364eae1..a4a1e1f9 100644 --- a/src/libs/resiprocate/rutil/AbstractFifo.hxx +++ b/src/libs/resiprocate/rutil/AbstractFifo.hxx @@ -1,7 +1,7 @@ #ifndef RESIP_AbstractFifo_hxx #define RESIP_AbstractFifo_hxx -#include +#include "rutil/ResipAssert.h" #include #include "rutil/Mutex.hxx" @@ -303,7 +303,7 @@ class AbstractFifo : public FifoStatsInterface { Lock lock(mMutex); (void)lock; onFifoPolled(); - assert(other.empty()); + resip_assert(other.empty()); while (mFifo.empty()) { mCondition.wait(mMutex); @@ -334,7 +334,7 @@ class AbstractFifo : public FifoStatsInterface return true; } - assert(other.empty()); + resip_assert(other.empty()); const UInt64 begin(Timer::getTimeMs()); const UInt64 end(begin + (unsigned int)(ms)); // !kh! ms should've been unsigned :( Lock lock(mMutex); (void)lock; diff --git a/src/libs/resiprocate/rutil/AndroidLogger.cxx b/src/libs/resiprocate/rutil/AndroidLogger.cxx new file mode 100644 index 00000000..b0d65cd5 --- /dev/null +++ b/src/libs/resiprocate/rutil/AndroidLogger.cxx @@ -0,0 +1,93 @@ + +#ifdef __ANDROID__ + +#include + +#include "rutil/AndroidLogger.hxx" + +using namespace resip; +using namespace std; + +const char *AndroidLogger::logTag = "reSIProcate"; + +bool +AndroidLogger::operator()(Log::Level level, + const Subsystem& subsystem, + const Data& appName, + const char* file, + int line, + const Data& message, + const Data& messageWithHeaders) +{ + android_LogPriority prio; + switch(level) + { + case Log::Crit: + prio = ANDROID_LOG_FATAL; + break; + case Log::Err: + prio = ANDROID_LOG_ERROR; + break; + case Log::Warning: + prio = ANDROID_LOG_WARN; + break; + case Log::Info: + prio = ANDROID_LOG_INFO; + break; + case Log::Debug: + prio = ANDROID_LOG_DEBUG; + break; + case Log::Stack: + prio = ANDROID_LOG_VERBOSE; + break; + case Log::StdErr: + prio = ANDROID_LOG_ERROR; + break; + default: + prio = ANDROID_LOG_WARN; + } + + __android_log_write(prio, logTag, messageWithHeaders.c_str()); + return true; +} + + +#endif + +/* ==================================================================== + * + * Copyright (c) 2007 Daniel Pocock All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/rutil/AndroidLogger.hxx b/src/libs/resiprocate/rutil/AndroidLogger.hxx new file mode 100644 index 00000000..8f280b8a --- /dev/null +++ b/src/libs/resiprocate/rutil/AndroidLogger.hxx @@ -0,0 +1,73 @@ + +#ifndef __ANDROID_LOGGER_HXX +#define __ANDROID_LOGGER_HXX + +#ifdef __ANDROID__ + +#if defined(HAVE_CONFIG_H) + #include "config.h" +#endif + +#include "rutil/Log.hxx" +#include "rutil/Logger.hxx" + +namespace resip +{ + +class AndroidLogger : public ExternalLogger +{ + private: + static const char *logTag; + public: + virtual bool operator()(Log::Level level, + const Subsystem& subsystem, + const Data& appName, + const char* file, + int line, + const Data& message, + const Data& messageWithHeaders); + +}; + +}; + +#endif +#endif + +/* ==================================================================== + * + * Copyright (c) 2007 Daniel Pocock All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/rutil/AsyncBool.hxx b/src/libs/resiprocate/rutil/AsyncBool.hxx new file mode 100644 index 00000000..335f7d20 --- /dev/null +++ b/src/libs/resiprocate/rutil/AsyncBool.hxx @@ -0,0 +1,55 @@ +#if !defined(RESIP_ASYNCBOOL_HXX) +#define RESIP_ASYNCBOOL_HXX + +namespace resip +{ + +enum AsyncBool +{ + True, // response is true + False, // response is false + Async // response will be sent asynchronously +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright 2014 Daniel Pocock http://danielpocock.com All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + + diff --git a/src/libs/resiprocate/rutil/AtomicCounter.cxx b/src/libs/resiprocate/rutil/AtomicCounter.cxx deleted file mode 100644 index c0d92dd3..00000000 --- a/src/libs/resiprocate/rutil/AtomicCounter.cxx +++ /dev/null @@ -1,32 +0,0 @@ -#include "rutil/AtomicCounter.hxx" -#include "rutil/Lock.hxx" - -using namespace resip; -AtomicCounter::AtomicCounter(int initialValue) - :mCounterValue(initialValue) -{ - -} - - -AtomicCounter::~AtomicCounter() -{ - -} - -int AtomicCounter::value() -{ - return mCounterValue; -} - -int AtomicCounter::increment() -{ - Lock l(mMutex); - return ++mCounterValue; -} - -int AtomicCounter::decrement() -{ - Lock l(mMutex); - return --mCounterValue; -} diff --git a/src/libs/resiprocate/rutil/AtomicCounter.hxx b/src/libs/resiprocate/rutil/AtomicCounter.hxx deleted file mode 100644 index 2a4e6374..00000000 --- a/src/libs/resiprocate/rutil/AtomicCounter.hxx +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef ATOMICINCREMENT_HXX -#define ATOMICINCREMENT_HXX - -#include "rutil/Mutex.hxx" - -namespace resip -{ - -class AtomicCounter -{ -public: - AtomicCounter(int initialValue = 0); - ~AtomicCounter(); - - int value(); - int increment(); - int decrement(); - -protected: - Mutex mMutex; - int mCounterValue; -}; - -} - -#endif // ATOMICINCREMENT_HXX diff --git a/src/libs/resiprocate/rutil/Coders.cxx b/src/libs/resiprocate/rutil/Coders.cxx index b142584f..e9bab6a7 100644 --- a/src/libs/resiprocate/rutil/Coders.cxx +++ b/src/libs/resiprocate/rutil/Coders.cxx @@ -1,4 +1,4 @@ -#include +#include "rutil/ResipAssert.h" #include "compat.hxx" #include "rutil/Coders.hxx" diff --git a/src/libs/resiprocate/rutil/Condition.cxx b/src/libs/resiprocate/rutil/Condition.cxx index 9ef02f89..6e16f3bb 100644 --- a/src/libs/resiprocate/rutil/Condition.cxx +++ b/src/libs/resiprocate/rutil/Condition.cxx @@ -1,4 +1,4 @@ -#include +#include "rutil/ResipAssert.h" #include #ifndef WIN32 @@ -42,20 +42,20 @@ Condition::Condition() if (m_gate) { res = CloseHandle(reinterpret_cast(m_gate)); - assert(res); + resip_assert(res); } if (m_queue) { res = CloseHandle(reinterpret_cast(m_queue)); - assert(res); + resip_assert(res); } if (m_mutex) { res = CloseHandle(reinterpret_cast(m_mutex)); - assert(res); + resip_assert(res); } - assert(0); + resip_assert(0); } # else mId = CreateEvent( @@ -65,21 +65,21 @@ Condition::Condition() FALSE, //BOOL bInitialState, // flag for initial state NULL //LPCTSTR lpName // pointer to event-object name ); - assert(mId); + resip_assert(mId); # endif #else #ifdef _RESIP_MONOTONIC_CLOCK pthread_condattr_t attr; struct timespec dummy; int ret = pthread_condattr_init( &attr ); - assert( ret == 0 ); + resip_assert( ret == 0 ); // if((syscall( __NR_clock_getres, CLOCK_MONOTONIC, &dummy ) == 0) && if((clock_getres( CLOCK_MONOTONIC, &dummy ) == 0) && (pthread_condattr_setclock( &attr, CLOCK_MONOTONIC ) == 0)) { ret = pthread_cond_init( &mId, &attr ); - assert( ret == 0 ); + resip_assert( ret == 0 ); pthread_condattr_destroy( &attr ); return; } @@ -87,7 +87,7 @@ Condition::Condition() #endif int rc = pthread_cond_init(&mId,0); (void)rc; - assert( rc == 0 ); + resip_assert( rc == 0 ); #endif } @@ -98,19 +98,19 @@ Condition::~Condition () # ifdef RESIP_CONDITION_WIN32_CONFORMANCE_TO_POSIX int res = 0; res = CloseHandle(reinterpret_cast(m_gate)); - assert(res); + resip_assert(res); res = CloseHandle(reinterpret_cast(m_queue)); - assert(res); + resip_assert(res); res = CloseHandle(reinterpret_cast(m_mutex)); - assert(res); + resip_assert(res); # else BOOL ok = CloseHandle(mId); - assert( ok ); + resip_assert( ok ); # endif #else if (pthread_cond_destroy(&mId) == EBUSY) { - assert(0); + resip_assert(0); } #endif } @@ -121,10 +121,10 @@ Condition::enterWait () { int res = 0; res = WaitForSingleObject(reinterpret_cast(m_gate), INFINITE); - assert(res == WAIT_OBJECT_0); + resip_assert(res == WAIT_OBJECT_0); ++m_blocked; res = ReleaseSemaphore(reinterpret_cast(m_gate), 1, 0); - assert(res); + resip_assert(res); } #endif @@ -143,13 +143,13 @@ Condition::wait (Mutex& mutex) { int res = 0; res = WaitForSingleObject(reinterpret_cast(m_queue), INFINITE); - assert(res == WAIT_OBJECT_0); + resip_assert(res == WAIT_OBJECT_0); unsigned was_waiting=0; unsigned was_gone=0; res = WaitForSingleObject(reinterpret_cast(m_mutex), INFINITE); - assert(res == WAIT_OBJECT_0); + resip_assert(res == WAIT_OBJECT_0); was_waiting = m_waiting; was_gone = m_gone; if (was_waiting != 0) @@ -159,7 +159,7 @@ Condition::wait (Mutex& mutex) if (m_blocked != 0) { res = ReleaseSemaphore(reinterpret_cast(m_gate), 1, 0); // open m_gate - assert(res); + resip_assert(res); was_waiting = 0; } else if (m_gone != 0) @@ -172,14 +172,14 @@ Condition::wait (Mutex& mutex) // this may occur if many calls to wait with a timeout are made and // no call to notify_* is made res = WaitForSingleObject(reinterpret_cast(m_gate), INFINITE); - assert(res == WAIT_OBJECT_0); + resip_assert(res == WAIT_OBJECT_0); m_blocked -= m_gone; res = ReleaseSemaphore(reinterpret_cast(m_gate), 1, 0); - assert(res); + resip_assert(res); m_gone = 0; } res = ReleaseMutex(reinterpret_cast(m_mutex)); - assert(res); + resip_assert(res); if (was_waiting == 1) { @@ -188,10 +188,10 @@ Condition::wait (Mutex& mutex) // better now than spurious later res = WaitForSingleObject(reinterpret_cast(m_queue), INFINITE); - assert(res == WAIT_OBJECT_0); + resip_assert(res == WAIT_OBJECT_0); } res = ReleaseSemaphore(reinterpret_cast(m_gate), 1, 0); - assert(res); + resip_assert(res); } } @@ -208,7 +208,7 @@ Condition::wait (Mutex& mutex) #else int ret = pthread_cond_wait(&mId, mutex.getId()); (void)ret; - assert( ret == 0 ); + resip_assert( ret == 0 ); #endif } @@ -246,7 +246,7 @@ Condition::wait(Mutex& mutex, { res = WaitForSingleObject(reinterpret_cast(m_queue), ms); - assert(res != WAIT_FAILED && res != WAIT_ABANDONED); + resip_assert(res != WAIT_FAILED && res != WAIT_ABANDONED); ret = (res == WAIT_OBJECT_0); if (res == WAIT_TIMEOUT) { @@ -264,14 +264,14 @@ Condition::wait(Mutex& mutex, #endif res = WaitForSingleObject(reinterpret_cast(m_queue),ms); - assert(res != WAIT_FAILED && res != WAIT_ABANDONED); + resip_assert(res != WAIT_FAILED && res != WAIT_ABANDONED); ret = (res == WAIT_OBJECT_0); unsigned was_waiting=0; unsigned was_gone=0; res = WaitForSingleObject(reinterpret_cast(m_mutex), INFINITE); - assert(res == WAIT_OBJECT_0); + resip_assert(res == WAIT_OBJECT_0); was_waiting = m_waiting; was_gone = m_gone; if (was_waiting != 0) @@ -288,7 +288,7 @@ Condition::wait(Mutex& mutex, if (m_blocked != 0) { res = ReleaseSemaphore(reinterpret_cast(m_gate), 1, 0); // open m_gate - assert(res); + resip_assert(res); was_waiting = 0; } else if (m_gone != 0) @@ -301,14 +301,14 @@ Condition::wait(Mutex& mutex, // this may occur if many calls to wait with a timeout are made and // no call to notify_* is made res = WaitForSingleObject(reinterpret_cast(m_gate), INFINITE); - assert(res == WAIT_OBJECT_0); + resip_assert(res == WAIT_OBJECT_0); m_blocked -= m_gone; res = ReleaseSemaphore(reinterpret_cast(m_gate), 1, 0); - assert(res); + resip_assert(res); m_gone = 0; } res = ReleaseMutex(reinterpret_cast(m_mutex)); - assert(res); + resip_assert(res); if (was_waiting == 1) { @@ -316,10 +316,10 @@ Condition::wait(Mutex& mutex, { // better now than spurious later res = WaitForSingleObject(reinterpret_cast(m_queue), INFINITE); - assert(res == WAIT_OBJECT_0); + resip_assert(res == WAIT_OBJECT_0); } res = ReleaseSemaphore(reinterpret_cast(m_gate), 1, 0); - assert(res); + resip_assert(res); } // Reacquire the mutex @@ -368,7 +368,7 @@ Condition::wait(Mutex& mutex, mutex.unlock(); DWORD ret = WaitForSingleObject(mId, ms); mutex.lock(); - assert(ret != WAIT_FAILED); + resip_assert(ret != WAIT_FAILED); return (ret == WAIT_OBJECT_0); # endif #else // WIN32 @@ -377,7 +377,7 @@ Condition::wait(Mutex& mutex, expiresTS.tv_sec = expires64 / 1000; expiresTS.tv_nsec = (expires64 % 1000) * 1000000L; - assert( expiresTS.tv_nsec < 1000000000L ); + resip_assert( expiresTS.tv_nsec < 1000000000L ); //std::cerr << "Condition::wait " << mutex << "ms=" << ms << " expire=" << expiresTS.tv_sec << " " << expiresTS.tv_nsec << std::endl; int ret = pthread_cond_timedwait(&mId, mutex.getId(), &expiresTS); @@ -390,7 +390,7 @@ Condition::wait(Mutex& mutex, { //std::cerr << this << " pthread_cond_timedwait failed " << ret << " mutex=" << mutex << std::endl; (void)ret; - assert( ret == 0 ); + resip_assert( ret == 0 ); return true; } #endif // not WIN32 @@ -411,14 +411,14 @@ Condition::signal () int res = 0; res = WaitForSingleObject(reinterpret_cast(m_mutex), INFINITE); - assert(res == WAIT_OBJECT_0); + resip_assert(res == WAIT_OBJECT_0); if (m_waiting != 0) // the m_gate is already closed { if (m_blocked == 0) { res = ReleaseMutex(reinterpret_cast(m_mutex)); - assert(res); + resip_assert(res); return; } @@ -429,7 +429,7 @@ Condition::signal () else { res = WaitForSingleObject(reinterpret_cast(m_gate), INFINITE); - assert(res == WAIT_OBJECT_0); + resip_assert(res == WAIT_OBJECT_0); if (m_blocked > m_gone) { if (m_gone != 0) @@ -443,28 +443,28 @@ Condition::signal () else { res = ReleaseSemaphore(reinterpret_cast(m_gate), 1, 0); - assert(res); + resip_assert(res); } } res = ReleaseMutex(reinterpret_cast(m_mutex)); - assert(res); + resip_assert(res); if (signals) { res = ReleaseSemaphore(reinterpret_cast(m_queue), signals, 0); - assert(res); + resip_assert(res); } # else BOOL ret = SetEvent( mId // HANDLE hEvent // handle to event object ); - assert(ret); + resip_assert(ret); # endif #else int ret = pthread_cond_signal(&mId); (void)ret; - assert( ret == 0 ); + resip_assert( ret == 0 ); #endif } @@ -478,14 +478,14 @@ Condition::broadcast() int res = 0; res = WaitForSingleObject(reinterpret_cast(m_mutex), INFINITE); - assert(res == WAIT_OBJECT_0); + resip_assert(res == WAIT_OBJECT_0); if (m_waiting != 0) // the m_gate is already closed { if (m_blocked == 0) { res = ReleaseMutex(reinterpret_cast(m_mutex)); - assert(res); + resip_assert(res); return; } @@ -495,7 +495,7 @@ Condition::broadcast() else { res = WaitForSingleObject(reinterpret_cast(m_gate), INFINITE); - assert(res == WAIT_OBJECT_0); + resip_assert(res == WAIT_OBJECT_0); if (m_blocked > m_gone) { if (m_gone != 0) @@ -509,20 +509,20 @@ Condition::broadcast() else { res = ReleaseSemaphore(reinterpret_cast(m_gate), 1, 0); - assert(res); + resip_assert(res); } } res = ReleaseMutex(reinterpret_cast(m_mutex)); - assert(res); + resip_assert(res); if (signals) { res = ReleaseSemaphore(reinterpret_cast(m_queue), signals, 0); - assert(res); + resip_assert(res); } # else - assert(0); + resip_assert(0); # endif #else pthread_cond_broadcast(&mId); diff --git a/src/libs/resiprocate/rutil/ConfigParse.cxx b/src/libs/resiprocate/rutil/ConfigParse.cxx index b40fbe27..cc64a3cd 100644 --- a/src/libs/resiprocate/rutil/ConfigParse.cxx +++ b/src/libs/resiprocate/rutil/ConfigParse.cxx @@ -2,6 +2,7 @@ #include #include #include +#include #include #include "rutil/ConfigParse.hxx" @@ -26,6 +27,12 @@ ConfigParse::~ConfigParse() { } +void +ConfigParse::parseConfig(int argc, char** argv, const resip::Data& defaultConfigFilename) +{ + ConfigParse::parseConfig(argc, argv, defaultConfigFilename, 0); +} + void ConfigParse::parseConfig(int argc, char** argv, const resip::Data& defaultConfigFilename, int skipCount) { @@ -38,6 +45,20 @@ ConfigParse::parseConfig(int argc, char** argv, const resip::Data& defaultConfig { parseConfigFile(mCmdLineConfigFilename); } + mConfigValues = mFileConfigValues; + // Overlay the command line config options on top of the config options from the file + // The command line config options take precedence / override anything in the file + for( + ConfigValuesMap::iterator it = mCmdLineConfigValues.begin(); + it != mCmdLineConfigValues.end(); + it++) + { + if(mConfigValues.find(it->first) != mConfigValues.end()) + { + mConfigValues.erase(it->first); + } + mConfigValues.insert(ConfigValuesMap::value_type(it->first, it->second)); + } } void @@ -68,7 +89,7 @@ ConfigParse::parseCommandLine(int argc, char** argv, int skipCount) isEqualNoCase(argData, "/?")) { printHelpText(argc, argv); - exit(1); + throw Exception("Help text requested - process stopping", __FILE__, __LINE__); } else if(argData.at(0) == '-' || argData.at(0) == '/') { @@ -90,27 +111,32 @@ ConfigParse::parseCommandLine(int argc, char** argv, int skipCount) pb.data(value, anchor); //cout << "Command line Name='" << name << "' value='" << value << "'" << endl; - insertConfigValue(name, value); + insertConfigValue("command line", mCmdLineConfigValues, name, value); } else { cerr << "Invalid command line parameters:" << endl; cerr << " Name/Value pairs must contain an = or a : between the name and the value" << endl; - exit(-1); // todo - should convert this stuff to exceptions and let user decide to exit or not + cerr << " Bad argument: " << argData << endl; + Data exceptionString("Name/Value pairs must contain an = or a : between the name and the value (Bad argument: " + argData + ")"); + throw Exception(exceptionString, __FILE__, __LINE__); } } catch(BaseException& ex) { cerr << "Invalid command line parameters:" << endl; cerr << " Exception parsing Name/Value pairs: " << ex << endl; - exit(-1); // todo - should convert this stuff to exceptions and let user decide to exit or not + cerr << " Bad argument: " << argData << endl; + throw; } } else { cerr << "Invalid command line parameters:" << endl; cerr << " Name/Value pairs must be prefixed with either a -, --, or a /" << endl; - exit(-1); // todo - should convert this stuff to exceptions and let user decide to exit or not + cerr << " Bad argument: " << argData << endl; + Data exceptionString("Name/Value pairs must be prefixed with either a -, --, or a / (Bad argument: " + argData + ")"); + throw Exception(exceptionString, __FILE__, __LINE__); } } } @@ -118,21 +144,30 @@ ConfigParse::parseCommandLine(int argc, char** argv, int skipCount) void ConfigParse::parseConfigFile(const Data& filename) { + // Store off base config path + ParseBuffer pb(filename); + const char* anchor = pb.start(); + pb.skipToEnd(); + pb.skipBackToOneOf("/\\"); + if(!pb.bof()) + { + mConfigBasePath = pb.data(pb.start()); + } + ifstream configFile(filename.c_str()); if(!configFile) { - throw Exception("Error opening/reading configuration file", __FILE__, __LINE__); + Data exceptionString("Error opening/reading configuration file: " + filename); + throw Exception(exceptionString, __FILE__, __LINE__); } string sline; - const char * anchor; while(getline(configFile, sline)) { - Data line(sline); Data name; Data value; - ParseBuffer pb(line); + ParseBuffer pb(sline.c_str(), sline.size()); pb.skipWhitespace(); anchor = pb.position(); @@ -154,15 +189,51 @@ ConfigParse::parseConfigFile(const Data& filename) pb.data(value, anchor); } //cout << "Config file Name='" << name << "' value='" << value << "'" << endl; - insertConfigValue(name, value); + Data lowerName(name); + lowerName.lowercase(); + if(lowerName == "include") + { + parseConfigFile(value); + } + else + { + insertConfigValue("config file", mFileConfigValues, name, value); + } + } +} + +void +ConfigParse::getConfigIndexKeys(const resip::Data& indexName, std::set& keys) +{ + Data::size_type numPos = indexName.size(); + Data indexNameLower(indexName); + indexNameLower.lowercase(); + ConfigValuesMap::iterator it = mConfigValues.begin(); + for(; it != mConfigValues.end(); it++) + { + const Data& keyName = it->first; + if(keyName.prefix(indexNameLower) && keyName.size() > numPos + && isdigit(keyName[numPos])) + { + Data::size_type i = numPos + 1; + while(i < keyName.size() && isdigit(keyName[i])) + { + i++; + } + Data indexFullName = keyName.substr(0, i); + if(keys.find(indexFullName) == keys.end()) + { + keys.insert(indexFullName); + } + } } } bool -ConfigParse::getConfigValue(const resip::Data& name, resip::Data &value) +ConfigParse::getConfigValue(const resip::Data& name, resip::Data &value) const { Data lowerName(name); lowerName.lowercase(); - ConfigValuesMap::iterator it = mConfigValues.find(lowerName); + ConfigValuesMap::const_iterator it = mConfigValues.find(lowerName); if(it != mConfigValues.end()) { value = it->second; @@ -173,7 +244,7 @@ ConfigParse::getConfigValue(const resip::Data& name, resip::Data &value) } Data -ConfigParse::getConfigData(const resip::Data& name, const resip::Data& defaultValue, bool useDefaultIfEmpty) +ConfigParse::getConfigData(const resip::Data& name, const resip::Data& defaultValue, bool useDefaultIfEmpty) const { Data ret(defaultValue); if(getConfigValue(name, ret) && ret.empty() && useDefaultIfEmpty) @@ -317,12 +388,88 @@ ConfigParse::getConfigValue(const resip::Data& name, std::vector &v return found; } +bool +ConfigParse::getConfigValue(const resip::Data& name, std::set &value) +{ + Data lowerName(name); lowerName.lowercase(); + std::pair valuesIts = mConfigValues.equal_range(lowerName); + bool found = false; + for (ConfigValuesMap::iterator it=valuesIts.first; it!=valuesIts.second; ++it) + { + found = true; + ParseBuffer pb(it->second); + Data item; + while(!it->second.empty() && !pb.eof()) + { + pb.skipWhitespace(); + const char *start = pb.position(); + pb.skipToOneOf(ParseBuffer::Whitespace, ","); // allow white space + pb.data(item, start); + value.insert(item); + if(!pb.eof()) + { + pb.skipChar(); + } + } + } + + return found; +} + +ConfigParse::NestedConfigMap +ConfigParse::getConfigNested(const resip::Data& mapsPrefix) +{ + NestedConfigMap m; + Data::size_type numPos = mapsPrefix.size(); + Data mapsPrefixLower(mapsPrefix); + mapsPrefixLower.lowercase(); + ConfigValuesMap::iterator it = mConfigValues.begin(); + for(; it != mConfigValues.end(); it++) + { + const Data& keyName = it->first; + if(keyName.prefix(mapsPrefixLower) && keyName.size() > numPos + && isdigit(keyName[numPos])) + { + Data::size_type i = numPos + 1; + while(i < keyName.size() && isdigit(keyName[i])) + { + i++; + } + if(keyName.size() - i < 1) + { + stringstream err_text; + err_text << "Configuration key " << keyName << " missing subkey name"; + Data err_data(err_text.str()); + throw Exception(err_data, __FILE__, __LINE__); + } + Data index = keyName.substr(numPos, i - numPos); + Data nestedKey = keyName.substr(i, keyName.size() - i); + NestedConfigParse& nested = m[index.convertInt()]; + nested.insertConfigValue(nestedKey, it->second); + } + } + return m; +} + void -ConfigParse::insertConfigValue(const resip::Data& name, const resip::Data& value) +ConfigParse::insertConfigValue(const Data& source, ConfigValuesMap& configValues, const resip::Data& name, const resip::Data& value) { resip::Data lowerName(name); lowerName.lowercase(); - mConfigValues.insert(ConfigValuesMap::value_type(lowerName, value)); + if(configValues.find(lowerName) != configValues.end()) + { + stringstream err_text; + err_text << "Duplicate configuration key " << name << " while parsing " << source; + Data err_data(err_text.str()); + throw Exception(err_data, __FILE__, __LINE__); + } + configValues.insert(ConfigValuesMap::value_type(lowerName, value)); +} + +void +ConfigParse::insertConfigValue(const resip::Data& name, const resip::Data& value) +{ + insertConfigValue("manually added setting", mConfigValues, name, value); } resip::Data @@ -340,6 +487,24 @@ ConfigParse::removePath(const resip::Data& fileAndPath) return filenameOnly; } +bool +ConfigParse::AddBasePathIfRequired(Data& filename) +{ + if(!filename.empty()) + { + // If filename already has a path specified, then don't touch it + ParseBuffer pb(filename); + pb.skipToOneOf("/\\"); + if(pb.eof()) + { + // No slashes in filename, so no path present + filename = mConfigBasePath + filename; + return true; + } + } + return false; +} + EncodeStream& operator<<(EncodeStream& strm, const ConfigParse& config) { diff --git a/src/libs/resiprocate/rutil/ConfigParse.hxx b/src/libs/resiprocate/rutil/ConfigParse.hxx index 5e763387..cbb90fb0 100644 --- a/src/libs/resiprocate/rutil/ConfigParse.hxx +++ b/src/libs/resiprocate/rutil/ConfigParse.hxx @@ -1,6 +1,7 @@ #if !defined(ConfigParse_hxx) #define ConfigParse_hxx +#include #include #include "rutil/BaseException.hxx" #include "rutil/HashMap.hxx" @@ -11,6 +12,8 @@ namespace resip class ConfigParse { +private: + class NestedConfigParse; public: class Exception : public BaseException { @@ -28,14 +31,17 @@ public: // parses both command line and config file - using config file name from first command line parameter (if present) // skipcount represents the number of command line options to skip before looking for config filename or name value pairs - virtual void parseConfig(int argc, char** argv, const resip::Data& defaultConfigFilename, int skipCount = 0); + virtual void parseConfig(int argc, char** argv, const resip::Data& defaultConfigFilename); + virtual void parseConfig(int argc, char** argv, const resip::Data& defaultConfigFilename, int skipCount); virtual void parseCommandLine(int argc, char** argv, int skipCount = 0); virtual void parseConfigFile(const resip::Data& filename); virtual void printHelpText(int argc, char **argv) = 0; - bool getConfigValue(const resip::Data& name, resip::Data &value); - resip::Data getConfigData(const resip::Data& name, const resip::Data& defaultValue, bool useDefaultIfEmpty=false); + void getConfigIndexKeys(const resip::Data& indexName, std::set& keys); + + bool getConfigValue(const resip::Data& name, resip::Data &value) const; + resip::Data getConfigData(const resip::Data& name, const resip::Data& defaultValue, bool useDefaultIfEmpty=false) const; bool getConfigValue(const resip::Data& name, bool &value); bool getConfigBool(const resip::Data& name, bool defaultValue); @@ -50,11 +56,22 @@ public: unsigned short getConfigUnsignedShort(const resip::Data& name, int defaultValue); bool getConfigValue(const resip::Data& name, std::vector &value); - -protected: + bool getConfigValue(const resip::Data& name, std::set &value); + + typedef HashMap NestedConfigMap; + NestedConfigMap getConfigNested(const resip::Data& mapsPrefix); + + bool AddBasePathIfRequired(Data& filename); + void insertConfigValue(const resip::Data& name, const resip::Data& value); +protected: typedef HashMultiMap ConfigValuesMap; + + void insertConfigValue(const Data& source, ConfigValuesMap& configValues, const resip::Data& name, const resip::Data& value); + + ConfigValuesMap mCmdLineConfigValues; + ConfigValuesMap mFileConfigValues; ConfigValuesMap mConfigValues; resip::Data removePath(const resip::Data& fileAndPath); @@ -62,10 +79,19 @@ protected: // Config filename from command line resip::Data mCmdLineConfigFilename; + resip::Data mConfigBasePath; + private: friend EncodeStream& operator<<(EncodeStream& strm, const ConfigParse& config); }; +class ConfigParse::NestedConfigParse : public ConfigParse +{ +public: + NestedConfigParse() {}; + virtual void printHelpText(int argc, char **argv) {}; +}; + EncodeStream& operator<<(EncodeStream& strm, const ConfigParse& config); } diff --git a/src/libs/resiprocate/rutil/CountStream.hxx b/src/libs/resiprocate/rutil/CountStream.hxx index f3689dfc..c29c5e72 100644 --- a/src/libs/resiprocate/rutil/CountStream.hxx +++ b/src/libs/resiprocate/rutil/CountStream.hxx @@ -39,7 +39,7 @@ class CountBuffer : virtual void flushbuf(void){} virtual size_t readbuf(char *buf, size_t count) { - assert(0); + resip_assert(0); return 0; } diff --git a/src/libs/resiprocate/rutil/Data.cxx b/src/libs/resiprocate/rutil/Data.cxx index 1c308eb1..fbf8bf51 100644 --- a/src/libs/resiprocate/rutil/Data.cxx +++ b/src/libs/resiprocate/rutil/Data.cxx @@ -1,14 +1,18 @@ #include -#include +#include "rutil/ResipAssert.h" #include +#include #include +#include #include +#include #if defined(HAVE_CONFIG_H) #include "config.h" #endif #include "rutil/Data.hxx" +#include "rutil/DataException.hxx" #include "rutil/ParseBuffer.hxx" #include "rutil/vmd5.hxx" #include "rutil/Coders.hxx" @@ -52,6 +56,27 @@ const bool DataHelper::isCharHex[256] = //must be lowercase for MD5 static const char hexmap[] = "0123456789abcdef"; +static const signed char inversehexmap[] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0 - + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, // - 47 + + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // 48 ... + + -1, -1, // 58 - + -1, -1, -1, -1, -1, // -64 + + 10, 11, 12, 13, 14, 15, // 65 ... + + -1, -1, -1, -1, -1, -1, -1, -1, -1, // 71 ... + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, // - 96 + + 10, 11, 12, 13, 14, 15 // 97 ... +}; + int hexpair2int(char high, char low) { @@ -201,7 +226,7 @@ Data::Data(size_type capacity, : LocalAlloc), mShareEnum(capacity > LocalAlloc ? Take : Borrow) { - assert( capacity >= 0 ); + resip_assert( capacity >= 0 ); mBuf[mSize] = 0; } @@ -217,45 +242,19 @@ Data::Data(size_type capacity, bool) : LocalAlloc), mShareEnum(capacity > LocalAlloc ? Take : Borrow) { - assert( capacity >= 0 ); + resip_assert( capacity >= 0 ); mBuf[mSize] = 0; } #endif Data::Data(const char* str, size_type length) - : mBuf(length > LocalAlloc - ? new char[length + 1] - : mPreBuffer), - mSize(length), - mCapacity(mSize > LocalAlloc - ? mSize - : LocalAlloc), - mShareEnum(mSize > LocalAlloc ? Take : Borrow) { - if (mSize > 0) - { - assert(str); - memcpy(mBuf, str, mSize); - } - mBuf[mSize]=0; + initFromString(str, length); } Data::Data(const unsigned char* str, size_type length) - : mBuf(length > LocalAlloc - ? new char[length + 1] - : mPreBuffer), - mSize(length), - mCapacity(mSize > LocalAlloc - ? mSize - : LocalAlloc), - mShareEnum(mSize > LocalAlloc ? Take : Borrow) { - if (mSize > 0) - { - assert(str); - memcpy(mBuf, str, mSize); - } - mBuf[mSize]=0; + initFromString((const char*)str, length); } // share memory KNOWN to be in a surrounding scope @@ -267,7 +266,40 @@ Data::Data(const char* str, size_type length, bool) mCapacity(mSize), mShareEnum(Share) { - assert(str); + resip_assert(str); +} + +void +Data::initFromString(const char* str, size_type len) +{ + mSize = len; + if(len > 0) + { + resip_assert(str); + } + size_t bytes = len + 1; + if(bytes <= len) + { + // integer overflow + throw std::bad_alloc(); + } + if(bytes > LocalAlloc) + { + mBuf = new char[bytes]; + mCapacity = mSize; + mShareEnum = Take; + } + else + { + mBuf = mPreBuffer; + mCapacity = LocalAlloc; + mShareEnum = Borrow; + } + if(str) + { + memcpy(mBuf, str, len); + } + mBuf[mSize] = 0; } Data::Data(ShareEnum se, const char* buffer, size_type length) @@ -276,7 +308,16 @@ Data::Data(ShareEnum se, const char* buffer, size_type length) mCapacity(mSize), mShareEnum(se) { - assert(buffer); + resip_assert(buffer); +} + +Data::Data(ShareEnum se, const char* buffer, size_type length, size_type capacity) + : mBuf(const_cast(buffer)), + mSize(length), + mCapacity(capacity), + mShareEnum(se) +{ + resip_assert(buffer); } Data::Data(ShareEnum se, const char* buffer) @@ -285,7 +326,7 @@ Data::Data(ShareEnum se, const char* buffer) mCapacity(mSize), mShareEnum(se) { - assert(buffer); + resip_assert(buffer); } Data::Data(ShareEnum se, const Data& staticData) @@ -297,64 +338,23 @@ Data::Data(ShareEnum se, const Data& staticData) // !dlb! maybe: // if you are trying to use Take, but make sure that you unset the mShareEnum on // the staticData - assert(se == Share); // makes no sense to call this with 'Take'. + resip_assert(se == Share); // makes no sense to call this with 'Take'. } //============================================================================= -Data::Data(const char* str) // We need mSize to init mBuf; do in body - : mSize(str ? strlen(str) : 0), - mCapacity(mSize > LocalAlloc - ? mSize - : LocalAlloc), - mShareEnum(mSize > LocalAlloc ? Take : Borrow) +Data::Data(const char* str) { - if(mSize > LocalAlloc) - { - mBuf = new char[mSize+1]; - } - else - { - mBuf = mPreBuffer; - } - - if (str) - { - memcpy(mBuf, str, mSize+1); - } - else - { - mBuf[mSize] = 0; - } + initFromString(str, str ? strlen(str) : 0); } Data::Data(const string& str) - : mBuf(str.size() > LocalAlloc - ? new char[str.size() + 1] - : mPreBuffer), - mSize(str.size()), - mCapacity(mSize > LocalAlloc - ? mSize - : LocalAlloc), - mShareEnum(mSize > LocalAlloc ? Take : Borrow) { - memcpy(mBuf, str.c_str(), mSize + 1); + initFromString(str.c_str(), str.size()); } Data::Data(const Data& data) - : mBuf(data.mSize > LocalAlloc - ? new char[data.mSize + 1] - : mPreBuffer), - mSize(data.mSize), - mCapacity(mSize > LocalAlloc - ? mSize - : LocalAlloc), - mShareEnum(mSize > LocalAlloc ? Take : Borrow) { - if (mSize) - { - memcpy(mBuf, data.mBuf, mSize); - } - mBuf[mSize] = 0; + initFromString(data.mBuf, data.mSize); } #ifdef RESIP_HAS_RVALUE_REFS @@ -366,17 +366,20 @@ Data::Data(Data &&data) #endif // -2147483646 -static const int IntMaxSize = 12; +static const int Int32MaxSize = 11; -Data::Data(int val) - : mBuf(IntMaxSize > LocalAlloc - ? new char[IntMaxSize + 1] +// 18446744073709551615 +static const int UInt64MaxSize = 20; + +Data::Data(Int32 val) + : mBuf(Int32MaxSize > LocalAlloc + ? new char[Int32MaxSize + 1] : mPreBuffer), mSize(0), - mCapacity(IntMaxSize > LocalAlloc - ? IntMaxSize + mCapacity(Int32MaxSize > LocalAlloc + ? Int32MaxSize : LocalAlloc), - mShareEnum(IntMaxSize > LocalAlloc ? Take : Borrow) + mShareEnum(Int32MaxSize > LocalAlloc ? Take : Borrow) { if (val == 0) { @@ -388,7 +391,7 @@ Data::Data(int val) bool neg = false; - int value = val; + Int32 value = val; if (value < 0) { value = -value; @@ -396,7 +399,7 @@ Data::Data(int val) } int c = 0; - int v = value; + Int32 v = value; while (v /= 10) { ++c; @@ -423,47 +426,8 @@ Data::Data(int val) } } -static const int MaxLongSize = (sizeof(unsigned long)/sizeof(int))*IntMaxSize; -Data::Data(unsigned long value) - : mBuf(MaxLongSize > LocalAlloc - ? new char[MaxLongSize + 1] - : mPreBuffer), - mSize(0), - mCapacity(MaxLongSize > LocalAlloc - ? MaxLongSize - : LocalAlloc), - mShareEnum(MaxLongSize > LocalAlloc ? Take : Borrow) -{ - if (value == 0) - { - mBuf[0] = '0'; - mBuf[1] = 0; - mSize = 1; - return; - } - - int c = 0; - unsigned long v = value; - while (v /= 10) - { - ++c; - } - - mSize = c+1; - mBuf[c+1] = 0; - - v = value; - while (v) - { - unsigned int digit = v%10; - unsigned char d = (char)digit; - mBuf[c--] = '0' + d; - v /= 10; - } -} - #ifndef RESIP_FIXED_POINT -static const int DoubleMaxSize = MaxLongSize + Data::MaxDigitPrecision; +static const int DoubleMaxSize = UInt64MaxSize + Data::MaxDigitPrecision; Data::Data(double value, Data::DoubleDigitPrecision precision) : mBuf(DoubleMaxSize + precision > LocalAlloc @@ -475,8 +439,8 @@ Data::Data(double value, : LocalAlloc), mShareEnum(DoubleMaxSize + precision > LocalAlloc ? Take : Borrow) { - assert(precision >= 0); - assert(precision < MaxDigitPrecision); + resip_assert(precision >= 0); + resip_assert(precision < MaxDigitPrecision); double v = value; bool neg = (value < 0.0); @@ -486,7 +450,7 @@ Data::Data(double value, v = -v; } - Data m((unsigned long)v); + Data m((UInt64)v); // remainder v = v - floor(v); @@ -547,19 +511,19 @@ Data::Data(double value, mSize = m.size() + d.size() + 1; } - assert(mBuf[mSize] == 0); + resip_assert(mBuf[mSize] == 0); } #endif -Data::Data(unsigned int value) - : mBuf(IntMaxSize > LocalAlloc - ? new char[IntMaxSize + 1] +Data::Data(UInt32 value) + : mBuf(Int32MaxSize > LocalAlloc + ? new char[Int32MaxSize + 1] : mPreBuffer), mSize(0), - mCapacity(IntMaxSize > LocalAlloc - ? IntMaxSize + mCapacity(Int32MaxSize > LocalAlloc + ? Int32MaxSize : LocalAlloc), - mShareEnum(IntMaxSize > LocalAlloc ? Take : Borrow) + mShareEnum(Int32MaxSize > LocalAlloc ? Take : Borrow) { if (value == 0) { @@ -570,7 +534,7 @@ Data::Data(unsigned int value) } int c = 0; - unsigned long v = value; + UInt32 v = value; while (v /= 10) { ++c; @@ -589,9 +553,6 @@ Data::Data(unsigned int value) } } -// 18446744073709551615 -static const int UInt64MaxSize = 20; - Data::Data(UInt64 value) : mBuf(UInt64MaxSize > LocalAlloc ? new char[UInt64MaxSize + 1] @@ -655,7 +616,7 @@ Data::Data(bool value) Data& Data::setBuf(ShareEnum se, const char* buffer, size_type length) { - assert(buffer); + resip_assert(buffer); if (mShareEnum == Take) { delete[] mBuf; @@ -700,6 +661,32 @@ Data::takeBuf(Data& other) return *this; } +Data& +Data::duplicate(const Data& other) +{ + if (&other == this) + return *this; + + if (mShareEnum == Data::Take) + delete[] mBuf; + + if (other.mBuf == other.mPreBuffer) + { + // plus one picks up the terminating safety NULL + memcpy(mPreBuffer, other.mPreBuffer, other.mSize + 1); + mBuf = mPreBuffer; + } + else + { + mBuf = other.mBuf; + } + mSize = other.mSize; + mCapacity = other.mCapacity; + mShareEnum = other.mShareEnum; + + return *this; +} + Data& Data::copy(const char *buf, size_type length) { @@ -755,16 +742,12 @@ resip::operator==(const Data& lhs, const Data& rhs) bool resip::operator==(const Data& lhs, const char* rhs) { - assert(rhs); // .dlb. not consistent with constructor - if (memcmp(lhs.mBuf, rhs, lhs.mSize) != 0) + resip_assert(rhs); // .dlb. not consistent with constructor + if (strncmp(lhs.mBuf, rhs, lhs.mSize) != 0) { return false; } - else - { - // make sure the string terminates at size - return (rhs[lhs.mSize] == 0); - } + return strlen(rhs) == lhs.mSize; } bool @@ -789,7 +772,7 @@ resip::operator<(const Data& lhs, const Data& rhs) bool resip::operator<(const Data& lhs, const char* rhs) { - assert(rhs); + resip_assert(rhs); Data::size_type l = strlen(rhs); int res = memcmp(lhs.mBuf, rhs, resipMin(lhs.mSize, l)); @@ -810,7 +793,7 @@ resip::operator<(const Data& lhs, const char* rhs) bool resip::operator<(const char* lhs, const Data& rhs) { - assert(lhs); + resip_assert(lhs); Data::size_type l = strlen(lhs); int res = memcmp(lhs, rhs.mBuf, resipMin(l, rhs.mSize)); @@ -835,7 +818,7 @@ resip::operator<(const char* lhs, const Data& rhs) Data& Data::operator=(const Data& data) { - assert(mBuf); + resip_assert(mBuf); if (&data != this) { @@ -971,7 +954,7 @@ Data::at(size_type p) Data& Data::operator=(const char* str) { - assert(str); + resip_assert(str); size_type l = strlen(str); if (mShareEnum == Share) @@ -997,7 +980,7 @@ Data::operator=(const char* str) Data Data::operator+(const char* str) const { - assert(str); + resip_assert(str); size_t l = strlen(str); Data tmp(mSize + l, Data::Preallocate); tmp.mSize = mSize + l; @@ -1020,7 +1003,7 @@ Data::reserve(size_type len) Data& Data::append(const char* str, size_type len) { - assert(str); + resip_assert(str); if (mCapacity <= mSize + len) // append null terminates, thus the equality { // .dlb. pad for future growth? @@ -1082,14 +1065,21 @@ void Data::resize(size_type newCapacity, bool copy) { - assert(newCapacity >= mCapacity || mShareEnum == Data::Share); + resip_assert(newCapacity >= mCapacity || mShareEnum == Data::Share); char *oldBuf = mBuf; bool needToDelete=(mShareEnum==Take); + size_t newBytes = newCapacity + 1; + if(newBytes <= newCapacity) + { + // integer overflow + throw std::range_error("newCapacity too big"); + } + if(newCapacity > LocalAlloc) { - mBuf = new char[newCapacity+1]; + mBuf = new char[newBytes]; mShareEnum = Take; } else @@ -1133,7 +1123,7 @@ Data::md5(EncodingType type) const default: return digest.hex(); } - assert(0); + resip_assert(0); return digest.hex(); } @@ -1168,7 +1158,7 @@ Data::escaped() const int hi = (c & 0xF0)>>4; int low = (c & 0x0F); - + ret += hexmap[hi]; ret += hexmap[low]; } @@ -1214,7 +1204,7 @@ Data::charEncoded() const int hi = (c & 0xF0)>>4; int low = (c & 0x0F); - + ret += hexmap[hi]; ret += hexmap[low]; } @@ -1246,7 +1236,7 @@ Data::charUnencoded() const // !rwm! changed from high==0 || low==0 if (high == 0 && low == 0) { - assert(0); + resip_assert(0); // ugh return ret; } @@ -1537,6 +1527,42 @@ Data::hex() const return ret; } +Data +Data::fromHex() const +{ + bool oddSize = mSize & 1; + size_type resultSize = (mSize + (mSize & 1)) / 2; + Data ret(resultSize, Data::Preallocate); + + const unsigned char* p = (unsigned char*)mBuf; + char* r = ret.mBuf; + size_type i = 0; + if(oddSize) + { + if(!isHex(*p)) + { + throw DataException("Encountered non-hex digit", + __FILE__,__LINE__); + } + *r++ = inversehexmap[*p++]; + i++; + } + for ( ; i < mSize; i+=2) + { + const unsigned char high = *p++; + const unsigned char low = *p++; + if(!isHex(high) || !isHex(low)) + { + throw DataException("Encountered non-hex digit", + __FILE__,__LINE__); + } + + *r++ = (inversehexmap[high] << 4) + inversehexmap[low]; + } + ret.mSize = resultSize; + return ret; +} + Data& Data::lowercase() { @@ -1815,14 +1841,14 @@ Data::postfix(const Data& post) const Data Data::substr(size_type first, size_type count) const { - assert(first <= mSize); + resip_assert(first <= mSize); if ( count == Data::npos) { return Data(mBuf+first, mSize-first); } else { - assert(first + count <= mSize); + resip_assert(first + count <= mSize); return Data(mBuf+first, count); } } @@ -1849,7 +1875,7 @@ Data::replace(const Data& match, const Data& replaceWith, int max) { - assert(!match.empty()); + resip_assert(!match.empty()); int count = 0; @@ -1967,6 +1993,19 @@ Data::rawCaseInsensitiveHash(const unsigned char* c, size_t size) return ntohl((u_long)st); } +#if defined(RESIP_BIG_ENDIAN) || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) + +#if !defined (get16bits) +#define get16bits(d) ((((UInt32)(((const UInt8 *)(d))[0])) << 8)\ + +(UInt32)(((const UInt8 *)(d))[1]) ) +#endif + +#if !defined (get32bits) +#define get32bits(d) ((get16bits(d) << 16) + get16bits(d+2)) +#endif + +#else // little endian: + #undef get16bits #if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \ || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__) @@ -1987,6 +2026,7 @@ Data::rawCaseInsensitiveHash(const unsigned char* c, size_t size) #if !defined (get32bits) #define get32bits(d) ((get16bits(d+2) << 16) + get16bits(d)) #endif +#endif // This is intended to be a faster case-insensitive hash function that works // well when the buffer is a RFC 3261 token. @@ -2152,7 +2192,7 @@ switch(size) \ bool Data::sizeEqualCaseInsensitiveTokenCompare(const Data& rhs) const { - assert(mSize==rhs.mSize); + resip_assert(mSize==rhs.mSize); const char* d1(mBuf); const char* d2(rhs.mBuf); @@ -2163,7 +2203,7 @@ Data::sizeEqualCaseInsensitiveTokenCompare(const Data& rhs) const return true; } - int unalignedPrefix((ptrdiff_t)d1 & 3); + int unalignedPrefix(4-((ptrdiff_t)d1 & 3)); compUnalignedRemainder(d1, d2, unalignedPrefix); @@ -2256,7 +2296,7 @@ Data::escapeToStream(std::ostream& str, } int hi = (*p & 0xF0)>>4; int low = (*p & 0x0F); - + str << '%' << hex[hi] << hex[low]; anchor=++p; } @@ -2272,6 +2312,57 @@ Data::escapeToStream(std::ostream& str, return str; } +Data +Data::fromFile(const Data& filename) +{ + ifstream is; + is.open(filename.c_str(), ios::binary ); + if ( !is.is_open() ) + { + throw DataException("Could not read file ", + __FILE__,__LINE__); + } + + resip_assert(is.is_open()); + + int length = 0; + + // get length of file: +#if !defined(__MSL_CPP__) || (__MSL_CPP_ >= 0x00012000) + is.seekg (0, ios::end); + length = (int)is.tellg(); + is.seekg (0, ios::beg); +#else + // this is a work around for a bug in CodeWarrior 9's implementation of seekg. + // http://groups.google.ca/group/comp.sys.mac.programmer.codewarrior/browse_frm/thread/a4279eb75f3bd55a + FILE * tmpFile = fopen(filename.c_str(), "r+b"); + resip_assert(tmpFile != NULL); + fseek(tmpFile, 0, SEEK_END); + length = ftell(tmpFile); + fseek(tmpFile, 0, SEEK_SET); +#endif // __MWERKS__ + + // tellg/tell will return -1 if the stream is bad + if (length == -1) + { + throw DataException("Could not seek into file ", + __FILE__,__LINE__); + } + + // !jf! +1 is a workaround for a bug in Data::c_str() that adds the 0 without + // resizing. + char* buffer = new char [length+1]; + + // read data as a block: + is.read (buffer,length); + + Data target(Data::Take, buffer, length); + + is.close(); + + return target; +} + HashValueImp(resip::Data, data.hash()); static signed char base64Lookup[128] = @@ -2371,8 +2462,8 @@ Data::base64encode(bool useSafeSet) const unsigned char* codeChar = useSafeSet ? codeCharSafe : codeCharUnsafe; int srcLength = (int)this->size(); - unsigned int dstLimitLength = srcLength*4/3 + 1 + 2; // +2 for the == chars - unsigned char * dstData = new unsigned char[dstLimitLength]; + unsigned int dstLimitLength = 4 * (srcLength / 3 + (srcLength%3==0 ? 0 : 1)); + unsigned char * dstData = new unsigned char[dstLimitLength + 1]; unsigned int dstIndex = 0; const char * p = static_cast( this->data() ); @@ -2381,9 +2472,9 @@ Data::base64encode(bool useSafeSet) const { unsigned char codeBits = (p[index] & 0xfc)>>2; - assert(codeBits < 64); + resip_assert(codeBits < 64); dstData[dstIndex++] = codeChar[codeBits]; // c0 output - assert(dstIndex <= dstLimitLength); + resip_assert(dstIndex <= dstLimitLength); // do second codeBits codeBits = ((p[index]&0x3)<<4); @@ -2391,16 +2482,16 @@ Data::base64encode(bool useSafeSet) const { codeBits |= ((p[index+1]&0xf0)>>4); } - assert(codeBits < 64); + resip_assert(codeBits < 64); dstData[dstIndex++] = codeChar[codeBits]; // c1 output - assert(dstIndex <= dstLimitLength); + resip_assert(dstIndex <= dstLimitLength); if (index+1 >= srcLength) { dstData[dstIndex++] = codeChar[64]; - assert(dstIndex <= dstLimitLength); + resip_assert(dstIndex <= dstLimitLength); dstData[dstIndex++] = codeChar[64]; - assert(dstIndex <= dstLimitLength); + resip_assert(dstIndex <= dstLimitLength); break; // encoded d0 only } @@ -2410,25 +2501,26 @@ Data::base64encode(bool useSafeSet) const { codeBits |= ((p[index+2]&0xc0)>>6); } - assert(codeBits < 64); + resip_assert(codeBits < 64); dstData[dstIndex++] = codeChar[codeBits]; // c2 output - assert(dstIndex <= dstLimitLength); + resip_assert(dstIndex <= dstLimitLength); if (index+2 >= srcLength) { dstData[dstIndex++] = codeChar[64]; - assert(dstIndex <= dstLimitLength); + resip_assert(dstIndex <= dstLimitLength); break; // encoded d0 d1 only } // do fourth codeBits codeBits = ((p[index+2]&0x3f)); - assert(codeBits < 64); + resip_assert(codeBits < 64); dstData[dstIndex++] = codeChar[codeBits]; // c3 output - assert(dstIndex <= dstLimitLength); + resip_assert(dstIndex <= dstLimitLength); // outputed all d0,d1, and d2 } + dstData[dstIndex] = 0; return Data(Data::Take, reinterpret_cast(dstData), dstIndex); } diff --git a/src/libs/resiprocate/rutil/Data.hxx b/src/libs/resiprocate/rutil/Data.hxx index 0297a397..468e268d 100644 --- a/src/libs/resiprocate/rutil/Data.hxx +++ b/src/libs/resiprocate/rutil/Data.hxx @@ -8,7 +8,7 @@ #include #include #include -#include +#include "rutil/ResipAssert.h" #include "rutil/compat.hxx" #include "rutil/DataStream.hxx" @@ -88,7 +88,7 @@ class Data public: RESIP_HeapCount(Data); - typedef unsigned int size_type; + typedef UInt32 size_type; inline Data() : mBuf(mPreBuffer), @@ -187,7 +187,7 @@ class Data that value. (E.g. "Data(75)" will create a Data with length=2, and contents of 0x37 0x35). */ - explicit Data(int value); + explicit Data(Int32 value); /** Converts the passed in value into ascii-decimal @@ -195,15 +195,7 @@ class Data that value. (E.g. "Data(75)" will create a Data with length=2, and contents of 0x37 0x35). */ - explicit Data(unsigned long value); - - /** - Converts the passed in value into ascii-decimal - representation, and then creates a "Data" containing - that value. (E.g. "Data(75)" will create a Data - with length=2, and contents of 0x37 0x35). - */ - explicit Data(unsigned int value); + explicit Data(UInt32 value); /** Converts the passed in value into ascii-decimal @@ -280,6 +272,14 @@ class Data Data(ShareEnum, const char* buffer, size_type length); + /** + Creates a Data from the passed-in buffer. + + @see ShareEnum + */ + + Data(ShareEnum, const char* buffer, size_type length, size_type capacity); + /** Takes a null-terminated string and creates a buffer. @@ -347,7 +347,15 @@ class Data /** Functional equivalent of: *this = Data(buf, length) - but avoid the intermediate allocation and free. Also, + and Data& copy(const char *buf, size_type length) + but avoids an actual copy of the data if {other} is Shared + or Borrowed. Will have the same storage mode as {other}. + **/ + Data& duplicate(const Data& other); + + /** + Functional equivalent of: *this = Data(buf, length) + but avoids the intermediate allocation and free. Also, will never decrease capacity. Safe to call even if {buf} is part of {this}. @@ -455,7 +463,7 @@ class Data */ inline Data& operator+=(const char* str) { - assert(str); + resip_assert(str); return append(str, (size_type)strlen(str)); } @@ -483,7 +491,7 @@ class Data */ inline char& operator[](size_type p) { - assert(p < mSize); + resip_assert(p < mSize); own(); return mBuf[p]; } @@ -493,7 +501,7 @@ class Data */ inline char operator[](size_type p) const { - assert(p < mSize); + resip_assert(p < mSize); return mBuf[p]; } @@ -642,6 +650,11 @@ class Data */ Data hex() const; + /** + Returns the binary form of the hexadecimal string in this Data + */ + Data fromHex() const; + /** Returns a representation of the contents of the data with any non-printable characters escaped. @@ -732,7 +745,7 @@ class Data the capacity of the Data. It does not write terminating NULL, and thus is safe to use with external buffers. */ - Data& clear() { return truncate2(0); } + Data& clear() { return truncate2(0); }; /** Takes the contents of the Data and converts them to an @@ -935,12 +948,19 @@ class Data std::ostream& escapeToStream(std::ostream& str, const std::bitset<256>& shouldEscape) const; + static Data fromFile(const Data& filename); + private: /** @deprecated use Data(ShareEnum ...) */ Data(const char* buffer, size_type length, bool); + /** + Used by string constructors + */ + inline void initFromString(const char* str, size_type len); + /** Copies the contents of this data to a new buffer if the Data does not own the current buffer. @@ -994,6 +1014,9 @@ static bool invokeDataInit = Data::init(DataLocalSize(0)) inline bool Data::isHex(unsigned char c) { + // Shut up the warning about invokeDataInit defined, but not used + if(0){(void) invokeDataInit;} + return DataHelper::isCharHex[c]; } @@ -1081,10 +1104,6 @@ inline bool operator!=(const char* lhs, const Data& rhs) { return !(rhs == lhs); inline bool operator>(const char* lhs, const Data& rhs) { return rhs < lhs; } inline bool operator<=(const char* lhs, const Data& rhs) { return !(rhs < lhs); } inline bool operator>=(const char* lhs, const Data& rhs) { return !(lhs < rhs); } - -extern bool operator==(const Data& lhs, const Data& rhs); -extern bool operator<(const Data& lhs, const Data& rhs); - #ifndef RESIP_USE_STL_STREAMS EncodeStream& operator<<(EncodeStream& strm, const Data& d); #endif diff --git a/src/libs/resiprocate/rutil/DataStream.cxx b/src/libs/resiprocate/rutil/DataStream.cxx index 678f302e..88956f5a 100644 --- a/src/libs/resiprocate/rutil/DataStream.cxx +++ b/src/libs/resiprocate/rutil/DataStream.cxx @@ -2,7 +2,7 @@ #include "config.h" #endif -#include +#include "rutil/ResipAssert.h" #include "rutil/DataStream.hxx" #include "rutil/Data.hxx" @@ -42,7 +42,7 @@ size_t DataBuffer::readbuf(char *buf, size_t count) if (!buf) { - assert(0); + resip_assert(0); return 0; } @@ -140,7 +140,7 @@ oDataStream::oDataStream(Data& str) EncodeStream(this) { // don't call this with a read-only buffer! - assert(str.mShareEnum != Data::Share); + resip_assert(str.mShareEnum != Data::Share); } oDataStream::~oDataStream() @@ -170,7 +170,7 @@ DataStream::DataStream(Data& str) #endif { // don't call this with a read-only buffer! - assert(str.mShareEnum != Data::Share); + resip_assert(str.mShareEnum != Data::Share); } DataStream::~DataStream() diff --git a/src/libs/resiprocate/rutil/DigestStream.hxx b/src/libs/resiprocate/rutil/DigestStream.hxx index dc2f4a02..85a07896 100644 --- a/src/libs/resiprocate/rutil/DigestStream.hxx +++ b/src/libs/resiprocate/rutil/DigestStream.hxx @@ -3,7 +3,7 @@ #include #include "rutil/Data.hxx" -#include +#include namespace resip { diff --git a/src/libs/resiprocate/rutil/DinkyPool.hxx b/src/libs/resiprocate/rutil/DinkyPool.hxx index d57ad8a9..3dc3bb99 100644 --- a/src/libs/resiprocate/rutil/DinkyPool.hxx +++ b/src/libs/resiprocate/rutil/DinkyPool.hxx @@ -20,9 +20,7 @@ template class DinkyPool : public PoolBase { public: - DinkyPool() : - count(0){} - + DinkyPool() : count(0), heapBytes(0) {} ~DinkyPool(){} void* allocate(size_t size) @@ -33,6 +31,7 @@ class DinkyPool : public PoolBase count+=(size+7)/8; return result; } + heapBytes += size; return ::operator new(size); } @@ -49,6 +48,11 @@ class DinkyPool : public PoolBase { return std::numeric_limits::max(); } + + size_t getHeapBytes() const { return heapBytes; } + size_t getPoolBytes() const { return count*8; } + size_t getPoolSizeBytes() const { return sizeof(mBuf); } + private: // disabled DinkyPool& operator=(const DinkyPool& rhs); @@ -56,6 +60,7 @@ class DinkyPool : public PoolBase size_t count; // 8-byte chunks alloced so far char mBuf[(S+7)/8][8]; // 8-byte chunks for alignment + size_t heapBytes; }; } diff --git a/src/libs/resiprocate/rutil/DnsUtil.cxx b/src/libs/resiprocate/rutil/DnsUtil.cxx index 3560ede3..fae042ff 100644 --- a/src/libs/resiprocate/rutil/DnsUtil.cxx +++ b/src/libs/resiprocate/rutil/DnsUtil.cxx @@ -56,7 +56,7 @@ DnsUtil::lookupARecords(const Data& host) struct hostent hostbuf; char buffer[8192]; ret = gethostbyname_r( host.c_str(), &hostbuf, buffer, sizeof(buffer), &result, &herrno); - assert (ret != ERANGE); + resip_assert (ret != ERANGE); #elif defined(__QNX__) || defined(__SUNPRO_CC) struct hostent hostbuf; char buffer[8192]; @@ -67,7 +67,7 @@ DnsUtil::lookupARecords(const Data& host) result = gethostbyname( host.c_str() ); ret = (result == 0); #else - assert(0); + resip_assert(0); return names; #endif @@ -96,8 +96,8 @@ DnsUtil::lookupARecords(const Data& host) } else { - assert(result); - assert(result->h_length == 4); + resip_assert(result); + resip_assert(result->h_length == 4); char str[256]; for (char** pptr = result->h_addr_list; *pptr != 0; pptr++) { @@ -113,59 +113,75 @@ DnsUtil::lookupARecords(const Data& host) } } - -Data +// The following statics ensure we can initialize the static storage of +// localHostName at runtime, instead of at global static initialization time. +// Under windows, when building a DLL you cannot call initNetwork and +// other socket API's reliably from DLLMain, so we need to delay this call. +// We use the gate bool to ensure we don't need to do a mutex check everytime +// and we use a Mutex to ensure that multiple threads can invokve getLocalHostName +// for the first time, at the same time. +static Mutex getLocalHostNameInitializerMutex; +static bool getLocalHostNameInitializerGate = false; +static Data localHostName; +const Data& DnsUtil::getLocalHostName() { - char buffer[MAXHOSTNAMELEN]; - initNetwork(); - buffer[0] = '\0'; - if (gethostname(buffer,sizeof(buffer)) == -1) + if(!getLocalHostNameInitializerGate) { - int err = getErrno(); - switch (err) + Lock lock(getLocalHostNameInitializerMutex); + char buffer[MAXHOSTNAMELEN + 1]; + initNetwork(); + // can't assume the name is NUL terminated when truncation occurs, + // so insert trailing NUL here + buffer[0] = buffer[MAXHOSTNAMELEN] = '\0'; + if (gethostname(buffer,sizeof(buffer)-1) == -1) { + int err = getErrno(); + switch (err) + { // !RjS! This makes no sense for non-windows. The // current hack (see the #define in .hxx) needs // to be reworked. - case WSANOTINITIALISED: - CritLog( << "could not find local hostname because network not initialized:" << strerror(err) ); - break; - default: - CritLog( << "could not find local hostname:" << strerror(err) ); - break; + case WSANOTINITIALISED: + CritLog( << "could not find local hostname because network not initialized:" << strerror(err) ); + break; + default: + CritLog( << "could not find local hostname:" << strerror(err) ); + break; + } + throw Exception("could not find local hostname",__FILE__,__LINE__); } - throw Exception("could not find local hostname",__FILE__,__LINE__); - } - struct addrinfo* result=0; - struct addrinfo hints; - memset(&hints, 0, sizeof(hints)); - hints.ai_flags |= AI_CANONNAME; - hints.ai_family |= AF_UNSPEC; - int res = getaddrinfo(buffer, 0, &hints, &result); - if (!res) - { - // !jf! this should really use the Data class - if (strchr(result->ai_canonname, '.') != 0) + struct addrinfo* result=0; + struct addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_flags |= AI_CANONNAME; + hints.ai_family |= AF_UNSPEC; + int res = getaddrinfo(buffer, 0, &hints, &result); + if (!res) { - strncpy(buffer, result->ai_canonname, sizeof(buffer)); + // !jf! this should really use the Data class + if (strchr(result->ai_canonname, '.') != 0) + { + strncpy(buffer, result->ai_canonname, sizeof(buffer)); + } + else + { + InfoLog( << "local hostname does not contain a domain part " << buffer); + } + freeaddrinfo(result); } - else + else { - InfoLog( << "local hostname does not contain a domain part " << buffer); + InfoLog (<< "Couldn't determine local hostname. Error was: " << gai_strerror(res) << ". Returning empty string"); } - freeaddrinfo(result); - } - else - { - InfoLog (<< "Couldn't determine local hostname. Error was: " << gai_strerror(res) << ". Returning empty string"); - } - return Data(buffer); + localHostName = buffer; + getLocalHostNameInitializerGate = true; + } + return localHostName; } - Data DnsUtil::getLocalDomainName() { @@ -177,12 +193,15 @@ DnsUtil::getLocalDomainName() } else { -#if defined( __APPLE__ ) || defined( WIN32 ) || defined(__SUNPRO_CC) || defined(__sun__) || defined(__ANDROID_API__) +#if defined( __APPLE__ ) || defined( WIN32 ) || defined(__SUNPRO_CC) || defined(__sun__) || defined( __ANDROID__ ) throw Exception("Could not find domainname in local hostname",__FILE__,__LINE__); #else DebugLog( << "No domain portion in hostname <" << lhn << ">, so using getdomainname"); - char buffer[MAXHOSTNAMELEN]; - if (int e = getdomainname(buffer,sizeof(buffer)) == -1) + char buffer[MAXHOSTNAMELEN + 1]; + // can't assume the name is NUL terminated when truncation occurs, + // so insert trailing NUL here + buffer[0] = buffer[MAXHOSTNAMELEN] = '\0'; + if (int e = getdomainname(buffer,sizeof(buffer)-1) == -1) { if ( e != 0 ) { @@ -281,7 +300,7 @@ DnsUtil::isIpV4Address(const Data& ipAddress) // .bwc. I have tried using std::bitset instead of the 0 <= *last <= 9 // check, but it is slower. - while(*last >= '0' && *last <= '9' && last - first <= 3 && last != end) + while(last != end && *last >= '0' && *last <= '9' && last - first <= 3) { // Skip at most 3 decimals, without going past the end of the buffer. ++last; @@ -330,7 +349,7 @@ DnsUtil::isIpV4Address(const Data& ipAddress) if(octets < 4) { - if(*last == '.') + if(last != end && *last == '.') { // Skip over the '.' ++last; @@ -446,7 +465,7 @@ DnsUtil::getInterfaces(const Data& matching) struct ifconf ifc; int s = socket( AF_INET, SOCK_DGRAM, 0 ); - assert( s != INVALID_SOCKET ); // can run out of file descs + resip_assert( s != INVALID_SOCKET ); // can run out of file descs const int len = 100 * sizeof(struct ifreq); int maxRet = 40; @@ -538,10 +557,14 @@ DnsUtil::getInterfaces(const Data& matching) continue; } - if ( (name[0]<'A') || (name[0]>'z') ) // should never happen + if ( ( (name[0]<'A') || (name[0]>'z') ) +#if defined(__MACH__) && defined(__GNU__) // for GNU HURD + && (name[0] != '/') +#endif + ) // should never happen { DebugLog (<< " ignore because: name looks bogus"); - assert(0); + resip_assert(0); continue; } @@ -565,7 +588,7 @@ DnsUtil::getInterfaces(const Data& matching) return results; } #else - assert(0); + resip_assert(0); #endif #endif diff --git a/src/libs/resiprocate/rutil/DnsUtil.hxx b/src/libs/resiprocate/rutil/DnsUtil.hxx index 414a3049..b311563a 100644 --- a/src/libs/resiprocate/rutil/DnsUtil.hxx +++ b/src/libs/resiprocate/rutil/DnsUtil.hxx @@ -43,7 +43,7 @@ class DnsUtil * currently knows it ala gethostname(3) */ - static Data getLocalHostName(); + static const Data& getLocalHostName(); /** @returns the suffix after the first "." in whatever getLocalHostName returns */ static Data getLocalDomainName(); diff --git a/src/libs/resiprocate/rutil/FdPoll.cxx b/src/libs/resiprocate/rutil/FdPoll.cxx index 19a17197..a9d84e16 100644 --- a/src/libs/resiprocate/rutil/FdPoll.cxx +++ b/src/libs/resiprocate/rutil/FdPoll.cxx @@ -1,947 +1,1315 @@ -#include -#include - -#include "rutil/FdPoll.hxx" -#include "rutil/FdSetIOObserver.hxx" -#include "rutil/Logger.hxx" -#include "rutil/BaseException.hxx" - -#include - -#ifdef RESIP_POLL_IMPL_EPOLL -# include -#endif - -using namespace resip; -#define RESIPROCATE_SUBSYSTEM Subsystem::SIP - -/***************************************************************** - * - * FdPollItemIf and FdPollItemBase impl - * - *****************************************************************/ - -FdPollItemIf::~FdPollItemIf() -{ -} - -FdPollItemBase::FdPollItemBase(FdPollGrp *grp, Socket fd, FdPollEventMask mask) : - mPollGrp(grp), mPollSocket(fd) -{ - if (mPollGrp) - mPollHandle = mPollGrp->addPollItem(fd, mask, this); -} - -FdPollItemBase::~FdPollItemBase() -{ - if (mPollGrp) - mPollGrp->delPollItem(mPollHandle); -} - -/***************************************************************** - * - * FdPollGrp - * - * Implementation for some of the base class methods. - * While some of these are epoll-specific, we can (and do) implement - * them at this level. - * For now we use delegation for the impl data structures - * rather than inhieritance. Long term, not sure which will - * be cleaner. - * - *****************************************************************/ - -FdPollGrp::FdPollGrp() -{ -} - -FdPollGrp::~FdPollGrp() -{ -} - -void -FdPollGrp::processItem(FdPollItemIf *item, FdPollEventMask mask) -{ - try - { - item->processPollEvent( mask ); - } - catch(BaseException& e) - { - // kill it or something? - ErrLog(<<"Exception thrown for FdPollItem: " << e); - } - item = NULL; // WATCHOUT: item may have been deleted - /* - * If FPEM_Error was reported, should really make sure it was deleted - * or disabled from polling. Otherwise were in stuck in an infinite loop. - * But difficult to do that checking robustly until we serials the items. - */ -} - -int -FdPollGrp::getEPollFd() const -{ - return -1; -} - -/***************************************************************** - * - * FdPollImplFdSet - * - *****************************************************************/ - -/** - This is an implemention built around FdSet, which in turn is built - around select(). As such, it should work on all platforms. The - number of concurrent fds is limited by your platform's select call. -**/ - -namespace resip -{ - -class FdPollItemFdSetInfo -{ - public: - FdPollItemFdSetInfo() - : mSocketFd(INVALID_SOCKET), mItemObj(0), mEvMask(0), mNextIdx(-1) - { - } - - Socket mSocketFd; // socket - FdPollItemIf* mItemObj; // callback object - FdPollEventMask mEvMask; // events the application wants - int mNextIdx; // next link for live or free list -}; - - - -class FdPollImplFdSet : public FdPollGrp -{ - public: - FdPollImplFdSet(); - ~FdPollImplFdSet(); - - virtual const char* getImplName() const { return "fdset"; } - - virtual FdPollItemHandle addPollItem(Socket fd, - FdPollEventMask newMask, FdPollItemIf *item); - virtual void modPollItem(FdPollItemHandle handle, - FdPollEventMask newMask); - virtual void delPollItem(FdPollItemHandle handle); - - virtual void registerFdSetIOObserver(FdSetIOObserver& observer); - virtual void unregisterFdSetIOObserver(FdSetIOObserver& observer); - - virtual bool waitAndProcess(int ms=0); - virtual void buildFdSet(FdSet& fdSet); - virtual bool processFdSet(FdSet& fdset); - - protected: - virtual unsigned int buildFdSetForObservers(FdSet& fdSet); - void killCache(Socket fd); - - std::vector mItems; - std::vector mFdSetObservers; - - /* - * The ItemInfos are stored in a vector (above) that grows as needed. - * Every Info is in one single-linked list, either the "Live" list - * or the "Free" list. This is somewhat like using - * boost::intrusive::slist, except we use indices not pointers - * since the vector may reallocate and move around. - */ - int mLiveHeadIdx; - int mFreeHeadIdx; - - /* - * This is temporary cache of poll events. It is a member (and - * not on stack) for two reasons: (1) simpler memory management, - * and (2) so delPollItem() can traverse it and clean up. - */ - FdSet mSelectSet; -}; - -}; // namespace - -// NOTE: shift by one so that idx=0 doesn't have NULL handle -#define IMPL_FDSET_IdxToHandle(idx) ((FdPollItemHandle)( ((char*)0) + ((idx)+1) )) -#define IMPL_FDSET_HandleToIdx(handle) ( ((char*)(handle)) - ((char*)0) - 1) - -FdPollImplFdSet::FdPollImplFdSet() - : mLiveHeadIdx(-1), mFreeHeadIdx(-1) -{ -} - -FdPollImplFdSet::~FdPollImplFdSet() -{ - // assert( mEvCacheLen == 0 ); // poll not active - unsigned itemIdx; - for (itemIdx=0; itemIdx < mItems.size(); itemIdx++) - { - FdPollItemFdSetInfo& info = mItems[itemIdx]; - if (info.mItemObj) - { - CritLog(<<"FdPollItem idx="<= 0 ) - { - useIdx = mFreeHeadIdx; - mFreeHeadIdx = mItems[useIdx].mNextIdx; - } - else - { - useIdx = mItems.size(); - unsigned newsz = 10+useIdx + useIdx/3; // plus 30% margin - // WATCHOUT: below may trigger re-allocation, invalidating any iters - // We don't use iters (only indices), but need to watchout for - // cached pointers - mItems.resize(newsz); - // push new items onto the free list - unsigned itemIdx; - for (itemIdx=useIdx+1; itemIdx < newsz; itemIdx++) - { - mItems[itemIdx].mNextIdx = mFreeHeadIdx; - mFreeHeadIdx = itemIdx; - } - } - FdPollItemFdSetInfo& info = mItems[useIdx]; - info.mItemObj = item; - info.mSocketFd = fd; - info.mEvMask = newMask; - info.mNextIdx = mLiveHeadIdx; - mLiveHeadIdx = useIdx; - - if ( info.mEvMask & FPEM_Read ) - mSelectSet.setRead(info.mSocketFd); - if ( info.mEvMask & FPEM_Write ) - mSelectSet.setWrite(info.mSocketFd); - if ( info.mEvMask & FPEM_Error ) - mSelectSet.setExcept(info.mSocketFd); - - return IMPL_FDSET_IdxToHandle(useIdx); -} - -void -FdPollImplFdSet::modPollItem(const FdPollItemHandle handle, FdPollEventMask newMask) -{ - int useIdx = IMPL_FDSET_HandleToIdx(handle); - assert(useIdx>=0 && ((unsigned)useIdx) < mItems.size()); - FdPollItemFdSetInfo& info = mItems[useIdx]; - assert(info.mSocketFd!=INVALID_SOCKET); - assert(info.mItemObj); - info.mEvMask = newMask; - - killCache(info.mSocketFd); - if ( info.mEvMask & FPEM_Read ) - mSelectSet.setRead(info.mSocketFd); - if ( info.mEvMask & FPEM_Write ) - mSelectSet.setWrite(info.mSocketFd); - if ( info.mEvMask & FPEM_Error ) - mSelectSet.setExcept(info.mSocketFd); -} - -void -FdPollImplFdSet::delPollItem(FdPollItemHandle handle) -{ - int useIdx = IMPL_FDSET_HandleToIdx(handle); - //DebugLog(<<"deleting epoll item fd="<=0 && ((unsigned)useIdx) < mItems.size()); - FdPollItemFdSetInfo& info = mItems[useIdx]; - assert(info.mSocketFd!=INVALID_SOCKET); - assert(info.mItemObj); - killCache(info.mSocketFd); - // we don't change the lists here since the select loop might - // be iterating. Just mark it as dead and gc it later. - info.mSocketFd = INVALID_SOCKET; - info.mItemObj = NULL; - info.mEvMask = 0; -} - -void -FdPollImplFdSet::registerFdSetIOObserver(FdSetIOObserver& observer) -{ - // .bwc. Could make this sorted. Probably not worth the trouble. - mFdSetObservers.push_back(&observer); -} - -void -FdPollImplFdSet::unregisterFdSetIOObserver(FdSetIOObserver& observer) -{ - // .bwc. Could make this sorted. Probably not worth the trouble. - for(std::vector::iterator o=mFdSetObservers.begin(); - o!=mFdSetObservers.end();++o) - { - if(*o==&observer) - { - mFdSetObservers.erase(o); - return; - } - } -} - - -/** - There is a boundary case: - 1. fdA and fdB are added to epoll - 2. events occur on fdA and fdB - 2. waitAndProcess() select and gets events for fdA and fdB - 3. handler for fdA deletes fdB (closing fd) - 5. handler (same or differnt) opens new fd, gets fd as fdB, and adds - it to us but under different object - 6. cache processes "old" fdB event masks but binds it to the new - (wrong) object - - For read or write events it would be relatively harmless to - pass these events to the new object (all objects should be prepared - to get EAGAIN). But passing an error event could incorrectly kill - the wrong object. - - To prevent this, we kill the events in the mSelectSet. In POSIX, - I'm pretty sure this is always safe. In Windows, I don't know what - happens if the fd isn't already in the FdSet. -**/ -void -FdPollImplFdSet::killCache(Socket fd) -{ - mSelectSet.clear(fd); -} - - -bool -FdPollImplFdSet::waitAndProcess(int ms) -{ - if(ms<0) - { - // On Linux, passing a NULL timeout ptr to select() will wait - // forever, but I don't want to trust that on all platforms. - // So use 60sec as approximation of "forever". - // Use 60sec b/c fits in short. - ms = 60*1000; - } - - // Create copy; is cheaper than rebuilding from scratch every time. - FdSet fdset(mSelectSet); - ms = resipMin(buildFdSetForObservers(fdset), (unsigned int)ms); - - // Step 2: Select on our built FdSet - int numReady = fdset.selectMilliSeconds(ms); - if ( numReady < 0 ) - { - int err = getErrno(); - if ( err!=EINTR ) - { - CritLog(<<"select() failed: "<::iterator o=mFdSetObservers.begin(); - o!=mFdSetObservers.end();++o) - { - (*o)->buildFdSet(fdset); - ms = resipMin(ms, (*o)->getTimeTillNextProcessMS()); - } - return ms; -} - -bool -FdPollImplFdSet::processFdSet(FdSet& fdset) -{ - bool didsomething = false; - int itemIdx; - int* prevIdxRef = &mLiveHeadIdx; - int loopCnt = 0; - - // Step 3: Invoke callbacks - // Could take advantage of early via numReady, but book keeping - // seems tedious especially if items are deleted during walk - while ( (itemIdx = *prevIdxRef) != -1 ) - { - FdPollItemFdSetInfo& info = mItems[itemIdx]; - assert( ++loopCnt < 99123123 ); - if ( info.mEvMask!=0 && info.mItemObj!=0 ) - { - FdPollEventMask usrMask = 0; - assert(info.mSocketFd!=INVALID_SOCKET); - if ( fdset.readyToRead(info.mSocketFd) ) - usrMask |= FPEM_Read; - if ( fdset.readyToWrite(info.mSocketFd) ) - usrMask |= FPEM_Write; - if ( fdset.hasException(info.mSocketFd) ) - usrMask |= FPEM_Error; - - // items's mask may have changed since select occured, so mask it again - usrMask &= info.mEvMask; - if ( usrMask ) - { - processItem(info.mItemObj, usrMask); - didsomething = true; - } - } - // WATCHOUT: {info} may have moved due to add during processItem() - // set pointer using index, not {info} - prevIdxRef = &mItems[itemIdx].mNextIdx; - } - - // Step 3.1: Invoke callbacks on any FdSetIOObservers - for(std::vector::iterator o=mFdSetObservers.begin(); - o!=mFdSetObservers.end();++o) - { - // This is not strictly correct; we do not know if this observer actually - // put any FDs in the set, or if any of these FDs ended up being ready. - // Eventually, it would be nice to have process() return whether any - // actual IO was performed. - didsomething=true; - (*o)->process(fdset); - } - - return didsomething; -} - - -// end of ImplFdSet - - -/***************************************************************** - * - * FdPollImplEpoll - * - *****************************************************************/ - -#ifdef RESIP_POLL_IMPL_EPOLL - -namespace resip -{ - - - -class FdPollImplEpoll : public FdPollGrp -{ - public: - FdPollImplEpoll(); - ~FdPollImplEpoll(); - - virtual const char* getImplName() const { return "epoll"; } - - virtual FdPollItemHandle addPollItem(Socket fd, - FdPollEventMask newMask, FdPollItemIf *item); - virtual void modPollItem(FdPollItemHandle handle, - FdPollEventMask newMask); - virtual void delPollItem(FdPollItemHandle handle); - virtual void registerFdSetIOObserver(FdSetIOObserver& observer); - virtual void unregisterFdSetIOObserver(FdSetIOObserver& observer); - - virtual bool waitAndProcess(int ms=0); - - /// See baseclass. This is integer fd, not Socket - virtual int getEPollFd() const { return mEPollFd; } - virtual void buildFdSet(FdSet& fdSet); - virtual bool processFdSet(FdSet& fdset); - - protected: - void killCache(Socket fd); - bool epollWait(int ms); - - std::vector mItems; // indexed by fd - std::vector mFdSetObservers; - int mEPollFd; // from epoll_create() - - /* - * This is temporary cache of poll events. It is a member (and - * not on stack) for two reasons: (1) simpler memory management, - * and (2) so delPollItem() can traverse it and clean up. - */ - std::vector mEvCache; - int mEvCacheCur; - int mEvCacheLen; -}; - -}; // namespace - -// NOTE: shift by one so that fd=0 doesn't have NULL handle -#define IMPL_EPOLL_FdToHandle(fd) ((FdPollItemHandle)( ((char*)0) + ((fd)+1) )) -#define IMPL_EPOLL_HandleToFd(handle) ( ((char*)(handle)) - ((char*)0) - 1) - -FdPollImplEpoll::FdPollImplEpoll() : - mEPollFd(-1) -{ - int sz = 200; // ignored - if ( (mEPollFd = epoll_create(sz)) < 0 ) - { - CritLog(<<"epoll_create() failed: "<=0); - //DebugLog(<<"adding epoll item fd="<=0 && ((unsigned)fd) < mItems.size()); - assert(mItems[fd] != NULL); - - struct epoll_event ev; - memset(&ev, 0, sizeof(ev)); // make valgrind happy - ev.events = CvtUsrToSysMask(newMask); - ev.data.fd = fd; - if (epoll_ctl(mEPollFd, EPOLL_CTL_MOD, fd, &ev) < 0) - { - CritLog(<<"epoll_ctl(MOD) failed: "<::iterator o=mFdSetObservers.begin(); - o!=mFdSetObservers.end();++o) - { - if(*o==&observer) - { - mFdSetObservers.erase(o); - return; - } - } -} - - -/** - There is a boundary case: - 1. fdA and fdB are added to epoll - 2. events occur on fdA and fdB - 2. waitAndProcess() reads queue for fdA and fdB into its cache - 3. handler for fdA deletes fdB (closing fd) - 5. handler (same or differnt) opens new fd, gets fd as fdB, and adds - it to epoll but under different object - 6. cache processes "old" fdB but binds it to the new (wrong) object - - For read or write events it would be relatively harmless to - pass these events to the new object (all objects should be prepared - to get EAGAIN). But passing an error event could incorrectly kill - the wrong object. - - To prevent this, we walk the cache and kill any events for our fd. - In theory, the kernel does the same. - - An alternative approach would be use a serial number counter, - as a lifetime indicator for each fd, and store both a 32-bit serial - and 32-bit fd into the epoll event in the kernel. We could then - recognize stale events. -**/ -void -FdPollImplEpoll::killCache(int fd) -{ - int ne; - for (ne=mEvCacheCur; ne < mEvCacheLen; ne++) - { - if ( mEvCache[ne].data.fd == fd ) - { - mEvCache[ne].data.fd = INVALID_SOCKET; - } - } -} - - -bool -FdPollImplEpoll::waitAndProcess(int ms) -{ - bool didSomething = false; - int waitMs = ms; - assert( mEvCache.size() > 0 ); - - if(!mFdSetObservers.empty()) - { - if(ms < 0) - { - ms=INT_MAX; - waitMs=INT_MAX; - } - - // Warning; big fat hack. This is likely to be a tad inefficient, and this - // is why we want to move away from FdSetIOObserver, at least in - // conjunction with stuff that uses epoll. The only holdout right now is - // the cares DNS code. - // Also, a fair bit of duplicated code here. - - FdSet fdset; - buildFdSet(fdset); // add our epoll fd, and fds from mFdSetObservers - - for(std::vector::iterator o=mFdSetObservers.begin(); - o!=mFdSetObservers.end();++o) - { - ms = resipMin((unsigned int)ms, (*o)->getTimeTillNextProcessMS()); - } - - // Avoid waiting too much; this ends up overcompensating unless the - // select() times out, but it is better than just setting to 0. We could - // record the time taken by the select() call, but this would be more - // expensive. - waitMs -= ms; - - int numReady = fdset.selectMilliSeconds(ms); - - // Should we still do this? If our epoll fd is not marked ready, should we - // do the epoll_wait below? I want to say no... - if ( numReady < 0 ) - { - int err = getErrno(); - if ( err!=EINTR ) - { - CritLog(<<"select() failed: "<::iterator o=mFdSetObservers.begin(); - o!=mFdSetObservers.end();++o) - { - (*o)->buildFdSet(fdset); - } -} - -bool -FdPollImplEpoll::processFdSet(FdSet& fdset) -{ - bool didsomething=false; - for(std::vector::iterator o=mFdSetObservers.begin(); - o!=mFdSetObservers.end();++o) - { - // This is not strictly correct; we do not know if this observer - // actually put any FDs in the set, or if any of these FDs ended up - // being ready. - // Eventually, it would be nice to have process() return whether any - // actual IO was performed. - didsomething=true; - (*o)->process(fdset); - } - - int fd = getEPollFd(); - if (fd !=- 1 && fdset.readyToRead(fd)) - { - epollWait(0); - } - return didsomething; -} - -bool -FdPollImplEpoll::epollWait(int waitMs) -{ - bool maybeMore; - bool didsomething=false; - do - { - int nfds = epoll_wait(mEPollFd, &mEvCache.front(), mEvCache.size(), waitMs); - if (nfds < 0) - { - if (errno==EINTR) - { - // signal handler (like alarm) broke loop. generally ok - DebugLog(<<"epoll_wait() broken by EINTR"); - nfds = 0; // clean-up and return. could add return code - // to indicate this, but not needed by us - } - else - { - CritLog(<<"epoll_wait() failed: " << strerror(errno)); - abort(); // TBD: just throw instead? - } - } - waitMs = 0; // don't wait anymore - mEvCacheLen = nfds; // for killCache() - maybeMore = ( ((unsigned)nfds)==mEvCache.size()) ? 1 : 0; - int ne; - for (ne=0; ne < nfds; ne++) - { - int fd = mEvCache[ne].data.fd; - if (fd == INVALID_SOCKET) - { - continue; // was killed by killCache() - } - int sysEvtMask = mEvCache[ne].events; - assert(fd>=0 && fd < (int)mItems.size()); - FdPollItemIf *item = mItems[fd]; - if (item == NULL) - { - /* this can happen if item was deleted after - * event was generated in kernel, etc. */ - continue; - } - mEvCacheCur = ne; // for killCache() - processItem(item, CvtSysToUsrMask(sysEvtMask)); - item = NULL; // WATCHOUT: item may not exist anymore - didsomething = true; - } - mEvCacheLen = 0; - } while (maybeMore); - return didsomething; -} - -#endif // RESIP_POLL_IMPL_EPOLL - -/***************************************************************** - * - * Factory - * - *****************************************************************/ - -/*static*/FdPollGrp* -FdPollGrp::create(const char *implName) -{ - if ( implName==0 || implName[0]==0 || strcmp(implName,"event")==0 ) - implName = 0; // pick the first (best) one supported -#ifdef RESIP_POLL_IMPL_EPOLL - if ( implName==0 || strcmp(implName,"epoll")==0 ) - { - return new FdPollImplEpoll(); - } -#endif - if ( implName==0 || strcmp(implName,"fdset")==0 ) - { - return new FdPollImplFdSet(); - } - assert(0); - return NULL; -} - -/*static*/const char* -FdPollGrp::getImplList() -{ - // .kw. this isn't really scalable approach if we get a lot of impls - // but it works for now -#ifdef RESIP_POLL_IMPL_EPOLL - return "event|epoll|fdset"; -#else - return "event|fdset"; -#endif -} - -/* ==================================================================== - * The Vovida Software License, Version 1.0 - * - * Copyright (c) 2000-2005 Jacob Butcher - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The names "VOCAL", "Vovida Open Communication Application Library", - * and "Vovida Open Communication Application Library (VOCAL)" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact vocal@vovida.org. - * - * 4. Products derived from this software may not be called "VOCAL", nor - * may "VOCAL" appear in their name, without prior written - * permission of Vovida Networks, Inc. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND - * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA - * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES - * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE - * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * vi: set shiftwidth=3 expandtab: - */ +#include "rutil/ResipAssert.h" +#include + +#include "rutil/FdPoll.hxx" +#include "rutil/FdSetIOObserver.hxx" +#include "rutil/Logger.hxx" +#include "rutil/BaseException.hxx" + +#include + +#ifdef RESIP_POLL_IMPL_EPOLL +# include +#endif + +using namespace resip; +#define RESIPROCATE_SUBSYSTEM Subsystem::SIP + +/***************************************************************** + * + * FdPollItemIf and FdPollItemBase impl + * + *****************************************************************/ + +FdPollItemIf::~FdPollItemIf() +{ +} + +FdPollItemBase::FdPollItemBase(FdPollGrp *grp, Socket fd, FdPollEventMask mask) : + mPollGrp(grp), mPollSocket(fd), mPollHandle(0) +{ + if(mPollGrp) + { + mPollHandle = mPollGrp->addPollItem(fd, mask, this); + } +} + +FdPollItemBase::~FdPollItemBase() +{ + if(mPollGrp) + { + mPollGrp->delPollItem(mPollHandle); + } +} + +/***************************************************************** + * + * FdPollGrp + * + * Implementation for some of the base class methods. + * While some of these are epoll-specific, we can (and do) implement + * them at this level. + * For now we use delegation for the impl data structures + * rather than inhieritance. Long term, not sure which will + * be cleaner. + * + *****************************************************************/ + +FdPollGrp::FdPollGrp() +{ +} + +FdPollGrp::~FdPollGrp() +{ +} + +void +FdPollGrp::processItem(FdPollItemIf *item, FdPollEventMask mask) +{ + try + { + item->processPollEvent( mask ); + } + catch(BaseException& e) + { + // kill it or something? + ErrLog(<<"Exception thrown for FdPollItem: " << e); + } + item = NULL; // WATCHOUT: item may have been deleted + /* + * If FPEM_Error was reported, should really make sure it was deleted + * or disabled from polling. Otherwise were in stuck in an infinite loop. + * But difficult to do that checking robustly until we serials the items. + */ +} + +int +FdPollGrp::getEPollFd() const +{ + return -1; +} + +/***************************************************************** + * + * FdPollImplFdSet + * + *****************************************************************/ + +/** + This is an implemention built around FdSet, which in turn is built + around select(). As such, it should work on all platforms. The + number of concurrent fds is limited by your platform's select call. +**/ + +namespace resip +{ + +class FdPollItemFdSetInfo +{ + public: + FdPollItemFdSetInfo() + : mSocketFd(INVALID_SOCKET), mItemObj(0), mEvMask(0), mNextIdx(-1) + { + } + + Socket mSocketFd; // socket + FdPollItemIf* mItemObj; // callback object + FdPollEventMask mEvMask; // events the application wants + int mNextIdx; // next link for live or free list +}; + +class FdPollImplFdSet : public FdPollGrp +{ + public: + FdPollImplFdSet(); + ~FdPollImplFdSet(); + + virtual const char* getImplName() const { return "fdset"; } + virtual ImplType getImplType() const { return FdSetImpl; } + + virtual FdPollItemHandle addPollItem(Socket fd, FdPollEventMask newMask, FdPollItemIf *item); + virtual void modPollItem(FdPollItemHandle handle, FdPollEventMask newMask); + virtual void delPollItem(FdPollItemHandle handle); + + virtual void registerFdSetIOObserver(FdSetIOObserver& observer); + virtual void unregisterFdSetIOObserver(FdSetIOObserver& observer); + + virtual bool waitAndProcess(int ms=0); + virtual void buildFdSet(FdSet& fdSet); + virtual bool processFdSet(FdSet& fdset); + + protected: + virtual unsigned int buildFdSetForObservers(FdSet& fdSet); + void killCache(Socket fd); + + std::vector mItems; + std::vector mFdSetObservers; + + /* + * The ItemInfos are stored in a vector (above) that grows as needed. + * Every Info is in one single-linked list, either the "Live" list + * or the "Free" list. This is somewhat like using + * boost::intrusive::slist, except we use indices not pointers + * since the vector may reallocate and move around. + */ + int mLiveHeadIdx; + int mFreeHeadIdx; + + /* + * This is temporary cache of poll events. It is a member (and + * not on stack) for two reasons: (1) simpler memory management, + * and (2) so delPollItem() can traverse it and clean up. + */ + FdSet mSelectSet; +}; + +}; // namespace + +// NOTE: shift by one so that idx=0 doesn't have NULL handle +#define IMPL_FDSET_IdxToHandle(idx) ((FdPollItemHandle)( ((char*)0) + ((idx)+1) )) +#define IMPL_FDSET_HandleToIdx(handle) ( ((char*)(handle)) - ((char*)0) - 1) + +FdPollImplFdSet::FdPollImplFdSet() + : mLiveHeadIdx(-1), mFreeHeadIdx(-1) +{ +} + +FdPollImplFdSet::~FdPollImplFdSet() +{ + unsigned itemIdx; + for (itemIdx=0; itemIdx < mItems.size(); itemIdx++) + { + FdPollItemFdSetInfo& info = mItems[itemIdx]; + if (info.mItemObj) + { + CritLog(<<"FdPollItem idx="<= 0 ) + { + useIdx = mFreeHeadIdx; + mFreeHeadIdx = mItems[useIdx].mNextIdx; + } + else + { + useIdx = mItems.size(); + unsigned newsz = 10+useIdx + useIdx/3; // plus 30% margin + // WATCHOUT: below may trigger re-allocation, invalidating any iters + // We don't use iters (only indices), but need to watchout for + // cached pointers + mItems.resize(newsz); + // push new items onto the free list + unsigned itemIdx; + for (itemIdx=useIdx+1; itemIdx < newsz; itemIdx++) + { + mItems[itemIdx].mNextIdx = mFreeHeadIdx; + mFreeHeadIdx = itemIdx; + } + } + FdPollItemFdSetInfo& info = mItems[useIdx]; + info.mItemObj = item; + info.mSocketFd = fd; + info.mEvMask = newMask; + info.mNextIdx = mLiveHeadIdx; + mLiveHeadIdx = useIdx; + + if(info.mEvMask & FPEM_Read) mSelectSet.setRead(info.mSocketFd); + if(info.mEvMask & FPEM_Write) mSelectSet.setWrite(info.mSocketFd); + if(info.mEvMask & FPEM_Error) mSelectSet.setExcept(info.mSocketFd); + + return IMPL_FDSET_IdxToHandle(useIdx); +} + +void +FdPollImplFdSet::modPollItem(const FdPollItemHandle handle, FdPollEventMask newMask) +{ + int useIdx = IMPL_FDSET_HandleToIdx(handle); + resip_assert(useIdx>=0 && ((unsigned)useIdx) < mItems.size()); + FdPollItemFdSetInfo& info = mItems[useIdx]; + resip_assert(info.mSocketFd!=INVALID_SOCKET); + resip_assert(info.mItemObj); + info.mEvMask = newMask; + + if(info.mSocketFd != INVALID_SOCKET && info.mSocketFd) + { + killCache(info.mSocketFd); + if(info.mEvMask & FPEM_Read) mSelectSet.setRead(info.mSocketFd); + if(info.mEvMask & FPEM_Write) mSelectSet.setWrite(info.mSocketFd); + if(info.mEvMask & FPEM_Error) mSelectSet.setExcept(info.mSocketFd); + } +} + +void +FdPollImplFdSet::delPollItem(FdPollItemHandle handle) +{ + if(!handle) return; + + int useIdx = IMPL_FDSET_HandleToIdx(handle); + //DebugLog(<<"deleting epoll item fd="<=0 && ((unsigned)useIdx) < mItems.size()); + FdPollItemFdSetInfo& info = mItems[useIdx]; + resip_assert(info.mSocketFd!=INVALID_SOCKET); + resip_assert(info.mItemObj); + killCache(info.mSocketFd); + // we don't change the lists here since the select loop might + // be iterating. Just mark it as dead and gc it later. + info.mSocketFd = INVALID_SOCKET; + info.mItemObj = NULL; + info.mEvMask = 0; +} + +void +FdPollImplFdSet::registerFdSetIOObserver(FdSetIOObserver& observer) +{ + // .bwc. Could make this sorted. Probably not worth the trouble. + mFdSetObservers.push_back(&observer); +} + +void +FdPollImplFdSet::unregisterFdSetIOObserver(FdSetIOObserver& observer) +{ + // .bwc. Could make this sorted. Probably not worth the trouble. + for(std::vector::iterator o=mFdSetObservers.begin(); + o!=mFdSetObservers.end();++o) + { + if(*o==&observer) + { + mFdSetObservers.erase(o); + return; + } + } +} + + +/** + There is a boundary case: + 1. fdA and fdB are added to epoll + 2. events occur on fdA and fdB + 2. waitAndProcess() select and gets events for fdA and fdB + 3. handler for fdA deletes fdB (closing fd) + 5. handler (same or differnt) opens new fd, gets fd as fdB, and adds + it to us but under different object + 6. cache processes "old" fdB event masks but binds it to the new + (wrong) object + + For read or write events it would be relatively harmless to + pass these events to the new object (all objects should be prepared + to get EAGAIN). But passing an error event could incorrectly kill + the wrong object. + + To prevent this, we kill the events in the mSelectSet. In POSIX, + I'm pretty sure this is always safe. In Windows, I don't know what + happens if the fd isn't already in the FdSet. +**/ +void +FdPollImplFdSet::killCache(Socket fd) +{ + mSelectSet.clear(fd); +} + +bool +FdPollImplFdSet::waitAndProcess(int ms) +{ + if(ms<0) + { + // On Linux, passing a NULL timeout ptr to select() will wait + // forever, but I don't want to trust that on all platforms. + // So use 60sec as approximation of "forever". + // Use 60sec b/c fits in short. + ms = 60*1000; + } + + // Create copy; is cheaper than rebuilding from scratch every time. + FdSet fdset(mSelectSet); + ms = resipMin(buildFdSetForObservers(fdset), (unsigned int)ms); + + // Step 2: Select on our built FdSet + int numReady = fdset.selectMilliSeconds(ms); + if ( numReady < 0 ) + { + int err = getErrno(); + if ( err!=EINTR ) + { + CritLog(<<"select() failed: "<::iterator o=mFdSetObservers.begin(); + o!=mFdSetObservers.end();++o) + { + (*o)->buildFdSet(fdset); + ms = resipMin(ms, (*o)->getTimeTillNextProcessMS()); + } + return ms; +} + +bool +FdPollImplFdSet::processFdSet(FdSet& fdset) +{ + bool didsomething = false; + int itemIdx; + int* prevIdxRef = &mLiveHeadIdx; + int loopCnt = 0; + + // Step 3: Invoke callbacks + // Could take advantage of early via numReady, but book keeping + // seems tedious especially if items are deleted during walk + while ( (itemIdx = *prevIdxRef) != -1 ) + { + FdPollItemFdSetInfo& info = mItems[itemIdx]; + resip_assert( ++loopCnt < 99123123 ); + if ( info.mEvMask!=0 && info.mItemObj!=0 ) + { + FdPollEventMask usrMask = 0; + resip_assert(info.mSocketFd!=INVALID_SOCKET); + if(fdset.readyToRead(info.mSocketFd)) usrMask |= FPEM_Read; + if(fdset.readyToWrite(info.mSocketFd)) usrMask |= FPEM_Write; + if(fdset.hasException(info.mSocketFd)) usrMask |= FPEM_Error; + + // items's mask may have changed since select occured, so mask it again + usrMask &= info.mEvMask; + if ( usrMask ) + { + processItem(info.mItemObj, usrMask); + didsomething = true; + } + } + // WATCHOUT: {info} may have moved due to add during processItem() + // set pointer using index, not {info} + prevIdxRef = &mItems[itemIdx].mNextIdx; + } + + // Step 3.1: Invoke callbacks on any FdSetIOObservers + for(std::vector::iterator o=mFdSetObservers.begin(); + o!=mFdSetObservers.end();++o) + { + // This is not strictly correct; we do not know if this observer actually + // put any FDs in the set, or if any of these FDs ended up being ready. + // Eventually, it would be nice to have process() return whether any + // actual IO was performed. + didsomething=true; + (*o)->process(fdset); + } + + return didsomething; +} + +// end of ImplFdSet + + +/***************************************************************** + * + * FdPollImplPoll + * + *****************************************************************/ +#ifdef RESIP_POLL_IMPL_POLL + +namespace resip +{ + +class FdPollItemPollInfo +{ + public: + FdPollItemPollInfo() + : mSocketFd(INVALID_SOCKET), mItemObj(0), mFdPollCacheIndex(-1) + { + } + + Socket mSocketFd; // socket + FdPollItemIf* mItemObj; // callback object + unsigned int mFdPollCacheIndex; +}; + +class FdPollImplPoll : public FdPollGrp +{ + public: + FdPollImplPoll(); + ~FdPollImplPoll(); + + virtual const char* getImplName() const { return "poll"; } + virtual ImplType getImplType() const { return PollImpl; } + + virtual FdPollItemHandle addPollItem(Socket fd, FdPollEventMask newMask, FdPollItemIf *item); + virtual void modPollItem(FdPollItemHandle handle, FdPollEventMask newMask); + virtual void delPollItem(FdPollItemHandle handle); + virtual void registerFdSetIOObserver(FdSetIOObserver& observer); + virtual void unregisterFdSetIOObserver(FdSetIOObserver& observer); + + virtual bool waitAndProcess(int ms=0); + + /// See baseclass. This is integer fd, not Socket + virtual int getEPollFd() const { return -1; } + virtual void buildFdSet(FdSet& fdSet); + virtual bool processFdSet(FdSet& fdset); + + protected: + typedef std::map FdPollItemPollInfoMap; + FdPollItemPollInfoMap mItems; // indexed by fd/handle + std::vector mFdSetObservers; + + /* + * This is temporary cache of pollfds. It is a member (and + * not on stack) for two reasons: (1) simpler memory management, + * and (2) so delPollItem() can traverse it and clean up. + */ + std::vector mPollFdCache; // This list is adjustable while we are waiting/processing + std::vector mPollFds; + Mutex mMutex; +}; + +// NOTE: shift by one so that fd=0 doesn't have NULL handle +#define IMPL_POLL_FdToHandle(fd) ((FdPollItemHandle)( ((char*)0) + ((fd)+1) )) +#define IMPL_POLL_HandleToFd(handle) ( ((char*)(handle)) - ((char*)0) - 1) + +}; // namespace + +FdPollImplPoll::FdPollImplPoll() +{ + int sz = 200; + mPollFdCache.reserve(sz); + mPollFds.reserve(sz); +} + +FdPollImplPoll::~FdPollImplPoll() +{ + FdPollItemPollInfoMap::iterator it; + for(it = mItems.begin(); it != mItems.end(); it++) + { + CritLog(<<"FdPollItem fd=" << it->first <<" not deleted prior to destruction"); + } +} + +static inline unsigned short +CvtSysToUsrMask(unsigned long sysMask) +{ + unsigned usrMask = 0; + if(sysMask & POLLIN) usrMask |= FPEM_Read; + if(sysMask & POLLOUT) usrMask |= FPEM_Write; + if(sysMask & (POLLERR|POLLHUP)) usrMask |= FPEM_Error|FPEM_Read|FPEM_Write; + // NOTE: above, fake read and write if error to encourage + // apps to actually do something about it + return usrMask; +} + +static inline unsigned long +CvtUsrToSysMask(unsigned short usrMask) +{ + unsigned long sysMask = 0; + if(usrMask & FPEM_Read) sysMask |= POLLIN; + if(usrMask & FPEM_Write) sysMask |= POLLOUT; + //if(usrMask & FPEM_Error) sysMask |= POLLERR; // Note: We don't need to ask for error signalling, POLLERR is an output mask only for revents member + return sysMask; +} + +FdPollItemHandle +FdPollImplPoll::addPollItem(Socket fd, FdPollEventMask newMask, FdPollItemIf *item) +{ + resip_assert(fd>=0); + //InfoLog(<<"adding poll item fd="<second; + resip_assert(info.mSocketFd!=INVALID_SOCKET); + resip_assert(info.mItemObj); + + if(info.mSocketFd != INVALID_SOCKET && info.mSocketFd) + { + mPollFdCache[info.mFdPollCacheIndex].events = (short)CvtUsrToSysMask(newMask); + } + } +} + +void +FdPollImplPoll::delPollItem(FdPollItemHandle handle) +{ + int fd = IMPL_POLL_HandleToFd(handle); + //InfoLog(<<"deleting poll item fd="<second; + resip_assert(info.mSocketFd!=INVALID_SOCKET); + resip_assert(info.mItemObj); + resip_assert(info.mFdPollCacheIndex != -1); + resip_assert(mPollFdCache.size() >= 1); + + if(mPollFdCache.size() > 1) + { + // About to reassign this cache slot to be the current last item in the cache, then + // we will remove the last item + size_t lastCacheIndex = mPollFdCache.size() - 1; + + // Adjust index of last item in cache - to be index of deleted item + mItems[mPollFdCache[lastCacheIndex].fd].mFdPollCacheIndex = info.mFdPollCacheIndex; + + // Adjust Cache - reassign index being deleted to last index + mPollFdCache[info.mFdPollCacheIndex] = mPollFdCache[mPollFdCache.size() - 1]; + } + // Remove last cache item - no longer used - was last item, or re-assigned above + mPollFdCache.pop_back(); + + // Remove from Map + mItems.erase(it); + } +} + +void +FdPollImplPoll::registerFdSetIOObserver(FdSetIOObserver& observer) +{ + // .bwc. Could make this sorted. Probably not worth the trouble. + mFdSetObservers.push_back(&observer); +} + +void +FdPollImplPoll::unregisterFdSetIOObserver(FdSetIOObserver& observer) +{ + // .bwc. Could make this sorted. Probably not worth the trouble. + for(std::vector::iterator o=mFdSetObservers.begin(); + o!=mFdSetObservers.end();++o) + { + if(*o==&observer) + { + mFdSetObservers.erase(o); + return; + } + } +} + +bool +FdPollImplPoll::waitAndProcess(int ms) +{ + int waitMs = ms; + + // Copy vector - cheaper than rebuilding from scratch each time + // Need to copy, since vector cannot be changed while Poll is running. + { // Scope for Lock + Lock lock(mMutex); + mPollFds = mPollFdCache; + //InfoLog(<<"FdPollImplPoll::waitAndProcess() ms=" << ms << ", numFds " << mPollFds.size()); + } + size_t observerStartIndex = mPollFds.size(); // record so we know if an observer Fd signalled from Poll or not + bool observerFdSignalled = false; + FdSet fdset; // for FdSet Observer processing + + if(!mFdSetObservers.empty()) + { + if(ms < 0) + { + ms=INT_MAX; + waitMs=INT_MAX; + } + + // Warning; big fat hack. This is likely to be a tad inefficient, and this + // is why we want to move away from FdSetIOObserver, at least in + // conjunction with stuff that uses poll/epoll. The only holdout right now is + // the cares DNS code. + // Also, a fair bit of duplicated code here. + + // gather fds from mFdSetObservers + for(std::vector::iterator o=mFdSetObservers.begin(); o!=mFdSetObservers.end(); ++o) + { + (*o)->buildFdSet(fdset); + waitMs = resipMin((unsigned int)ms, (*o)->getTimeTillNextProcessMS()); + } + + // Get fd's into poll handle list - build up map of masks first + std::map observerFds; + unsigned int i; + for(i = 0; i < fdset.read.fd_count; i++) + { + observerFds[fdset.read.fd_array[i]] |= POLLIN; + } + for(i = 0; i < fdset.write.fd_count; i++) + { + observerFds[fdset.write.fd_array[i]] |= POLLOUT; + } + // Note: We don't need to ask for error signalling, POLLERR is an output mask only for revents member + + // Add items from map to mPollFds vector + std::map::iterator it; + for(it = observerFds.begin(); it != observerFds.end(); it++) + { + pollfd pollFD; + pollFD.fd = it->first; + pollFD.events = it->second; + mPollFds.push_back(pollFD); + } + } + + if(mPollFds.size() == 0) + { + // no handles to poll + return false; + } + + bool didsomething=false; + + pollfd *pollFDArray = &(mPollFds.front()); +#ifdef WIN32 + int numReadyFDs = WSAPoll(pollFDArray, mPollFds.size(), waitMs); +#else + int numReadyFDs = poll(pollFDArray, mPollFds.size(), waitMs); +#endif + if ( numReadyFDs < 0 ) + { + int err = getErrno(); + if ( err != EINTR ) + { + CritLog(<<"poll() failed: " << err << " " << strerror(err)); + resip_assert(0); // .kw. not sure correct behavior... + } + return false; + } + + if ( numReadyFDs==0 ) + { + return false; // timer expired + } + + // Process poll result now + { // Scope for Lock + Lock lock(mMutex); + for (unsigned short index = 0; index < mPollFds.size() && numReadyFDs > 0; index++) + { + int revents = pollFDArray[index].revents; + if (revents) + { + //InfoLog(<<"FdPollImplPoll::waitAndProcess() fd=" << pollFDArray[index].fd << " signalled, revent=" << revents); + + numReadyFDs--; + // array indexes below observerStartIndex are standard/non-observer fd's + if(index < observerStartIndex) + { + FdPollItemPollInfoMap::iterator it = mItems.find(pollFDArray[index].fd); + if(it != mItems.end()) + { + FdPollItemIf* pdPollItem = it->second.mItemObj; + processItem(pdPollItem, CvtSysToUsrMask(revents)); + didsomething = true; + } + } + else + { + // And observer fd signalled - flag it + observerFdSignalled = true; + didsomething = true; + } + } + }//for + } + + // Do observer processing now (if required) + if(observerFdSignalled) + { + // Call select in order to get Fdset properly populated - use a wait + // time of 0 since we know something has signalled from Poll call + int numReady = fdset.selectMilliSeconds(0); + if ( numReady < 0 ) + { + int err = getErrno(); + if (err != EINTR) + { + CritLog(<<"select() failed: "<::iterator o=mFdSetObservers.begin(); o!=mFdSetObservers.end(); ++o) + { + (*o)->process(fdset); + } + } + + return didsomething; +} + +void +FdPollImplPoll::buildFdSet(FdSet& fdset) +{ + CritLog(<<"buildFdSet failed - API not supported for FdPollImplPoll."); + resip_assert(false); +} + +bool +FdPollImplPoll::processFdSet(FdSet& fdset) +{ + CritLog(<<"processFdSet failed - API not supported for FdPollImplPoll."); + resip_assert(false); + return false; +} + +#endif // RESIP_POLL_IMPL_POLL + + + +/***************************************************************** + * + * FdPollImplEpoll + * + *****************************************************************/ + +#ifdef RESIP_POLL_IMPL_EPOLL + +namespace resip +{ + +class FdPollImplEpoll : public FdPollGrp +{ + public: + FdPollImplEpoll(); + ~FdPollImplEpoll(); + + virtual const char* getImplName() const { return "epoll"; } + virtual ImplType getImplType() const { return EPollImpl; } + + virtual FdPollItemHandle addPollItem(Socket fd, + FdPollEventMask newMask, FdPollItemIf *item); + virtual void modPollItem(FdPollItemHandle handle, + FdPollEventMask newMask); + virtual void delPollItem(FdPollItemHandle handle); + virtual void registerFdSetIOObserver(FdSetIOObserver& observer); + virtual void unregisterFdSetIOObserver(FdSetIOObserver& observer); + + virtual bool waitAndProcess(int ms=0); + + /// See baseclass. This is integer fd, not Socket + virtual int getEPollFd() const { return mEPollFd; } + virtual void buildFdSet(FdSet& fdSet); + virtual bool processFdSet(FdSet& fdset); + + protected: + void killCache(Socket fd); + bool epollWait(int ms); + + std::vector mItems; // indexed by fd + std::vector mFdSetObservers; + int mEPollFd; // from epoll_create() + + /* + * This is temporary cache of poll events. It is a member (and + * not on stack) for two reasons: (1) simpler memory management, + * and (2) so delPollItem() can traverse it and clean up. + */ + std::vector mEvCache; + int mEvCacheCur; + int mEvCacheLen; +}; + +}; // namespace + +// NOTE: shift by one so that fd=0 doesn't have NULL handle +#define IMPL_EPOLL_FdToHandle(fd) ((FdPollItemHandle)( ((char*)0) + ((fd)+1) )) +#define IMPL_EPOLL_HandleToFd(handle) ( ((char*)(handle)) - ((char*)0) - 1) + +FdPollImplEpoll::FdPollImplEpoll() : + mEPollFd(-1) +{ + int sz = 200; // ignored + if ( (mEPollFd = epoll_create(sz)) < 0 ) + { + CritLog(<<"epoll_create() failed: "<=0); + //DebugLog(<<"adding epoll item fd="<=0 && ((unsigned)fd) < mItems.size()); + resip_assert(mItems[fd] != NULL); + + struct epoll_event ev; + memset(&ev, 0, sizeof(ev)); // make valgrind happy + ev.events = CvtUsrToSysMask(newMask); + ev.data.fd = fd; + if (epoll_ctl(mEPollFd, EPOLL_CTL_MOD, fd, &ev) < 0) + { + CritLog(<<"epoll_ctl(MOD) failed: "<::iterator o=mFdSetObservers.begin(); + o!=mFdSetObservers.end();++o) + { + if(*o==&observer) + { + mFdSetObservers.erase(o); + return; + } + } +} + + +/** + There is a boundary case: + 1. fdA and fdB are added to epoll + 2. events occur on fdA and fdB + 2. waitAndProcess() reads queue for fdA and fdB into its cache + 3. handler for fdA deletes fdB (closing fd) + 5. handler (same or differnt) opens new fd, gets fd as fdB, and adds + it to epoll but under different object + 6. cache processes "old" fdB but binds it to the new (wrong) object + + For read or write events it would be relatively harmless to + pass these events to the new object (all objects should be prepared + to get EAGAIN). But passing an error event could incorrectly kill + the wrong object. + + To prevent this, we walk the cache and kill any events for our fd. + In theory, the kernel does the same. + + An alternative approach would be use a serial number counter, + as a lifetime indicator for each fd, and store both a 32-bit serial + and 32-bit fd into the epoll event in the kernel. We could then + recognize stale events. +**/ +void +FdPollImplEpoll::killCache(int fd) +{ + int ne; + for (ne=mEvCacheCur; ne < mEvCacheLen; ne++) + { + if ( mEvCache[ne].data.fd == fd ) + { + mEvCache[ne].data.fd = INVALID_SOCKET; + } + } +} + + +bool +FdPollImplEpoll::waitAndProcess(int ms) +{ + bool didSomething = false; + int waitMs = ms; + resip_assert( mEvCache.size() > 0 ); + + if(!mFdSetObservers.empty()) + { + if(ms < 0) + { + ms=INT_MAX; + waitMs=INT_MAX; + } + + // Warning; big fat hack. This is likely to be a tad inefficient, and this + // is why we want to move away from FdSetIOObserver, at least in + // conjunction with stuff that uses epoll. The only holdout right now is + // the cares DNS code. + // Also, a fair bit of duplicated code here. + + FdSet fdset; + buildFdSet(fdset); // add our epoll fd, and fds from mFdSetObservers + + for(std::vector::iterator o=mFdSetObservers.begin(); + o!=mFdSetObservers.end();++o) + { + ms = resipMin((unsigned int)ms, (*o)->getTimeTillNextProcessMS()); + } + + // Avoid waiting too much; this ends up overcompensating unless the + // select() times out, but it is better than just setting to 0. We could + // record the time taken by the select() call, but this would be more + // expensive. + waitMs -= ms; + + int numReady = fdset.selectMilliSeconds(ms); + + // Should we still do this? If our epoll fd is not marked ready, should we + // do the epoll_wait below? I want to say no... + if ( numReady < 0 ) + { + int err = getErrno(); + if ( err!=EINTR ) + { + CritLog(<<"select() failed: "<::iterator o=mFdSetObservers.begin(); + o!=mFdSetObservers.end();++o) + { + (*o)->buildFdSet(fdset); + } +} + +bool +FdPollImplEpoll::processFdSet(FdSet& fdset) +{ + bool didsomething=false; + for(std::vector::iterator o=mFdSetObservers.begin(); + o!=mFdSetObservers.end();++o) + { + // This is not strictly correct; we do not know if this observer + // actually put any FDs in the set, or if any of these FDs ended up + // being ready. + // Eventually, it would be nice to have process() return whether any + // actual IO was performed. + didsomething=true; + (*o)->process(fdset); + } + + int fd = getEPollFd(); + if (fd !=- 1 && fdset.readyToRead(fd)) + { + epollWait(0); + } + return didsomething; +} + +bool +FdPollImplEpoll::epollWait(int waitMs) +{ + bool maybeMore; + bool didsomething=false; + do + { + int nfds = epoll_wait(mEPollFd, &mEvCache.front(), mEvCache.size(), waitMs); + if (nfds < 0) + { + if (errno==EINTR) + { + // signal handler (like alarm) broke loop. generally ok + DebugLog(<<"epoll_wait() broken by EINTR"); + nfds = 0; // clean-up and return. could add return code + // to indicate this, but not needed by us + } + else + { + CritLog(<<"epoll_wait() failed: " << strerror(errno)); + abort(); // TBD: just throw instead? + } + } + waitMs = 0; // don't wait anymore + mEvCacheLen = nfds; // for killCache() + maybeMore = ( ((unsigned)nfds)==mEvCache.size()) ? 1 : 0; + int ne; + for (ne=0; ne < nfds; ne++) + { + int fd = mEvCache[ne].data.fd; + if (fd == INVALID_SOCKET) + { + continue; // was killed by killCache() + } + int sysEvtMask = mEvCache[ne].events; + resip_assert(fd>=0 && fd < (int)mItems.size()); + FdPollItemIf *item = mItems[fd]; + if (item == NULL) + { + /* this can happen if item was deleted after + * event was generated in kernel, etc. */ + continue; + } + mEvCacheCur = ne; // for killCache() + processItem(item, CvtSysToUsrMask(sysEvtMask)); + item = NULL; // WATCHOUT: item may not exist anymore + didsomething = true; + } + mEvCacheLen = 0; + } while (maybeMore); + return didsomething; +} + +#endif // RESIP_POLL_IMPL_EPOLL + +/***************************************************************** + * + * Factory + * + *****************************************************************/ + +/*static*/FdPollGrp* +FdPollGrp::create(const char *implName) +{ + if ( implName==0 || implName[0]==0 || strcmp(implName,"event")==0 ) + implName = 0; // pick the first (best) one supported +#ifdef RESIP_POLL_IMPL_EPOLL + if ( implName==0 || strcmp(implName,"epoll")==0 ) + { + return new FdPollImplEpoll(); + } +#endif +#ifdef RESIP_POLL_IMPL_POLL + if ( implName==0 || strcmp(implName,"poll")==0 ) + { + return new FdPollImplPoll(); + } +#endif + if ( implName==0 || strcmp(implName,"fdset")==0 ) + { + return new FdPollImplFdSet(); + } + resip_assert(0); + return NULL; +} + +/*static*/const char* +FdPollGrp::getImplList() +{ + // .kw. this isn't really scalable approach if we get a lot of impls + // but it works for now +#ifdef RESIP_POLL_IMPL_EPOLL + #ifdef RESIP_POLL_IMPL_POLL + return "event|epoll|fdset|poll"; + #else + return "event|epoll|fdset"; + #endif +#else + #ifdef RESIP_POLL_IMPL_POLL + return "event|fdset|poll"; + #else + return "event|fdset"; + #endif +#endif +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000-2005 Jacob Butcher + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/rutil/FdPoll.hxx b/src/libs/resiprocate/rutil/FdPoll.hxx index e0e36e55..b2749fe9 100644 --- a/src/libs/resiprocate/rutil/FdPoll.hxx +++ b/src/libs/resiprocate/rutil/FdPoll.hxx @@ -14,7 +14,11 @@ */ #if defined(HAVE_EPOLL) -#define RESIP_POLL_IMPL_EPOLL // Only one currently implemented +#define RESIP_POLL_IMPL_EPOLL +#endif + +#if defined(HAVE_POLL) || (_WIN32_WINNT >= 0x0600) +#define RESIP_POLL_IMPL_POLL #endif namespace resip { @@ -71,6 +75,8 @@ class FdPollGrp FdPollGrp(); virtual ~FdPollGrp(); + typedef enum {FdSetImpl = 0, PollImpl, EPollImpl } ImplType; + /// factory static FdPollGrp* create(const char *implName=NULL); /// Return candidate impl names with vertical bar (|) between them @@ -78,6 +84,7 @@ class FdPollGrp static const char* getImplList(); virtual const char* getImplName() const = 0; + virtual ImplType getImplType() const = 0; virtual FdPollItemHandle addPollItem(Socket sock, FdPollEventMask newMask, FdPollItemIf *item) = 0; virtual void modPollItem(FdPollItemHandle handle, FdPollEventMask newMask) = 0; @@ -97,8 +104,9 @@ class FdPollGrp /// get the epoll-fd (epoll_create()) /// This is fd (type int), not Socket. It may be -1 if epoll /// is not enabled. - virtual int getEPollFd() const; + virtual int getEPollFd() const; + // Legacy API's (deprecated) - use waitAndProcess instead virtual void buildFdSet(FdSet& fdSet)=0; virtual bool processFdSet(FdSet& fdset)=0; diff --git a/src/libs/resiprocate/rutil/Fifo.hxx b/src/libs/resiprocate/rutil/Fifo.hxx index 303b44c1..fdf17c1e 100644 --- a/src/libs/resiprocate/rutil/Fifo.hxx +++ b/src/libs/resiprocate/rutil/Fifo.hxx @@ -1,7 +1,7 @@ #if !defined(RESIP_FIFO_HXX) #define RESIP_FIFO_HXX -#include +#include "rutil/ResipAssert.h" #include "rutil/AbstractFifo.hxx" #include "rutil/SelectInterruptor.hxx" @@ -94,7 +94,7 @@ Fifo::clear() delete mFifo.front(); mFifo.pop_front(); } - assert(mFifo.empty()); + resip_assert(mFifo.empty()); } template @@ -116,7 +116,7 @@ Fifo::addMultiple(Messages& msgs) { size_t inSize = msgs.size(); size_t size = AbstractFifo::addMultiple(msgs); - if(size==inSize && mInterruptor) + if(size==inSize && inSize != 0 && mInterruptor) { // Only do this when the queue goes from empty to not empty. mInterruptor->handleProcessNotification(); diff --git a/src/libs/resiprocate/rutil/FileSystem.cxx b/src/libs/resiprocate/rutil/FileSystem.cxx index e1c6c979..cd046648 100644 --- a/src/libs/resiprocate/rutil/FileSystem.cxx +++ b/src/libs/resiprocate/rutil/FileSystem.cxx @@ -1,7 +1,9 @@ #include "rutil/FileSystem.hxx" #include "rutil/Logger.hxx" -#include +#include + +#include "rutil/ResipAssert.h" using namespace resip; #define RESIPROCATE_SUBSYSTEM Subsystem::SIP @@ -25,15 +27,22 @@ FileSystem::Directory::iterator::iterator() : mNixDir(0), mDirent(0) FileSystem::Directory::iterator::iterator(const Directory& dir) { - assert(!dir.getPath().empty()); + resip_assert(!dir.getPath().empty()); //InfoLog(<< "FileSystem::Directory::iterator::iterator: " << dir.getPath()); + mPath = dir.getPath(); if ((mNixDir = opendir( dir.getPath().c_str() ))) { + errno = 0; mDirent = readdir(mNixDir); + if(errno != 0) + { + throw Exception("Failed readdir", __FILE__, __LINE__); + } if (mDirent) { //InfoLog(<< "FileSystem::Directory::iterator::iterator, first file " << mFile); mFile = mDirent->d_name; + mFullFilename = mPath + '/' + mFile; } } else @@ -57,10 +66,16 @@ FileSystem::Directory::iterator::operator++() { if (mDirent) { + errno = 0; mDirent = readdir(mNixDir); + if(errno != 0) + { + throw Exception("Failed readdir", __FILE__, __LINE__); + } if (mDirent) { mFile = mDirent->d_name; + mFullFilename = mPath + '/' + mFile; //InfoLog(<< "FileSystem::Directory::iterator::iterator, next file " << mFile); } } @@ -103,7 +118,18 @@ FileSystem::Directory::iterator::operator->() const bool FileSystem::Directory::iterator::is_directory() const { +#if HAVE_STRUCT_DIRENT_D_TYPE return mDirent->d_type == DT_DIR; +#else + struct stat s; + StackLog(<<"calling stat() for " << mDirent->d_name); + if(stat(mFullFilename.c_str(), &s) < 0) + { + ErrLog(<<"Error calling stat() for " << mFullFilename.c_str() << ": " << strerror(errno)); + throw Exception("stat() failed", __FILE__, __LINE__); + } + return S_ISDIR(s.st_mode); +#endif } int @@ -127,7 +153,7 @@ FileSystem::Directory::iterator::iterator() : FileSystem::Directory::iterator::iterator(const Directory& dir) { Data searchPath; - if (dir.getPath().postfix("/") || dir.getPath().postfix("\\")) + if (dir.getPath().empty() || dir.getPath().postfix("/") || dir.getPath().postfix("\\")) { searchPath = dir.getPath() + Data("*"); } @@ -145,6 +171,7 @@ FileSystem::Directory::iterator::iterator(const Directory& dir) else { mFile = fileData.cFileName; + mFullFilename = mPath + '/' + mFile; } } @@ -174,6 +201,7 @@ FileSystem::Directory::iterator::operator++() else { mFile = fileData.cFileName; + mFullFilename = mPath + '/' + mFile; mIsDirectory = (fileData.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) > 0; } return *this; diff --git a/src/libs/resiprocate/rutil/FileSystem.hxx b/src/libs/resiprocate/rutil/FileSystem.hxx index 221a3bcf..4487dfc8 100644 --- a/src/libs/resiprocate/rutil/FileSystem.hxx +++ b/src/libs/resiprocate/rutil/FileSystem.hxx @@ -1,15 +1,18 @@ #ifndef RESIP_FileSystem_hxx #define RESIP_FileSystem_hxx +#include "rutil/BaseException.hxx" #include "rutil/Data.hxx" #if !defined(WIN32) #include #include #include -# if !defined(TARGET_ANDROID) -# include -# endif +#if defined(__ANDROID__) +#include +#else +#include +#endif #include #include #else @@ -28,6 +31,18 @@ namespace resip class FileSystem { public: + + class Exception : public BaseException + { + public: + Exception(const Data& msg, + const Data& file, + const int line) + : BaseException(msg, file, line) {} + protected: + virtual const char* name() const { return "ConfigParse::Exception"; } + }; + class Directory { public: @@ -61,6 +76,8 @@ class FileSystem struct dirent* mDirent; #endif Data mFile; + Data mPath; + Data mFullFilename; }; iterator begin() const; diff --git a/src/libs/resiprocate/rutil/GeneralCongestionManager.cxx b/src/libs/resiprocate/rutil/GeneralCongestionManager.cxx index 6997d34e..5164b2f9 100644 --- a/src/libs/resiprocate/rutil/GeneralCongestionManager.cxx +++ b/src/libs/resiprocate/rutil/GeneralCongestionManager.cxx @@ -1,6 +1,7 @@ #include "rutil/GeneralCongestionManager.hxx" #include "rutil/AbstractFifo.hxx" +#include "rutil/Lock.hxx" #include "rutil/Logger.hxx" #define RESIPROCATE_SUBSYSTEM Subsystem::STATS @@ -26,6 +27,7 @@ GeneralCongestionManager::registerFifo(resip::FifoStatsInterface* fifo, MetricType metric, UInt32 maxTolerance) { + Lock lock(mFifosMutex); FifoInfo info; info.fifo=fifo; info.metric=metric; @@ -37,6 +39,7 @@ GeneralCongestionManager::registerFifo(resip::FifoStatsInterface* fifo, void GeneralCongestionManager::unregisterFifo(resip::FifoStatsInterface* fifo) { + Lock lock(mFifosMutex); if(fifo->getRole() < mFifos.size()) { mFifos[fifo->getRole()].fifo=0; @@ -49,9 +52,11 @@ GeneralCongestionManager::updateFifoTolerances( MetricType metric, UInt32 maxTolerance ) { + Lock lock(mFifosMutex); for(std::vector::iterator i=mFifos.begin(); i!=mFifos.end(); ++i) { - if(fifoDescription.empty() || isEqualNoCase(i->fifo->getDescription(), fifoDescription)) + if(i->fifo && // ensure fifo isn't 0'd out from unregister call + (fifoDescription.empty() || isEqualNoCase(i->fifo->getDescription(), fifoDescription))) { i->maxTolerance=UINT_MAX; // Set temporarily to UINT_MAX, so that we don't inadvertantly reject a request while the metric and tolerance are being changed. i->metric=metric; @@ -64,6 +69,13 @@ GeneralCongestionManager::updateFifoTolerances( CongestionManager::RejectionBehavior GeneralCongestionManager::getRejectionBehavior(const FifoStatsInterface *fifo) const +{ + Lock lock(mFifosMutex); + return getRejectionBehaviorInternal(fifo); +} + +CongestionManager::RejectionBehavior +GeneralCongestionManager::getRejectionBehaviorInternal(const FifoStatsInterface *fifo) const { // !bwc! We need to also keep an eye on memory usage, and push back if it // looks like we're going to start hitting swap sometime soon. @@ -88,6 +100,7 @@ GeneralCongestionManager::getRejectionBehavior(const FifoStatsInterface *fifo) c void GeneralCongestionManager::logCurrentState() const { + Lock lock(mFifosMutex); WarningLog(<<"FIFO STATISTICS"); for(std::vector::const_iterator i=mFifos.begin(); i!=mFifos.end();++i) @@ -106,6 +119,7 @@ GeneralCongestionManager::logCurrentState() const EncodeStream& GeneralCongestionManager::encodeCurrentState(EncodeStream& strm) const { + Lock lock(mFifosMutex); for(std::vector::const_iterator i=mFifos.begin(); i!=mFifos.end();++i) { @@ -125,12 +139,12 @@ GeneralCongestionManager::getCongestionPercent(const FifoStatsInterface* fifo) c { if(fifo->getRole() >= mFifos.size()) { - assert(0); + resip_assert(0); return 0; } const FifoInfo& info = mFifos[fifo->getRole()]; - assert(info.fifo==fifo); + resip_assert(info.fifo==fifo); switch(info.metric) { case SIZE: @@ -140,7 +154,7 @@ GeneralCongestionManager::getCongestionPercent(const FifoStatsInterface* fifo) c case WAIT_TIME: return resipIntDiv(100*(UInt32)(fifo->expectedWaitTimeMilliSec()),info.maxTolerance); default: - assert(0); + resip_assert(0); return 0; } return 0; @@ -149,7 +163,7 @@ GeneralCongestionManager::getCongestionPercent(const FifoStatsInterface* fifo) c EncodeStream& GeneralCongestionManager::encodeFifoStats(const FifoStatsInterface& fifoStats, EncodeStream& strm) const { - CongestionManager::RejectionBehavior behavior = getRejectionBehavior(&fifoStats); + CongestionManager::RejectionBehavior behavior = getRejectionBehaviorInternal(&fifoStats); const FifoInfo& info = mFifos[fifoStats.getRole()]; strm < @@ -141,6 +142,7 @@ class GeneralCongestionManager : public CongestionManager @brief Returns the percent of maximum tolerances that this queue is at. */ virtual UInt16 getCongestionPercent(const FifoStatsInterface* fifo) const; + virtual RejectionBehavior getRejectionBehaviorInternal(const FifoStatsInterface *fifo) const; virtual EncodeStream& encodeFifoStats(const FifoStatsInterface& fifoStats, EncodeStream& strm) const; @@ -152,6 +154,11 @@ class GeneralCongestionManager : public CongestionManager } FifoInfo; // !bwc! TODO pick a better name std::vector mFifos; + // !slg! would love to get rid of the following mutex - but we need to protect + // threads querying the congestion stats and make sure runtime transport + // additions are safe (ie: registerFifo and unregisterFifo being called + // when the fifos are in full motion. + mutable Mutex mFifosMutex; UInt16 mRejectionThresholds[REJECTING_NON_ESSENTIAL+1]; MetricType mDefaultMetric; UInt32 mDefaultMaxTolerance; diff --git a/src/libs/resiprocate/rutil/GenericIPAddress.cxx b/src/libs/resiprocate/rutil/GenericIPAddress.cxx new file mode 100644 index 00000000..bdace148 --- /dev/null +++ b/src/libs/resiprocate/rutil/GenericIPAddress.cxx @@ -0,0 +1,69 @@ + +#include "rutil/DnsUtil.hxx" +#include "rutil/GenericIPAddress.hxx" + +using namespace resip; + +EncodeStream& +resip::operator<<(EncodeStream& ostrm, const GenericIPAddress& addr) +{ + ostrm << "[ " ; + +#ifdef USE_IPV6 + if (addr.address.sa_family == AF_INET6) + { + ostrm << "V6 " << DnsUtil::inet_ntop(addr.v6Address.sin6_addr) << " port=" << ntohs(addr.v6Address.sin6_port); + } + else +#endif + if (addr.address.sa_family == AF_INET) + { + ostrm << "V4 " << DnsUtil::inet_ntop(addr.v4Address.sin_addr) << ":" << ntohs(addr.v4Address.sin_port); + } + else + { + resip_assert(0); + } + + ostrm << " ]"; + + return ostrm; +} + +/* ==================================================================== +* +* Copyright 2016 Daniel Pocock https://danielpocock.com +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* +* 3. Neither the name of the author(s) nor the names of any contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +* +* ==================================================================== +* +* +*/ + diff --git a/src/libs/resiprocate/rutil/GenericIPAddress.hxx b/src/libs/resiprocate/rutil/GenericIPAddress.hxx index 53bbc676..696e36f0 100644 --- a/src/libs/resiprocate/rutil/GenericIPAddress.hxx +++ b/src/libs/resiprocate/rutil/GenericIPAddress.hxx @@ -2,18 +2,15 @@ #define RESIP_GENERIC_IP_ADDRESS_HXX #ifndef WIN32 -# include +#include #else -# include -# include +#include +#include #endif #include "rutil/Socket.hxx" #include "rutil/compat.hxx" -#ifndef IPPROTO_IPV6 -# define IPPROTO_IPV6 -#endif namespace resip { @@ -65,7 +62,7 @@ struct GenericIPAddress return sizeof(sockaddr_in6); } #endif - assert(0); + resip_assert(0); return 0; } @@ -107,7 +104,7 @@ struct GenericIPAddress return (v6Address.sin6_port == addr.v6Address.sin6_port && memcmp(&v6Address.sin6_addr, &addr.v6Address.sin6_addr, sizeof(in6_addr)) == 0); #else - assert(0); + resip_assert(0); return false; #endif } @@ -183,8 +180,13 @@ struct GenericIPAddress } } + friend EncodeStream& operator<<(EncodeStream& strm, const GenericIPAddress& addr); + }; +EncodeStream& +operator<<(EncodeStream& ostrm, const GenericIPAddress& addr); + } diff --git a/src/libs/resiprocate/rutil/GenericTimerQueue.hxx b/src/libs/resiprocate/rutil/GenericTimerQueue.hxx index fd42c8dd..0dbe2270 100644 --- a/src/libs/resiprocate/rutil/GenericTimerQueue.hxx +++ b/src/libs/resiprocate/rutil/GenericTimerQueue.hxx @@ -69,7 +69,7 @@ class GenericTimerQueue for (typename ItVector::iterator i = iterators.begin(); i != iterators.end(); ++i) { - assert((*i)->getEvent()); + resip_assert((*i)->getEvent()); processTimer((*i)->getEvent()); } diff --git a/src/libs/resiprocate/rutil/HashMap.hxx b/src/libs/resiprocate/rutil/HashMap.hxx index 96ebbb38..8e584b6a 100644 --- a/src/libs/resiprocate/rutil/HashMap.hxx +++ b/src/libs/resiprocate/rutil/HashMap.hxx @@ -11,7 +11,33 @@ @ingroup data_structures */ -# if ( (__GNUC__ == 4) && (__GNUC_MINOR__ >= 3) ) || ( __GNUC__ > 4 ) +// For GNU libstdc++ the decision which hashmap implementation to use must be +// done on the version of libstdc++ and not on the compiler version. +// Otherwise for example mixing RHEL6 GCC (4.4.7) and Clang 3.4 on RHEL6 will produce +// ABI incompatible results. +// The version encodings are described here: +// https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html +#include // force include of nonstandard + +# if (defined(__cplusplus) && (__cplusplus >= 201103L)) || (defined(WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1900)) || (defined(_LIBCPP_VERSION) && (_LIBCPP_VERSION >= 1000)) +# include +# include +# define HASH_MAP_NAMESPACE std +# define HashMap std::unordered_map +# define HashSet std::unordered_set +# define HashMultiMap std::unordered_multimap + +# define HashValue(type) \ + namespace std \ + { \ + template <> \ + struct hash \ + { \ + size_t operator()(const type& data) const; \ + }; \ + } +# define HashValueImp(type, ret) size_t HASH_MAP_NAMESPACE::hash::operator()(const type& data) const { return ret; } +# elif ( defined(__GLIBCXX__) && (__GLIBCXX__ >= 20080306) ) // >= 4.3.0 # include # include # define HASH_MAP_NAMESPACE std::tr1 @@ -19,55 +45,49 @@ # define HashSet std::tr1::unordered_set # define HashMultiMap std::tr1::unordered_multimap -#define HashValue(type) \ -namespace std \ -{ \ -namespace tr1 \ -{ \ -template <> \ -struct hash \ -{ \ - size_t operator()(const type& data) const; \ -}; \ -} \ -} -#define HashValueImp(type, ret) size_t HASH_MAP_NAMESPACE::hash::operator()(const type& data) const { return ret; } - -# elif ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) || ( __GNUC__ > 3 ) +# define HashValue(type) \ + namespace std \ + { \ + namespace tr1 \ + { \ + template <> \ + struct hash \ + { \ + size_t operator()(const type& data) const; \ + }; \ + } \ + } + #define HashValueImp(type, ret) size_t HASH_MAP_NAMESPACE::hash::operator()(const type& data) const { return ret; } +# elif ( ( defined(__GLIBCPP__) && (__GLIBCPP__ >= 20020514) ) || ( defined(__GLIBCXX__) && (__GLIBCXX__ >= 20020514) ) || defined(_LIBCPP_VERSION) ) // >= 3.1.0 or libc++ # include # include # define HASH_MAP_NAMESPACE __gnu_cxx # define HashMap __gnu_cxx::hash_map # define HashSet __gnu_cxx::hash_set # define HashMultiMap __gnu_cxx::hash_multimap -// this allows us to hash on a pointer as the key -namespace HASH_MAP_NAMESPACE -{ -/** -@internal -*/ -template -struct hash -{ - size_t operator()(const T* t) const - { - return size_t(t); - } -}; - -} - -#define HashValue(type) \ -namespace HASH_MAP_NAMESPACE \ -{ \ -template <> \ -struct hash \ -{ \ - size_t operator()(const type& data) const; \ -}; \ -} -#define HashValueImp(type, ret) size_t HASH_MAP_NAMESPACE::hash::operator()(const type& data) const { return ret; } + // this allows us to hash on a pointer as the key + namespace HASH_MAP_NAMESPACE + { + template + struct hash + { + size_t operator()(const T* t) const + { + return size_t(t); + } + }; + } +# define HashValue(type) \ + namespace HASH_MAP_NAMESPACE \ + { \ + template <> \ + struct hash \ + { \ + size_t operator()(const type& data) const; \ + }; \ + } +# define HashValueImp(type, ret) size_t HASH_MAP_NAMESPACE::hash::operator()(const type& data) const { return ret; } # elif defined(__INTEL_COMPILER ) # include # define HASH_MAP_NAMESPACE std diff --git a/src/libs/resiprocate/rutil/HeapInstanceCounter.cxx b/src/libs/resiprocate/rutil/HeapInstanceCounter.cxx index 7f31dd91..a9be870a 100644 --- a/src/libs/resiprocate/rutil/HeapInstanceCounter.cxx +++ b/src/libs/resiprocate/rutil/HeapInstanceCounter.cxx @@ -3,7 +3,7 @@ #include "rutil/Logger.hxx" #include "rutil/Data.hxx" -#include +#include "rutil/ResipAssert.h" #include using namespace std; diff --git a/src/libs/resiprocate/rutil/Inserter.hxx b/src/libs/resiprocate/rutil/Inserter.hxx index 0b6c9ccb..85418635 100644 --- a/src/libs/resiprocate/rutil/Inserter.hxx +++ b/src/libs/resiprocate/rutil/Inserter.hxx @@ -8,7 +8,7 @@ #include #include #include -#include +#include "rutil/ResipAssert.h" #include "HashMap.hxx" #include "rutil/compat.hxx" @@ -283,7 +283,7 @@ EncodeStream& operator<<(EncodeStream& s, const InserterClass& inserter) { #if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER < 1310) - assert(0); // CJ - really need to fix this + resip_assert(0); // CJ - really need to fix this return s; #else return insert(s, inserter._t); @@ -536,7 +536,7 @@ EncodeStream& operator<<(EncodeStream& s, const InserterPClass& inserter) { #if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER < 1310) - assert(0); // CJ - really need to fix this + resip_assert(0); // CJ - really need to fix this return s; #else return insertP(s, inserter._t); diff --git a/src/libs/resiprocate/rutil/IntrusiveListElement.hxx b/src/libs/resiprocate/rutil/IntrusiveListElement.hxx index 58cba828..4c652a86 100644 --- a/src/libs/resiprocate/rutil/IntrusiveListElement.hxx +++ b/src/libs/resiprocate/rutil/IntrusiveListElement.hxx @@ -74,7 +74,7 @@ class IntrusiveListElement // make this element an empty list static P makeList(P elem) { - assert(!elem->IntrusiveListElement

::mNext); + resip_assert(!elem->IntrusiveListElement

::mNext); elem->IntrusiveListElement

::mPrev = elem; elem->IntrusiveListElement

::mNext = elem; @@ -84,8 +84,8 @@ class IntrusiveListElement bool empty() const { - assert(mPrev); - assert(mNext); + resip_assert(mPrev); + resip_assert(mNext); return static_cast*>(mNext) == static_cast*>(this); } @@ -132,15 +132,15 @@ class IntrusiveListElement iterator begin() { - assert(mPrev); - assert(mNext); + resip_assert(mPrev); + resip_assert(mNext); return iterator(mNext); } iterator end() { - assert(mPrev); - assert(mNext); + resip_assert(mPrev); + resip_assert(mNext); return iterator(static_cast

(this)); } @@ -149,8 +149,8 @@ class IntrusiveListElement // pushing an element onto the same list twice is undefined void push_front(P elem) { - assert(mPrev); - assert(mNext); + resip_assert(mPrev); + resip_assert(mNext); elem->IntrusiveListElement

::mNext = mNext; elem->IntrusiveListElement

::mPrev = static_cast

(this); @@ -162,8 +162,8 @@ class IntrusiveListElement // putting an element onto the same list twice is undefined void push_back(P elem) { - assert(mPrev); - assert(mNext); + resip_assert(mPrev); + resip_assert(mNext); elem->IntrusiveListElement

::mPrev = mPrev; elem->IntrusiveListElement

::mNext = static_cast

(this); @@ -211,7 +211,7 @@ class IntrusiveListElement1 // make this element an empty list static P makeList(P elem) { - assert(!elem->IntrusiveListElement1

::mNext); + resip_assert(!elem->IntrusiveListElement1

::mNext); elem->IntrusiveListElement1

::mPrev = elem; elem->IntrusiveListElement1

::mNext = elem; @@ -221,8 +221,8 @@ class IntrusiveListElement1 bool empty() const { - assert(mPrev); - assert(mNext); + resip_assert(mPrev); + resip_assert(mNext); return static_cast*>(mNext) == static_cast*>(this); } @@ -269,15 +269,15 @@ class IntrusiveListElement1 iterator begin() { - assert(mPrev); - assert(mNext); + resip_assert(mPrev); + resip_assert(mNext); return iterator(mNext); } iterator end() { - assert(mPrev); - assert(mNext); + resip_assert(mPrev); + resip_assert(mNext); return iterator(static_cast

(this)); } @@ -286,8 +286,8 @@ class IntrusiveListElement1 // pushing an element onto the same list twice is undefined void push_front(P elem) { - assert(mPrev); - assert(mNext); + resip_assert(mPrev); + resip_assert(mNext); elem->IntrusiveListElement1

::mNext = mNext; elem->IntrusiveListElement1

::mPrev = static_cast

(this); @@ -299,8 +299,8 @@ class IntrusiveListElement1 // putting an element onto the same list twice is undefined void push_back(P elem) { - assert(mPrev); - assert(mNext); + resip_assert(mPrev); + resip_assert(mNext); elem->IntrusiveListElement1

::mPrev = mPrev; elem->IntrusiveListElement1

::mNext = static_cast

(this); @@ -348,7 +348,7 @@ class IntrusiveListElement2 // make this element an empty list static P makeList(P elem) { - assert(!elem->IntrusiveListElement2

::mNext); + resip_assert(!elem->IntrusiveListElement2

::mNext); elem->IntrusiveListElement2

::mPrev = elem; elem->IntrusiveListElement2

::mNext = elem; @@ -358,8 +358,8 @@ class IntrusiveListElement2 bool empty() const { - assert(mPrev); - assert(mNext); + resip_assert(mPrev); + resip_assert(mNext); return static_cast*>(mNext) == static_cast*>(this); } @@ -406,15 +406,15 @@ class IntrusiveListElement2 iterator begin() { - assert(mPrev); - assert(mNext); + resip_assert(mPrev); + resip_assert(mNext); return iterator(mNext); } iterator end() { - assert(mPrev); - assert(mNext); + resip_assert(mPrev); + resip_assert(mNext); return iterator(static_cast

(this)); } @@ -423,8 +423,8 @@ class IntrusiveListElement2 // pushing an element onto the same list twice is undefined void push_front(P elem) { - assert(mPrev); - assert(mNext); + resip_assert(mPrev); + resip_assert(mNext); elem->IntrusiveListElement2

::mNext = mNext; elem->IntrusiveListElement2

::mPrev = static_cast

(this); @@ -436,8 +436,8 @@ class IntrusiveListElement2 // putting an element onto the same list twice is undefined void push_back(P elem) { - assert(mPrev); - assert(mNext); + resip_assert(mPrev); + resip_assert(mNext); elem->IntrusiveListElement2

::mPrev = mPrev; elem->IntrusiveListElement2

::mNext = static_cast

(this); @@ -485,7 +485,7 @@ class IntrusiveListElement3 // make this element an empty list static P makeList(P elem) { - assert(!elem->IntrusiveListElement3

::mNext); + resip_assert(!elem->IntrusiveListElement3

::mNext); elem->IntrusiveListElement3

::mPrev = elem; elem->IntrusiveListElement3

::mNext = elem; @@ -495,8 +495,8 @@ class IntrusiveListElement3 bool empty() const { - assert(mPrev); - assert(mNext); + resip_assert(mPrev); + resip_assert(mNext); return static_cast*>(mNext) == static_cast*>(this); } @@ -543,15 +543,15 @@ class IntrusiveListElement3 iterator begin() { - assert(mPrev); - assert(mNext); + resip_assert(mPrev); + resip_assert(mNext); return iterator(mNext); } iterator end() { - assert(mPrev); - assert(mNext); + resip_assert(mPrev); + resip_assert(mNext); return iterator(static_cast

(this)); } @@ -560,8 +560,8 @@ class IntrusiveListElement3 // pushing an element onto the same list twice is undefined void push_front(P elem) { - assert(mPrev); - assert(mNext); + resip_assert(mPrev); + resip_assert(mNext); elem->IntrusiveListElement3

::mNext = mNext; elem->IntrusiveListElement3

::mPrev = static_cast

(this); @@ -573,8 +573,8 @@ class IntrusiveListElement3 // putting an element onto the same list twice is undefined void push_back(P elem) { - assert(mPrev); - assert(mNext); + resip_assert(mPrev); + resip_assert(mNext); elem->IntrusiveListElement3

::mPrev = mPrev; elem->IntrusiveListElement3

::mNext = static_cast

(this); diff --git a/src/libs/resiprocate/rutil/Log.cxx b/src/libs/resiprocate/rutil/Log.cxx index 1e7308b7..b043d683 100644 --- a/src/libs/resiprocate/rutil/Log.cxx +++ b/src/libs/resiprocate/rutil/Log.cxx @@ -1,6 +1,6 @@ #include "rutil/Socket.hxx" -#include +#include "rutil/ResipAssert.h" #include #include #include @@ -28,8 +28,14 @@ const Data Log::delim(" | "); Log::ThreadData Log::mDefaultLoggerData(0, Log::Cout, Log::Info, NULL, NULL); Data Log::mAppName; Data Log::mHostname; +#ifndef WIN32 +int Log::mSyslogFacility = LOG_DAEMON; +#else +int Log::mSyslogFacility = -1; +#endif unsigned int Log::MaxLineCount = 0; // no limit by default unsigned int Log::MaxByteCount = 0; // no limit by default +bool Log::KeepAllLogFiles = false; // do not keep all log files by default #ifdef WIN32 int Log::mPid=0; @@ -106,31 +112,130 @@ LogStaticInitializer::~LogStaticInitializer() } void -Log::initialize(const char* typed, const char* leveld, const char* appName, const char *logFileName, ExternalLogger* externalLogger) +Log::initialize(const char* typed, const char* leveld, const char* appName, const char *logFileName, ExternalLogger* externalLogger, const char* syslogFacilityName) { - Log::initialize(Data(typed), Data(leveld), Data(appName), logFileName, externalLogger); + Log::initialize(Data(typed), Data(leveld), Data(appName), logFileName, externalLogger, syslogFacilityName); } void Log::initialize(const Data& typed, const Data& leveld, const Data& appName, - const char *logFileName, ExternalLogger* externalLogger) + const char *logFileName, ExternalLogger* externalLogger, + const Data& syslogFacilityName) { Type type = Log::Cout; if (isEqualNoCase(typed, "cout")) type = Log::Cout; else if (isEqualNoCase(typed, "cerr")) type = Log::Cerr; else if (isEqualNoCase(typed, "file")) type = Log::File; +#ifndef WIN32 else type = Log::Syslog; +#endif Level level = Log::Info; level = toLevel(leveld); - Log::initialize(type, level, appName, logFileName, externalLogger); + Log::initialize(type, level, appName, logFileName, externalLogger, syslogFacilityName); +} + +int +Log::parseSyslogFacilityName(const Data& facilityName) +{ +#ifndef WIN32 + /* In theory, some platforms may not have all the log facilities + defined in syslog.h. Only LOG_USER and LOG_LOCAL[0-7] are considered + mandatory. + If the compile fails with errors in this method, then the unsupported + facility names could be wrapped in conditional logic. + */ + if(facilityName == "LOG_AUTH") + { + return LOG_AUTH; + } + else if(facilityName == "LOG_AUTHPRIV") + { + return LOG_AUTHPRIV; + } + else if(facilityName == "LOG_CRON") + { + return LOG_CRON; + } + else if(facilityName == "LOG_DAEMON") + { + return LOG_DAEMON; + } + else if(facilityName == "LOG_FTP") + { + return LOG_FTP; + } + else if(facilityName == "LOG_KERN") + { + return LOG_KERN; + } + else if(facilityName == "LOG_LOCAL0") + { + return LOG_LOCAL0; + } + else if(facilityName == "LOG_LOCAL1") + { + return LOG_LOCAL1; + } + else if(facilityName == "LOG_LOCAL2") + { + return LOG_LOCAL2; + } + else if(facilityName == "LOG_LOCAL3") + { + return LOG_LOCAL3; + } + else if(facilityName == "LOG_LOCAL4") + { + return LOG_LOCAL4; + } + else if(facilityName == "LOG_LOCAL5") + { + return LOG_LOCAL5; + } + else if(facilityName == "LOG_LOCAL6") + { + return LOG_LOCAL6; + } + else if(facilityName == "LOG_LOCAL7") + { + return LOG_LOCAL7; + } + else if(facilityName == "LOG_LPR") + { + return LOG_LPR; + } + else if(facilityName == "LOG_MAIL") + { + return LOG_MAIL; + } + else if(facilityName == "LOG_NEWS") + { + return LOG_NEWS; + } + else if(facilityName == "LOG_SYSLOG") + { + return LOG_SYSLOG; + } + else if(facilityName == "LOG_USER") + { + return LOG_USER; + } + else if(facilityName == "LOG_UUCP") + { + return LOG_UUCP; + } +#endif + // Nothing matched or syslog not supported on this platform + return -1; } void Log::initialize(Type type, Level level, const Data& appName, const char * logFileName, - ExternalLogger* externalLogger) + ExternalLogger* externalLogger, + const Data& syslogFacilityName) { Lock lock(_mutex); mDefaultLoggerData.reset(); @@ -145,7 +250,28 @@ Log::initialize(Type type, Level level, const Data& appName, pb.skipBackToChar('/'); #endif mAppName = pb.position(); - + +#ifndef WIN32 + if (!syslogFacilityName.empty()) + { + mSyslogFacility = parseSyslogFacilityName(syslogFacilityName); + if(mSyslogFacility == -1) + { + mSyslogFacility = LOG_DAEMON; + if(type == Log::Syslog) + { + syslog(LOG_DAEMON | LOG_ERR, "invalid syslog facility name specified (%s), falling back to LOG_DAEMON", syslogFacilityName.c_str()); + } + } + } +#else + if (type == Syslog) + { + std::cerr << "syslog not supported on windows, using cout!" << std::endl; + type = Cout; + } +#endif + char buffer[1024]; gethostname(buffer, sizeof(buffer)); mHostname = buffer; @@ -160,9 +286,10 @@ void Log::initialize(Type type, Level level, const Data& appName, - ExternalLogger& logger) + ExternalLogger& logger, + const Data& syslogFacilityName) { - initialize(type, level, appName, 0, &logger); + initialize(type, level, appName, 0, &logger, syslogFacilityName); } void @@ -284,6 +411,36 @@ Log::setMaxByteCount(unsigned int maxByteCount, Log::LocalLoggerId loggerId) } } +void +Log::setKeepAllLogFiles(bool keepAllLogFiles) +{ + Lock lock(_mutex); + getLoggerData().setKeepAllLogFiles(keepAllLogFiles); +} + +void +Log::setKeepAllLogFiles(bool keepAllLogFiles, Log::LocalLoggerId loggerId) +{ + if (loggerId) + { + ThreadData *pData = mLocalLoggerMap.getData(loggerId); + if (pData) + { + // Local logger found. Set logging level. + pData->setKeepAllLogFiles(keepAllLogFiles); + + // We don't need local logger instance anymore. + mLocalLoggerMap.decreaseUseCount(loggerId); + pData = NULL; + } + } + else + { + Lock lock(_mutex); + mDefaultLoggerData.setKeepAllLogFiles(keepAllLogFiles); + } +} + const static Data log_("LOG_"); Data @@ -300,7 +457,7 @@ Log::toLevel(const Data& l) int i=0; while (strlen(mDescriptions[i])) { - if (strcmp(pri.c_str(), mDescriptions[i]) == 0) + if (isEqualNoCase(pri, Data(mDescriptions[i]))) { return Level(i-1); } @@ -366,14 +523,26 @@ Log::tags(Log::Level level, << GetCurrentThreadId() << Log::delim << file << ":" << line; #else // #if defined( WIN32 ) || defined( __APPLE__ ) - strm << mDescriptions[level+1] << Log::delim - << timestamp(ts) << Log::delim -// << mHostname << Log::delim - << mAppName << Log::delim - << subsystem << Log::delim -// << mPid << Log::delim - << pthread_self() << Log::delim - << pfile << ":" << line; + if(resip::Log::getLoggerData().type() == Syslog) + { + strm // << mDescriptions[level+1] << Log::delim + // << timestamp(ts) << Log::delim + // << mHostname << Log::delim + // << mAppName << Log::delim + << subsystem << Log::delim + // << mPid << Log::delim + << pthread_self() << Log::delim + << pfile << ":" << line; + } + else + strm << mDescriptions[level+1] << Log::delim + << timestamp(ts) << Log::delim + // << mHostname << Log::delim + << mAppName << Log::delim + << subsystem << Log::delim + // << mPid << Log::delim + << pthread_self() << Log::delim + << pfile << ":" << line; #endif return strm; } @@ -424,20 +593,25 @@ Log::timestamp(Data& res) "%Y%m%d-%H%M%S", /* guaranteed to fit in 256 chars, hence don't check return code */ #ifdef WIN32 - localtime(&timeInSeconds)); + localtime (&timeInSeconds)); // Thread safe call on Windows #else - localtime_r(&timeInSeconds, &localTimeResult)); + localtime_r (&timeInSeconds, &localTimeResult)); // Thread safe version of localtime on linux #endif } char msbuf[5]; /* Dividing (without remainder) by 1000 rounds the microseconds measure to the nearest millisecond. */ - sprintf(msbuf, ".%3.3ld", long(tv.tv_usec / 1000)); + snprintf(msbuf, 5, ".%3.3ld", long(tv.tv_usec / 1000)); int datebufCharsRemaining = datebufSize - (int)strlen(datebuf); +#if defined(WIN32) && defined(_M_ARM) + // There is a bug under ARM with strncat - we use strcat instead - buffer is plenty large accomdate our timestamp, no + // real need to be safe here anyway. + strcat(datebuf, msbuf); +#else strncat (datebuf, msbuf, datebufCharsRemaining - 1); - +#endif datebuf[datebufSize - 1] = '\0'; /* Just in case strncat truncated msbuf, thereby leaving its last character at the end, instead of a null terminator */ @@ -478,7 +652,7 @@ Log::getThreadSetting() Lock lock(_mutex); ThreadIf::Id thread = ThreadIf::selfId(); HashMap >::iterator res = Log::mThreadToLevel.find(thread); - assert(res != Log::mThreadToLevel.end()); + resip_assert(res != Log::mThreadToLevel.end()); if (res->second.second) { setting->mLevel = res->second.first.mLevel; @@ -509,7 +683,7 @@ void Log::setThreadSetting(ThreadSetting info) { #ifndef LOG_ENABLE_THREAD_SETTING - assert(0); + resip_assert(0); #else //cerr << "Log::setThreadSetting: " << "service: " << info.service << " level " << toString(info.level) << " for " << pthread_self() << endl; ThreadIf::Id thread = ThreadIf::selfId(); @@ -535,7 +709,7 @@ Log::setServiceLevel(int service, Level l) Lock lock(_mutex); Log::mServiceToLevel[service] = l; #ifndef LOG_ENABLE_THREAD_SETTING - assert(0); + resip_assert(0); #else set& threads = Log::mServiceToThreads[service]; for (set::iterator i = threads.begin(); i != threads.end(); i++) @@ -600,6 +774,14 @@ Log::reset() getLoggerData().reset(); } +#ifndef WIN32 +void +Log::droppingPrivileges(uid_t uid, pid_t pid) +{ + getLoggerData().droppingPrivileges(uid, pid); +} +#endif + bool Log::isLogging(Log::Level level, const resip::Subsystem& sub) { @@ -702,7 +884,7 @@ void Log::LocalLoggerMap::decreaseUseCount(Log::LocalLoggerId loggerId) if (it != mLoggerInstancesMap.end()) { it->second.second--; - assert(it->second.second >= 0); + resip_assert(it->second.second >= 0); } } @@ -772,7 +954,12 @@ Log::Guard::~Guard() else { // endl is magic in syslog -- so put it here - Instance((int)mData.size()+2) << mData << std::endl; + std::ostream& _instance = Instance((int)mData.size()+2); + if (logType == resip::Log::Syslog) + { + _instance << mLevel; + } + _instance << mData << std::endl; } } @@ -785,8 +972,7 @@ Log::ThreadData::Instance(unsigned int bytesToWrite) case Log::Syslog: if (mLogger == 0) { - std::cerr << "Creating a syslog stream" << std::endl; - mLogger = new SysLogStream; + mLogger = new SysLogStream(mAppName, mSyslogFacility); } return *mLogger; @@ -798,28 +984,40 @@ Log::ThreadData::Instance(unsigned int bytesToWrite) case Log::File: if (mLogger == 0 || - (maxLineCount() && mLineCount >= maxLineCount()) || - (maxByteCount() && ((unsigned int)mLogger->tellp()+bytesToWrite) >= maxByteCount())) + (maxLineCount() && mLineCount >= maxLineCount()) || + (maxByteCount() && ((unsigned int)mLogger->tellp() + bytesToWrite) >= maxByteCount())) { - std::cerr << "Creating a logger for file \"" << mLogFileName.c_str() << "\"" << std::endl; Data logFileName(mLogFileName != "" ? mLogFileName : "resiprocate.log"); if (mLogger) { - Data oldLogFileName(logFileName + ".old"); - delete mLogger; - // Keep one backup file: Delete .old file, Rename log file to .old - // Could be expanded in the future to keep X backup log files - remove(oldLogFileName.c_str()); - rename(logFileName.c_str(), oldLogFileName.c_str()); + if (keepAllLogFiles()) + { + char buffer[256]; + Data ts(Data::Borrow, buffer, sizeof(buffer)); + Data oldLogFileName(logFileName + "_" + timestamp(ts)); + + delete mLogger; + + // Keep all log files, rename the log file with timestamp + rename(logFileName.c_str(), oldLogFileName.c_str()); + } + else + { + Data oldLogFileName(logFileName + ".old"); + delete mLogger; + // Keep one backup file: Delete .old file, Rename log file to .old + // Could be expanded in the future to keep X backup log files + remove(oldLogFileName.c_str()); + rename(logFileName.c_str(), oldLogFileName.c_str()); + } } - // Append to log if we have a line count or byte count limit - otherwise truncate - mLogger = new std::ofstream(logFileName.c_str(), std::ios_base::out | ((maxLineCount() > 0 || maxByteCount() > 0) ? std::ios_base::app : std::ios_base::trunc)); + mLogger = new std::ofstream(logFileName.c_str(), std::ios_base::out | std::ios_base::app); mLineCount = 0; } mLineCount++; return *mLogger; default: - assert(0); + resip_assert(0); return std::cout; } } @@ -831,6 +1029,22 @@ Log::ThreadData::reset() mLogger = NULL; } +#ifndef WIN32 +void +Log::ThreadData::droppingPrivileges(uid_t uid, pid_t pid) +{ + if(mType == Log::File) + { + Data logFileName(mLogFileName != "" ? mLogFileName : "resiprocate.log"); + if(chown(logFileName.c_str(), uid, pid) < 0) + { + // Some error occurred + std::cerr << "ERROR: chown failed on " << logFileName << std::endl; + } + } +} +#endif + /* ==================================================================== * The Vovida Software License, Version 1.0 * diff --git a/src/libs/resiprocate/rutil/Log.hxx b/src/libs/resiprocate/rutil/Log.hxx index 41e8233e..fab31122 100644 --- a/src/libs/resiprocate/rutil/Log.hxx +++ b/src/libs/resiprocate/rutil/Log.hxx @@ -163,25 +163,31 @@ class Log return mAppName; } + static int parseSyslogFacilityName(const Data& facilityName); + static void initialize(Type type, Level level, const Data& appName, const char * logFileName = 0, - ExternalLogger* externalLogger = 0); + ExternalLogger* externalLogger = 0, + const Data& syslogFacility = "LOG_DAEMON"); static void initialize(const Data& type, const Data& level, const Data& appName, const char * logFileName = 0, - ExternalLogger* externalLogger = 0); + ExternalLogger* externalLogger = 0, + const Data& syslogFacility = "LOG_DAEMON"); static void initialize(const char* type, const char* level, const char* appName, const char * logFileName = 0, - ExternalLogger* externalLogger = 0); + ExternalLogger* externalLogger = 0, + const char* syslogFacility = "LOG_DAEMON"); static void initialize(Type type, Level level, const Data& appName, - ExternalLogger& logger); + ExternalLogger& logger, + const Data& syslogFacility = "LOG_DAEMON"); /** @brief Set logging level for current thread. * If thread has no local logger attached, then set global logging level. @@ -202,6 +208,8 @@ class Log static void setMaxLineCount(unsigned int maxLineCount, LocalLoggerId loggerId); static void setMaxByteCount(unsigned int maxByteCount); static void setMaxByteCount(unsigned int maxByteCount, LocalLoggerId loggerId); + static void setKeepAllLogFiles(bool keepAllLogFiles); + static void setKeepAllLogFiles(bool keepAllLogFiles, LocalLoggerId loggerId); static Level toLevel(const Data& l); static Type toType(const Data& t); static Data toString(Level l); @@ -230,7 +238,7 @@ class Log Type type, Level level, const char * logFileName = NULL, - ExternalLogger* externalLogger = NULL); + ExternalLogger* externalLogger = NULL); /** Destroy existing logger instance. * @retval 0 on success @@ -253,16 +261,19 @@ class Log static bool isLogging(Log::Level level, const Subsystem&); static void OutputToWin32DebugWindow(const Data& result); static void reset(); ///< Frees logger stream - - public: - static unsigned int MaxLineCount; - static unsigned int MaxByteCount; +#ifndef WIN32 + static void droppingPrivileges(uid_t uid, pid_t pid); +#endif protected: static Mutex _mutex; static volatile short touchCount; static const Data delim; + static unsigned int MaxLineCount; + static unsigned int MaxByteCount; + static bool KeepAllLogFiles; + class ThreadData { public: @@ -273,6 +284,8 @@ class Log mMaxLineCount(0), mMaxByteCount(0), mExternalLogger(pExternalLogger), + mKeepAllLogFiles(false), + mKeepAllLogFilesSet(false), mId(id), mType(type), mLogger(NULL), @@ -302,16 +315,25 @@ class Log LocalLoggerId id() const {return mId;} unsigned int maxLineCount() { return mMaxLineCount ? mMaxLineCount : MaxLineCount; } // return local max, if not set use global max unsigned int maxByteCount() { return mMaxByteCount ? mMaxByteCount : MaxByteCount; } // return local max, if not set use global max + bool keepAllLogFiles() { return mKeepAllLogFilesSet ? mKeepAllLogFiles : KeepAllLogFiles; } // return local if set, if not use global setting + Type type() const {return mType;} + + void setKeepAllLogFiles(bool keepAllLogFiles) { mKeepAllLogFiles = keepAllLogFiles; mKeepAllLogFilesSet = true; } std::ostream& Instance(unsigned int bytesToWrite); ///< Return logger stream instance, creating it if needed. void reset(); ///< Frees logger stream - +#ifndef WIN32 + void droppingPrivileges(uid_t uid, pid_t pid); +#endif volatile Level mLevel; volatile unsigned int mMaxLineCount; volatile unsigned int mMaxByteCount; ExternalLogger* mExternalLogger; protected: + volatile bool mKeepAllLogFiles; + volatile bool mKeepAllLogFilesSet; + friend class Guard; const LocalLoggerId mId; Type mType; @@ -323,6 +345,7 @@ class Log static ThreadData mDefaultLoggerData; ///< Default logger settings. static Data mAppName; static Data mHostname; + static int mSyslogFacility; #ifndef WIN32 static pid_t mPid; #else @@ -357,7 +380,7 @@ class Log Type type, Level level, const char * logFileName = NULL, - ExternalLogger* externalLogger = NULL); + ExternalLogger* externalLogger = NULL); /** Remove existing logger instance from map and destroy. * @retval 0 on success diff --git a/src/libs/resiprocate/rutil/MD5Stream.cxx b/src/libs/resiprocate/rutil/MD5Stream.cxx index b1ab07c4..0c9bdc09 100644 --- a/src/libs/resiprocate/rutil/MD5Stream.cxx +++ b/src/libs/resiprocate/rutil/MD5Stream.cxx @@ -11,6 +11,7 @@ MD5Buffer::MD5Buffer() { MD5Init(&mContext); setp(mBuf, mBuf + sizeof(mBuf)); + mLen = 0; } MD5Buffer::~MD5Buffer() @@ -26,6 +27,7 @@ MD5Buffer::sync() MD5Update(&mContext, reinterpret_cast (pbase()), (unsigned int)len); // reset the put buffer setp(mBuf, mBuf + sizeof(mBuf)); + mLen += len; } return 0; } @@ -61,6 +63,12 @@ MD5Buffer::getBin() return digest; } +size_t +MD5Buffer::bytesTaken() +{ + return mLen; +} + MD5Stream::MD5Stream() : std::ostream(this) { @@ -84,6 +92,12 @@ MD5Stream::getBin() return MD5Buffer::getBin(); } +size_t +MD5Stream::bytesTaken() +{ + return MD5Buffer::bytesTaken(); +} + /* ==================================================================== * The Vovida Software License, Version 1.0 * diff --git a/src/libs/resiprocate/rutil/MD5Stream.hxx b/src/libs/resiprocate/rutil/MD5Stream.hxx index dd2df4eb..8fae5496 100644 --- a/src/libs/resiprocate/rutil/MD5Stream.hxx +++ b/src/libs/resiprocate/rutil/MD5Stream.hxx @@ -20,12 +20,14 @@ class MD5Buffer : public std::streambuf */ Data getHex(); Data getBin(); + size_t bytesTaken(); protected: virtual int sync(); virtual int overflow(int c = -1); private: char mBuf[64]; MD5Context mContext; + size_t mLen; }; /** @@ -43,6 +45,7 @@ class MD5Stream : private MD5Buffer, public std::ostream */ Data getHex(); Data getBin(); + size_t bytesTaken(); private: //MD5Buffer mStreambuf; }; diff --git a/src/libs/resiprocate/rutil/Makefile b/src/libs/resiprocate/rutil/Makefile deleted file mode 100644 index 127da8aa..00000000 --- a/src/libs/resiprocate/rutil/Makefile +++ /dev/null @@ -1,157 +0,0 @@ -############################################################################# -# Makefile for building: rutil -# Generated by qmake (2.01a) (Qt 4.7.4) on: ?? 19. ??? 14:08:39 2011 -# Project: rutil.pro -# Template: lib -# Command: d:\tools\qtsdk\desktop\qt\4.7.4\msvc2008\bin\qmake.exe -spec d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\win32-msvc2008 -o Makefile rutil.pro -############################################################################# - -first: debug -install: debug-install -uninstall: debug-uninstall -MAKEFILE = Makefile -QMAKE = d:\tools\qtsdk\desktop\qt\4.7.4\msvc2008\bin\qmake.exe -DEL_FILE = del -CHK_DIR_EXISTS= if not exist -MKDIR = mkdir -COPY = copy /y -COPY_FILE = $(COPY) -COPY_DIR = xcopy /s /q /y /i -INSTALL_FILE = $(COPY_FILE) -INSTALL_PROGRAM = $(COPY_FILE) -INSTALL_DIR = $(COPY_DIR) -DEL_FILE = del -SYMLINK = -DEL_DIR = rmdir -MOVE = move -CHK_DIR_EXISTS= if not exist -MKDIR = mkdir -SUBTARGETS = \ - debug \ - release - -debug: $(MAKEFILE).Debug FORCE - $(MAKE) -f $(MAKEFILE).Debug -debug-make_default: $(MAKEFILE).Debug FORCE - $(MAKE) -f $(MAKEFILE).Debug -debug-make_first: $(MAKEFILE).Debug FORCE - $(MAKE) -f $(MAKEFILE).Debug first -debug-all: $(MAKEFILE).Debug FORCE - $(MAKE) -f $(MAKEFILE).Debug all -debug-clean: $(MAKEFILE).Debug FORCE - $(MAKE) -f $(MAKEFILE).Debug clean -debug-distclean: $(MAKEFILE).Debug FORCE - $(MAKE) -f $(MAKEFILE).Debug distclean -debug-install: $(MAKEFILE).Debug FORCE - $(MAKE) -f $(MAKEFILE).Debug install -debug-uninstall: $(MAKEFILE).Debug FORCE - $(MAKE) -f $(MAKEFILE).Debug uninstall -release: $(MAKEFILE).Release FORCE - $(MAKE) -f $(MAKEFILE).Release -release-make_default: $(MAKEFILE).Release FORCE - $(MAKE) -f $(MAKEFILE).Release -release-make_first: $(MAKEFILE).Release FORCE - $(MAKE) -f $(MAKEFILE).Release first -release-all: $(MAKEFILE).Release FORCE - $(MAKE) -f $(MAKEFILE).Release all -release-clean: $(MAKEFILE).Release FORCE - $(MAKE) -f $(MAKEFILE).Release clean -release-distclean: $(MAKEFILE).Release FORCE - $(MAKE) -f $(MAKEFILE).Release distclean -release-install: $(MAKEFILE).Release FORCE - $(MAKE) -f $(MAKEFILE).Release install -release-uninstall: $(MAKEFILE).Release FORCE - $(MAKE) -f $(MAKEFILE).Release uninstall - -Makefile: rutil.pro d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\win32-msvc2008\qmake.conf d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\qconfig.pri \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\modules\qt_webkit_version.pri \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt_functions.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt_config.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\exclusive_builds.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\default_pre.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\default_pre.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\debug.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\debug_and_release.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\default_post.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\default_post.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\staticlib.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\static.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\rtti.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\exceptions.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\stl.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\embed_manifest_exe.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\embed_manifest_dll.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\warn_on.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\thread.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\moc.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\windows.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\resources.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\uic.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\yacc.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\lex.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\incredibuild_xge.prf \ - d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\include_source_dir.prf - $(QMAKE) -spec d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\win32-msvc2008 -o Makefile rutil.pro -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\qconfig.pri: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\modules\qt_webkit_version.pri: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt_functions.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt_config.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\exclusive_builds.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\default_pre.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\default_pre.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\debug.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\debug_and_release.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\default_post.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\default_post.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\staticlib.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\static.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\rtti.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\exceptions.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\stl.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\embed_manifest_exe.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\embed_manifest_dll.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\warn_on.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\qt.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\thread.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\moc.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\win32\windows.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\resources.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\uic.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\yacc.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\lex.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\incredibuild_xge.prf: -d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\features\include_source_dir.prf: -qmake: qmake_all FORCE - @$(QMAKE) -spec d:\Tools\QtSDK\Desktop\Qt\4.7.4\msvc2008\mkspecs\win32-msvc2008 -o Makefile rutil.pro - -qmake_all: FORCE - -make_default: debug-make_default release-make_default FORCE -make_first: debug-make_first release-make_first FORCE -all: debug-all release-all FORCE -clean: debug-clean release-clean FORCE - -$(DEL_FILE) ..\..\..\Libs\compiled\win\rutil.ilk - -$(DEL_FILE) vc*.pdb - -$(DEL_FILE) vc*.idb -distclean: debug-distclean release-distclean FORCE - -$(DEL_FILE) Makefile - -$(DEL_FILE) ..\..\..\Libs\compiled\win\rutil.pdb - -check: first - -debug-mocclean: $(MAKEFILE).Debug - $(MAKE) -f $(MAKEFILE).Debug mocclean -release-mocclean: $(MAKEFILE).Release - $(MAKE) -f $(MAKEFILE).Release mocclean -mocclean: debug-mocclean release-mocclean - -debug-mocables: $(MAKEFILE).Debug - $(MAKE) -f $(MAKEFILE).Debug mocables -release-mocables: $(MAKEFILE).Release - $(MAKE) -f $(MAKEFILE).Release mocables -mocables: debug-mocables release-mocables -FORCE: - -$(MAKEFILE).Debug: Makefile -$(MAKEFILE).Release: Makefile diff --git a/src/libs/resiprocate/rutil/Makefile.am b/src/libs/resiprocate/rutil/Makefile.am new file mode 100644 index 00000000..b3620daf --- /dev/null +++ b/src/libs/resiprocate/rutil/Makefile.am @@ -0,0 +1,257 @@ +# $Id$ + +if USE_ARES +SUBDIRS = dns/ares +else +SUBDIRS = +endif + +SUBDIRS += . test + +EXTRA_DIST = fixupGperf +EXTRA_DIST += mainpage.doc +EXTRA_DIST += *.vcxproj +EXTRA_DIST += WinCompat.cxx +EXTRA_DIST += msvc/*.h +EXTRA_DIST += dns/LocalDns.cxx + +#AM_CXXFLAGS = -I../contrib/ares -DUSE_ARES +AM_CXXFLAGS = -I $(top_srcdir) +if USE_ARES +AM_CXXFLAGS += -I $(top_srcdir)/rutil/dns/ares +endif + +lib_LTLIBRARIES = librutil.la + +librutil_la_LIBADD = $(LIBSSL_LIBADD) +librutil_la_LIBADD += $(LIBRADIUS_LIBADD) +librutil_la_LIBADD += $(LIBARES_LIBADD) +librutil_la_LIBADD += @LIBSTL_LIBADD@ +librutil_la_LIBADD += @LIBLOG_LIBADD@ +#librutil_la_LIBADD += -lrt +librutil_la_LIBADD += @LIBPTHREAD_LIBADD@ +librutil_la_LDFLAGS = @LIBTOOL_VERSION_RELEASE@ -export-dynamic + +librutil_la_SOURCES = \ + AbstractFifo.cxx \ + AndroidLogger.cxx \ + BaseException.cxx \ + Coders.cxx \ + Condition.cxx \ + ConfigParse.cxx \ + CountStream.cxx \ + ServerProcess.cxx \ + Data.cxx \ + DataStream.cxx \ + DnsUtil.cxx \ + FileSystem.cxx \ + GeneralCongestionManager.cxx \ + GenericIPAddress.cxx \ + HeapInstanceCounter.cxx \ + KeyValueStore.cxx \ + Lock.cxx \ + Log.cxx \ + MD5Stream.cxx \ + Mutex.cxx \ + NetNs.cxx \ + ParseBuffer.cxx \ + ParseException.cxx \ + Poll.cxx \ + PoolBase.cxx \ + FdPoll.cxx \ + RADIUSDigestAuthenticator.cxx \ + RWMutex.cxx \ + Random.cxx \ + RecursiveMutex.cxx \ + resipfaststreams.cxx \ + SelectInterruptor.cxx \ + Sha1.cxx \ + Socket.cxx \ + Subsystem.cxx \ + SysLogBuf.cxx \ + SysLogStream.cxx \ + ThreadIf.cxx \ + Time.cxx \ + Timer.cxx \ + TransportType.cxx \ + vmd5.cxx \ + XMLCursor.cxx \ + \ + dns/AresDns.cxx \ + dns/DnsCnameRecord.cxx \ + dns/DnsAAAARecord.cxx \ + dns/DnsHostRecord.cxx \ + dns/DnsNaptrRecord.cxx \ + dns/DnsResourceRecord.cxx \ + dns/DnsThread.hxx \ + dns/DnsSrvRecord.cxx \ + dns/DnsStub.cxx \ + dns/DnsThread.cxx \ + dns/ExternalDnsFactory.cxx \ + dns/RRCache.cxx \ + dns/RRList.cxx \ + dns/RRVip.cxx \ + dns/QueryTypes.cxx \ + dns/RROverlay.cxx \ + \ + stun/Stun.cxx \ + stun/Udp.cxx \ + \ + hep/HepAgent.cxx \ + hep/ResipHep.cxx + +if USE_SSL +librutil_la_SOURCES += \ + ssl/OpenSSLInit.cxx \ + ssl/SHA1Stream.cxx +endif + +rutilincludedir = $(includedir)/rutil +nobase_rutilinclude_HEADERS = compat.hxx \ + ResipAssert.h \ + FileSystem.hxx \ + HashMap.hxx \ + wince/WceCompat.hxx \ + SysLogStream.hxx \ + AsyncID.hxx \ + AsyncBool.hxx \ + ConfigParse.hxx \ + CongestionManager.hxx \ + GeneralCongestionManager.hxx \ + HeapInstanceCounter.hxx \ + KeyValueStore.hxx \ + SharedCount.hxx \ + FdSetIOObserver.hxx \ + Fifo.hxx \ + CircularBuffer.hxx \ + FiniteFifo.hxx \ + ParseBuffer.hxx \ + Log.hxx \ + ThreadIf.hxx \ + WinLeakCheck.hxx \ + Random.hxx \ + RecursiveMutex.hxx \ + AsyncProcessHandler.hxx \ + RADIUSDigestAuthenticator.hxx \ + RWMutex.hxx \ + Subsystem.hxx \ + Logger.hxx \ + MD5Stream.hxx \ + DnsUtil.hxx \ + Timer.hxx \ + DigestStream.hxx \ + TransportType.hxx \ + resipfaststreams.hxx \ + Coders.hxx \ + Sha1.hxx \ + SharedPtr.hxx \ + SelectInterruptor.hxx \ + Socket.hxx \ + dns/ExternalDnsFactory.hxx \ + dns/DnsStub.hxx \ + dns/DnsHostRecord.hxx \ + dns/QueryTypes.hxx \ + dns/RROverlay.hxx \ + dns/AresCompat.hxx \ + dns/ExternalDns.hxx \ + dns/DnsNaptrRecord.hxx \ + dns/RRList.hxx \ + dns/LocalDns.hxx \ + dns/RRFactory.hxx \ + dns/DnsSrvRecord.hxx \ + dns/DnsCnameRecord.hxx \ + dns/AresDns.hxx \ + dns/RRCache.hxx \ + dns/DnsHandler.hxx \ + dns/RRVip.hxx \ + dns/DnsAAAARecord.hxx \ + dns/DnsResourceRecord.hxx \ + Condition.hxx \ + WinCompat.hxx \ + vthread.hxx \ + ServerProcess.hxx \ + Data.hxx \ + Lock.hxx \ + TimeLimitFifo.hxx \ + Mutex.hxx \ + NetNs.hxx \ + GenericTimerQueue.hxx \ + IntrusiveListElement.hxx \ + ssl/SHA1Stream.hxx \ + ssl/OpenSSLInit.hxx \ + CountStream.hxx \ + vmd5.hxx \ + XMLCursor.hxx \ + PoolBase.hxx \ + FdPoll.hxx \ + Time.hxx \ + Lockable.hxx \ + stun/Udp.hxx \ + stun/Stun.hxx \ + SysLogBuf.hxx \ + Inserter.hxx \ + DataStream.hxx \ + GenericIPAddress.hxx \ + AbstractFifo.hxx \ + AndroidLogger.hxx \ + ParseException.hxx \ + BaseException.hxx \ + DataException.hxx \ + Poll.hxx \ + StlPoolAllocator.hxx \ + ProducerFifoBuffer.hxx \ + DinkyPool.hxx \ + ConsumerFifoBuffer.hxx \ + hep/HepAgent.hxx \ + hep/ResipHep.hxx + + +############################################################################## +# +# The Vovida Software License, Version 1.0 +# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The names "VOCAL", "Vovida Open Communication Application Library", +# and "Vovida Open Communication Application Library (VOCAL)" must +# not be used to endorse or promote products derived from this +# software without prior written permission. For written +# permission, please contact vocal@vovida.org. +# +# 4. Products derived from this software may not be called "VOCAL", nor +# may "VOCAL" appear in their name, without prior written +# permission of Vovida Networks, Inc. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. +# +# ==================================================================== +# +# This software consists of voluntary contributions made by Vovida +# Networks, Inc. and many individuals on behalf of Vovida Networks, +# Inc. For more information on Vovida Networks, Inc., please see +# . +# +############################################################################## diff --git a/src/libs/resiprocate/rutil/Makefile.in b/src/libs/resiprocate/rutil/Makefile.in new file mode 100644 index 00000000..821dae53 --- /dev/null +++ b/src/libs/resiprocate/rutil/Makefile.in @@ -0,0 +1,1379 @@ +# Makefile.in generated by automake 1.16.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2018 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# $Id$ + + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@USE_ARES_TRUE@am__append_1 = -I $(top_srcdir)/rutil/dns/ares +@USE_SSL_TRUE@am__append_2 = \ +@USE_SSL_TRUE@ ssl/OpenSSLInit.cxx \ +@USE_SSL_TRUE@ ssl/SHA1Stream.cxx + +subdir = rutil +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_have_epoll.m4 \ + $(top_srcdir)/m4/gprefver.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(nobase_rutilinclude_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(rutilincludedir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +am__DEPENDENCIES_1 = +librutil_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) +am__librutil_la_SOURCES_DIST = AbstractFifo.cxx AndroidLogger.cxx \ + BaseException.cxx Coders.cxx Condition.cxx ConfigParse.cxx \ + CountStream.cxx ServerProcess.cxx Data.cxx DataStream.cxx \ + DnsUtil.cxx FileSystem.cxx GeneralCongestionManager.cxx \ + GenericIPAddress.cxx HeapInstanceCounter.cxx KeyValueStore.cxx \ + Lock.cxx Log.cxx MD5Stream.cxx Mutex.cxx NetNs.cxx \ + ParseBuffer.cxx ParseException.cxx Poll.cxx PoolBase.cxx \ + FdPoll.cxx RADIUSDigestAuthenticator.cxx RWMutex.cxx \ + Random.cxx RecursiveMutex.cxx resipfaststreams.cxx \ + SelectInterruptor.cxx Sha1.cxx Socket.cxx Subsystem.cxx \ + SysLogBuf.cxx SysLogStream.cxx ThreadIf.cxx Time.cxx Timer.cxx \ + TransportType.cxx vmd5.cxx XMLCursor.cxx dns/AresDns.cxx \ + dns/DnsCnameRecord.cxx dns/DnsAAAARecord.cxx \ + dns/DnsHostRecord.cxx dns/DnsNaptrRecord.cxx \ + dns/DnsResourceRecord.cxx dns/DnsThread.hxx \ + dns/DnsSrvRecord.cxx dns/DnsStub.cxx dns/DnsThread.cxx \ + dns/ExternalDnsFactory.cxx dns/RRCache.cxx dns/RRList.cxx \ + dns/RRVip.cxx dns/QueryTypes.cxx dns/RROverlay.cxx \ + stun/Stun.cxx stun/Udp.cxx hep/HepAgent.cxx hep/ResipHep.cxx \ + ssl/OpenSSLInit.cxx ssl/SHA1Stream.cxx +am__dirstamp = $(am__leading_dot)dirstamp +@USE_SSL_TRUE@am__objects_1 = ssl/OpenSSLInit.lo ssl/SHA1Stream.lo +am_librutil_la_OBJECTS = AbstractFifo.lo AndroidLogger.lo \ + BaseException.lo Coders.lo Condition.lo ConfigParse.lo \ + CountStream.lo ServerProcess.lo Data.lo DataStream.lo \ + DnsUtil.lo FileSystem.lo GeneralCongestionManager.lo \ + GenericIPAddress.lo HeapInstanceCounter.lo KeyValueStore.lo \ + Lock.lo Log.lo MD5Stream.lo Mutex.lo NetNs.lo ParseBuffer.lo \ + ParseException.lo Poll.lo PoolBase.lo FdPoll.lo \ + RADIUSDigestAuthenticator.lo RWMutex.lo Random.lo \ + RecursiveMutex.lo resipfaststreams.lo SelectInterruptor.lo \ + Sha1.lo Socket.lo Subsystem.lo SysLogBuf.lo SysLogStream.lo \ + ThreadIf.lo Time.lo Timer.lo TransportType.lo vmd5.lo \ + XMLCursor.lo dns/AresDns.lo dns/DnsCnameRecord.lo \ + dns/DnsAAAARecord.lo dns/DnsHostRecord.lo \ + dns/DnsNaptrRecord.lo dns/DnsResourceRecord.lo \ + dns/DnsSrvRecord.lo dns/DnsStub.lo dns/DnsThread.lo \ + dns/ExternalDnsFactory.lo dns/RRCache.lo dns/RRList.lo \ + dns/RRVip.lo dns/QueryTypes.lo dns/RROverlay.lo stun/Stun.lo \ + stun/Udp.lo hep/HepAgent.lo hep/ResipHep.lo $(am__objects_1) +librutil_la_OBJECTS = $(am_librutil_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +librutil_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(librutil_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/AbstractFifo.Plo \ + ./$(DEPDIR)/AndroidLogger.Plo ./$(DEPDIR)/BaseException.Plo \ + ./$(DEPDIR)/Coders.Plo ./$(DEPDIR)/Condition.Plo \ + ./$(DEPDIR)/ConfigParse.Plo ./$(DEPDIR)/CountStream.Plo \ + ./$(DEPDIR)/Data.Plo ./$(DEPDIR)/DataStream.Plo \ + ./$(DEPDIR)/DnsUtil.Plo ./$(DEPDIR)/FdPoll.Plo \ + ./$(DEPDIR)/FileSystem.Plo \ + ./$(DEPDIR)/GeneralCongestionManager.Plo \ + ./$(DEPDIR)/GenericIPAddress.Plo \ + ./$(DEPDIR)/HeapInstanceCounter.Plo \ + ./$(DEPDIR)/KeyValueStore.Plo ./$(DEPDIR)/Lock.Plo \ + ./$(DEPDIR)/Log.Plo ./$(DEPDIR)/MD5Stream.Plo \ + ./$(DEPDIR)/Mutex.Plo ./$(DEPDIR)/NetNs.Plo \ + ./$(DEPDIR)/ParseBuffer.Plo ./$(DEPDIR)/ParseException.Plo \ + ./$(DEPDIR)/Poll.Plo ./$(DEPDIR)/PoolBase.Plo \ + ./$(DEPDIR)/RADIUSDigestAuthenticator.Plo \ + ./$(DEPDIR)/RWMutex.Plo ./$(DEPDIR)/Random.Plo \ + ./$(DEPDIR)/RecursiveMutex.Plo \ + ./$(DEPDIR)/SelectInterruptor.Plo \ + ./$(DEPDIR)/ServerProcess.Plo ./$(DEPDIR)/Sha1.Plo \ + ./$(DEPDIR)/Socket.Plo ./$(DEPDIR)/Subsystem.Plo \ + ./$(DEPDIR)/SysLogBuf.Plo ./$(DEPDIR)/SysLogStream.Plo \ + ./$(DEPDIR)/ThreadIf.Plo ./$(DEPDIR)/Time.Plo \ + ./$(DEPDIR)/Timer.Plo ./$(DEPDIR)/TransportType.Plo \ + ./$(DEPDIR)/XMLCursor.Plo ./$(DEPDIR)/resipfaststreams.Plo \ + ./$(DEPDIR)/vmd5.Plo dns/$(DEPDIR)/AresDns.Plo \ + dns/$(DEPDIR)/DnsAAAARecord.Plo \ + dns/$(DEPDIR)/DnsCnameRecord.Plo \ + dns/$(DEPDIR)/DnsHostRecord.Plo \ + dns/$(DEPDIR)/DnsNaptrRecord.Plo \ + dns/$(DEPDIR)/DnsResourceRecord.Plo \ + dns/$(DEPDIR)/DnsSrvRecord.Plo dns/$(DEPDIR)/DnsStub.Plo \ + dns/$(DEPDIR)/DnsThread.Plo \ + dns/$(DEPDIR)/ExternalDnsFactory.Plo \ + dns/$(DEPDIR)/QueryTypes.Plo dns/$(DEPDIR)/RRCache.Plo \ + dns/$(DEPDIR)/RRList.Plo dns/$(DEPDIR)/RROverlay.Plo \ + dns/$(DEPDIR)/RRVip.Plo hep/$(DEPDIR)/HepAgent.Plo \ + hep/$(DEPDIR)/ResipHep.Plo ssl/$(DEPDIR)/OpenSSLInit.Plo \ + ssl/$(DEPDIR)/SHA1Stream.Plo stun/$(DEPDIR)/Stun.Plo \ + stun/$(DEPDIR)/Udp.Plo +am__mv = mv -f +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CXXFLAGS) $(CXXFLAGS) +AM_V_CXX = $(am__v_CXX_@AM_V@) +am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) +am__v_CXX_0 = @echo " CXX " $@; +am__v_CXX_1 = +CXXLD = $(CXX) +CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) +am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) +am__v_CXXLD_0 = @echo " CXXLD " $@; +am__v_CXXLD_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(librutil_la_SOURCES) +DIST_SOURCES = $(am__librutil_la_SOURCES_DIST) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +HEADERS = $(nobase_rutilinclude_HEADERS) +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = . test dns/ares +am__DIST_COMMON = $(srcdir)/Makefile.in \ + $(top_srcdir)/build-aux/depcomp TODO +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DEPS_PYTHON_CFLAGS = @DEPS_PYTHON_CFLAGS@ +DEPS_PYTHON_LIBS = @DEPS_PYTHON_LIBS@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GPERF = @GPERF@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBARES_LIBADD = @LIBARES_LIBADD@ +LIBGEOIP_LIBADD = @LIBGEOIP_LIBADD@ +LIBLOG_LIBADD = @LIBLOG_LIBADD@ +LIBMYSQL_LIBADD = @LIBMYSQL_LIBADD@ +LIBNETSNMP_LDADD = @LIBNETSNMP_LDADD@ +LIBOBJS = @LIBOBJS@ +LIBPOPT_LIBADD = @LIBPOPT_LIBADD@ +LIBPOSTGRESQL_LIBADD = @LIBPOSTGRESQL_LIBADD@ +LIBPTHREAD_LIBADD = @LIBPTHREAD_LIBADD@ +LIBRADIUS_LIBADD = @LIBRADIUS_LIBADD@ +LIBS = @LIBS@ +LIBSSL_LIBADD = @LIBSSL_LIBADD@ +LIBSTL_LIBADD = @LIBSTL_LIBADD@ +LIBTOOL = @LIBTOOL@ +LIBTOOL_VERSION_RELEASE = @LIBTOOL_VERSION_RELEASE@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +PYCXX_SRCDIR = @PYCXX_SRCDIR@ +QT5_CFLAGS = @QT5_CFLAGS@ +QT5_LIBS = @QT5_LIBS@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SO_RELEASE = @SO_RELEASE@ +STRIP = @STRIP@ +TP_QT5_CFLAGS = @TP_QT5_CFLAGS@ +TP_QT5_LIBS = @TP_QT5_LIBS@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +reproplugindir = @reproplugindir@ +returnpkglibdir = @returnpkglibdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +@USE_ARES_FALSE@SUBDIRS = . test +@USE_ARES_TRUE@SUBDIRS = dns/ares . test +EXTRA_DIST = fixupGperf mainpage.doc *.vcxproj WinCompat.cxx msvc/*.h \ + dns/LocalDns.cxx + +#AM_CXXFLAGS = -I../contrib/ares -DUSE_ARES +AM_CXXFLAGS = -I $(top_srcdir) $(am__append_1) +lib_LTLIBRARIES = librutil.la +#librutil_la_LIBADD += -lrt +librutil_la_LIBADD = $(LIBSSL_LIBADD) $(LIBRADIUS_LIBADD) \ + $(LIBARES_LIBADD) @LIBSTL_LIBADD@ @LIBLOG_LIBADD@ \ + @LIBPTHREAD_LIBADD@ $(am__empty) +librutil_la_LDFLAGS = @LIBTOOL_VERSION_RELEASE@ -export-dynamic +librutil_la_SOURCES = AbstractFifo.cxx AndroidLogger.cxx \ + BaseException.cxx Coders.cxx Condition.cxx ConfigParse.cxx \ + CountStream.cxx ServerProcess.cxx Data.cxx DataStream.cxx \ + DnsUtil.cxx FileSystem.cxx GeneralCongestionManager.cxx \ + GenericIPAddress.cxx HeapInstanceCounter.cxx KeyValueStore.cxx \ + Lock.cxx Log.cxx MD5Stream.cxx Mutex.cxx NetNs.cxx \ + ParseBuffer.cxx ParseException.cxx Poll.cxx PoolBase.cxx \ + FdPoll.cxx RADIUSDigestAuthenticator.cxx RWMutex.cxx \ + Random.cxx RecursiveMutex.cxx resipfaststreams.cxx \ + SelectInterruptor.cxx Sha1.cxx Socket.cxx Subsystem.cxx \ + SysLogBuf.cxx SysLogStream.cxx ThreadIf.cxx Time.cxx Timer.cxx \ + TransportType.cxx vmd5.cxx XMLCursor.cxx dns/AresDns.cxx \ + dns/DnsCnameRecord.cxx dns/DnsAAAARecord.cxx \ + dns/DnsHostRecord.cxx dns/DnsNaptrRecord.cxx \ + dns/DnsResourceRecord.cxx dns/DnsThread.hxx \ + dns/DnsSrvRecord.cxx dns/DnsStub.cxx dns/DnsThread.cxx \ + dns/ExternalDnsFactory.cxx dns/RRCache.cxx dns/RRList.cxx \ + dns/RRVip.cxx dns/QueryTypes.cxx dns/RROverlay.cxx \ + stun/Stun.cxx stun/Udp.cxx hep/HepAgent.cxx hep/ResipHep.cxx \ + $(am__append_2) +rutilincludedir = $(includedir)/rutil +nobase_rutilinclude_HEADERS = compat.hxx \ + ResipAssert.h \ + FileSystem.hxx \ + HashMap.hxx \ + wince/WceCompat.hxx \ + SysLogStream.hxx \ + AsyncID.hxx \ + AsyncBool.hxx \ + ConfigParse.hxx \ + CongestionManager.hxx \ + GeneralCongestionManager.hxx \ + HeapInstanceCounter.hxx \ + KeyValueStore.hxx \ + SharedCount.hxx \ + FdSetIOObserver.hxx \ + Fifo.hxx \ + CircularBuffer.hxx \ + FiniteFifo.hxx \ + ParseBuffer.hxx \ + Log.hxx \ + ThreadIf.hxx \ + WinLeakCheck.hxx \ + Random.hxx \ + RecursiveMutex.hxx \ + AsyncProcessHandler.hxx \ + RADIUSDigestAuthenticator.hxx \ + RWMutex.hxx \ + Subsystem.hxx \ + Logger.hxx \ + MD5Stream.hxx \ + DnsUtil.hxx \ + Timer.hxx \ + DigestStream.hxx \ + TransportType.hxx \ + resipfaststreams.hxx \ + Coders.hxx \ + Sha1.hxx \ + SharedPtr.hxx \ + SelectInterruptor.hxx \ + Socket.hxx \ + dns/ExternalDnsFactory.hxx \ + dns/DnsStub.hxx \ + dns/DnsHostRecord.hxx \ + dns/QueryTypes.hxx \ + dns/RROverlay.hxx \ + dns/AresCompat.hxx \ + dns/ExternalDns.hxx \ + dns/DnsNaptrRecord.hxx \ + dns/RRList.hxx \ + dns/LocalDns.hxx \ + dns/RRFactory.hxx \ + dns/DnsSrvRecord.hxx \ + dns/DnsCnameRecord.hxx \ + dns/AresDns.hxx \ + dns/RRCache.hxx \ + dns/DnsHandler.hxx \ + dns/RRVip.hxx \ + dns/DnsAAAARecord.hxx \ + dns/DnsResourceRecord.hxx \ + Condition.hxx \ + WinCompat.hxx \ + vthread.hxx \ + ServerProcess.hxx \ + Data.hxx \ + Lock.hxx \ + TimeLimitFifo.hxx \ + Mutex.hxx \ + NetNs.hxx \ + GenericTimerQueue.hxx \ + IntrusiveListElement.hxx \ + ssl/SHA1Stream.hxx \ + ssl/OpenSSLInit.hxx \ + CountStream.hxx \ + vmd5.hxx \ + XMLCursor.hxx \ + PoolBase.hxx \ + FdPoll.hxx \ + Time.hxx \ + Lockable.hxx \ + stun/Udp.hxx \ + stun/Stun.hxx \ + SysLogBuf.hxx \ + Inserter.hxx \ + DataStream.hxx \ + GenericIPAddress.hxx \ + AbstractFifo.hxx \ + AndroidLogger.hxx \ + ParseException.hxx \ + BaseException.hxx \ + DataException.hxx \ + Poll.hxx \ + StlPoolAllocator.hxx \ + ProducerFifoBuffer.hxx \ + DinkyPool.hxx \ + ConsumerFifoBuffer.hxx \ + hep/HepAgent.hxx \ + hep/ResipHep.hxx + +all: all-recursive + +.SUFFIXES: +.SUFFIXES: .cxx .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign rutil/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign rutil/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } +dns/$(am__dirstamp): + @$(MKDIR_P) dns + @: > dns/$(am__dirstamp) +dns/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) dns/$(DEPDIR) + @: > dns/$(DEPDIR)/$(am__dirstamp) +dns/AresDns.lo: dns/$(am__dirstamp) dns/$(DEPDIR)/$(am__dirstamp) +dns/DnsCnameRecord.lo: dns/$(am__dirstamp) \ + dns/$(DEPDIR)/$(am__dirstamp) +dns/DnsAAAARecord.lo: dns/$(am__dirstamp) \ + dns/$(DEPDIR)/$(am__dirstamp) +dns/DnsHostRecord.lo: dns/$(am__dirstamp) \ + dns/$(DEPDIR)/$(am__dirstamp) +dns/DnsNaptrRecord.lo: dns/$(am__dirstamp) \ + dns/$(DEPDIR)/$(am__dirstamp) +dns/DnsResourceRecord.lo: dns/$(am__dirstamp) \ + dns/$(DEPDIR)/$(am__dirstamp) +dns/DnsSrvRecord.lo: dns/$(am__dirstamp) dns/$(DEPDIR)/$(am__dirstamp) +dns/DnsStub.lo: dns/$(am__dirstamp) dns/$(DEPDIR)/$(am__dirstamp) +dns/DnsThread.lo: dns/$(am__dirstamp) dns/$(DEPDIR)/$(am__dirstamp) +dns/ExternalDnsFactory.lo: dns/$(am__dirstamp) \ + dns/$(DEPDIR)/$(am__dirstamp) +dns/RRCache.lo: dns/$(am__dirstamp) dns/$(DEPDIR)/$(am__dirstamp) +dns/RRList.lo: dns/$(am__dirstamp) dns/$(DEPDIR)/$(am__dirstamp) +dns/RRVip.lo: dns/$(am__dirstamp) dns/$(DEPDIR)/$(am__dirstamp) +dns/QueryTypes.lo: dns/$(am__dirstamp) dns/$(DEPDIR)/$(am__dirstamp) +dns/RROverlay.lo: dns/$(am__dirstamp) dns/$(DEPDIR)/$(am__dirstamp) +stun/$(am__dirstamp): + @$(MKDIR_P) stun + @: > stun/$(am__dirstamp) +stun/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) stun/$(DEPDIR) + @: > stun/$(DEPDIR)/$(am__dirstamp) +stun/Stun.lo: stun/$(am__dirstamp) stun/$(DEPDIR)/$(am__dirstamp) +stun/Udp.lo: stun/$(am__dirstamp) stun/$(DEPDIR)/$(am__dirstamp) +hep/$(am__dirstamp): + @$(MKDIR_P) hep + @: > hep/$(am__dirstamp) +hep/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) hep/$(DEPDIR) + @: > hep/$(DEPDIR)/$(am__dirstamp) +hep/HepAgent.lo: hep/$(am__dirstamp) hep/$(DEPDIR)/$(am__dirstamp) +hep/ResipHep.lo: hep/$(am__dirstamp) hep/$(DEPDIR)/$(am__dirstamp) +ssl/$(am__dirstamp): + @$(MKDIR_P) ssl + @: > ssl/$(am__dirstamp) +ssl/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) ssl/$(DEPDIR) + @: > ssl/$(DEPDIR)/$(am__dirstamp) +ssl/OpenSSLInit.lo: ssl/$(am__dirstamp) ssl/$(DEPDIR)/$(am__dirstamp) +ssl/SHA1Stream.lo: ssl/$(am__dirstamp) ssl/$(DEPDIR)/$(am__dirstamp) + +librutil.la: $(librutil_la_OBJECTS) $(librutil_la_DEPENDENCIES) $(EXTRA_librutil_la_DEPENDENCIES) + $(AM_V_CXXLD)$(librutil_la_LINK) -rpath $(libdir) $(librutil_la_OBJECTS) $(librutil_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f dns/*.$(OBJEXT) + -rm -f dns/*.lo + -rm -f hep/*.$(OBJEXT) + -rm -f hep/*.lo + -rm -f ssl/*.$(OBJEXT) + -rm -f ssl/*.lo + -rm -f stun/*.$(OBJEXT) + -rm -f stun/*.lo + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AbstractFifo.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AndroidLogger.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/BaseException.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Coders.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Condition.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ConfigParse.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CountStream.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Data.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DataStream.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DnsUtil.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FdPoll.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FileSystem.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GeneralCongestionManager.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GenericIPAddress.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HeapInstanceCounter.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/KeyValueStore.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Lock.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Log.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MD5Stream.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Mutex.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/NetNs.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ParseBuffer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ParseException.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Poll.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PoolBase.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RADIUSDigestAuthenticator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RWMutex.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Random.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RecursiveMutex.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SelectInterruptor.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ServerProcess.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Sha1.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Socket.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Subsystem.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SysLogBuf.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SysLogStream.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ThreadIf.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Time.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Timer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TransportType.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XMLCursor.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/resipfaststreams.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmd5.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dns/$(DEPDIR)/AresDns.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dns/$(DEPDIR)/DnsAAAARecord.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dns/$(DEPDIR)/DnsCnameRecord.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dns/$(DEPDIR)/DnsHostRecord.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dns/$(DEPDIR)/DnsNaptrRecord.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dns/$(DEPDIR)/DnsResourceRecord.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dns/$(DEPDIR)/DnsSrvRecord.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dns/$(DEPDIR)/DnsStub.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dns/$(DEPDIR)/DnsThread.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dns/$(DEPDIR)/ExternalDnsFactory.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dns/$(DEPDIR)/QueryTypes.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dns/$(DEPDIR)/RRCache.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dns/$(DEPDIR)/RRList.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dns/$(DEPDIR)/RROverlay.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@dns/$(DEPDIR)/RRVip.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@hep/$(DEPDIR)/HepAgent.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@hep/$(DEPDIR)/ResipHep.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@ssl/$(DEPDIR)/OpenSSLInit.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@ssl/$(DEPDIR)/SHA1Stream.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@stun/$(DEPDIR)/Stun.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@stun/$(DEPDIR)/Udp.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.cxx.o: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< + +.cxx.obj: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.cxx.lo: +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + -rm -rf dns/.libs dns/_libs + -rm -rf hep/.libs hep/_libs + -rm -rf ssl/.libs ssl/_libs + -rm -rf stun/.libs stun/_libs +install-nobase_rutilincludeHEADERS: $(nobase_rutilinclude_HEADERS) + @$(NORMAL_INSTALL) + @list='$(nobase_rutilinclude_HEADERS)'; test -n "$(rutilincludedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(rutilincludedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(rutilincludedir)" || exit 1; \ + fi; \ + $(am__nobase_list) | while read dir files; do \ + xfiles=; for file in $$files; do \ + if test -f "$$file"; then xfiles="$$xfiles $$file"; \ + else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \ + test -z "$$xfiles" || { \ + test "x$$dir" = x. || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(rutilincludedir)/$$dir'"; \ + $(MKDIR_P) "$(DESTDIR)$(rutilincludedir)/$$dir"; }; \ + echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(rutilincludedir)/$$dir'"; \ + $(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(rutilincludedir)/$$dir" || exit $$?; }; \ + done + +uninstall-nobase_rutilincludeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(nobase_rutilinclude_HEADERS)'; test -n "$(rutilincludedir)" || list=; \ + $(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \ + dir='$(DESTDIR)$(rutilincludedir)'; $(am__uninstall_files_from_dir) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(rutilincludedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f dns/$(DEPDIR)/$(am__dirstamp) + -rm -f dns/$(am__dirstamp) + -rm -f hep/$(DEPDIR)/$(am__dirstamp) + -rm -f hep/$(am__dirstamp) + -rm -f ssl/$(DEPDIR)/$(am__dirstamp) + -rm -f ssl/$(am__dirstamp) + -rm -f stun/$(DEPDIR)/$(am__dirstamp) + -rm -f stun/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-recursive + -rm -f ./$(DEPDIR)/AbstractFifo.Plo + -rm -f ./$(DEPDIR)/AndroidLogger.Plo + -rm -f ./$(DEPDIR)/BaseException.Plo + -rm -f ./$(DEPDIR)/Coders.Plo + -rm -f ./$(DEPDIR)/Condition.Plo + -rm -f ./$(DEPDIR)/ConfigParse.Plo + -rm -f ./$(DEPDIR)/CountStream.Plo + -rm -f ./$(DEPDIR)/Data.Plo + -rm -f ./$(DEPDIR)/DataStream.Plo + -rm -f ./$(DEPDIR)/DnsUtil.Plo + -rm -f ./$(DEPDIR)/FdPoll.Plo + -rm -f ./$(DEPDIR)/FileSystem.Plo + -rm -f ./$(DEPDIR)/GeneralCongestionManager.Plo + -rm -f ./$(DEPDIR)/GenericIPAddress.Plo + -rm -f ./$(DEPDIR)/HeapInstanceCounter.Plo + -rm -f ./$(DEPDIR)/KeyValueStore.Plo + -rm -f ./$(DEPDIR)/Lock.Plo + -rm -f ./$(DEPDIR)/Log.Plo + -rm -f ./$(DEPDIR)/MD5Stream.Plo + -rm -f ./$(DEPDIR)/Mutex.Plo + -rm -f ./$(DEPDIR)/NetNs.Plo + -rm -f ./$(DEPDIR)/ParseBuffer.Plo + -rm -f ./$(DEPDIR)/ParseException.Plo + -rm -f ./$(DEPDIR)/Poll.Plo + -rm -f ./$(DEPDIR)/PoolBase.Plo + -rm -f ./$(DEPDIR)/RADIUSDigestAuthenticator.Plo + -rm -f ./$(DEPDIR)/RWMutex.Plo + -rm -f ./$(DEPDIR)/Random.Plo + -rm -f ./$(DEPDIR)/RecursiveMutex.Plo + -rm -f ./$(DEPDIR)/SelectInterruptor.Plo + -rm -f ./$(DEPDIR)/ServerProcess.Plo + -rm -f ./$(DEPDIR)/Sha1.Plo + -rm -f ./$(DEPDIR)/Socket.Plo + -rm -f ./$(DEPDIR)/Subsystem.Plo + -rm -f ./$(DEPDIR)/SysLogBuf.Plo + -rm -f ./$(DEPDIR)/SysLogStream.Plo + -rm -f ./$(DEPDIR)/ThreadIf.Plo + -rm -f ./$(DEPDIR)/Time.Plo + -rm -f ./$(DEPDIR)/Timer.Plo + -rm -f ./$(DEPDIR)/TransportType.Plo + -rm -f ./$(DEPDIR)/XMLCursor.Plo + -rm -f ./$(DEPDIR)/resipfaststreams.Plo + -rm -f ./$(DEPDIR)/vmd5.Plo + -rm -f dns/$(DEPDIR)/AresDns.Plo + -rm -f dns/$(DEPDIR)/DnsAAAARecord.Plo + -rm -f dns/$(DEPDIR)/DnsCnameRecord.Plo + -rm -f dns/$(DEPDIR)/DnsHostRecord.Plo + -rm -f dns/$(DEPDIR)/DnsNaptrRecord.Plo + -rm -f dns/$(DEPDIR)/DnsResourceRecord.Plo + -rm -f dns/$(DEPDIR)/DnsSrvRecord.Plo + -rm -f dns/$(DEPDIR)/DnsStub.Plo + -rm -f dns/$(DEPDIR)/DnsThread.Plo + -rm -f dns/$(DEPDIR)/ExternalDnsFactory.Plo + -rm -f dns/$(DEPDIR)/QueryTypes.Plo + -rm -f dns/$(DEPDIR)/RRCache.Plo + -rm -f dns/$(DEPDIR)/RRList.Plo + -rm -f dns/$(DEPDIR)/RROverlay.Plo + -rm -f dns/$(DEPDIR)/RRVip.Plo + -rm -f hep/$(DEPDIR)/HepAgent.Plo + -rm -f hep/$(DEPDIR)/ResipHep.Plo + -rm -f ssl/$(DEPDIR)/OpenSSLInit.Plo + -rm -f ssl/$(DEPDIR)/SHA1Stream.Plo + -rm -f stun/$(DEPDIR)/Stun.Plo + -rm -f stun/$(DEPDIR)/Udp.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: install-nobase_rutilincludeHEADERS + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f ./$(DEPDIR)/AbstractFifo.Plo + -rm -f ./$(DEPDIR)/AndroidLogger.Plo + -rm -f ./$(DEPDIR)/BaseException.Plo + -rm -f ./$(DEPDIR)/Coders.Plo + -rm -f ./$(DEPDIR)/Condition.Plo + -rm -f ./$(DEPDIR)/ConfigParse.Plo + -rm -f ./$(DEPDIR)/CountStream.Plo + -rm -f ./$(DEPDIR)/Data.Plo + -rm -f ./$(DEPDIR)/DataStream.Plo + -rm -f ./$(DEPDIR)/DnsUtil.Plo + -rm -f ./$(DEPDIR)/FdPoll.Plo + -rm -f ./$(DEPDIR)/FileSystem.Plo + -rm -f ./$(DEPDIR)/GeneralCongestionManager.Plo + -rm -f ./$(DEPDIR)/GenericIPAddress.Plo + -rm -f ./$(DEPDIR)/HeapInstanceCounter.Plo + -rm -f ./$(DEPDIR)/KeyValueStore.Plo + -rm -f ./$(DEPDIR)/Lock.Plo + -rm -f ./$(DEPDIR)/Log.Plo + -rm -f ./$(DEPDIR)/MD5Stream.Plo + -rm -f ./$(DEPDIR)/Mutex.Plo + -rm -f ./$(DEPDIR)/NetNs.Plo + -rm -f ./$(DEPDIR)/ParseBuffer.Plo + -rm -f ./$(DEPDIR)/ParseException.Plo + -rm -f ./$(DEPDIR)/Poll.Plo + -rm -f ./$(DEPDIR)/PoolBase.Plo + -rm -f ./$(DEPDIR)/RADIUSDigestAuthenticator.Plo + -rm -f ./$(DEPDIR)/RWMutex.Plo + -rm -f ./$(DEPDIR)/Random.Plo + -rm -f ./$(DEPDIR)/RecursiveMutex.Plo + -rm -f ./$(DEPDIR)/SelectInterruptor.Plo + -rm -f ./$(DEPDIR)/ServerProcess.Plo + -rm -f ./$(DEPDIR)/Sha1.Plo + -rm -f ./$(DEPDIR)/Socket.Plo + -rm -f ./$(DEPDIR)/Subsystem.Plo + -rm -f ./$(DEPDIR)/SysLogBuf.Plo + -rm -f ./$(DEPDIR)/SysLogStream.Plo + -rm -f ./$(DEPDIR)/ThreadIf.Plo + -rm -f ./$(DEPDIR)/Time.Plo + -rm -f ./$(DEPDIR)/Timer.Plo + -rm -f ./$(DEPDIR)/TransportType.Plo + -rm -f ./$(DEPDIR)/XMLCursor.Plo + -rm -f ./$(DEPDIR)/resipfaststreams.Plo + -rm -f ./$(DEPDIR)/vmd5.Plo + -rm -f dns/$(DEPDIR)/AresDns.Plo + -rm -f dns/$(DEPDIR)/DnsAAAARecord.Plo + -rm -f dns/$(DEPDIR)/DnsCnameRecord.Plo + -rm -f dns/$(DEPDIR)/DnsHostRecord.Plo + -rm -f dns/$(DEPDIR)/DnsNaptrRecord.Plo + -rm -f dns/$(DEPDIR)/DnsResourceRecord.Plo + -rm -f dns/$(DEPDIR)/DnsSrvRecord.Plo + -rm -f dns/$(DEPDIR)/DnsStub.Plo + -rm -f dns/$(DEPDIR)/DnsThread.Plo + -rm -f dns/$(DEPDIR)/ExternalDnsFactory.Plo + -rm -f dns/$(DEPDIR)/QueryTypes.Plo + -rm -f dns/$(DEPDIR)/RRCache.Plo + -rm -f dns/$(DEPDIR)/RRList.Plo + -rm -f dns/$(DEPDIR)/RROverlay.Plo + -rm -f dns/$(DEPDIR)/RRVip.Plo + -rm -f hep/$(DEPDIR)/HepAgent.Plo + -rm -f hep/$(DEPDIR)/ResipHep.Plo + -rm -f ssl/$(DEPDIR)/OpenSSLInit.Plo + -rm -f ssl/$(DEPDIR)/SHA1Stream.Plo + -rm -f stun/$(DEPDIR)/Stun.Plo + -rm -f stun/$(DEPDIR)/Udp.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES \ + uninstall-nobase_rutilincludeHEADERS + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--depfiles check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-libLTLIBRARIES install-man \ + install-nobase_rutilincludeHEADERS install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES \ + uninstall-nobase_rutilincludeHEADERS + +.PRECIOUS: Makefile + + +############################################################################## +# +# The Vovida Software License, Version 1.0 +# Copyright (c) 2000-2007 Vovida Networks, Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The names "VOCAL", "Vovida Open Communication Application Library", +# and "Vovida Open Communication Application Library (VOCAL)" must +# not be used to endorse or promote products derived from this +# software without prior written permission. For written +# permission, please contact vocal@vovida.org. +# +# 4. Products derived from this software may not be called "VOCAL", nor +# may "VOCAL" appear in their name, without prior written +# permission of Vovida Networks, Inc. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND +# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA +# NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES +# IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. +# +# ==================================================================== +# +# This software consists of voluntary contributions made by Vovida +# Networks, Inc. and many individuals on behalf of Vovida Networks, +# Inc. For more information on Vovida Networks, Inc., please see +# . +# +############################################################################## + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/libs/resiprocate/rutil/Mutex.cxx b/src/libs/resiprocate/rutil/Mutex.cxx index 1c6993ed..a1f9cd83 100644 --- a/src/libs/resiprocate/rutil/Mutex.cxx +++ b/src/libs/resiprocate/rutil/Mutex.cxx @@ -6,7 +6,7 @@ typedef unsigned int size_t; } */ -#include +#include "rutil/ResipAssert.h" #include #include "rutil/Mutex.hxx" @@ -24,7 +24,7 @@ Mutex::Mutex() #ifndef WIN32 int rc = pthread_mutex_init(&mId,0); (void)rc; - assert( rc == 0 ); + resip_assert( rc == 0 ); #else // Note: Windows Critical sections are recursive in nature and perhaps // this implementation calls for a non-recursive implementation @@ -40,8 +40,8 @@ Mutex::~Mutex () #ifndef WIN32 int rc = pthread_mutex_destroy(&mId); (void)rc; - assert( rc != EBUSY ); // currently locked - assert( rc == 0 ); + resip_assert( rc != EBUSY ); // currently locked + resip_assert( rc == 0 ); #else DeleteCriticalSection(&mId); #endif @@ -54,9 +54,9 @@ Mutex::lock() #ifndef WIN32 int rc = pthread_mutex_lock(&mId); (void)rc; - assert( rc != EINVAL ); - assert( rc != EDEADLK ); - assert( rc == 0 ); + resip_assert( rc != EINVAL ); + resip_assert( rc != EDEADLK ); + resip_assert( rc == 0 ); #else EnterCriticalSection(&mId); #endif @@ -68,9 +68,9 @@ Mutex::unlock() #ifndef WIN32 int rc = pthread_mutex_unlock(&mId); (void)rc; - assert( rc != EINVAL ); - assert( rc != EPERM ); - assert( rc == 0 ); + resip_assert( rc != EINVAL ); + resip_assert( rc != EPERM ); + resip_assert( rc == 0 ); #else LeaveCriticalSection(&mId); #endif diff --git a/src/libs/resiprocate/rutil/NetNs.cxx b/src/libs/resiprocate/rutil/NetNs.cxx new file mode 100644 index 00000000..952c8135 --- /dev/null +++ b/src/libs/resiprocate/rutil/NetNs.cxx @@ -0,0 +1,282 @@ +#ifdef USE_NETNS + +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////////// +// Note: valgrind v3.7.0 does not support the setns() call, so we use the +// following to check for valgrind and do a crude fix-up. +/////////////////////////////////////////////////////////////////////////////// +#ifdef BUILD_FOR_VALGRIND +#include +#endif +#ifndef RUNNING_ON_VALGRIND +#define RUNNING_ON_VALGRIND 0 +#warning Defaulting RUNNING_ON_VALGRIND to 0 +#endif + +#ifndef HAVE_SETNS +# include +#endif + +#include "rutil/NetNs.hxx" +#include "rutil/FileSystem.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT +#define DEFAULT_NET_NAMESPACE "/proc/1/ns/net" +#define NET_NAMESPACE_DIR "/var/run/netns/" + +using namespace resip; + +// Static declarations +HashMap NetNs::sIdDictionaryToNetNs; +HashMap NetNs::sNetNsDictionaryToId; + +// Methods +int NetNs::setNs(const Data& netNs) +{ + int netNsFd = openNetNs(netNs); + if(netNsFd < 0) + { + Data deviceName; + makeNetNsDeviceName(netNs, deviceName); + + if(errno == EACCES) + { + // This is a bit heuristic, but let it go if we did not have permission to open the global + // netns. This is probably because we are not running as root/privileged user and cannot + // open the global net namespace file. If thats the case, odds are that we were also not + // able to change to a non-global/default net namespaces. So we should still be in the + // global net namespace. Let this be a no-op + if(netNs.empty()) + { + WarningLog(<< "Permission denied opening global netns. Assuming already using global netns."); + } + else + { + throw Exception("Permission denied opening \"" + deviceName + "\" to set setns, may need to run as root", + __FILE__,__LINE__); + } + } + else + { + throw Exception("Can't open name space \"" + deviceName + "\" errno: " + Data((int) errno), __FILE__,__LINE__); + } + } + + // Should only get here with an invalid netNsFd when we don't have permission + // to open global netns file. As described above. So no-op if we have an invalid netNsFd for + // the global netns namespace + if(netNsFd >= 0) + { + DebugLog(<< "setns(\"" << netNs << "\"(" << netNsFd << "))"); + int error; + +#ifdef HAVE_SETNS +#define DO_SETNS(fd, flag) setns(fd, flag) +#else +// Make system call directly +#define DO_SETNS(fd, flag) syscall(__NR_setns, fd, flag) +#endif + + /////////////////////////////////////////////////////////////////////////////// + // Note: valgrind v3.7.0 does not support the setns() call. In order to work + // around this, we make the syscall to setns, indicate that an "error" occurred, and + // then suppress throwing the exception. It's kind of an ugly hack, but it + // does let us run valgrind on our code. + /////////////////////////////////////////////////////////////////////////////// + + error = DO_SETNS(netNsFd, CLONE_NEWNET); + + if(error) + { + // setns normally closes the file descriptor when it is done, but because + // it failed close the FD here just in case. + close(netNsFd); + + if (!(RUNNING_ON_VALGRIND)) { + throw Exception("Can't change to name space \"" + netNs + "\"(fd:" + + Data((int) netNsFd) + "), error: " + Data((int) error) + + " errno: " + Data((int) errno), __FILE__,__LINE__); + } + } + + // Add name to the dictionary if it is not already in there + } + return(getNetNsId(netNs, true)); +} + +int NetNs::getPublicNetNs(std::vector& netNsNames) +{ + // Add global netns name + int nameCount = 1; + netNsNames.push_back(""); + + FileSystem::Directory namespaceDir(NET_NAMESPACE_DIR); + for(FileSystem::Directory::iterator dirItr = namespaceDir.begin(); dirItr != namespaceDir.end(); ++dirItr) + { + if(!dirItr.is_directory()) + { + netNsNames.push_back(*dirItr); + nameCount++; + } + } + return(nameCount); +} + +void NetNs::makeNetNsDeviceName(const Data& netNs, Data& netNsDeviceName) +{ + if(netNs.empty()) + { + // empty string means the global namespace. As it does not + // have a name, we instead open and switch to the namespace used + // by process 1 which should be the global namespace + netNsDeviceName = DEFAULT_NET_NAMESPACE; + } + else + { + netNsDeviceName = NET_NAMESPACE_DIR; + netNsDeviceName += netNs; + } +} + +int NetNs::openNetNs(const Data& netNs) +{ + Data nameSpacePath; + makeNetNsDeviceName(netNs, nameSpacePath); + int netNsFd = open(nameSpacePath.c_str(), O_RDONLY); + + if(netNsFd >= 0) + { + DebugLog(<< "Opened netns: " << nameSpacePath << " fd: " << Data((int) netNsFd)); + } + + return(netNsFd); +} + +bool NetNs::netNsExists(const Data& netNs) +{ + int netNsFd = openNetNs(netNs); + if(netNsFd >= 0 ) + { + DebugLog(<< "Closing netns fd: " << Data((int) netNsFd)); + close(netNsFd); + } + + return(netNsFd >= 0); +} + +int NetNs::getNetNsId(const Data& netNsName, bool shouldAdd) +{ + initDictionary(); + + int netNsId = -1; + + HashMap::iterator netNsIterator = sNetNsDictionaryToId.find(netNsName); + if(netNsIterator != sNetNsDictionaryToId.end()) + { + netNsId = netNsIterator->second; + } + else if(shouldAdd) + { + netNsId = netNsName.caseInsensitiveTokenHash(); + int originalId = netNsId; + // If hash is not unique, find the next available id + while(sIdDictionaryToNetNs.find(netNsId) != sIdDictionaryToNetNs.end()) + { + netNsId++; + } + + // This means another netns name had the same hash (i.e. the hash is + // not unique. So there is a likelyhood that in another instance + // of resip::SipStack (e.g. configured for replicating this instance) + // we could get a different id for this netns name. + // That could cause problems if the Tuple binary token was generated on + // on instance of resip:SipStack for the Record-Route and another instance + // of resip::SipStack recieved that Route as its Route to pop off. + if(originalId != netNsId) + { + WarningLog(<< "Non-unique netns hashes. " << netNsName << ": " << netNsId + << sIdDictionaryToNetNs[originalId] << ": " << originalId); + } + + DebugLog(<< "Adding netns to dictionary: " << netNsName << ": " << netNsId); + sIdDictionaryToNetNs[netNsId] = netNsName; + sNetNsDictionaryToId[netNsName] = netNsId; + } + + return(netNsId); +} + +const Data& NetNs::getNetNsName(int netNsId) +{ + initDictionary(); + + HashMap::iterator idIterator = sIdDictionaryToNetNs.find(netNsId); + if(idIterator == sIdDictionaryToNetNs.end()) + { + throw Exception("netns id: " + Data(netNsId) + " does not exist", + __FILE__,__LINE__); + } + return(idIterator->second); +} + +void NetNs::initDictionary() +{ + // Make sure there is an entry in the dictionary for the + // global namespace "" (empty string) + if(sIdDictionaryToNetNs.size() == 0 && + sNetNsDictionaryToId.size() == 0) + { + Data defaultNetNs(""); + sIdDictionaryToNetNs[defaultNetNs.caseInsensitiveTokenHash()] = defaultNetNs; + sNetNsDictionaryToId[""] = 0; + + // No locking, so test no one else touched + // the dictionary + resip_assert(sIdDictionaryToNetNs.size() == 1); + resip_assert(sNetNsDictionaryToId.size() == 1); + } +} + +#endif + +/* ==================================================================== + * + * Copyright (c) Daniel Petrie, SIPez LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/rutil/NetNs.hxx b/src/libs/resiprocate/rutil/NetNs.hxx new file mode 100644 index 00000000..6b355a4c --- /dev/null +++ b/src/libs/resiprocate/rutil/NetNs.hxx @@ -0,0 +1,175 @@ +#if !defined(RESIP_NETNS_HXX) && defined(USE_NETNS) +#define RESIP_NETNS_HXX + +#include +#include "rutil/HashMap.hxx" +#include "rutil/BaseException.hxx" + +namespace resip +{ + +class NetNs +{ + /** + * Class containing utilities for working with netns (network name spaces). + * netns is supported in linux kernal 3.X on some distros. netns in the + * kernel, provides the ability to have multiple network stacks. As the + * sockets interfaces are not changed, one uses setns to context switch + * between the different named netns to create a socket in the desired + * network stack. + * + **/ + + public: + + class Exception : public BaseException + { + public: + Exception(const Data& message, const Data& fileName, int lineNumber) : + BaseException(message, fileName, lineNumber){}; + + virtual const char* name() const {return("NetNs::Exception");}; + }; + + virtual ~NetNs(); + + // @ brief sets the kernel netns for the current thread + static int setNs(const Data& netNs); + /** + * Set the netns (network namespace) for the current thread to + * the given namespace name. + * + * @param netns[in] - name of the netns to switch to + * + * @returns netns id from NetNs dictionary if success + * + * @throws Exception if unable to open netns or switch to the + * specified netns + * + */ + + // @brief gets public netns namespace names + static int getPublicNetNs(std::vector& netNsNames); + /** + * Looks up in the system, the list of public netns namespace + * names. This may be different than the set of names in the + * NetNs class maintained dictionary which only tracks netns names + * that have been used by setNs. + * + * @param[in/out] netNsNames - vector containing system public netns + * names. + * + * @returns number of names found + * + **/ + + // @brief Get the netns id for the given name in the netns dictonary. + static int getNetNsId(const Data& netNsName, bool shouldAdd = false); + /** + * Optionally adds the netns name to the dictonary. + * + * @param netNsName[in] - name of the netns to look up in the dictonary + * + * @param shouldAdd[in] - if false, throws exception if name is not + * already in the dictionary. If true, will add the name to + * the dictionary if not found. + * + * @returns netns id + * + **/ + + // @brief construct netns device name to open for name + static void makeNetNsDeviceName(const Data& netNs, Data& deviceName); + /** + * Constructs full pathname for netns name which is to be opened + * for setting the netns. + * + * @param netNs[in] - netns namespace name + * @param deviceName[out] - full pathname to open for setting netns + * + **/ + + // @brief Opens the file for the named netns + static int openNetNs(const Data& netNs); + /** + * Opens the file associated with the named netns + * + * @param netns[in] - name of the netns to attempt opening + * + * @returns a valid file descriptor or error + * + **/ + + // @brief Checks if the named netns exists + static bool netNsExists(const Data& netNs); + /** + * Tests if the file for the named netns can be opened. + * Closes the file if successful. + * + * @param netns[in] - name of the netns to attempt opening + * + * @returns true/false if named netns exists and can be opened. + * + **/ + + // @brief Find the netns name for the given netns dictionary id + static const Data& getNetNsName(int netNsId); + /** + * Looks for the netns name in the netns dictionary. Throws exception + * if not found. + * + * @returns netns name + **/ + + private: + // Currently this is just a container for static methods. So + // no reason to actually construct one of these. + NetNs(); + + NetNs(const NetNs& ); + NetNs& operator=(const NetNs&); + + static void initDictionary(); + + static HashMap sIdDictionaryToNetNs; ///< Map from netns id to netns name + static HashMap sNetNsDictionaryToId; ///< Map from netns name to netns id +}; + +} + +#endif + +/* ==================================================================== + * + * Copyright (c) Daniel Petrie, SIPez LLC. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * vi: set shiftwidth=3 expandtab: + */ diff --git a/src/libs/resiprocate/rutil/ParseBuffer.cxx b/src/libs/resiprocate/rutil/ParseBuffer.cxx index 5d6398df..76946973 100644 --- a/src/libs/resiprocate/rutil/ParseBuffer.cxx +++ b/src/libs/resiprocate/rutil/ParseBuffer.cxx @@ -1,4 +1,4 @@ -#include +#include "rutil/ResipAssert.h" #include "rutil/Logger.hxx" #include "rutil/ParseBuffer.hxx" @@ -22,6 +22,14 @@ ParseBuffer::ParseBuffer(const char* buff, size_t len, mErrorContext(errorContext) {} +ParseBuffer::ParseBuffer(const char* buff, + const Data& errorContext) + : mBuff(buff), + mPosition(buff), + mEnd(buff+strlen(buff)), + mErrorContext(errorContext) +{} + ParseBuffer::ParseBuffer(const Data& data, const Data& errorContext) : mBuff(data.data()), @@ -234,12 +242,14 @@ ParseBuffer::skipToTermCRLF() ParseBuffer::CurrentPosition ParseBuffer::skipToChars(const char* cs) { - assert(cs); + resip_assert(cs); unsigned int l = (unsigned int)strlen(cs); const char* rpos; const char* cpos; - while (mPosition < mEnd) + // Checking mPosition >= mEnd - l +1 is unnecessary because there won't be + // enough bytes left to find [cs]. + while (mPosition < mEnd - l + 1) { rpos = mPosition; cpos = cs; @@ -254,6 +264,8 @@ ParseBuffer::skipToChars(const char* cs) return CurrentPosition(*this); skip: ; } + // Advance to the end since we didn't find a match. + mPosition = mEnd; return CurrentPosition(*this); } @@ -648,10 +660,10 @@ ParseBuffer::integer() fail(__FILE__, __LINE__,"Expected a digit, got eof "); } - int signum = 1; + bool negative = false; if (*mPosition == '-') { - signum = -1; + negative = true; ++mPosition; assertNotEof(); } @@ -663,25 +675,33 @@ ParseBuffer::integer() if (!isdigit(*mPosition)) { - Data msg("Expected a digit, got: "); - msg += Data(mPosition, (mEnd - mPosition)); + Data msg("Expected a digit, got: "); + msg += Data(mPosition, (mEnd - mPosition)); fail(__FILE__, __LINE__,msg); } - - int num = 0; - int last=0; + + // The absolute value limit depending on the detected sign + const unsigned int absoluteLimit = negative ? -(unsigned int)INT_MIN : INT_MAX; + // maximum value for full number except last digit + const unsigned int border = absoluteLimit / 10; + // value the last digit must not exceed + const unsigned int digitLimit = absoluteLimit % 10; + + unsigned int num = 0; while (!eof() && isdigit(*mPosition)) { - last=num; - num = num*10 + (*mPosition-'0'); - if(last > num) - { + const unsigned int c = *mPosition++ - '0'; + if (num > border || (num == border && c > digitLimit)) { fail(__FILE__, __LINE__,"Overflow detected."); } - ++mPosition; - } - - return signum*num; + num *= 10; + num += c; + } + if (negative) + { + num = -num; + } + return num; } UInt8 @@ -849,7 +869,7 @@ ParseBuffer::qVal() return 0; } - if (*mPosition == '.') + if (!eof() && *mPosition == '.') { skipChar(); diff --git a/src/libs/resiprocate/rutil/ParseBuffer.hxx b/src/libs/resiprocate/rutil/ParseBuffer.hxx index ceb489c2..984a60d7 100644 --- a/src/libs/resiprocate/rutil/ParseBuffer.hxx +++ b/src/libs/resiprocate/rutil/ParseBuffer.hxx @@ -21,6 +21,9 @@ class ParseBuffer ParseBuffer(const char* buff, size_t len, const Data& errorContext = Data::Empty); + explicit ParseBuffer(const char* buff, + const Data& errorContext = Data::Empty); + explicit ParseBuffer(const Data& data, const Data& errorContext = Data::Empty); @@ -96,8 +99,8 @@ class ParseBuffer ParseBuffer& operator=(const ParseBuffer& other); void reset(const char* pos) { - assert( mBuff <= mEnd); - assert( (pos >= mBuff) && (pos <= mEnd) ); + resip_assert( mBuff <= mEnd); + resip_assert( (pos >= mBuff) && (pos <= mEnd) ); mPosition = pos; } @@ -110,6 +113,7 @@ class ParseBuffer Pointer start() const { return Pointer(*this, mBuff, eof()); } CurrentPosition position() const { return CurrentPosition(*this); } Pointer end() const { return Pointer(*this, mEnd, true); } + size_t lengthRemaining() { return mEnd - mPosition; } CurrentPosition skipChar() { diff --git a/src/libs/resiprocate/rutil/Poll.cxx b/src/libs/resiprocate/rutil/Poll.cxx index f09ceeca..d24ae10d 100644 --- a/src/libs/resiprocate/rutil/Poll.cxx +++ b/src/libs/resiprocate/rutil/Poll.cxx @@ -1,6 +1,38 @@ #include + +// One of the following macros must be defined: +//#define RESIP_POLL_IMPL_POLL +#define RESIP_POLL_IMPL_SELECT +//#define RESIP_POLL_IMPL_EPOLL // Not yet implemented. + +/* + Define this macro to support applications that must call system call "poll" + or its ilk themselves rather than calling method "Poll::wait". +*/ +#define RESIP_POLL_EXTERN + #include "rutil/Poll.hxx" +#include + +#ifdef RESIP_POLL_IMPL_POLL +# include +#endif + +#ifdef RESIP_POLL_IMPL_SELECT +# ifdef WIN32 +# include +# else +# include +# include +# include +# endif // WIN32 +#endif // RESIP_POLL_IMPL_SELECT + +#ifdef RESIP_POLL_EXTERN +# include +#endif // RESIP_POLL_EXTERN + using namespace resip; using namespace std; @@ -8,6 +40,48 @@ using namespace std; #error "Define one of RESIP_POLL_IMPL_POLL, RESIP_POLL_IMPL_SELECT, or RESIP_POLL_EPOLL." #endif +namespace resip +{ +// We hide anything that effects the ABI here +class PollImpl +{ + public: + PollImpl(); + ~PollImpl(); + // Fields: + std::vector _fdEntryVector; +#ifdef RESIP_POLL_IMPL_POLL + std::vector _pollFDVector; +#endif +#ifdef RESIP_POLL_IMPL_SELECT + int/*FD*/ _maxFDPlus1; + fd_set _readFDSet; + fd_set _writeFDSet; +#endif +#ifdef RESIP_POLL_EXTERN + std::map _fdEntryMap; +#endif + std::vector _waitResult; + + +}; +} + +PollImpl::PollImpl() +#ifdef RESIP_POLL_IMPL_SELECT + : +_maxFDPlus1(0) //!jacob! Can select handle an empty poll set? +#endif +{ +#ifdef RESIP_POLL_IMPL_SELECT + FD_ZERO(&_readFDSet); + FD_ZERO(&_writeFDSet); +#endif +} + +PollImpl::~PollImpl() +{} + /////////////////////////////////////////////////////////////////////////////// //constructor @@ -17,46 +91,46 @@ Poll::FDEntry::FDEntry(Poll* poll, _poll(poll), _fd(fd), _stateBitMask(isTransport ? Poll::FDEntry::rsbmIsTransport : 0), - _index((unsigned short)poll->_fdEntryVector.size()) + _index((unsigned short)poll->mImpl->_fdEntryVector.size()) { - _poll->_fdEntryVector.push_back(this); + _poll->mImpl->_fdEntryVector.push_back(this); #ifdef RESIP_POLL_IMPL_POLL pollfd pollFD; pollFD.fd = fd; pollFD.events = POLLIN; - _poll->_pollFDVector.push_back(pollFD); + _poll->mImpl->_pollFDVector.push_back(pollFD); #endif #ifdef RESIP_POLL_IMPL_SELECT - if (_fd >= _poll->_maxFDPlus1) + if (_fd >= _poll->mImpl->_maxFDPlus1) { - _poll->_maxFDPlus1 = _fd + 1; + _poll->mImpl->_maxFDPlus1 = _fd + 1; } - FD_SET(_fd, &(_poll->_readFDSet)); + FD_SET(_fd, &(_poll->mImpl->_readFDSet)); #endif #ifdef RESIP_POLL_EXTERN - _poll->_fdEntryMap.insert(std::pair(_fd, this)); + _poll->mImpl->_fdEntryMap.insert(std::pair(_fd, this)); #endif } //destructor Poll::FDEntry::~FDEntry() { - vector &fdEntryVector = _poll->_fdEntryVector; + vector &fdEntryVector = _poll->mImpl->_fdEntryVector; Poll::FDEntry *lastFDEntry = fdEntryVector[fdEntryVector.size() - 1]; lastFDEntry->_index = _index; fdEntryVector[_index] = lastFDEntry; fdEntryVector.pop_back(); #ifdef RESIP_POLL_IMPL_POLL - vector &pollFDVector = _poll->_pollFDVector; + vector &pollFDVector = _poll->mImpl->_pollFDVector; pollFDVector[_index] = pollFDVector[pollFDVector.size() - 1]; pollFDVector.pop_back(); #endif #ifdef RESIP_POLL_IMPL_SELECT - FD_CLR(_fd, &(_poll->_readFDSet)); - FD_CLR(_fd, &(_poll->_writeFDSet)); + FD_CLR(_fd, &(_poll->mImpl->_readFDSet)); + FD_CLR(_fd, &(_poll->mImpl->_writeFDSet)); #endif #ifdef RESIP_POLL_EXTERN - _poll->_fdEntryMap.erase(_fd); + _poll->mImpl->_fdEntryMap.erase(_fd); #endif } @@ -73,19 +147,19 @@ Poll::FDEntry::setIsWritePending(bool isWritePending) { _stateBitMask |= Poll::FDEntry::rsbmIsWritePending; #ifdef RESIP_POLL_IMPL_POLL - _poll->_pollFDVector[_index].events |= Poll::FDEntry::fdsbmWritable; + _poll->mImpl->_pollFDVector[_index].events |= Poll::FDEntry::fdsbmWritable; #endif #ifdef RESIP_POLL_IMPL_SELECT - FD_SET(_fd, &(_poll->_writeFDSet)); + FD_SET(_fd, &(_poll->mImpl->_writeFDSet)); #endif } else { _stateBitMask &= ~Poll::FDEntry::rsbmIsWritePending; #ifdef RESIP_POLL_IMPL_POLL - _poll->_pollFDVector[_index].events &= ~Poll::FDEntry::fdsbmWritable; + _poll->mImpl->_pollFDVector[_index].events &= ~Poll::FDEntry::fdsbmWritable; #endif #ifdef RESIP_POLL_IMPL_SELECT - FD_CLR(_fd, &(_poll->_writeFDSet)); + FD_CLR(_fd, &(_poll->mImpl->_writeFDSet)); #endif } } @@ -124,17 +198,9 @@ Poll::findFDInWaitResult(int/*FD*/ fd, } //constructor -Poll::Poll() -#ifdef RESIP_POLL_IMPL_SELECT - : -_maxFDPlus1(0) //!jacob! Can select handle an empty poll set? -#endif -{ -#ifdef RESIP_POLL_IMPL_SELECT - FD_ZERO(&_readFDSet); - FD_ZERO(&_writeFDSet); -#endif -} +Poll::Poll() : + mImpl(new PollImpl) +{} //destructor Poll::~Poll() @@ -146,8 +212,8 @@ Poll::~Poll() const vector & Poll::beforeExternWait() { - _waitResult.clear(); - return _fdEntryVector; + mImpl->_waitResult.clear(); + return mImpl->_fdEntryVector; } bool @@ -155,13 +221,13 @@ Poll::setEntryFDStateForExternWait(int/*FD*/ fd, Poll::FDEntry::StateBitMask fdStateBitMask) { map::const_iterator fdEntryIterator = - _fdEntryMap.find(fd); - bool isFDInPoll = (fdEntryIterator != _fdEntryMap.end()); + mImpl->_fdEntryMap.find(fd); + bool isFDInPoll = (fdEntryIterator != mImpl->_fdEntryMap.end()); if (isFDInPoll) { Poll::FDEntry *fdEntry = fdEntryIterator->second; fdEntry->_stateBitMask |= fdStateBitMask & Poll::FDEntry::fdsbmAll; - _waitResult.push_back(fdEntry); + mImpl->_waitResult.push_back(fdEntry); } return isFDInPoll; } @@ -169,7 +235,7 @@ Poll::setEntryFDStateForExternWait(int/*FD*/ fd, const vector & Poll::afterExternWait() { - return _waitResult; + return mImpl->_waitResult; } #else //!defined(RESIP_POLL_EXTERN) } { @@ -177,11 +243,11 @@ Poll::afterExternWait() const vector & Poll::wait(int timeoutMilliSeconds) { - _waitResult.clear(); + mImpl->_waitResult.clear(); #ifdef RESIP_POLL_IMPL_POLL - pollfd *pollFDArray = &(_pollFDVector.front()); + pollfd *pollFDArray = &(mImpl->_pollFDVector.front()); int numReadyFDs = poll(pollFDArray, - _pollFDVector.size(), + mImpl->_pollFDVector.size(), timeoutMilliSeconds); if (numReadyFDs < 0) { @@ -192,26 +258,26 @@ Poll::wait(int timeoutMilliSeconds) int revents = pollFDArray[index].revents; if (revents) { - Poll::FDEntry *fdEntry = _fdEntryVector[index]; + Poll::FDEntry *fdEntry = mImpl->_fdEntryVector[index]; fdEntry->_stateBitMask |= revents; - _waitResult.push_back(fdEntry); + mImpl->_waitResult.push_back(fdEntry); --numReadyFDs; } }//for - qsort(&(_waitResult.front()), - _waitResult.size(), + qsort(&(mImpl->_waitResult.front()), + mImpl->_waitResult.size(), sizeof(Poll::FDEntry *), reinterpret_cast(&Poll::FDEntry::compare)); #endif #ifdef RESIP_POLL_IMPL_SELECT - fd_set readableFDSet = _readFDSet; - fd_set writableFDSet = _writeFDSet; - fd_set errorFDSet = _readFDSet; + fd_set readableFDSet = mImpl->_readFDSet; + fd_set writableFDSet = mImpl->_writeFDSet; + fd_set errorFDSet = mImpl->_readFDSet; timeval timeoutTimeVal; timeoutTimeVal.tv_sec = timeoutMilliSeconds / 1000; timeoutTimeVal.tv_usec = 1000 * (timeoutMilliSeconds % 1000); - int numReadyFDs = select(_maxFDPlus1, + int numReadyFDs = select(mImpl->_maxFDPlus1, &readableFDSet, &writableFDSet, &errorFDSet, @@ -222,7 +288,7 @@ Poll::wait(int timeoutMilliSeconds) } for (unsigned short index = 0; numReadyFDs > 0; ++index) { - Poll::FDEntry *fdEntry = _fdEntryVector[index]; + Poll::FDEntry *fdEntry = mImpl->_fdEntryVector[index]; bool isFDReadable = FD_ISSET(fdEntry->_fd, &readableFDSet); bool isFDWritable = FD_ISSET(fdEntry->_fd, &writableFDSet); bool isFDError = FD_ISSET(fdEntry->_fd, &errorFDSet); @@ -240,12 +306,12 @@ Poll::wait(int timeoutMilliSeconds) { fdEntry->_stateBitMask |= Poll::FDEntry::fdsbmError; } - _waitResult.push_back(fdEntry); + mImpl->_waitResult.push_back(fdEntry); --numReadyFDs; } }//for #endif - return _waitResult; + return mImpl->_waitResult; } #endif //!defined(RESIP_POLL_EXTERN) } diff --git a/src/libs/resiprocate/rutil/Poll.hxx b/src/libs/resiprocate/rutil/Poll.hxx index 53a54c64..e82ce2cc 100644 --- a/src/libs/resiprocate/rutil/Poll.hxx +++ b/src/libs/resiprocate/rutil/Poll.hxx @@ -1,41 +1,15 @@ #if !defined(RESIP_POLL_HXX) #define RESIP_POLL_HXX -// One of the following macros must be defined: -//#define RESIP_POLL_IMPL_POLL -#define RESIP_POLL_IMPL_SELECT -//#define RESIP_POLL_IMPL_EPOLL // Not yet implemented. - -/* - Define this macro to support applications that must call system call "poll" - or its ilk themselves rather than calling method "Poll::wait". -*/ -#define RESIP_POLL_EXTERN - +#include #include -#ifdef RESIP_POLL_IMPL_POLL -# include -#endif - -#ifdef RESIP_POLL_IMPL_SELECT -# ifdef WIN32 -# include -# else -# include -# include -# include -# endif // WIN32 -#endif // RESIP_POLL_IMPL_SELECT - -#ifdef RESIP_POLL_EXTERN -# include -#endif // RESI - namespace resip { /////////////////////////////////////////////////////////////////////////////// +class PollImpl; + /** @brief This class abstracts the Unix system call "poll". @@ -136,22 +110,7 @@ class Poll { friend class Poll::FDEntry; private: - - // Fields: - std::vector _fdEntryVector; -#ifdef RESIP_POLL_IMPL_POLL - std::vector _pollFDVector; -#endif -#ifdef RESIP_POLL_IMPL_SELECT - int/*FD*/ _maxFDPlus1; - fd_set _readFDSet; - fd_set _writeFDSet; -#endif -#ifdef RESIP_POLL_EXTERN - std::map _fdEntryMap; -#endif - std::vector _waitResult; - + std::auto_ptr mImpl; public: /* diff --git a/src/libs/resiprocate/rutil/ProducerFifoBuffer.hxx b/src/libs/resiprocate/rutil/ProducerFifoBuffer.hxx index c12cb770..e80b71b0 100644 --- a/src/libs/resiprocate/rutil/ProducerFifoBuffer.hxx +++ b/src/libs/resiprocate/rutil/ProducerFifoBuffer.hxx @@ -38,7 +38,10 @@ class ProducerFifoBuffer void flush() { - mFifo.addMultiple(mBuffer); + if(mBuffer.size() > 0) + { + mFifo.addMultiple(mBuffer); + } } inline size_t getBufferSize() const diff --git a/src/libs/resiprocate/rutil/RADIUSDigestAuthenticator.cxx b/src/libs/resiprocate/rutil/RADIUSDigestAuthenticator.cxx index 4cd9ea91..c4fdb438 100644 --- a/src/libs/resiprocate/rutil/RADIUSDigestAuthenticator.cxx +++ b/src/libs/resiprocate/rutil/RADIUSDigestAuthenticator.cxx @@ -17,7 +17,7 @@ struct attr *RADIUSDigestAuthenticator::attrs = NULL; struct val *RADIUSDigestAuthenticator::vals = NULL; rc_handle *RADIUSDigestAuthenticator::rh = NULL; -inline void init_av(rc_handle *rh, struct attr *at, struct val *vl, char *fn) +inline void init_av(rc_handle *rh, struct attr *at, struct val *vl, const char *fn) { int i; DICT_ATTR *da; @@ -56,7 +56,10 @@ RADIUSDigestAuthListener::~RADIUSDigestAuthListener() { void RADIUSDigestAuthenticator::init(const char *radiusConfigFile) { if(attrs != NULL) - throw; // may only be called once + { + WarningLog(<<"invoked more than once, ignoring"); + return; + } if((attrs = (struct attr *)malloc(sizeof(struct attr) * A_MAX)) == NULL) { @@ -92,7 +95,12 @@ void RADIUSDigestAuthenticator::init(const char *radiusConfigFile) const char *myRADIUSConfigFile = RADIUS_CONFIG; if(radiusConfigFile != NULL) - myRADIUSConfigFile = radiusConfigFile; + { + myRADIUSConfigFile = radiusConfigFile; + } + // FIXME: this should not use a cast, freeradius-client.h to be fixed + // pull request submitted via github + // https://github.com/FreeRADIUS/freeradius-client/pull/8 if((rh = rc_read_config((char *)myRADIUSConfigFile)) == NULL) { ErrLog(<< "radius: Error opening configuration file \n"); @@ -238,13 +246,18 @@ void RADIUSDigestAuthenticator::thread() } else { - DebugLog(<<"rc_auth failure for " << username.c_str()); + DebugLog(<<"rc_auth failure for " << username.c_str() + <<", code = " << i); rc_avpair_free(vp_s_start); rc_avpair_free(vp_r_start); - if(i == BADRESP_RC) - listener->onAccessDenied(); + if(i == REJECT_RC) + { + listener->onAccessDenied(); + } else - listener->onError(); + { + listener->onError(); + } } delete listener; DebugLog(<<"RADIUSDigestAuthenticator::thread() exiting"); @@ -350,9 +363,13 @@ void TestRADIUSDigestAuthListener::onSuccess(const resip::Data& rpid) { DebugLog(<<"TestRADIUSDigestAuthListener::onSuccess"); if(!rpid.empty()) - DebugLog(<<"TestRADIUSDigestAuthListener::onSuccess rpid = " << rpid); + { + DebugLog(<<"TestRADIUSDigestAuthListener::onSuccess rpid = " << rpid); + } else - DebugLog(<<"TestRADIUSDigestAuthListener::onSuccess, no rpid"); + { + DebugLog(<<"TestRADIUSDigestAuthListener::onSuccess, no rpid"); + } } void TestRADIUSDigestAuthListener::onAccessDenied() diff --git a/src/libs/resiprocate/rutil/RADIUSDigestAuthenticator.hxx b/src/libs/resiprocate/rutil/RADIUSDigestAuthenticator.hxx index cbf5ff5a..c20f1c0f 100644 --- a/src/libs/resiprocate/rutil/RADIUSDigestAuthenticator.hxx +++ b/src/libs/resiprocate/rutil/RADIUSDigestAuthenticator.hxx @@ -6,9 +6,21 @@ #include "config.h" #endif +#include "compat.hxx" + #ifdef USE_RADIUS_CLIENT +#ifdef RESIP_HAVE_RADCLI +#include +typedef UInt32 UINT4; +#else +#ifdef RESIP_HAVE_FREERADIUS_CLIENT +#include +typedef UInt32 UINT4; +#else #include +#endif +#endif #include "rutil/Data.hxx" #include "rutil/ThreadIf.hxx" diff --git a/src/libs/resiprocate/rutil/RWMutex.cxx b/src/libs/resiprocate/rutil/RWMutex.cxx index 6dddfe53..fbf675d5 100644 --- a/src/libs/resiprocate/rutil/RWMutex.cxx +++ b/src/libs/resiprocate/rutil/RWMutex.cxx @@ -50,7 +50,7 @@ #include "RWMutex.hxx" #include "Lock.hxx" -#include +#include "rutil/ResipAssert.h" using resip::RWMutex; using resip::Lock; @@ -117,7 +117,7 @@ RWMutex::unlock() // if ( mWriterHasLock ) { - assert( mReaderCount == 0 ); + resip_assert( mReaderCount == 0 ); mWriterHasLock = false; @@ -141,7 +141,7 @@ RWMutex::unlock() // else { - assert( mReaderCount > 0 ); + resip_assert( mReaderCount > 0 ); mReaderCount--; diff --git a/src/libs/resiprocate/rutil/Random.cxx b/src/libs/resiprocate/rutil/Random.cxx index 7f6be609..b5fac987 100644 --- a/src/libs/resiprocate/rutil/Random.cxx +++ b/src/libs/resiprocate/rutil/Random.cxx @@ -2,7 +2,7 @@ #include "config.h" #endif -#include +#include "rutil/ResipAssert.h" #include #ifdef WIN32 @@ -37,7 +37,10 @@ #endif #if ( USE_OPENSSL == 1 ) +# include +#if !defined(LIBRESSL_VERSION_NUMBER) # include +#endif # include # include #endif @@ -268,7 +271,7 @@ Random::getRandom() // rand() returns [0,RAND_MAX], which on Windows is 15 bits and positive // code below gets 30bits of randomness; with bit31 and bit15 // always zero; result is always positive - assert( RAND_MAX == 0x7fff ); + resip_assert( RAND_MAX == 0x7fff ); // WATCHOUT: on Linux, rand() returns 31bits, and assert above will fail int r1 = rand(); int r2 = rand(); @@ -324,7 +327,7 @@ Random::getCryptoRandom() ERR_error_string_n(err,buf,sizeof(buf)); ErrLog( << buf ); - assert(0); + resip_assert(0); } return ret; #else @@ -336,7 +339,7 @@ Data Random::getRandom(unsigned int len) { initialize(); - assert(len < Random::maxLength+1); + resip_assert(len < Random::maxLength+1); union { @@ -443,7 +446,7 @@ Random::getVersion4UuidUrn() void Random::getCryptoRandom(unsigned char* buf, unsigned int numBytes) { - assert(numBytes < Random::maxLength+1); + resip_assert(numBytes < Random::maxLength+1); #if USE_OPENSSL initialize(); @@ -457,7 +460,7 @@ Random::getCryptoRandom(unsigned char* buf, unsigned int numBytes) ERR_error_string_n(err,buf,sizeof(buf)); ErrLog( << buf ); - assert(0); + resip_assert(0); } #else // !bwc! Should optimize this. @@ -469,7 +472,7 @@ Random::getCryptoRandom(unsigned char* buf, unsigned int numBytes) #ifdef WIN32 Random::Initializer::Initializer() : mThreadStorage(::TlsAlloc()) { - assert(mThreadStorage != TLS_OUT_OF_INDEXES); + resip_assert(mThreadStorage != TLS_OUT_OF_INDEXES); } Random::Initializer::~Initializer() diff --git a/src/libs/resiprocate/rutil/Random.hxx b/src/libs/resiprocate/rutil/Random.hxx index 9b6a77d5..098aab6f 100644 --- a/src/libs/resiprocate/rutil/Random.hxx +++ b/src/libs/resiprocate/rutil/Random.hxx @@ -4,7 +4,7 @@ #include "rutil/Mutex.hxx" #include "rutil/Data.hxx" #include "rutil/ThreadIf.hxx" // for ThreadLocalStorage -#include +#include "rutil/ResipAssert.h" struct random_data; /** diff --git a/src/libs/resiprocate/rutil/RecursiveMutex.cxx b/src/libs/resiprocate/rutil/RecursiveMutex.cxx index 2fa0a06b..813aeb9c 100644 --- a/src/libs/resiprocate/rutil/RecursiveMutex.cxx +++ b/src/libs/resiprocate/rutil/RecursiveMutex.cxx @@ -1,4 +1,4 @@ -#include +#include "rutil/ResipAssert.h" #include #include "rutil/RecursiveMutex.hxx" @@ -36,26 +36,26 @@ namespace resip RecursiveMutex::RecursiveMutex() { - assert(0); + resip_assert(0); } RecursiveMutex::~RecursiveMutex () { - assert(0); + resip_assert(0); } void RecursiveMutex::lock() { - assert(0); + resip_assert(0); } void RecursiveMutex::unlock() { - assert(0); + resip_assert(0); } } @@ -69,18 +69,14 @@ RecursiveMutex::RecursiveMutex() { #ifndef WIN32 int rc = pthread_mutexattr_init(&mMutexAttr); - #if defined(__linux__) - #if defined(PTHREAD_MUTEX_RECURSIVE_NP) + #if defined(__linux__) && defined(PTHREAD_MUTEX_RECURSIVE_NP) pthread_mutexattr_settype(&mMutexAttr, PTHREAD_MUTEX_RECURSIVE_NP); - #else - pthread_mutexattr_settype(&mMutexAttr, PTHREAD_MUTEX_RECURSIVE); - #endif #else pthread_mutexattr_settype(&mMutexAttr, PTHREAD_MUTEX_RECURSIVE); #endif rc = pthread_mutex_init(&mId, &mMutexAttr); - assert( rc == 0 ); + resip_assert( rc == 0 ); #else InitializeCriticalSection(&mId); #endif @@ -91,8 +87,8 @@ RecursiveMutex::~RecursiveMutex () { #ifndef WIN32 int rc = pthread_mutex_destroy(&mId); - assert( rc != EBUSY ); // currently locked - assert( rc == 0 ); + resip_assert( rc != EBUSY ); // currently locked + resip_assert( rc == 0 ); rc = pthread_mutexattr_destroy(&mMutexAttr); #else DeleteCriticalSection(&mId); @@ -106,9 +102,9 @@ RecursiveMutex::lock() #ifndef WIN32 int rc = pthread_mutex_lock(&mId); (void)rc; - assert( rc != EINVAL ); - assert( rc != EDEADLK ); - assert( rc == 0 ); + resip_assert( rc != EINVAL ); + resip_assert( rc != EDEADLK ); + resip_assert( rc == 0 ); #else EnterCriticalSection(&mId); #endif @@ -120,9 +116,9 @@ RecursiveMutex::unlock() #ifndef WIN32 int rc = pthread_mutex_unlock(&mId); (void)rc; - assert( rc != EINVAL ); - assert( rc != EPERM ); - assert( rc == 0 ); + resip_assert( rc != EINVAL ); + resip_assert( rc != EPERM ); + resip_assert( rc == 0 ); #else LeaveCriticalSection(&mId); #endif diff --git a/src/libs/resiprocate/rutil/ResipAssert.h b/src/libs/resiprocate/rutil/ResipAssert.h new file mode 100644 index 00000000..c9652437 --- /dev/null +++ b/src/libs/resiprocate/rutil/ResipAssert.h @@ -0,0 +1,150 @@ + +#ifndef __ASSERTION_H +#define __ASSERTION_H + +/** + * This file needs to work for both C and C++ code. + * + * The resip_assert() macro is preferred over regular assert() + * for all library and application code. Unit tests should continue + * to use regular assert(). Third party code placed on contrib + * should not be adapted to use resip_assert() + * + * It is possible to redefine resip_assert() to provide additional logging + * or throw an exception such as std::runtime_error() as desired. + * + * On UNIX systems, this could add a call to syslog. On Windows, + * it could be a notification in the system's event log. + * + * CAUTION: do not call other reSIProcate stack methods from here. + * For example, do not try to use the reSIProcate logger or even + * basic classes like resip::Data. If the resip_assert() was + * invoked from one of those other low-level classes then the stack + * may be in such a bad state that they behave unpredictably + * or even worse, recursion may occur if resip_assert() is invoked + * again. We may do further work on this code to make it work + * safely with the logger but at present it is not ready for that. + */ + +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +// Uncomment or define on the compiler command line to have +// assertion failures logged to the Windows event logger +//#define LOG_EVENT_AND_ASSERT + +#if defined(WIN32) && defined(LOG_EVENT_AND_ASSERT) + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#include +#include +#include +#include + +#define SysLogAssertEvent(x) \ +{ \ + HKEY key; \ + long errorCode = \ + RegCreateKeyEx(HKEY_LOCAL_MACHINE, _T("System\\CurrentControlSet\\Services\\EventLog\\Application\\reSIProcate"), \ + 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &key, NULL); \ + if (ERROR_SUCCESS == errorCode) \ + { \ + HANDLE eventLogHandle; \ + RegCloseKey(key); \ + eventLogHandle = RegisterEventSource(NULL, _T("reSIProcate")); \ + if (eventLogHandle != NULL) \ + { \ + TCHAR appPath[MAX_PATH]; \ + TCHAR moduleInfo[1024]; \ + TCHAR fileInfo[1024]; \ + TCHAR lineInfo[1024]; \ + TCHAR assertInfo[1024]; \ + const TCHAR* lines[4] = { moduleInfo, fileInfo, lineInfo, assertInfo }; \ + GetModuleFileName(0, appPath, MAX_PATH); \ + _sntprintf_s(moduleInfo, 1024, _TRUNCATE, _T("\r\nModule : %s"), appPath); \ + _sntprintf_s(fileInfo, 1024, _TRUNCATE, _T("\r\nFile : %s"), _T(__FILE__)); \ + _sntprintf_s(lineInfo, 1024, _TRUNCATE, _T("\r\nLine : %d"), __LINE__); \ + _sntprintf_s(assertInfo, 1024, _TRUNCATE, _T("\r\nAssert: %s"), _T(#x)); \ + ReportEvent(eventLogHandle, EVENTLOG_ERROR_TYPE, 0, 0, NULL, 4, 0, lines, NULL); \ + DeregisterEventSource(eventLogHandle); \ + } \ + } \ +} + +#define resip_assert(x) \ +{ \ + if ( !(x) ) \ + { \ + SysLogAssertEvent( (x) ); \ + } \ + { \ + assert( (x) ); \ + } \ +} + +#else + +#ifdef RESIP_ASSERT_SYSLOG +#include +#define RESIP_ASSERT_SYSLOG_PRIORITY (LOG_DAEMON | LOG_CRIT) +#define resip_assert(x) \ +{ \ + if ( !(x) ) \ + { \ + syslog( RESIP_ASSERT_SYSLOG_PRIORITY, "assertion failed: %s:%d: %s", __FILE__, __LINE__, #x ); \ + } \ + { \ + assert( (x) ); \ + } \ +} +#else +#define resip_assert(x) assert(x) +#endif + +#endif // defined(WIN32) && defined(LOG_EVENT_AND_ASSERT) + +#endif // __ASSERTION_H + +/* ==================================================================== + * + * Copyright (c) 2014 Daniel Pocock All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ + diff --git a/src/libs/resiprocate/rutil/SelectInterruptor.cxx b/src/libs/resiprocate/rutil/SelectInterruptor.cxx index 7dc7d7fe..203f39f6 100644 --- a/src/libs/resiprocate/rutil/SelectInterruptor.cxx +++ b/src/libs/resiprocate/rutil/SelectInterruptor.cxx @@ -1,6 +1,6 @@ #include "rutil/SelectInterruptor.hxx" -#include +#include "rutil/ResipAssert.h" #include "rutil/Logger.hxx" #ifndef WIN32 @@ -13,8 +13,9 @@ using namespace resip; SelectInterruptor::SelectInterruptor() { - return; #ifdef WIN32 + initNetwork(); // Required for windows + mSocket = ::socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); sockaddr_in loopback; @@ -27,14 +28,14 @@ SelectInterruptor::SelectInterruptor() memset(&mWakeupAddr, 0, sizeof(mWakeupAddr)); int len = sizeof(mWakeupAddr); int error = getsockname(mSocket, (sockaddr *)&mWakeupAddr, &len); - assert(error == 0); + resip_assert(error == 0); error= connect(mSocket, &mWakeupAddr, sizeof(mWakeupAddr)); - assert(error == 0); + resip_assert(error == 0); mReadThing = mSocket; #else int x = pipe(mPipe); (void)x; - assert( x != -1 ); + resip_assert( x != -1 ); // make write-side non-blocking to avoid deadlock makeSocketNonBlocking(mPipe[1]); // make read-side non-blocking so safe to read out entire pipe @@ -46,7 +47,6 @@ SelectInterruptor::SelectInterruptor() SelectInterruptor::~SelectInterruptor() { - return; #ifdef WIN32 closesocket(mSocket); #else @@ -58,16 +58,14 @@ SelectInterruptor::~SelectInterruptor() void SelectInterruptor::handleProcessNotification() { - return; interrupt(); } void SelectInterruptor::buildFdSet(FdSet& fdset) { - return; #ifdef WIN32 - fdset.setRead(mSocket); + fdset.setRead(mSocket); #else fdset.setRead(mPipe[0]); #endif @@ -76,37 +74,32 @@ SelectInterruptor::buildFdSet(FdSet& fdset) void SelectInterruptor::processCleanup() { - return; #ifdef WIN32 - { - char rdBuf[16]; - recv(mSocket, rdBuf, sizeof(rdBuf), 0); - } + char rdBuf[16]; + recv(mSocket, rdBuf, sizeof(rdBuf), 0); #else - { - char rdBuf[16]; - int x; - while ( (x=read(mPipe[0], rdBuf, sizeof(rdBuf))) == sizeof(rdBuf) ) - ; - // WATCHOUT: EWOULDBLOCK *will* happen above when the pending - // number of bytes is exactly size of rdBuf - // XXX: should check for certain errors (like fd closed) and die? - } + char rdBuf[16]; + int x; + while ( (x=read(mPipe[0], rdBuf, sizeof(rdBuf))) == sizeof(rdBuf) ) + ; + // WATCHOUT: EWOULDBLOCK *will* happen above when the pending + // number of bytes is exactly size of rdBuf + // XXX: should check for certain errors (like fd closed) and die? #endif } void SelectInterruptor::process(FdSet& fdset) { - return; if (fdset.readyToRead(mReadThing)) + { processCleanup(); + } } void SelectInterruptor::processPollEvent(FdPollEventMask mask) { - return; if(mask & FPEM_Read) { processCleanup(); @@ -117,22 +110,29 @@ SelectInterruptor::processPollEvent(FdPollEventMask mask) void SelectInterruptor::interrupt() { - return; - static char wakeUp[] = "w"; #ifdef WIN32 - int count = send(mSocket, wakeUp, sizeof(wakeUp), 0); - assert(count == sizeof(wakeUp)); + u_long readSize = 0; + ioctlsocket(mSocket, FIONREAD, &readSize); + // Only bother signalling socket if there is no data on it already + if(readSize == 0) + { + int count = send(mSocket, wakeUp, sizeof(wakeUp), 0); + resip_assert(count == sizeof(wakeUp)); + } #else ssize_t res = write(mPipe[1], wakeUp, sizeof(wakeUp)); - if ( res == -1 && errno==EAGAIN ) + + if ( res == -1 && (errno == EAGAIN || errno == EWOULDBLOCK) ) // Treat EGAIN and EWOULDBLOCK as the same: http://stackoverflow.com/questions/7003234/which-systems-define-eagain-and-ewouldblock-as-different-values { ; // this can happen when SipStack thread gets behind. // no need to block since our only purpose is to wake up the thread // also, this write can occur within the SipStack thread, in which // case we get dead-lock if this blocks - } else { - assert(res == sizeof(wakeUp)); + } + else + { + resip_assert(res == sizeof(wakeUp)); } #endif } diff --git a/src/libs/resiprocate/rutil/SelectInterruptor.hxx b/src/libs/resiprocate/rutil/SelectInterruptor.hxx index ec68783b..d6d4ebe2 100644 --- a/src/libs/resiprocate/rutil/SelectInterruptor.hxx +++ b/src/libs/resiprocate/rutil/SelectInterruptor.hxx @@ -5,14 +5,6 @@ #include "rutil/FdPoll.hxx" #include "rutil/Socket.hxx" -#if 0 -#if defined(WIN32) -#include -#else -#include -#endif -#endif - namespace resip { @@ -32,7 +24,7 @@ class SelectInterruptor : public AsyncProcessHandler, public FdPollItemIf virtual void handleProcessNotification(); /** -// cause the 'artificial' fd to signal + cause the 'artificial' fd to signal */ void interrupt(); @@ -54,7 +46,7 @@ class SelectInterruptor : public AsyncProcessHandler, public FdPollItemIf * Declared as Socket for easier cross-platform even though pipe fd * under linux. */ - Socket getReadSocket() const { return INVALID_SOCKET;/*mReadThing;*/ } + Socket getReadSocket() const { return mReadThing; } protected: diff --git a/src/libs/resiprocate/rutil/ServerProcess.cxx b/src/libs/resiprocate/rutil/ServerProcess.cxx index ec16e7ea..0f44bbeb 100644 --- a/src/libs/resiprocate/rutil/ServerProcess.cxx +++ b/src/libs/resiprocate/rutil/ServerProcess.cxx @@ -4,6 +4,8 @@ #endif #ifndef WIN32 +#include +#include #include #include #endif @@ -16,18 +18,233 @@ #include "rutil/ServerProcess.hxx" #include "rutil/Log.hxx" #include "rutil/Logger.hxx" +#include "rutil/Time.hxx" #define RESIPROCATE_SUBSYSTEM resip::Subsystem::SIP using namespace resip; using namespace std; -ServerProcess::ServerProcess() : mPidFile("") +static ServerProcess* _instance = NULL; + +static void +signalHandler(int signo) { + resip_assert(_instance); + _instance->onSignal(signo); +} + +ServerProcess::ServerProcess() : mPidFile(""), + mFinished(false), + mReceivedHUP(false) +{ + resip_assert(!_instance); + _instance = this; } ServerProcess::~ServerProcess() { + _instance = NULL; +} + +void +ServerProcess::onSignal(int signo) +{ +#ifndef _WIN32 + if(signo == SIGHUP) + { + InfoLog(<<"Received HUP signal, logger reset"); + Log::reset(); + mReceivedHUP = true; + return; + } +#endif + std::cerr << "Shutting down" << endl; + mFinished = true; +} + +void +ServerProcess::installSignalHandler() +{ + // Install signal handlers +#ifndef _WIN32 + if ( signal( SIGPIPE, SIG_IGN) == SIG_ERR) + { + cerr << "Couldn't install signal handler for SIGPIPE" << endl; + exit(-1); + } + if ( signal( SIGHUP, signalHandler ) == SIG_ERR ) + { + cerr << "Couldn't install signal handler for SIGHUP" << endl; + exit( -1 ); + } +#endif + + if ( signal( SIGINT, signalHandler ) == SIG_ERR ) + { + cerr << "Couldn't install signal handler for SIGINT" << endl; + exit( -1 ); + } + + if ( signal( SIGTERM, signalHandler ) == SIG_ERR ) + { + cerr << "Couldn't install signal handler for SIGTERM" << endl; + exit( -1 ); + } +} + +void +ServerProcess::dropPrivileges(const Data& runAsUser, const Data& runAsGroup) +{ +#ifdef WIN32 + // setuid is not supported on Windows + throw std::runtime_error("Unable to drop privileges on Windows, please check the config"); +#else + int rval; + uid_t cur_uid; + gid_t cur_gid; + uid_t new_uid; + gid_t new_gid; + const char *username; + struct passwd *pw; + struct group *gr; + + if(runAsUser.empty()) + { + ErrLog(<<"Unable to drop privileges, username not specified"); + throw std::runtime_error("Unable to drop privileges, username not specified"); + } + username = runAsUser.c_str(); + pw = getpwnam(username); + if (pw == NULL) + { + ErrLog(<<"Unable to drop privileges, user not found"); + throw std::runtime_error("Unable to drop privileges, user not found"); + } + new_uid = pw->pw_uid; + + if(!runAsGroup.empty()) + { + gr = getgrnam(runAsGroup.c_str()); + if (gr == NULL) + { + ErrLog(<<"Unable to drop privileges, group not found"); + throw std::runtime_error("Unable to drop privileges, group not found"); + } + new_gid = gr->gr_gid; + } + else + { + // Use default group for the specified user + new_gid = pw->pw_gid; + } + + cur_gid = getgid(); + if (cur_gid != new_gid) + { + if (cur_gid != 0) + { + ErrLog(<<"Unable to drop privileges, not root!"); + throw std::runtime_error("Unable to drop privileges, not root!"); + } + + rval = setgid(new_gid); + if (rval < 0) + { + ErrLog(<<"Unable to drop privileges, operation failed (setgid)"); + throw std::runtime_error("Unable to drop privileges, operation failed"); + } + } + + if(initgroups(username, new_gid) < 0) + { + ErrLog(<<"Unable to drop privileges, operation failed (initgroups)"); + throw std::runtime_error("Unable to drop privileges, operation failed"); + } + + cur_uid = getuid(); + if (cur_uid != new_uid) + { + if (cur_uid != 0) + { + ErrLog(<<"Unable to drop privileges, not root!"); + throw std::runtime_error("Unable to drop privileges, not root!"); + } + + // If logging to file, the file ownership may be root and needs to + // be changed + Log::droppingPrivileges(new_uid, new_gid); + if(mPidFile.size() > 0) + { + if(chown(mPidFile.c_str(), new_uid, new_gid) < 0) + { + ErrLog(<<"Failed to change ownership of PID file"); + } + } + + rval = setuid(new_uid); + if (rval < 0) + { + ErrLog(<<"Unable to drop privileges, operation failed (setuid)"); + throw std::runtime_error("Unable to drop privileges, operation failed"); + } + } +#endif +} + +bool +ServerProcess::isAlreadyRunning() +{ +#ifndef __linux__ + //WarningLog(<<"can't check if process already running on this platform (not implemented yet)"); + return false; +#else + if(mPidFile.size() == 0) + { + // if no PID file specified, we do not make any check + return false; + } + + pid_t running_pid; + std::ifstream _pid(mPidFile.c_str(), std::ios_base::in); + if(!_pid.good()) + { + // if the file doesn't exist or can't be opened, just ignore + return false; + } + _pid >> running_pid; + _pid.close(); + + StackLog(<< mPidFile << " contains PID " << running_pid); + + Data ourProc = Data("/proc/self/exe"); + Data otherProc = Data("/proc/") + Data(running_pid) + Data("/exe"); + char our_exe[513], other_exe[513]; + int buf_size; + + buf_size = readlink(ourProc.c_str(), our_exe, 512); + if(buf_size < 0 || buf_size == 512) + { + // if readlink fails, just ignore + return false; + } + our_exe[buf_size] = 0; + + buf_size = readlink(otherProc.c_str(), other_exe, 512); + if(buf_size < 0 || buf_size == 512) + { + // if readlink fails, just ignore + return false; + } + other_exe[buf_size] = 0; + + if(strcmp(our_exe, other_exe) == 0) + { + ErrLog(<<"already running PID: " << running_pid); + return true; + } + return false; +#endif } void @@ -35,12 +252,14 @@ ServerProcess::daemonize() { #ifdef WIN32 // fork is not possible on Windows + ErrLog(<<"Unable to fork/daemonize on Windows, please check the config"); throw std::runtime_error("Unable to fork/daemonize on Windows, please check the config"); #else pid_t pid; if ((pid = fork()) < 0) { // fork() failed + ErrLog(<<"fork() failed: "< + Small changes to fit into bglibs + -- Bruce Guenter + Translation to simpler C++ Code + -- Volker Grabsch +*/ + +#include "Sha1.hxx" +#include +#include +#include + +using namespace resip; + +SHA1::SHA1() +{ + reset(); +} + + +void SHA1::update(const std::string &s) +{ + std::istringstream is(s); + update(is); +} + + +void SHA1::update(std::istream &is) +{ + std::string rest_of_buffer; + read(is, rest_of_buffer, BLOCK_BYTES - buffer.size()); + buffer += rest_of_buffer; + + while (is) + { + uint32_t block[BLOCK_INTS]; + buffer_to_block(buffer, block); + transform(block); + read(is, buffer, BLOCK_BYTES); + } +} + + +/* + * Add padding and return the message digest. + */ + +std::string SHA1::final() +{ + /* Use input and create digest */ + createDigest(); + + /* Hex std::string */ + std::ostringstream result; + for (unsigned int i = 0; i < DIGEST_INTS; i++) + { + result << std::hex << std::setfill('0') << std::setw(8); + result << (digest[i] & 0xffffffff); + } + + /* Reset for next run */ + reset(); + + return result.str(); +} + +resip::Data SHA1::finalBin() +{ + /* Use input and create digest */ + createDigest(); + + resip::Data result(21, Data::Preallocate); // Data likes a NULL at the end use 21 instead of 20 + for (unsigned int i = 0; i < DIGEST_INTS; i++) + { + uint32_t digesttemp = htonl(digest[i]); + result.append((const char*)&digesttemp, sizeof(digest[0])); + } + + /* Reset for next run */ + reset(); + + return result; +} + +void SHA1::createDigest() +{ + /* Total number of hashed bits */ + uint64_t total_bits = (transforms*BLOCK_BYTES + buffer.size()) * 8; + + /* Padding */ + buffer += (char)0x80; + unsigned int orig_size = buffer.size(); + while (buffer.size() < BLOCK_BYTES) + { + buffer += (char)0x00; + } + + uint32_t block[BLOCK_INTS]; + buffer_to_block(buffer, block); + + if (orig_size > BLOCK_BYTES - 8) + { + transform(block); + for (unsigned int i = 0; i < BLOCK_INTS - 2; i++) + { + block[i] = 0; + } + } + + /* Append total_bits, split this uint64_t into two uint32_t */ + block[BLOCK_INTS - 1] = (uint32_t)total_bits; + block[BLOCK_INTS - 2] = (total_bits >> 32); + transform(block); +} + +std::string SHA1::from_file(const std::string &filename) +{ + std::ifstream stream(filename.c_str(), std::ios::binary); + SHA1 checksum; + checksum.update(stream); + return checksum.final(); +} + + +void SHA1::reset() +{ + /* SHA1 initialization constants */ + digest[0] = 0x67452301; + digest[1] = 0xefcdab89; + digest[2] = 0x98badcfe; + digest[3] = 0x10325476; + digest[4] = 0xc3d2e1f0; + + /* Reset counters */ + transforms = 0; + buffer = ""; +} + + +/* + * Hash a single 512-bit block. This is the core of the algorithm. + */ + +void SHA1::transform(uint32_t block[BLOCK_BYTES]) +{ + /* Copy digest[] to working vars */ + uint32_t a = digest[0]; + uint32_t b = digest[1]; + uint32_t c = digest[2]; + uint32_t d = digest[3]; + uint32_t e = digest[4]; + + /* Help macros */ +#define rol(value, bits) (((value) << (bits)) | (((value) & 0xffffffff) >> (32 - (bits)))) +#define blk(i) (block[i&15] = rol(block[(i+13)&15] ^ block[(i+8)&15] ^ block[(i+2)&15] ^ block[i&15],1)) + + /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z += ((w&(x^y))^y) + block[i] + 0x5a827999 + rol(v,5); w=rol(w,30); +#define R1(v,w,x,y,z,i) z += ((w&(x^y))^y) + blk(i) + 0x5a827999 + rol(v,5); w=rol(w,30); +#define R2(v,w,x,y,z,i) z += (w^x^y) + blk(i) + 0x6ed9eba1 + rol(v,5); w=rol(w,30); +#define R3(v,w,x,y,z,i) z += (((w|x)&y)|(w&x)) + blk(i) + 0x8f1bbcdc + rol(v,5); w=rol(w,30); +#define R4(v,w,x,y,z,i) z += (w^x^y) + blk(i) + 0xca62c1d6 + rol(v,5); w=rol(w,30); + + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); + R0(e,a,b,c,d, 1); + R0(d,e,a,b,c, 2); + R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); + R0(a,b,c,d,e, 5); + R0(e,a,b,c,d, 6); + R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); + R0(b,c,d,e,a, 9); + R0(a,b,c,d,e,10); + R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); + R0(c,d,e,a,b,13); + R0(b,c,d,e,a,14); + R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); + R1(d,e,a,b,c,17); + R1(c,d,e,a,b,18); + R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); + R2(e,a,b,c,d,21); + R2(d,e,a,b,c,22); + R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); + R2(a,b,c,d,e,25); + R2(e,a,b,c,d,26); + R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); + R2(b,c,d,e,a,29); + R2(a,b,c,d,e,30); + R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); + R2(c,d,e,a,b,33); + R2(b,c,d,e,a,34); + R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); + R2(d,e,a,b,c,37); + R2(c,d,e,a,b,38); + R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); + R3(e,a,b,c,d,41); + R3(d,e,a,b,c,42); + R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); + R3(a,b,c,d,e,45); + R3(e,a,b,c,d,46); + R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); + R3(b,c,d,e,a,49); + R3(a,b,c,d,e,50); + R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); + R3(c,d,e,a,b,53); + R3(b,c,d,e,a,54); + R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); + R3(d,e,a,b,c,57); + R3(c,d,e,a,b,58); + R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); + R4(e,a,b,c,d,61); + R4(d,e,a,b,c,62); + R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); + R4(a,b,c,d,e,65); + R4(e,a,b,c,d,66); + R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); + R4(b,c,d,e,a,69); + R4(a,b,c,d,e,70); + R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); + R4(c,d,e,a,b,73); + R4(b,c,d,e,a,74); + R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); + R4(d,e,a,b,c,77); + R4(c,d,e,a,b,78); + R4(b,c,d,e,a,79); + + /* Add the working vars back into digest[] */ + digest[0] += a; + digest[1] += b; + digest[2] += c; + digest[3] += d; + digest[4] += e; + + /* Count the number of transformations */ + transforms++; +} + + +void SHA1::buffer_to_block(const std::string &buffer, uint32_t block[BLOCK_BYTES]) +{ + /* Convert the std::string (byte buffer) to a uint32_t array (MSB) */ + for (unsigned int i = 0; i < BLOCK_INTS; i++) + { + block[i] = (buffer[4*i+3] & 0xff) + | (buffer[4*i+2] & 0xff)<<8 + | (buffer[4*i+1] & 0xff)<<16 + | (buffer[4*i+0] & 0xff)<<24; + } +} + + +void SHA1::read(std::istream &is, std::string &s, int maxBuffer) +{ + char* sbuf = new char[maxBuffer]; + is.read(sbuf, maxBuffer); + s.assign(sbuf, (unsigned int)is.gcount()); + delete [] sbuf; +} + +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * . + * + */ diff --git a/src/libs/resiprocate/rutil/Sha1.hxx b/src/libs/resiprocate/rutil/Sha1.hxx new file mode 100644 index 00000000..e486a5f0 --- /dev/null +++ b/src/libs/resiprocate/rutil/Sha1.hxx @@ -0,0 +1,116 @@ +/* + Original Source code contained this header: + + sha1.h - header of + + ============ + SHA-1 in C++ + ============ + + 100% Public Domain. + + Original C Code + -- Steve Reid + Small changes to fit into bglibs + -- Bruce Guenter + Translation to simpler C++ Code + -- Volker Grabsch +*/ + +/* Note: This class was brought in to facilitate simple SHA1 hashing for those that don't want to include + OpenSSL in their project. It is assumed that the OpenSSL implementaiton is more efficient and should be + used in favor of this class whenever possible */ + +#ifndef RESIP_SHA1_HXX +#define RESIP_SHA1_HXX + + +#include +#include + +#include + +#include "Data.hxx" + +namespace resip +{ + +class SHA1 // Produces a 160bit hash (20 hexidecimal digits, 40 characters when converted to a hex string) +{ +public: + SHA1(); + void update(const std::string &s); + void update(std::istream &is); + std::string final(); + resip::Data finalBin(); + static std::string from_file(const std::string &filename); + +private: + static const unsigned int DIGEST_INTS = 5; /* number of 32bit integers per SHA1 digest */ + static const unsigned int BLOCK_INTS = 16; /* number of 32bit integers per SHA1 block */ + static const unsigned int BLOCK_BYTES = BLOCK_INTS * 4; + + uint32_t digest[DIGEST_INTS]; + std::string buffer; + uint64_t transforms; + + void reset(); + void createDigest(); + void transform(uint32_t block[BLOCK_BYTES]); + + static void buffer_to_block(const std::string &buffer, uint32_t block[BLOCK_BYTES]); + static void read(std::istream &is, std::string &s, int max); +}; + +} + +#endif /* SHA1_HPP */ +/* ==================================================================== + * The Vovida Software License, Version 1.0 + * + * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The names "VOCAL", "Vovida Open Communication Application Library", + * and "Vovida Open Communication Application Library (VOCAL)" must + * not be used to endorse or promote products derived from this + * software without prior written permission. For written + * permission, please contact vocal@vovida.org. + * + * 4. Products derived from this software may not be called "VOCAL", nor + * may "VOCAL" appear in their name, without prior written + * permission of Vovida Networks, Inc. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND + * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA + * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES + * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * ==================================================================== + * + * This software consists of voluntary contributions made by Vovida + * Networks, Inc. and many individuals on behalf of Vovida Networks, + * Inc. For more information on Vovida Networks, Inc., please see + * . + * + */ diff --git a/src/libs/resiprocate/rutil/SharedCount.hxx b/src/libs/resiprocate/rutil/SharedCount.hxx index 46d51d3b..54e353a8 100644 --- a/src/libs/resiprocate/rutil/SharedCount.hxx +++ b/src/libs/resiprocate/rutil/SharedCount.hxx @@ -9,7 +9,7 @@ Boost.org */ -#include // std::unique_ptr, std::allocator +#include // std::auto_ptr, std::allocator #include // std::less #include // std::exception #include // std::bad_alloc @@ -239,9 +239,9 @@ public: } } - // unique_ptr is special cased to provide the strong guarantee + // auto_ptr is special cased to provide the strong guarantee template - explicit shared_count(std::unique_ptr & r): pi_(new sp_counted_base_impl< Y *, checked_deleter >(r.get(), checked_deleter())) + explicit shared_count(std::auto_ptr & r): pi_(new sp_counted_base_impl< Y *, checked_deleter >(r.get(), checked_deleter())) { r.release(); } diff --git a/src/libs/resiprocate/rutil/SharedPtr.hxx b/src/libs/resiprocate/rutil/SharedPtr.hxx index 1a7d4f9d..6bc9e55b 100644 --- a/src/libs/resiprocate/rutil/SharedPtr.hxx +++ b/src/libs/resiprocate/rutil/SharedPtr.hxx @@ -11,12 +11,12 @@ */ #include "rutil/SharedCount.hxx" -#include // for std::unique_ptr +#include // for std::auto_ptr #include // for std::swap #include // for std::less #include // for std::bad_cast #include // for std::basic_ostream -#include +#include "rutil/ResipAssert.h" namespace resip { @@ -151,7 +151,7 @@ public: } template - explicit SharedPtr(std::unique_ptr & r): px(r.get()), pn() + explicit SharedPtr(std::auto_ptr & r): px(r.get()), pn() { Y * tmp = r.get(); pn = shared_count(r); @@ -167,7 +167,7 @@ public: } template - SharedPtr & operator=(std::unique_ptr & r) + SharedPtr & operator=(std::auto_ptr & r) { this_type(r).swap(*this); return *this; @@ -180,7 +180,7 @@ public: template void reset(Y * p) // Y must be complete { - assert(p == 0 || p != px); // catch self-reset errors + resip_assert(p == 0 || p != px); // catch self-reset errors this_type(p).swap(*this); } @@ -191,13 +191,13 @@ public: reference operator* () const // never throws { - assert(px != 0); + resip_assert(px != 0); return *px; } T * operator-> () const // never throws { - assert(px != 0); + resip_assert(px != 0); return px; } @@ -335,7 +335,7 @@ template SharedPtr shared_polymorphic_cast(SharedPtr con template SharedPtr shared_polymorphic_downcast(SharedPtr const & r) { - assert(dynamic_cast(r.get()) == r.get()); + resip_assert(dynamic_cast(r.get()) == r.get()); return shared_static_cast(r); } diff --git a/src/libs/resiprocate/rutil/Socket.cxx b/src/libs/resiprocate/rutil/Socket.cxx index e7eabb63..aa0a9687 100644 --- a/src/libs/resiprocate/rutil/Socket.cxx +++ b/src/libs/resiprocate/rutil/Socket.cxx @@ -1,5 +1,5 @@ -#include +#include "rutil/ResipAssert.h" #include #include @@ -28,13 +28,6 @@ resip::makeSocketNonBlocking(Socket fd) return false; } #else - // Make socket non raising SIGPIPE -#ifdef TARGET_OSX - int set = 1; - setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int)); -#endif - - // Make socket non blocking int flags = fcntl( fd, F_GETFL, 0); int errNoBlock = fcntl(fd, F_SETFL, flags | O_NONBLOCK ); if ( errNoBlock != 0 ) // !cj! I may have messed up this line @@ -69,6 +62,23 @@ resip::makeSocketBlocking(Socket fd) +bool +resip::configureConnectedSocket(Socket fd) +{ +#ifdef REQUIRE_SO_NOSIGPIPE + int on = 1; + if ( ::setsockopt ( fd, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&on, sizeof(on)) ) + { + int e = getErrno(); + ErrLog (<< "Couldn't set sockoption SO_NOSIGPIPE: " << strerror(e)); + return false; + } +#endif + return true; +} + + + void resip::initNetwork() { @@ -87,7 +97,7 @@ resip::initNetwork() { // could not find a usable WinSock DLL //cerr << "Could not load winsock" << endl; - assert(0); // is this is failing, try a different version that 2.2, 1.0 or later will likely work + resip_assert(0); // is this is failing, try a different version that 2.2, 1.0 or later will likely work exit(1); } @@ -105,7 +115,7 @@ resip::initNetwork() WSACleanup( ); //cerr << "Bad winsock verion" << endl; // TODO !cj! - add error message logging - assert(0); // if this is failing, try a different version that 2.2, 1.0 or later will likely work + resip_assert(0); // if this is failing, try a different version that 2.2, 1.0 or later will likely work exit(1); } } @@ -139,8 +149,7 @@ int resip::getSocketError(Socket fd) { int errNum = 0; int errNumSize = sizeof(errNum); - getsockopt(fd, SOL_SOCKET, SO_ERROR, - (char *)&errNum, (socklen_t *)&errNumSize); + getsockopt(fd, SOL_SOCKET, SO_ERROR, (char *)&errNum, (socklen_t *)&errNumSize); /// XXX: should check return code of getsockopt return errNum; } @@ -222,7 +231,7 @@ static int trySetRcvBuf(Socket fd, int buflen) { return -1; } - assert(optlen == sizeof(rbuflen)); + resip_assert(optlen == sizeof(rbuflen)); if (rbuflen < buflen) { return -1; @@ -234,7 +243,7 @@ static int trySetRcvBuf(Socket fd, int buflen) **/ int resip::setSocketRcvBufLen(Socket fd, int buflen) { - assert(buflen >= 1024); + resip_assert(buflen >= 1024); int goal=buflen; int trylen=goal; int sts; diff --git a/src/libs/resiprocate/rutil/Socket.hxx b/src/libs/resiprocate/rutil/Socket.hxx index 14b236d5..73b52f41 100644 --- a/src/libs/resiprocate/rutil/Socket.hxx +++ b/src/libs/resiprocate/rutil/Socket.hxx @@ -1,7 +1,7 @@ #if !defined(RESIP_SOCKET_HXX) #define RESIP_SOCKET_HXX -#include +#include "rutil/ResipAssert.h" #include #include @@ -34,7 +34,6 @@ #endif typedef int socklen_t; - //this list taken from , see #if 0 removed block. #define EWOULDBLOCK WSAEWOULDBLOCK #define EINPROGRESS WSAEINPROGRESS @@ -65,7 +64,7 @@ typedef int socklen_t; #define ECONNREFUSED WSAECONNREFUSED #define ELOOP WSAELOOP //#define ENAMETOOLONG WSAENAMETOOLONG - +#define EHOSTDOWN WSAEHOSTDOWN #define EHOSTUNREACH WSAEHOSTUNREACH //#define ENOTEMPTY WSAENOTEMPTY #define EPROCLIM WSAEPROCLIM @@ -74,9 +73,6 @@ typedef int socklen_t; #define ESTALE WSAESTALE #define EREMOTE WSAEREMOTE - -# define EHOSTDOWN WSAEHOSTDOWN - #if defined(_MSC_VER) && (_MSC_VER >= 1600) #pragma warning (pop) #endif @@ -96,9 +92,7 @@ initNetwork(); #ifndef WIN32 typedef int Socket; // Un*x fds are signed -#ifndef INVALID_SOCKET #define INVALID_SOCKET (-1) -#endif #define SOCKET_ERROR (-1) inline int getErrno() { return errno; } #else @@ -115,6 +109,7 @@ typedef void(*AfterSocketCreationFuncPtr)(Socket s, int transportType, const cha bool makeSocketNonBlocking(Socket fd); bool makeSocketBlocking(Socket fd); +bool configureConnectedSocket(Socket fd); int closeSocket( Socket fd ); int getSocketError(Socket fd); // getsockopt(SOCK_SOCKET,SO_ERROR) int increaseLimitFds(unsigned int targetFds); @@ -134,6 +129,11 @@ public: FD_ZERO(&except); } + int select() + { + return numReady = ::select(size, &read, &write, &except, NULL); + } + int select(struct timeval& tv) { return numReady = ::select(size, &read, &write, &except, &tv); @@ -164,11 +164,11 @@ public: void setRead(Socket fd) { - assert( FD_SETSIZE >= 8 ); + resip_assert( FD_SETSIZE >= 8 ); #ifndef WIN32 // windows fd are not int's and don't start at 0 - this won't work in windows - assert( fd < (int)FD_SETSIZE ); // redefineing FD_SETSIZE will not work + resip_assert( fd < (int)FD_SETSIZE ); // redefineing FD_SETSIZE will not work #else - assert(read.fd_count < FD_SETSIZE); // Ensure there is room to add new FD + resip_assert(read.fd_count < FD_SETSIZE); // Ensure there is room to add new FD #endif FD_SET(fd, &read); size = ( int(fd+1) > size) ? int(fd+1) : size; @@ -177,9 +177,9 @@ public: void setWrite(Socket fd) { #ifndef WIN32 // windows fd are not int's and don't start at 0 - this won't work in windows - assert( fd < (int)FD_SETSIZE ); // redefinitn FD_SETSIZE will not work + resip_assert( fd < (int)FD_SETSIZE ); // redefinitn FD_SETSIZE will not work #else - assert(write.fd_count < FD_SETSIZE); // Ensure there is room to add new FD + resip_assert(write.fd_count < FD_SETSIZE); // Ensure there is room to add new FD #endif FD_SET(fd, &write); size = ( int(fd+1) > size) ? int(fd+1) : size; @@ -188,9 +188,9 @@ public: void setExcept(Socket fd) { #ifndef WIN32 // windows fd are not int's and don't start at 0 - this won't work in windows - assert( fd < (int)FD_SETSIZE ); // redefinitn FD_SETSIZE will not work + resip_assert( fd < (int)FD_SETSIZE ); // redefinitn FD_SETSIZE will not work #else - assert(except.fd_count < FD_SETSIZE); // Ensure there is room to add new FD + resip_assert(except.fd_count < FD_SETSIZE); // Ensure there is room to add new FD #endif FD_SET(fd,&except); size = ( int(fd+1) > size) ? int(fd+1) : size; diff --git a/src/libs/resiprocate/rutil/SysLogBuf.cxx b/src/libs/resiprocate/rutil/SysLogBuf.cxx index 4a3252d0..114bf351 100644 --- a/src/libs/resiprocate/rutil/SysLogBuf.cxx +++ b/src/libs/resiprocate/rutil/SysLogBuf.cxx @@ -1,10 +1,7 @@ -#if !defined(WIN32) -#include -#endif - #include -#include +#include "rutil/ResipAssert.h" #include "rutil/SysLogBuf.hxx" +#include "rutil/Log.hxx" #ifndef EOF # define EOF (-1) @@ -13,10 +10,32 @@ using resip::SysLogBuf; SysLogBuf::SysLogBuf () + : mLevel(Log::Debug), + mAppName(""), + mFacility(LOG_DAEMON) +{ + init(); +} + +SysLogBuf::SysLogBuf (const resip::Data& ident, int facility) + : mLevel(Log::Debug), + mAppName(ident), + mFacility(facility) +{ + init(); +} + +void +SysLogBuf::init() { #if !defined(WIN32) setp(buffer,buffer+Size); - openlog (0, LOG_NDELAY, LOG_LOCAL6); + const char* _ident = 0; + if(!mAppName.empty()) + { + _ident = mAppName.c_str(); + } + openlog (_ident, LOG_NDELAY | LOG_PID, mFacility); #endif } @@ -28,11 +47,44 @@ int SysLogBuf::sync() { #if !defined(WIN32) + // Default to debug level for Stack, Debug and unrecognised values + int _level = LOG_DEBUG; + // For efficiency, we check mLevel in decreasing order of frequency, + // anticipating that Stack is the most common and Crit is the least + // common. + switch(mLevel) + { + case Log::Stack: + case Log::Debug: + // This is just here to avoid traversing the rest + // of the switch block for every Stack or Debug message. + // They will just be logged with the default LOG_DEBUG + // specified above. + break; + case Log::Info: + _level = LOG_INFO; + break; + case Log::Warning: + _level = LOG_WARNING; + break; + case Log::Err: + _level = LOG_ERR; + break; + case Log::Crit: + _level = LOG_CRIT; + break; + default: + // just let it use the default value defined above + break; + } *(pptr()) = 0; - syslog (LOG_LOCAL6 | LOG_DEBUG, "%s", pbase()); + syslog (mFacility | _level, "%s", pbase()); + // Set mLevel back to the default level for the next log entry + // in case it is not explicitly specified next time. + mLevel = Log::Debug; setp(buffer, buffer+Size); #else - assert(0); + resip_assert(0); #endif return 0; } @@ -49,6 +101,16 @@ SysLogBuf::overflow (int c) return c; } +std::ostream& resip::operator<< (std::ostream& os, const resip::Log::Level& level) +{ + // FIXME - we should probably find a more precise way to make sure + // that this can never be done for the wrong type of stream. + // For now, we rely on Log.cxx checking if mLogger is of type Syslog + // and not sending Level to the stream otherwise. + static_cast(os.rdbuf())->mLevel = level; + return os; +} + /* ==================================================================== * The Vovida Software License, Version 1.0 * diff --git a/src/libs/resiprocate/rutil/SysLogBuf.hxx b/src/libs/resiprocate/rutil/SysLogBuf.hxx index 3c57921b..22c3a6b7 100644 --- a/src/libs/resiprocate/rutil/SysLogBuf.hxx +++ b/src/libs/resiprocate/rutil/SysLogBuf.hxx @@ -3,6 +3,14 @@ #include +#if !defined(WIN32) +#include +#else +#define LOG_DAEMON 0 +#endif + +#include "rutil/Log.hxx" + namespace resip { @@ -10,6 +18,7 @@ class SysLogBuf : public std::streambuf { public: SysLogBuf(); + SysLogBuf(const Data& ident, int facility); virtual ~SysLogBuf(); int sync (); @@ -20,9 +29,16 @@ class SysLogBuf : public std::streambuf //inline streamsize xsputn (char* text, streamsize n); private: + void init(); + friend std::ostream& operator<< (std::ostream& os, const resip::Log::Level& level); enum { Size=4095 }; char buffer[Size+1]; + Log::Level mLevel; + Data mAppName; + int mFacility; }; + +std::ostream& operator<< (std::ostream& os, const resip::Log::Level& level); } diff --git a/src/libs/resiprocate/rutil/SysLogStream.cxx b/src/libs/resiprocate/rutil/SysLogStream.cxx index 126272dd..24f6faba 100644 --- a/src/libs/resiprocate/rutil/SysLogStream.cxx +++ b/src/libs/resiprocate/rutil/SysLogStream.cxx @@ -14,6 +14,12 @@ SysLogStream::SysLogStream() : { } +SysLogStream::SysLogStream(const resip::Data& ident, int facility) : + SysLogBuf(ident, facility), + std::ostream (this) +{ +} + SysLogStream::~SysLogStream() { } diff --git a/src/libs/resiprocate/rutil/SysLogStream.hxx b/src/libs/resiprocate/rutil/SysLogStream.hxx index 4ee53f69..b5e51321 100644 --- a/src/libs/resiprocate/rutil/SysLogStream.hxx +++ b/src/libs/resiprocate/rutil/SysLogStream.hxx @@ -11,6 +11,7 @@ class SysLogStream : private SysLogBuf, public std::ostream { public: SysLogStream(); + SysLogStream(const Data& ident, int facility = LOG_DAEMON); virtual ~SysLogStream(); private: diff --git a/src/libs/resiprocate/rutil/ThreadIf.cxx b/src/libs/resiprocate/rutil/ThreadIf.cxx index b45f9349..348a8774 100644 --- a/src/libs/resiprocate/rutil/ThreadIf.cxx +++ b/src/libs/resiprocate/rutil/ThreadIf.cxx @@ -15,7 +15,7 @@ typedef unsigned(__stdcall *RESIP_THREAD_START_ROUTINE)(void*); #include "rutil/Socket.hxx" #endif -#include +#include "rutil/ResipAssert.h" #include #include "rutil/ThreadIf.hxx" #include "rutil/Mutex.hxx" @@ -44,10 +44,10 @@ __stdcall #endif threadIfThreadWrapper( void* threadParm ) { - assert( threadParm ); + resip_assert( threadParm ); ThreadIf* t = static_cast < ThreadIf* > ( threadParm ); - assert( t ); + resip_assert( t ); t->thread(); #ifdef WIN32 // Free data in TLS slots. @@ -102,7 +102,7 @@ ThreadIf::~ThreadIf() void ThreadIf::run() { - assert(mId == 0); + resip_assert(mId == 0); #if defined(WIN32) // !kh! @@ -127,13 +127,13 @@ ThreadIf::run() 0, //DWORD dwCreationFlags, // creation flags (unsigned*)&mId// LPDWORD lpThreadId // pointer to receive thread ID ); - assert( mThread != 0 ); + resip_assert( mThread != 0 ); #else // spawn the thread if ( int retval = pthread_create( &mId, 0, threadIfThreadWrapper, this) ) { std::cerr << "Failed to spawn thread: " << retval << std::endl; - assert(0); + resip_assert(0); // TODO - ADD LOGING HERE } #endif @@ -185,7 +185,7 @@ ThreadIf::join() if ( r != 0 ) { WarningLog( << "Internal error: pthread_join() returned " << r ); - assert(0); + resip_assert(0); // TODO } } diff --git a/src/libs/resiprocate/rutil/Time.cxx b/src/libs/resiprocate/rutil/Time.cxx index bb050d8f..6047505e 100644 --- a/src/libs/resiprocate/rutil/Time.cxx +++ b/src/libs/resiprocate/rutil/Time.cxx @@ -16,6 +16,24 @@ using namespace resip; +void resip::sleepMs(unsigned int ms) +{ +#ifdef WIN32 + Sleep(ms); +#else + usleep(ms*1000); +#endif +} + +void resip::sleepSeconds(unsigned int seconds) +{ +#ifdef WIN32 + Sleep(seconds*1000); +#else + sleep(seconds); +#endif +} + ResipClock::ResipClock(void) { } @@ -79,7 +97,7 @@ UInt64 ResipClock::WinMonoClock::GTCInterlocked::GTC64(void) #if defined(_MSC_VER) && (_MSC_VER >= 1400) //no atomic intrinsics on Visual Studio 2003 and below ULARGE_INTEGER timeVal; - assert(IS_ALIGNED(&mBaseTime,8)); //if the implementation ever changes to use 64-bit atomic read/write then 64-bit alignment will be required. + resip_assert(IS_ALIGNED(&mBaseTime,8)); //if the implementation ever changes to use 64-bit atomic read/write then 64-bit alignment will be required. //InterlockedCompareExchange64 will issue a LOCK CMPXCHG8B to ensure atomic access to mBaseTime //Not the most efficient wat to do a 64-bit atomic read (see fild instruction), but no intrinsic for 64-bit atomic read. @@ -112,7 +130,7 @@ UInt64 ResipClock::WinMonoClock::GTCInterlocked::GTC64(void) return timeVal.QuadPart; #else - assert(0); //this counter only compiles on Visual Studio 2005 + + resip_assert(0); //this counter only compiles on Visual Studio 2005 + return GTCLock::GTC64(); #endif //#if (_MSC_VER >= 1400) //no atomic intrinsics on Visual Studio 2003 and below } @@ -175,7 +193,7 @@ Mutex ResipClock::WinMonoClock::GTCLockDuringRange::mWrapCounterMutex; UInt64 ResipClock::getSystemTime() { - assert(sizeof(UInt64) == 64/8); + resip_assert(sizeof(UInt64) == 64/8); #if defined(WIN32) || defined(UNDER_CE) #ifdef _RESIP_MONOTONIC_CLOCK @@ -226,7 +244,7 @@ ResipClock::getSystemTime() UInt64 ResipClock::getForever() { - assert( sizeof(UInt64) == 8 ); + resip_assert( sizeof(UInt64) == 8 ); #if defined(WIN32) && !defined(__GNUC__) return 18446744073709551615ui64; #else @@ -246,9 +264,9 @@ ResipClock::getRandomFutureTimeMs( UInt64 futureMs ) UInt64 ret = now; ret += (futureMs*r)/10000; - assert( ret >= now ); - assert( ret >= now+(futureMs/2) ); - assert( ret <= now+futureMs ); + resip_assert( ret >= now ); + resip_assert( ret >= now+(futureMs/2) ); + resip_assert( ret <= now+futureMs ); return ret; } diff --git a/src/libs/resiprocate/rutil/Time.hxx b/src/libs/resiprocate/rutil/Time.hxx index b3dd1cbf..25c3d986 100644 --- a/src/libs/resiprocate/rutil/Time.hxx +++ b/src/libs/resiprocate/rutil/Time.hxx @@ -3,11 +3,14 @@ #include "rutil/Mutex.hxx" #include -#include +#include "rutil/ResipAssert.h" namespace resip { +void sleepMs(unsigned int ms); +void sleepSeconds(unsigned int seconds); + /** Clock used for timing in the Timer class and possibly other areas. Depending on the OS and compile settings this clock may not be monotonic. Define _RESIP_MONOTONIC_CLOCK to enable monotonic timers. The precision of this clock is available in microseconds, but the accuracy depends on other factors such as the OS and hardware. @@ -154,7 +157,7 @@ class ResipClock __int64 maxWait = (__int64)UINT_MAX - mBaseTimeUpdateInterval - mBaseTimeCushion; if (maxWait <= 0) { - assert(0); + resip_assert(0); const_cast(mBaseTimeUpdateInterval) = 60000; const_cast(mBaseTimeCushion) = 120000; return UINT_MAX - mBaseTimeUpdateInterval - mBaseTimeCushion; @@ -166,11 +169,7 @@ class ResipClock /** Last stored time. Using InterlockedExchange (CMPXCHG8B) the alignment is not necessary, but it shouldn't hurt. Align it on a cache line since it is rarely written and read often (to avoid false-sharing). */ -#ifdef _MSC_VER static _declspec(align(128)) volatile UInt64 mBaseTime; -#else - static volatile UInt64 mBaseTime; -#endif /** Max elapsed time since last GTC64 call, in milliseconds, before writing mBaseTime. Cannot exceed UINT_MAX - mBaseTimeCushion. */ diff --git a/src/libs/resiprocate/rutil/TimeLimitFifo.hxx b/src/libs/resiprocate/rutil/TimeLimitFifo.hxx index db6a9cf9..54ddd52d 100644 --- a/src/libs/resiprocate/rutil/TimeLimitFifo.hxx +++ b/src/libs/resiprocate/rutil/TimeLimitFifo.hxx @@ -1,7 +1,7 @@ #ifndef RESIP_TimeLimitFifo_hxx #define RESIP_TimeLimitFifo_hxx -#include +#include "rutil/ResipAssert.h" #include #include "rutil/AbstractFifo.hxx" #include @@ -67,7 +67,7 @@ class Timestamped assert(tlf.size() == 1); assert(tlf.timeDepth() == 0); - sleepMS(2000); + sleepMs(2000); // still not empty assert(!tlf.empty()); @@ -230,7 +230,7 @@ template TimeLimitFifo::~TimeLimitFifo() { clear(); - assert(empty()); + resip_assert(empty()); } template @@ -321,7 +321,7 @@ TimeLimitFifo::wouldAcceptInteral(DepthUsage usage) const return true; } - assert(usage == EnforceTimeDepth); + resip_assert(usage == EnforceTimeDepth); if (mFifo.size() == 0 || mMaxDurationSecs == 0 || diff --git a/src/libs/resiprocate/rutil/Timer.cxx b/src/libs/resiprocate/rutil/Timer.cxx index a5d96bae..13958820 100644 --- a/src/libs/resiprocate/rutil/Timer.cxx +++ b/src/libs/resiprocate/rutil/Timer.cxx @@ -13,7 +13,7 @@ # include #endif -#include +#include "rutil/ResipAssert.h" #include "rutil/Time.hxx" #include "rutil/Timer.hxx" #include "rutil/Logger.hxx" @@ -53,6 +53,9 @@ resip::Timer::TH = 64*T1; unsigned long resip::Timer::TS = 32000; +unsigned long +resip::Timer::TcpConnectTimeout = 0; // disabled + void Timer::resetT1(unsigned long t1) { @@ -103,8 +106,10 @@ Timer::toData(Type timer) return "Timer Stateless"; case TimerCleanUp: return "Timer Cleanup"; + case TcpConnectTimer: + return "TcpConnectTimer"; default: - assert(0); + resip_assert(0); } return "Bad Bad Bad in timer"; } @@ -159,7 +164,7 @@ TimerWithPayload::TimerWithPayload(unsigned long ms, Message* message) : mWhen(ms + Timer::getTimeMs()), mMessage(message) { - assert(mMessage); + resip_assert(mMessage); } std::ostream& diff --git a/src/libs/resiprocate/rutil/Timer.hxx b/src/libs/resiprocate/rutil/Timer.hxx index d10fa8aa..00388e37 100644 --- a/src/libs/resiprocate/rutil/Timer.hxx +++ b/src/libs/resiprocate/rutil/Timer.hxx @@ -10,6 +10,12 @@ #include #include "rutil/Time.hxx" +/// !slg! TODO - a large portion of the code in this file belongs in the resip/stack as +/// opposed to rutil. Candidates for move are: +/// 1. All SIP Specific timer logic in Timer class +/// 2. Transaction Timer +/// 3. TimerWithPayload + namespace resip { @@ -44,7 +50,8 @@ class Timer TimerStaleServer, TimerStateless, TimerCleanUp, - ApplicationTimer // .dlb. Fifo, so no thread issues + ApplicationTimer, // .dlb. Fifo, so no thread issues + TcpConnectTimer } Type; static Data toData(Type timer); @@ -115,7 +122,9 @@ class Timer static unsigned long TH; // default 64*T1 static unsigned long TD; - static unsigned long TS; + static unsigned long TS; + + static unsigned long TcpConnectTimeout; }; // !bwc! There is some duplicated code between TransactionTimer and @@ -177,11 +186,10 @@ class TimerWithPayload RESIP_HeapCount(TimerWithPayload); TimerWithPayload(unsigned long ms, Message* message); - - ~TimerWithPayload(){} + ~TimerWithPayload() {} // return the message to queue, possibly null - Message* getMessage() const { return mMessage;} + Message* getMessage() const { return mMessage; } UInt64 getWhen() const {return mWhen;} #ifndef RESIP_USE_STL_STREAMS diff --git a/src/libs/resiprocate/rutil/TransportType.cxx b/src/libs/resiprocate/rutil/TransportType.cxx index 5eec0c10..0fd07d13 100644 --- a/src/libs/resiprocate/rutil/TransportType.cxx +++ b/src/libs/resiprocate/rutil/TransportType.cxx @@ -12,7 +12,9 @@ static const Data transportNames[MAX_TRANSPORT] = Data("UDP"), Data("SCTP"), Data("DCCP"), - Data("DTLS") + Data("DTLS"), + Data("WS"), + Data("WSS") }; static const Data transportNamesLower[MAX_TRANSPORT] = @@ -23,7 +25,9 @@ static const Data transportNamesLower[MAX_TRANSPORT] = Data("udp"), Data("sctp"), Data("dccp"), - Data("dtls") + Data("dtls"), + Data("ws"), + Data("wss") }; TransportType @@ -61,14 +65,14 @@ getTransportNameFromTypeLower(const TransportType typeEnum) const resip::Data& toData(const TransportType typeEnum) { - assert(typeEnum >= UNKNOWN_TRANSPORT && typeEnum < MAX_TRANSPORT); + resip_assert(typeEnum >= UNKNOWN_TRANSPORT && typeEnum < MAX_TRANSPORT); return transportNames[typeEnum]; } const resip::Data& toDataLower(const TransportType typeEnum) { - assert(typeEnum >= UNKNOWN_TRANSPORT && typeEnum < MAX_TRANSPORT); + resip_assert(typeEnum >= UNKNOWN_TRANSPORT && typeEnum < MAX_TRANSPORT); return transportNamesLower[typeEnum]; } @@ -80,6 +84,8 @@ isReliable(TransportType type) case TLS: case TCP: case SCTP: + case WS: + case WSS: return true; case UDP: case DCCP: @@ -89,6 +95,38 @@ isReliable(TransportType type) } } +bool +isSecure(TransportType type) +{ + switch(type) + { + case TLS: + case DTLS: + case WSS: + return true; + case UDP: + case TCP: + case DCCP: + case SCTP: + case WS: + default: + return false; + } +} + +bool +isWebSocket(TransportType type) +{ + switch(type) + { + case WS: + case WSS: + return true; + default: + return false; + } +} + } /* ==================================================================== diff --git a/src/libs/resiprocate/rutil/TransportType.hxx b/src/libs/resiprocate/rutil/TransportType.hxx index 175451bc..b7420a04 100644 --- a/src/libs/resiprocate/rutil/TransportType.hxx +++ b/src/libs/resiprocate/rutil/TransportType.hxx @@ -20,6 +20,8 @@ typedef enum SCTP, DCCP, DTLS, + WS, + WSS, MAX_TRANSPORT } TransportType; @@ -55,6 +57,12 @@ const resip::Data& toDataLower(const TransportType typeEnum); /// Returns true if passed in transport type is a reliable transport protocol bool isReliable(TransportType type); +/// Returns true if passed in transport type is a secure transport protocol +bool isSecure(TransportType type); + +/// Returns true if passed in transport type is a WebSocket transport protocol +bool isWebSocket(TransportType type); + // Indicate whether or not to run a stun server on a Transport typedef enum { diff --git a/src/libs/resiprocate/rutil/WinCompat.cxx b/src/libs/resiprocate/rutil/WinCompat.cxx index a22024a3..e0eb0f08 100644 --- a/src/libs/resiprocate/rutil/WinCompat.cxx +++ b/src/libs/resiprocate/rutil/WinCompat.cxx @@ -1,11 +1,10 @@ -#if defined(TARGET_WIN) - #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include +#include #include "rutil/GenericIPAddress.hxx" #include "rutil/WinCompat.hxx" @@ -16,10 +15,6 @@ #define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT -#if defined(TARGET_WIN) && defined(_MSC_VER) -FILE _iob[] = { *stdin, *stdout, *stderr }; -extern "C" FILE * __cdecl __iob_func(void) { return _iob; } -#endif static char* ConvertLPWSTRToLPSTR(LPWSTR lpwszStrIn) { @@ -176,11 +171,11 @@ WinCompat::WinCompat() : return; } - getBestInterfaceEx = (GetBestInterfaceExProc) GetProcAddress(hLib, "GetBestInterfaceEx"); - getAdaptersAddresses = (GetAdaptersAddressesProc) GetProcAddress(hLib, "GetAdaptersAddresses"); - getAdaptersInfo = (GetAdaptersInfoProc) GetProcAddress(hLib, "GetAdaptersInfo"); - getBestRoute = (GetBestRouteProc) GetProcAddress(hLib, "GetBestRoute"); - getIpAddrTable = (GetIpAddrTableProc) GetProcAddress(hLib, "GetIpAddrTable"); + getBestInterfaceEx = (GetBestInterfaceExProc) GetProcAddress(hLib, TEXT("GetBestInterfaceEx")); + getAdaptersAddresses = (GetAdaptersAddressesProc) GetProcAddress(hLib, TEXT("GetAdaptersAddresses")); + getAdaptersInfo = (GetAdaptersInfoProc) GetProcAddress(hLib, TEXT("GetAdaptersInfo")); + getBestRoute = (GetBestRouteProc) GetProcAddress(hLib, TEXT("GetBestRoute")); + getIpAddrTable = (GetIpAddrTableProc) GetProcAddress(hLib, TEXT("GetIpAddrTable")); if (getAdaptersAddresses == NULL || getBestInterfaceEx == NULL) { loadLibraryWithIPv6Failed = true; @@ -202,6 +197,34 @@ void WinCompat::destroyInstance() mInstance = 0; } +bool WinCompat::windowsEventLog(WORD type, WORD numStrings, LPCTSTR* strings) +{ + // type can be: + // EVENTLOG_SUCCESS (0x0000) Information event + // EVENTLOG_AUDIT_FAILURE (0x0010) Failure Audit event + // EVENTLOG_AUDIT_SUCCESS (0x0008) Success Audit event + // EVENTLOG_ERROR_TYPE (0x0001) Error event + // EVENTLOG_INFORMATION_TYPE (0x0004) Information event + // EVENTLOG_WARNING_TYPE (0x0002) Warning event + + HKEY key; + long errorCode = + ::RegCreateKeyEx(HKEY_LOCAL_MACHINE, _T("System\\CurrentControlSet\\Services\\EventLog\\Application\\reSIProcate"), + 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &key, NULL); + if (ERROR_SUCCESS == errorCode) + { + ::RegCloseKey(key); + HANDLE eventLogHandle = ::RegisterEventSource(NULL, _T("reSIProcate")); + if (eventLogHandle != NULL) + { + BOOL retVal = ::ReportEvent(eventLogHandle, type, 0, 0, NULL, numStrings, 0, strings, NULL); + ::DeregisterEventSource(eventLogHandle); + return (retVal != FALSE); + } + } + return false; +} + WinCompat::~WinCompat() { if(hLib != NULL) @@ -252,16 +275,12 @@ WinCompat::determineSourceInterfaceWithIPv6(const GenericIPAddress& destination) int i; for (i = 0, AI = pAdapterAddresses; AI != NULL; AI = AI->Next, i++) { - PIP_ADAPTER_UNICAST_ADDRESS defaultAdaptorAddress = 0; for (PIP_ADAPTER_UNICAST_ADDRESS unicast = AI->FirstUnicastAddress; unicast; unicast = unicast->Next) { if (unicast->Address.lpSockaddr->sa_family != family) continue; - // Store first address of matching family as the Adaptors default address - if(!defaultAdaptorAddress) defaultAdaptorAddress = unicast; - if (family == AF_INET && reinterpret_cast(unicast->Address.lpSockaddr)->sin_addr.S_un.S_addr == destination.v4Address.sin_addr.S_un.S_addr) @@ -269,9 +288,18 @@ WinCompat::determineSourceInterfaceWithIPv6(const GenericIPAddress& destination) // Return default address for NIC. Note: We could also just return the destination, // however returning the default address for NIC is beneficial in cases where the // co-located registrar supports redundancy via a Virtual IP address. - GenericIPAddress ipaddress(*defaultAdaptorAddress->Address.lpSockaddr); - LocalFree(pAdapterAddresses); - return(ipaddress); + for (PIP_ADAPTER_UNICAST_ADDRESS unicastRet = AI->FirstUnicastAddress; + unicastRet; unicastRet = unicastRet->Next) + { +#if defined(AVOID_TRANSIENT_SOURCE_ADDRESSES) + if (unicastRet->Flags & IP_ADAPTER_ADDRESS_TRANSIENT) + continue; +#endif + + GenericIPAddress ipaddress(*unicastRet->Address.lpSockaddr); + LocalFree(pAdapterAddresses); + return(ipaddress); + } } #ifdef USE_IPV6 else if (family == AF_INET6 && @@ -279,16 +307,25 @@ WinCompat::determineSourceInterfaceWithIPv6(const GenericIPAddress& destination) &(reinterpret_cast(&destination.address)->sin6_addr), sizeof(IN6_ADDR)) == 0) { - // explicitly cast to sockaddr_in6, to use that version of GenericIPAddress' ctor. If we don't, then compiler - // defaults to ctor for sockaddr_in (at least under Win32), which will truncate the lower-bits of the IPv6 address. - const struct sockaddr_in6* psa = reinterpret_cast(defaultAdaptorAddress->Address.lpSockaddr); + for (PIP_ADAPTER_UNICAST_ADDRESS unicastRet = AI->FirstUnicastAddress; + unicastRet; unicastRet = unicastRet->Next) + { +#if defined(AVOID_TRANSIENT_SOURCE_ADDRESSES) + if (unicastRet->Flags & IP_ADAPTER_ADDRESS_TRANSIENT) + continue; +#endif - // Return default address for NIC. Note: We could also just return the destination, - // however returning the default address for NIC is beneficial in cases where the - // co-located registrar supports redundancy via a Virtual IP address. - GenericIPAddress ipaddress(*psa); - LocalFree(pAdapterAddresses); - return(ipaddress); + // explicitly cast to sockaddr_in6, to use that version of GenericIPAddress' ctor. If we don't, then compiler + // defaults to ctor for sockaddr_in (at least under Win32), which will truncate the lower-bits of the IPv6 address. + const struct sockaddr_in6* psa = reinterpret_cast(unicastRet->Address.lpSockaddr); + + // Return default address for NIC. Note: We could also just return the destination, + // however returning the default address for NIC is beneficial in cases where the + // co-located registrar supports redundancy via a Virtual IP address. + GenericIPAddress ipaddress(*psa); + LocalFree(pAdapterAddresses); + return(ipaddress); + } } #endif } @@ -310,6 +347,12 @@ WinCompat::determineSourceInterfaceWithIPv6(const GenericIPAddress& destination) { if (unicast->Address.lpSockaddr->sa_family != saddr->sa_family) continue; + +#if defined(AVOID_TRANSIENT_SOURCE_ADDRESSES) + if (unicast->Flags & IP_ADAPTER_ADDRESS_TRANSIENT) + continue; +#endif + if (saddr->sa_family == AF_INET && AI->IfIndex == dwBestIfIndex) { GenericIPAddress ipaddress(*unicast->Address.lpSockaddr); @@ -365,14 +408,14 @@ WinCompat::determineSourceInterfaceWithoutIPv6(const GenericIPAddress& destinati } else { - throw Exception("Can't find source address for destination (GetIpAddrTable to get buffer space failed), ret=" + Data(ret), __FILE__,__LINE__); + throw Exception("Can't find source address for destination (GetIpAddrTable to get buffer space failed), ret=" + Data((UInt32)ret), __FILE__,__LINE__); } ret = instance()->getIpAddrTable(pIpAddrTable, &addrSize, FALSE); if (NO_ERROR != ret) { delete [] (char *) pIpAddrTable; - throw Exception("Can't find source address for destination (GetIpAddrTable failed), addrSize=" + Data(addrSize) + ", ret=" + Data(ret), __FILE__,__LINE__); + throw Exception("Can't find source address for destination (GetIpAddrTable failed), addrSize=" + Data((UInt32)addrSize) + ", ret=" + Data((UInt32)ret), __FILE__,__LINE__); } // Check if address is local or not @@ -390,6 +433,11 @@ WinCompat::determineSourceInterfaceWithoutIPv6(const GenericIPAddress& destinati DWORD dwNicIndex = pIpAddrTable->table[i].dwIndex; for(DWORD j = 0; j dwNumEntries; j++) { +#if defined(AVOID_TRANSIENT_SOURCE_ADDRESSES) + if (pIpAddrTable->table[j].wType & MIB_IPADDR_TRANSIENT) + continue; +#endif + if(pIpAddrTable->table[j].dwIndex == dwNicIndex) // Default address is first address found for NIC { DebugLog(<< "Routing to a local address - returning default address for NIC"); @@ -409,7 +457,7 @@ WinCompat::determineSourceInterfaceWithoutIPv6(const GenericIPAddress& destinati if (NO_ERROR != ret) { delete [] (char *) pIpAddrTable; - throw Exception("Can't find source address for destination, ret=" + Data(ret), __FILE__,__LINE__); + throw Exception("Can't find source address for destination, ret=" + Data((UInt32)ret), __FILE__,__LINE__); } // look through the local ip address to find one that match the best route. @@ -423,6 +471,12 @@ WinCompat::determineSourceInterfaceWithoutIPv6(const GenericIPAddress& destinati ULONG addr = pIpAddrTable->table[i].dwAddr; ULONG gw = bestRoute.dwForwardNextHop; + +#if defined(AVOID_TRANSIENT_SOURCE_ADDRESSES) + if (entry.wType & MIB_IPADDR_TRANSIENT) + continue; +#endif + if(entry.dwIndex == bestRoute.dwForwardIfIndex) // Note: there MAY be > 1 entry with the same index, see AddIPAddress. { if( (entry.dwAddr & entry.dwMask) == (bestRoute.dwForwardNextHop & entry.dwMask) ) @@ -466,11 +520,16 @@ WinCompat::determineSourceInterfaceWithoutIPv6(const GenericIPAddress& destinati nicMask.s_addr = entry.dwMask; DebugLog(<<"IP Table entry " <dwNumEntries <<" if-index=" < > getInterfaces(const Data& matching); static void destroyInstance(); + static bool windowsEventLog(WORD type, WORD numStrings, LPCTSTR* strings); + private: static WinCompat* instance(); static WinCompat* mInstance; diff --git a/src/libs/resiprocate/rutil/XMLCursor.cxx b/src/libs/resiprocate/rutil/XMLCursor.cxx index bd8769fa..244b3225 100644 --- a/src/libs/resiprocate/rutil/XMLCursor.cxx +++ b/src/libs/resiprocate/rutil/XMLCursor.cxx @@ -95,13 +95,13 @@ XMLCursor::XMLCursor(const ParseBuffer& pb) } } } - mRoot = new Node(ParseBuffer(mData.data(), mData.size())); + mRoot.reset(new Node(ParseBuffer(mData.data(), mData.size()))); } else { - mRoot = new Node(ParseBuffer(start, pb.end() - start)); + mRoot.reset(new Node(ParseBuffer(start, pb.end() - start))); } - mCursor = mRoot; + mCursor = mRoot.get(); if (mRoot->extractTag()) { @@ -122,26 +122,22 @@ XMLCursor::XMLCursor(const ParseBuffer& pb) { pbtemp.skipWhitespace(); } - //if (!pbtemp.eof()) + if (*pbtemp.position() == LA_QUOTE[0] && + *(pbtemp.position()+1) == SLASH[0]) { - if (*pbtemp.position() == LA_QUOTE[0] && - *(pbtemp.position()+1) == SLASH[0]) - { - pbtemp.skipChar(); - pbtemp.skipChar(); - if (strncmp(mRoot->mTag.data(), pbtemp.position(), mRoot->mTag.size()) == 0) - { - // no children ever - mRoot->mPb.reset(mRoot->mPb.end()); - return; - } - } + pbtemp.skipChar(); + pbtemp.skipChar(); + if (strncmp(mRoot->mTag.data(), pbtemp.position(), mRoot->mTag.size()) == 0) + { + // no children ever + mRoot->mPb.reset(mRoot->mPb.end()); + return; + } } } XMLCursor::~XMLCursor() { - delete mRoot; } void @@ -210,8 +206,8 @@ XMLCursor::parseNextRootChild() pb.skipChar(); // CodeWarrior isn't helpful enough to pick the "obvious" operator definition // so we add volatile here so CW is completely unconfused what to do. - // second note - MSVC 7.0 won't compile the volatile - tried the following to fix - const char* end = pb.position(); + // second note - MSVC 7.0 won't compile the volatile - tried the following to fix + const char* end = pb.position(); if ( (const char*)pb.end() < end + mTag.size() ) { InfoLog(<< "XML: unexpected end"); @@ -261,7 +257,7 @@ XMLCursor::nextSibling() } StackLog(<< "XMLCursor::nextSibling" << *this->mCursor << " " << *this->mCursor->mParent); - if (mCursor->mParent == mRoot) + if (mCursor->mParent == mRoot.get()) { parseNextRootChild(); } @@ -318,14 +314,14 @@ XMLCursor::parent() void XMLCursor::reset() { - mCursor = mRoot; + mCursor = mRoot.get(); mAttributesSet = false; } bool XMLCursor::atRoot() const { - return mCursor == mRoot; + return mCursor == mRoot.get(); } bool @@ -416,7 +412,7 @@ XMLCursor::getValue() const { ParseBuffer pb(mCursor->mPb); pb.skipToEnd(); - mValue = pb.data(pb.start()); + pb.data(mValue, pb.start()); XMLCursor::decode(mValue); } else @@ -474,7 +470,11 @@ bool XMLCursor::Node::extractTag() { ParseBuffer pb(mPb); - const char* anchor = pb.skipChar(); + if (!WhitespaceSignificant) + { + pb.skipWhitespace(); + } + const char* anchor = pb.skipChar(LA_QUOTE[0]); pb.skipToOneOf(ParseBuffer::Whitespace, SLASH_RA_QUOTE); pb.assertNotEof(); pb.data(mTag, anchor); @@ -552,8 +552,8 @@ XMLCursor::Node::skipToEndTag() mPb.skipChar(); // CodeWarrior isn't helpful enough to pick the "obvious" operator definition // so we add volatile here so CW is completely unconfused what to do. - // second note - MSVC 7.0 won't compile the volatile - tried the following to fix - const char* end = mPb.position(); + // second note - MSVC 7.0 won't compile the volatile - tried the following to fix + const char* end = mPb.position(); if ( (const char*)mPb.end() < end + mTag.size() ) { InfoLog(<< "XML: unexpected end"); diff --git a/src/libs/resiprocate/rutil/XMLCursor.hxx b/src/libs/resiprocate/rutil/XMLCursor.hxx index 691bfdfe..0e953ec4 100644 --- a/src/libs/resiprocate/rutil/XMLCursor.hxx +++ b/src/libs/resiprocate/rutil/XMLCursor.hxx @@ -2,6 +2,7 @@ #define RESIP_XMLCURSOR_HXX #include +#include #include #include "rutil/ParseBuffer.hxx" @@ -119,12 +120,13 @@ class XMLCursor static EncodeStream& encode(EncodeStream& strm, const AttributeMap& attrs); class Node; - class AttributeValueEqual { - Data data_; - public: - AttributeValueEqual(const Data& data) : data_(data) {}; - bool operator()(const std::pair& data) { return data.second == data_; } - }; + class AttributeValueEqual + { + Data data_; + public: + AttributeValueEqual(const Data& data) : data_(data) {}; + bool operator()(const std::pair& data) { return data.second == data_; } + }; private: static void skipProlog(ParseBuffer& pb); @@ -134,7 +136,7 @@ class XMLCursor void parseNextRootChild(); - Node* mRoot; + std::auto_ptr mRoot; Node* mCursor; //bool isEmpty; diff --git a/src/libs/resiprocate/rutil/cajun/Readme.txt b/src/libs/resiprocate/rutil/cajun/Readme.txt deleted file mode 100644 index 41ed4c59..00000000 --- a/src/libs/resiprocate/rutil/cajun/Readme.txt +++ /dev/null @@ -1,14 +0,0 @@ -CAJUN* is a C++ API for the JSON object interchange format. JSON is like XML, except it doesn't suck**. It is specifically designed for representing (in plain text format) structures familiar to software engineers: booleans, numerics, strings, arrays, and objects (i.e. name/value pairs, associative array, etc.); it humbly leaves text markup to XML. It is ideal for storing persistent application data, such as configuration or user data files. - -Too many JSON parsers I've seen suffer from overly complex designs and confusing interfaces, so in true software engineer form, I thought I could do better. The goal of JSON was to create an simple, "minimalist" interface while sacrificing absolutely no power or flexibility. The STL containers, while not without their violations of that spirit, served as an inspiration. The end result is (IMHO) an interface that should be immediately intuitive to anyone familiar with C++ and the Standard Library containers. It can best be described as working with an "element", where an element may consist of: -* String (mimics std::string) -* Numeric (double) -* Boolean (bool) -* Array (std::vector) -* Object (unsorted std::map) -* UnknownElement - like boost::any, but restricted to types below. Used to aggregate elements within Objects & Arrays, and for reading documents of unknown structure - -As with any design, sacrifices were made with CAJUN. Most situations I've encountered where JSON is well-suited (reading & writing application configuration and data files) are not typically performance bottlenecks, so simplicity, safety & flexibility were favored over raw speed. The end result is a library with simple, typesafe classes, no memory-management burden on the user, and exception-based error reporting. - -* C++ API for JSON. A pint on me for who ever comes up with a good meaning for "UN". -** To be fair, XML doesn't suck intentionally, it is just often used inappropriately. \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/cajun/ReleaseNotes.txt b/src/libs/resiprocate/rutil/cajun/ReleaseNotes.txt deleted file mode 100644 index c2529065..00000000 --- a/src/libs/resiprocate/rutil/cajun/ReleaseNotes.txt +++ /dev/null @@ -1,42 +0,0 @@ -2.0.2 (12/04/2011) -* Fixed exception text construction bug (pointer + offset, instead of std::string + std::string) -* Fixed crash in UnknownElement::operator= -* Fixed bug where object member names couldn't contain special characters -* Fixed crash when parsing an incomplete document -* Cosmetic changes to parser -* Added proper BSD license text - -2.0.1 (11/17/2009) -* A couple of Reader functions not inlined, sometimes resulting in linker duplicate symbols. Oops. - -2.0.0 (11/14/2009) -* Redesign/simplicification of the element class relationships: - * Element/Element_T base class or *Imp classes eliminated. Originally necessary for aggregation by Object/Array, but now unnecessary with UnknownElement type - * json_cast<> functions eliminated. Static type safety relaxed, allowing more concise document data extraction code (dynamic type safety still completely maintained). - * Quick-Interpreter/-Builder classes eliminated. Equivalent functionality now in "UnknownElement", but now more accessible - In summary, simpler design, less code in library, less code necessary to utilize library. See test app for many more new examples. -* Entire library is now inlined. Bound to be controversial, but... - * Modern compilers should eliminate redundant object code - * Fixes problems associated with different runtime libraries, library debug information, security & debug iterator compile-time options under MSVC++, among other things. - * Simply include the appropriate file & go - no linker settings to mess with. -* Added 64-bit build targets for MSVC 8/9 test app, just because. -* Scan/Parse exceptions moved into Reader class scope, and Parse exceptions fixed to always include bad token string -* A few more random bug fixes -* Tested under: - * MSVC++ 2005 - * MSVC++ 2008 - * GCC 4.4.0 - -1.1.0 (08/30/2009) -* Implemented operator == for all element types -* Added makefile for building with g++ (thanks George Morgan). -* Fixed a few compiler errors on non-Visual Studio compilers (my C++ wasn't as ANSI as I thought...) -* Support for (non-standard) comments REMOVED -* Support for Visual Studio 7.1 (2003) REMOVED -* Fixed the "Unexpected token..." exception string (was gibberish) -* Improvements to the QuickInterpreter & QuickBuilder interfaces -* Elements now sanity-check themselves during operations and throw an exception accordingly, for example if an Object gets tricked into thinking it's an Array (reinterpret_cast, reading a document with an Array root element into an Object, etc) -* Other random minor bug fixes & general cleanup - -1.0.0 (01/31/2009) -* Initial release! Remaining work: better documentation, better test/sample app, yada yada diff --git a/src/libs/resiprocate/rutil/cajun/json/elements.h b/src/libs/resiprocate/rutil/cajun/json/elements.h deleted file mode 100644 index df1a0ca3..00000000 --- a/src/libs/resiprocate/rutil/cajun/json/elements.h +++ /dev/null @@ -1,299 +0,0 @@ -/****************************************************************************** - -Copyright (c) 2009-2010, Terry Caton -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the projecct nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -******************************************************************************/ - -#pragma once - -#include -#include -#include -#include - -/* - -TODO: -* better documentation (doxygen?) -* Unicode support -* parent element accessors - -*/ - -namespace json -{ - -namespace Version -{ - enum { MAJOR = 2 }; - enum { MINOR = 0 }; - enum {ENGINEERING = 2 }; -} - -///////////////////////////////////////////////// -// forward declarations (more info further below) - - -class Visitor; -class ConstVisitor; - -template -class TrivialType_T; - -typedef TrivialType_T Number; -typedef TrivialType_T Boolean; -typedef TrivialType_T String; - -class Object; -class Array; -class Null; - - - -///////////////////////////////////////////////////////////////////////// -// Exception - base class for all JSON-related runtime errors - -class Exception : public std::runtime_error -{ -public: - Exception(const std::string& sMessage); -}; - - - - -///////////////////////////////////////////////////////////////////////// -// UnknownElement - provides a typesafe surrogate for any of the JSON- -// sanctioned element types. This class allows the Array and Object -// class to effectively contain a heterogeneous set of child elements. -// The cast operators provide convenient implicit downcasting, while -// preserving dynamic type safety by throwing an exception during a -// a bad cast. -// The object & array element index operators (operators [std::string] -// and [size_t]) provide convenient, quick access to child elements. -// They are a logical extension of the cast operators. These child -// element accesses can be chained together, allowing the following -// (when document structure is well-known): -// String str = objInvoices[1]["Customer"]["Company"]; - - -class UnknownElement -{ -public: - UnknownElement(); - UnknownElement(const UnknownElement& unknown); - UnknownElement(const Object& object); - UnknownElement(const Array& array); - UnknownElement(const Number& number); - UnknownElement(const Boolean& boolean); - UnknownElement(const String& string); - UnknownElement(const Null& null); - - ~UnknownElement(); - - UnknownElement& operator = (const UnknownElement& unknown); - - // implicit cast to actual element type. throws on failure - operator const Object& () const; - operator const Array& () const; - operator const Number& () const; - operator const Boolean& () const; - operator const String& () const; - operator const Null& () const; - - // implicit cast to actual element type. *converts* on failure, and always returns success - operator Object& (); - operator Array& (); - operator Number& (); - operator Boolean& (); - operator String& (); - operator Null& (); - - // provides quick access to children when real element type is object - UnknownElement& operator[] (const std::string& key); - const UnknownElement& operator[] (const std::string& key) const; - - // provides quick access to children when real element type is array - UnknownElement& operator[] (size_t index); - const UnknownElement& operator[] (size_t index) const; - - // implements visitor pattern - void Accept(ConstVisitor& visitor) const; - void Accept(Visitor& visitor); - - // tests equality. first checks type, then value if possible - bool operator == (const UnknownElement& element) const; - -private: - class Imp; - - template - class Imp_T; - - class CastVisitor; - class ConstCastVisitor; - - template - class CastVisitor_T; - - template - class ConstCastVisitor_T; - - template - const ElementTypeT& CastTo() const; - - template - ElementTypeT& ConvertTo(); - - Imp* m_pImp; -}; - - -///////////////////////////////////////////////////////////////////////////////// -// Array - mimics std::deque. The array contents are effectively -// heterogeneous thanks to the ElementUnknown class. push_back has been replaced -// by more generic insert functions. - -class Array -{ -public: - typedef std::deque Elements; - typedef Elements::iterator iterator; - typedef Elements::const_iterator const_iterator; - - iterator Begin(); - iterator End(); - const_iterator Begin() const; - const_iterator End() const; - - iterator Insert(const UnknownElement& element, iterator itWhere); - iterator Insert(const UnknownElement& element); - iterator Erase(iterator itWhere); - void Resize(size_t newSize); - void Clear(); - - size_t Size() const; - bool Empty() const; - - UnknownElement& operator[] (size_t index); - const UnknownElement& operator[] (size_t index) const; - - bool operator == (const Array& array) const; - -private: - Elements m_Elements; -}; - - -///////////////////////////////////////////////////////////////////////////////// -// Object - mimics std::map. The member value -// contents are effectively heterogeneous thanks to the UnknownElement class - -class Object -{ -public: - struct Member { - Member(const std::string& nameIn = std::string(), const UnknownElement& elementIn = UnknownElement()); - - bool operator == (const Member& member) const; - - std::string name; - UnknownElement element; - }; - - typedef std::list Members; // map faster, but does not preserve order - typedef Members::iterator iterator; - typedef Members::const_iterator const_iterator; - - bool operator == (const Object& object) const; - - iterator Begin(); - iterator End(); - const_iterator Begin() const; - const_iterator End() const; - - size_t Size() const; - bool Empty() const; - - iterator Find(const std::string& name); - const_iterator Find(const std::string& name) const; - - iterator Insert(const Member& member); - iterator Insert(const Member& member, iterator itWhere); - iterator Erase(iterator itWhere); - void Clear(); - - UnknownElement& operator [](const std::string& name); - const UnknownElement& operator [](const std::string& name) const; - -private: - class Finder; - - Members m_Members; -}; - - -///////////////////////////////////////////////////////////////////////////////// -// TrivialType_T - class template for encapsulates a simple data type, such as -// a string, number, or boolean. Provides implicit const & noncost cast operators -// for that type, allowing "DataTypeT type = trivialType;" - - -template -class TrivialType_T -{ -public: - TrivialType_T(const DataTypeT& t = DataTypeT()); - - operator DataTypeT&(); - operator const DataTypeT&() const; - - DataTypeT& Value(); - const DataTypeT& Value() const; - - bool operator == (const TrivialType_T& trivial) const; - -private: - DataTypeT m_tValue; -}; - - - -///////////////////////////////////////////////////////////////////////////////// -// Null - doesn't do much of anything but satisfy the JSON spec. It is the default -// element type of UnknownElement - -class Null -{ -public: - bool operator == (const Null& trivial) const; -}; - - -} // End namespace - - -#include "elements.inl" diff --git a/src/libs/resiprocate/rutil/cajun/json/elements.inl b/src/libs/resiprocate/rutil/cajun/json/elements.inl deleted file mode 100644 index dbfbf2af..00000000 --- a/src/libs/resiprocate/rutil/cajun/json/elements.inl +++ /dev/null @@ -1,442 +0,0 @@ -/****************************************************************************** - -Copyright (c) 2009-2010, Terry Caton -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the projecct nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -******************************************************************************/ - -#include "visitor.h" -#include "reader.h" -#include -#include -#include - -/* - -TODO: -* better documentation - -*/ - -namespace json -{ - - -inline Exception::Exception(const std::string& sMessage) : - std::runtime_error(sMessage) {} - - -///////////////////////// -// UnknownElement members - -class UnknownElement::Imp -{ -public: - virtual ~Imp() {} - virtual Imp* Clone() const = 0; - - virtual bool Compare(const Imp& imp) const = 0; - - virtual void Accept(ConstVisitor& visitor) const = 0; - virtual void Accept(Visitor& visitor) = 0; -}; - - -template -class UnknownElement::Imp_T : public UnknownElement::Imp -{ -public: - Imp_T(const ElementTypeT& element) : m_Element(element) {} - virtual Imp* Clone() const { return new Imp_T(*this); } - - virtual void Accept(ConstVisitor& visitor) const { visitor.Visit(m_Element); } - virtual void Accept(Visitor& visitor) { visitor.Visit(m_Element); } - - virtual bool Compare(const Imp& imp) const - { - ConstCastVisitor_T castVisitor; - imp.Accept(castVisitor); - return castVisitor.m_pElement && - m_Element == *castVisitor.m_pElement; - } - -private: - ElementTypeT m_Element; -}; - - -class UnknownElement::ConstCastVisitor : public ConstVisitor -{ - virtual void Visit(const Array& array) {} - virtual void Visit(const Object& object) {} - virtual void Visit(const Number& number) {} - virtual void Visit(const String& string) {} - virtual void Visit(const Boolean& boolean) {} - virtual void Visit(const Null& null) {} -}; - -template -class UnknownElement::ConstCastVisitor_T : public ConstCastVisitor -{ -public: - ConstCastVisitor_T() : m_pElement(0) {} - virtual void Visit(const ElementTypeT& element) { m_pElement = &element; } // we don't know what this is, but it overrides one of the base's no-op functions - const ElementTypeT* m_pElement; -}; - - -class UnknownElement::CastVisitor : public Visitor -{ - virtual void Visit(Array& array) {} - virtual void Visit(Object& object) {} - virtual void Visit(Number& number) {} - virtual void Visit(String& string) {} - virtual void Visit(Boolean& boolean) {} - virtual void Visit(Null& null) {} -}; - -template -class UnknownElement::CastVisitor_T : public CastVisitor -{ -public: - CastVisitor_T() : m_pElement(0) {} - virtual void Visit(ElementTypeT& element) { m_pElement = &element; } // we don't know what this is, but it overrides one of the base's no-op functions - ElementTypeT* m_pElement; -}; - - - - -inline UnknownElement::UnknownElement() : m_pImp( new Imp_T( Null() ) ) {} -inline UnknownElement::UnknownElement(const UnknownElement& unknown) : m_pImp( unknown.m_pImp->Clone()) {} -inline UnknownElement::UnknownElement(const Object& object) : m_pImp( new Imp_T(object) ) {} -inline UnknownElement::UnknownElement(const Array& array) : m_pImp( new Imp_T(array) ) {} -inline UnknownElement::UnknownElement(const Number& number) : m_pImp( new Imp_T(number) ) {} -inline UnknownElement::UnknownElement(const Boolean& boolean) : m_pImp( new Imp_T(boolean) ) {} -inline UnknownElement::UnknownElement(const String& string) : m_pImp( new Imp_T(string) ) {} -inline UnknownElement::UnknownElement(const Null& null) : m_pImp( new Imp_T(null) ) {} - -inline UnknownElement::~UnknownElement() { delete m_pImp; } - -inline UnknownElement::operator const Object& () const { return CastTo(); } -inline UnknownElement::operator const Array& () const { return CastTo(); } -inline UnknownElement::operator const Number& () const { return CastTo(); } -inline UnknownElement::operator const Boolean& () const { return CastTo(); } -inline UnknownElement::operator const String& () const { return CastTo(); } -inline UnknownElement::operator const Null& () const { return CastTo(); } - -inline UnknownElement::operator Object& () { return ConvertTo(); } -inline UnknownElement::operator Array& () { return ConvertTo(); } -inline UnknownElement::operator Number& () { return ConvertTo(); } -inline UnknownElement::operator Boolean& () { return ConvertTo(); } -inline UnknownElement::operator String& () { return ConvertTo(); } -inline UnknownElement::operator Null& () { return ConvertTo(); } - -inline UnknownElement& UnknownElement::operator = (const UnknownElement& unknown) -{ - // always check for this - if (&unknown != this) - { - // we might be copying from a subtree of ourselves. delete the old imp - // only after the clone operation is complete. yes, this could be made - // more efficient, but isn't worth the complexity - Imp* pOldImp = m_pImp; - m_pImp = unknown.m_pImp->Clone(); - delete pOldImp; - } - - return *this; -} - -inline UnknownElement& UnknownElement::operator[] (const std::string& key) -{ - // the people want an object. make us one if we aren't already - Object& object = ConvertTo(); - return object[key]; -} - -inline const UnknownElement& UnknownElement::operator[] (const std::string& key) const -{ - // throws if we aren't an object - const Object& object = CastTo(); - return object[key]; -} - -inline UnknownElement& UnknownElement::operator[] (size_t index) -{ - // the people want an array. make us one if we aren't already - Array& array = ConvertTo(); - return array[index]; -} - -inline const UnknownElement& UnknownElement::operator[] (size_t index) const -{ - // throws if we aren't an array - const Array& array = CastTo(); - return array[index]; -} - - -template -const ElementTypeT& UnknownElement::CastTo() const -{ - ConstCastVisitor_T castVisitor; - m_pImp->Accept(castVisitor); - if (castVisitor.m_pElement == 0) - throw Exception("Bad cast"); - return *castVisitor.m_pElement; -} - - - -template -ElementTypeT& UnknownElement::ConvertTo() -{ - CastVisitor_T castVisitor; - m_pImp->Accept(castVisitor); - if (castVisitor.m_pElement == 0) - { - // we're not the right type. fix it & try again - *this = ElementTypeT(); - m_pImp->Accept(castVisitor); - } - - return *castVisitor.m_pElement; -} - - -inline void UnknownElement::Accept(ConstVisitor& visitor) const { m_pImp->Accept(visitor); } -inline void UnknownElement::Accept(Visitor& visitor) { m_pImp->Accept(visitor); } - - -inline bool UnknownElement::operator == (const UnknownElement& element) const -{ - return m_pImp->Compare(*element.m_pImp); -} - - - -////////////////// -// Object members - - -inline Object::Member::Member(const std::string& nameIn, const UnknownElement& elementIn) : - name(nameIn), element(elementIn) {} - -inline bool Object::Member::operator == (const Member& member) const -{ - return name == member.name && - element == member.element; -} - -class Object::Finder : public std::unary_function -{ -public: - Finder(const std::string& name) : m_name(name) {} - bool operator () (const Object::Member& member) { - return member.name == m_name; - } - -private: - std::string m_name; -}; - - - -inline Object::iterator Object::Begin() { return m_Members.begin(); } -inline Object::iterator Object::End() { return m_Members.end(); } -inline Object::const_iterator Object::Begin() const { return m_Members.begin(); } -inline Object::const_iterator Object::End() const { return m_Members.end(); } - -inline size_t Object::Size() const { return m_Members.size(); } -inline bool Object::Empty() const { return m_Members.empty(); } - -inline Object::iterator Object::Find(const std::string& name) -{ - return std::find_if(m_Members.begin(), m_Members.end(), Finder(name)); -} - -inline Object::const_iterator Object::Find(const std::string& name) const -{ - return std::find_if(m_Members.begin(), m_Members.end(), Finder(name)); -} - -inline Object::iterator Object::Insert(const Member& member) -{ - return Insert(member, End()); -} - -inline Object::iterator Object::Insert(const Member& member, iterator itWhere) -{ - iterator it = Find(member.name); - if (it != m_Members.end()) - throw Exception(std::string("Object member already exists: ") + member.name); - - it = m_Members.insert(itWhere, member); - return it; -} - -inline Object::iterator Object::Erase(iterator itWhere) -{ - return m_Members.erase(itWhere); -} - -inline UnknownElement& Object::operator [](const std::string& name) -{ - - iterator it = Find(name); - if (it == m_Members.end()) - { - Member member(name); - it = Insert(member, End()); - } - return it->element; -} - -inline const UnknownElement& Object::operator [](const std::string& name) const -{ - const_iterator it = Find(name); - if (it == End()) - throw Exception(std::string("Object member not found: ") + name); - return it->element; -} - -inline void Object::Clear() -{ - m_Members.clear(); -} - -inline bool Object::operator == (const Object& object) const -{ - return m_Members == object.m_Members; -} - - -///////////////// -// Array members - -inline Array::iterator Array::Begin() { return m_Elements.begin(); } -inline Array::iterator Array::End() { return m_Elements.end(); } -inline Array::const_iterator Array::Begin() const { return m_Elements.begin(); } -inline Array::const_iterator Array::End() const { return m_Elements.end(); } - -inline Array::iterator Array::Insert(const UnknownElement& element, iterator itWhere) -{ - return m_Elements.insert(itWhere, element); -} - -inline Array::iterator Array::Insert(const UnknownElement& element) -{ - return Insert(element, End()); -} - -inline Array::iterator Array::Erase(iterator itWhere) -{ - return m_Elements.erase(itWhere); -} - -inline void Array::Resize(size_t newSize) -{ - m_Elements.resize(newSize); -} - -inline size_t Array::Size() const { return m_Elements.size(); } -inline bool Array::Empty() const { return m_Elements.empty(); } - -inline UnknownElement& Array::operator[] (size_t index) -{ - size_t nMinSize = index + 1; // zero indexed - if (m_Elements.size() < nMinSize) - m_Elements.resize(nMinSize); - return m_Elements[index]; -} - -inline const UnknownElement& Array::operator[] (size_t index) const -{ - if (index >= m_Elements.size()) - throw Exception("Array out of bounds"); - return m_Elements[index]; -} - -inline void Array::Clear() { - m_Elements.clear(); -} - -inline bool Array::operator == (const Array& array) const -{ - return m_Elements == array.m_Elements; -} - - -//////////////////////// -// TrivialType_T members - -template -TrivialType_T::TrivialType_T(const DataTypeT& t) : - m_tValue(t) {} - -template -TrivialType_T::operator DataTypeT&() -{ - return Value(); -} - -template -TrivialType_T::operator const DataTypeT&() const -{ - return Value(); -} - -template -DataTypeT& TrivialType_T::Value() -{ - return m_tValue; -} - -template -const DataTypeT& TrivialType_T::Value() const -{ - return m_tValue; -} - -template -bool TrivialType_T::operator == (const TrivialType_T& trivial) const -{ - return m_tValue == trivial.m_tValue; -} - - - -////////////////// -// Null members - -inline bool Null::operator == (const Null& trivial) const -{ - return true; -} - - - -} // End namespace diff --git a/src/libs/resiprocate/rutil/cajun/json/reader.h b/src/libs/resiprocate/rutil/cajun/json/reader.h deleted file mode 100644 index f4316702..00000000 --- a/src/libs/resiprocate/rutil/cajun/json/reader.h +++ /dev/null @@ -1,148 +0,0 @@ -/****************************************************************************** - -Copyright (c) 2009-2010, Terry Caton -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the projecct nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -******************************************************************************/ - - - -#pragma once - -#include "elements.h" -#include -#include - -namespace json -{ - -class Reader -{ -public: - // this structure will be reported in one of the exceptions defined below - struct Location - { - Location(); - - unsigned int m_nLine; // document line, zero-indexed - unsigned int m_nLineOffset; // character offset from beginning of line, zero indexed - unsigned int m_nDocOffset; // character offset from entire document, zero indexed - }; - - // thrown during the first phase of reading. generally catches low-level problems such - // as errant characters or corrupt/incomplete documents - class ScanException : public Exception - { - public: - ScanException(const std::string& sMessage, const Reader::Location& locError) : - Exception(sMessage), - m_locError(locError) {} - - Reader::Location m_locError; - }; - - // thrown during the second phase of reading. generally catches higher-level problems such - // as missing commas or brackets - class ParseException : public Exception - { - public: - ParseException(const std::string& sMessage, const Reader::Location& locTokenBegin, const Reader::Location& locTokenEnd) : - Exception(sMessage), - m_locTokenBegin(locTokenBegin), - m_locTokenEnd(locTokenEnd) {} - - Reader::Location m_locTokenBegin; - Reader::Location m_locTokenEnd; - }; - - - // if you know what the document looks like, call one of these... - static void Read(Object& object, std::istream& istr); - static void Read(Array& array, std::istream& istr); - static void Read(String& string, std::istream& istr); - static void Read(Number& number, std::istream& istr); - static void Read(Boolean& boolean, std::istream& istr); - static void Read(Null& null, std::istream& istr); - - // ...otherwise, if you don't know, call this & visit it - static void Read(UnknownElement& elementRoot, std::istream& istr); - -private: - struct Token - { - enum Type - { - TOKEN_OBJECT_BEGIN, // { - TOKEN_OBJECT_END, // } - TOKEN_ARRAY_BEGIN, // [ - TOKEN_ARRAY_END, // ] - TOKEN_NEXT_ELEMENT, // , - TOKEN_MEMBER_ASSIGN, // : - TOKEN_STRING, // "xxx" - TOKEN_NUMBER, // [+/-]000.000[e[+/-]000] - TOKEN_BOOLEAN, // true -or- false - TOKEN_NULL, // null - }; - - Type nType; - std::string sValue; - - // for malformed file debugging - Reader::Location locBegin; - Reader::Location locEnd; - }; - - class InputStream; - class TokenStream; - typedef std::vector Tokens; - - template - static void Read_i(ElementTypeT& element, std::istream& istr); - - // scanning istream into token sequence - void Scan(Tokens& tokens, InputStream& inputStream); - - void EatWhiteSpace(InputStream& inputStream); - std::string MatchString(InputStream& inputStream); - std::string MatchNumber(InputStream& inputStream); - std::string MatchExpectedString(InputStream& inputStream, const std::string& sExpected); - - // parsing token sequence into element structure - void Parse(UnknownElement& element, TokenStream& tokenStream); - void Parse(Object& object, TokenStream& tokenStream); - void Parse(Array& array, TokenStream& tokenStream); - void Parse(String& string, TokenStream& tokenStream); - void Parse(Number& number, TokenStream& tokenStream); - void Parse(Boolean& boolean, TokenStream& tokenStream); - void Parse(Null& null, TokenStream& tokenStream); - - const std::string& MatchExpectedToken(Token::Type nExpected, TokenStream& tokenStream); -}; - - -} // End namespace - - -#include "reader.inl" \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/cajun/json/reader.inl b/src/libs/resiprocate/rutil/cajun/json/reader.inl deleted file mode 100644 index b297fa33..00000000 --- a/src/libs/resiprocate/rutil/cajun/json/reader.inl +++ /dev/null @@ -1,533 +0,0 @@ -/****************************************************************************** - -Copyright (c) 2009-2010, Terry Caton -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the projecct nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -******************************************************************************/ - -#include -#include -#include - -/* - -TODO: -* better documentation -* unicode character decoding - -*/ - -namespace json -{ - -inline std::istream& operator >> (std::istream& istr, UnknownElement& elementRoot) { - Reader::Read(elementRoot, istr); - return istr; -} - -inline Reader::Location::Location() : - m_nLine(0), - m_nLineOffset(0), - m_nDocOffset(0) -{} - - -////////////////////// -// Reader::InputStream - -class Reader::InputStream // would be cool if we could inherit from std::istream & override "get" -{ -public: - InputStream(std::istream& iStr) : - m_iStr(iStr) {} - - // protect access to the input stream, so we can keeep track of document/line offsets - char Get(); // big, define outside - char Peek() { - assert(m_iStr.eof() == false); // enforce reading of only valid stream data - return m_iStr.peek(); - } - - bool EOS() { - m_iStr.peek(); // apparently eof flag isn't set until a character read is attempted. whatever. - return m_iStr.eof(); - } - - const Location& GetLocation() const { return m_Location; } - -private: - std::istream& m_iStr; - Location m_Location; -}; - - -inline char Reader::InputStream::Get() -{ - assert(m_iStr.eof() == false); // enforce reading of only valid stream data - char c = m_iStr.get(); - - ++m_Location.m_nDocOffset; - if (c == '\n') { - ++m_Location.m_nLine; - m_Location.m_nLineOffset = 0; - } - else { - ++m_Location.m_nLineOffset; - } - - return c; -} - - - -////////////////////// -// Reader::TokenStream - -class Reader::TokenStream -{ -public: - TokenStream(const Tokens& tokens); - - const Token& Peek(); - const Token& Get(); - - bool EOS() const; - -private: - const Tokens& m_Tokens; - Tokens::const_iterator m_itCurrent; -}; - - -inline Reader::TokenStream::TokenStream(const Tokens& tokens) : - m_Tokens(tokens), - m_itCurrent(tokens.begin()) -{} - -inline const Reader::Token& Reader::TokenStream::Peek() { - if (EOS()) - { - const Token& lastToken = *m_Tokens.rbegin(); - std::string sMessage = "Unexpected end of token stream"; - throw ParseException(sMessage, lastToken.locBegin, lastToken.locEnd); // nowhere to point to - } - return *(m_itCurrent); -} - -inline const Reader::Token& Reader::TokenStream::Get() { - const Token& token = Peek(); - ++m_itCurrent; - return token; -} - -inline bool Reader::TokenStream::EOS() const { - return m_itCurrent == m_Tokens.end(); -} - -/////////////////// -// Reader (finally) - - -inline void Reader::Read(Object& object, std::istream& istr) { Read_i(object, istr); } -inline void Reader::Read(Array& array, std::istream& istr) { Read_i(array, istr); } -inline void Reader::Read(String& string, std::istream& istr) { Read_i(string, istr); } -inline void Reader::Read(Number& number, std::istream& istr) { Read_i(number, istr); } -inline void Reader::Read(Boolean& boolean, std::istream& istr) { Read_i(boolean, istr); } -inline void Reader::Read(Null& null, std::istream& istr) { Read_i(null, istr); } -inline void Reader::Read(UnknownElement& unknown, std::istream& istr) { Read_i(unknown, istr); } - - -template -void Reader::Read_i(ElementTypeT& element, std::istream& istr) -{ - Reader reader; - - Tokens tokens; - InputStream inputStream(istr); - reader.Scan(tokens, inputStream); - - TokenStream tokenStream(tokens); - reader.Parse(element, tokenStream); - - if (tokenStream.EOS() == false) - { - const Token& token = tokenStream.Peek(); - std::string sMessage = std::string("Expected End of token stream; found ") + token.sValue; - throw ParseException(sMessage, token.locBegin, token.locEnd); - } -} - - -inline void Reader::Scan(Tokens& tokens, InputStream& inputStream) -{ - while (EatWhiteSpace(inputStream), // ignore any leading white space... - inputStream.EOS() == false) // ...before checking for EOS - { - // if all goes well, we'll create a token each pass - Token token; - token.locBegin = inputStream.GetLocation(); - - // gives us null-terminated string - char sChar = inputStream.Peek(); - switch (sChar) - { - case '{': - token.sValue = MatchExpectedString(inputStream, "{"); - token.nType = Token::TOKEN_OBJECT_BEGIN; - break; - - case '}': - token.sValue = MatchExpectedString(inputStream, "}"); - token.nType = Token::TOKEN_OBJECT_END; - break; - - case '[': - token.sValue = MatchExpectedString(inputStream, "["); - token.nType = Token::TOKEN_ARRAY_BEGIN; - break; - - case ']': - token.sValue = MatchExpectedString(inputStream, "]"); - token.nType = Token::TOKEN_ARRAY_END; - break; - - case ',': - token.sValue = MatchExpectedString(inputStream, ","); - token.nType = Token::TOKEN_NEXT_ELEMENT; - break; - - case ':': - token.sValue = MatchExpectedString(inputStream, ":"); - token.nType = Token::TOKEN_MEMBER_ASSIGN; - break; - - case '"': - token.sValue = MatchString(inputStream); - token.nType = Token::TOKEN_STRING; - break; - - case '-': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - token.sValue = MatchNumber(inputStream); - token.nType = Token::TOKEN_NUMBER; - break; - - case 't': - token.sValue = MatchExpectedString(inputStream, "true"); - token.nType = Token::TOKEN_BOOLEAN; - break; - - case 'f': - token.sValue = MatchExpectedString(inputStream, "false"); - token.nType = Token::TOKEN_BOOLEAN; - break; - - case 'n': - token.sValue = MatchExpectedString(inputStream, "null"); - token.nType = Token::TOKEN_NULL; - break; - - default: - { - std::string sErrorMessage = std::string("Unexpected character in stream: ") + sChar; - throw ScanException(sErrorMessage, inputStream.GetLocation()); - } - } - - token.locEnd = inputStream.GetLocation(); - tokens.push_back(token); - } -} - - -inline void Reader::EatWhiteSpace(InputStream& inputStream) -{ - while (inputStream.EOS() == false && - ::isspace(inputStream.Peek())) - inputStream.Get(); -} - -inline std::string Reader::MatchExpectedString(InputStream& inputStream, const std::string& sExpected) -{ - std::string::const_iterator it(sExpected.begin()), - itEnd(sExpected.end()); - for ( ; it != itEnd; ++it) { - if (inputStream.EOS() || // did we reach the end before finding what we're looking for... - inputStream.Get() != *it) // ...or did we find something different? - { - std::string sMessage = std::string("Expected string: ") + sExpected; - throw ScanException(sMessage, inputStream.GetLocation()); - } - } - - // all's well if we made it here - return sExpected; -} - - -inline std::string Reader::MatchString(InputStream& inputStream) -{ - MatchExpectedString(inputStream, "\""); - - std::string string; - while (inputStream.EOS() == false && - inputStream.Peek() != '"') - { - char c = inputStream.Get(); - - // escape? - if (c == '\\' && - inputStream.EOS() == false) // shouldn't have reached the end yet - { - c = inputStream.Get(); - switch (c) { - case '/': string.push_back('/'); break; - case '"': string.push_back('"'); break; - case '\\': string.push_back('\\'); break; - case 'b': string.push_back('\b'); break; - case 'f': string.push_back('\f'); break; - case 'n': string.push_back('\n'); break; - case 'r': string.push_back('\r'); break; - case 't': string.push_back('\t'); break; - //case 'u': string.push_back('\u'); break; // TODO: what do we do with this? - default: { - std::string sMessage = std::string("Unrecognized escape sequence found in string: \\") + c; - throw ScanException(sMessage, inputStream.GetLocation()); - } - } - } - else { - string.push_back(c); - } - } - - // eat the last '"' that we just peeked - MatchExpectedString(inputStream, "\""); - - // all's well if we made it here - return string; -} - - -inline std::string Reader::MatchNumber(InputStream& inputStream) -{ - const char sNumericChars[] = "0123456789.eE-+"; - std::set numericChars; - numericChars.insert(sNumericChars, sNumericChars + sizeof(sNumericChars)); - - std::string sNumber; - while (inputStream.EOS() == false && - numericChars.find(inputStream.Peek()) != numericChars.end()) - { - sNumber.push_back(inputStream.Get()); - } - - return sNumber; -} - - -inline void Reader::Parse(UnknownElement& element, Reader::TokenStream& tokenStream) -{ - const Token& token = tokenStream.Peek(); - switch (token.nType) { - case Token::TOKEN_OBJECT_BEGIN: - { - // implicit non-const cast will perform conversion for us (if necessary) - Object& object = element; - Parse(object, tokenStream); - break; - } - - case Token::TOKEN_ARRAY_BEGIN: - { - Array& array = element; - Parse(array, tokenStream); - break; - } - - case Token::TOKEN_STRING: - { - String& string = element; - Parse(string, tokenStream); - break; - } - - case Token::TOKEN_NUMBER: - { - Number& number = element; - Parse(number, tokenStream); - break; - } - - case Token::TOKEN_BOOLEAN: - { - Boolean& boolean = element; - Parse(boolean, tokenStream); - break; - } - - case Token::TOKEN_NULL: - { - Null& null = element; - Parse(null, tokenStream); - break; - } - - default: - { - std::string sMessage = std::string("Unexpected token: ") + token.sValue; - throw ParseException(sMessage, token.locBegin, token.locEnd); - } - } -} - - -inline void Reader::Parse(Object& object, Reader::TokenStream& tokenStream) -{ - MatchExpectedToken(Token::TOKEN_OBJECT_BEGIN, tokenStream); - - bool bContinue = (tokenStream.EOS() == false && - tokenStream.Peek().nType != Token::TOKEN_OBJECT_END); - while (bContinue) - { - Object::Member member; - - // first the member name. save the token in case we have to throw an exception - const Token& tokenName = tokenStream.Peek(); - member.name = MatchExpectedToken(Token::TOKEN_STRING, tokenStream); - - // ...then the key/value separator... - MatchExpectedToken(Token::TOKEN_MEMBER_ASSIGN, tokenStream); - - // ...then the value itself (can be anything). - Parse(member.element, tokenStream); - - // try adding it to the object (this could throw) - try - { - object.Insert(member); - } - catch (Exception&) - { - // must be a duplicate name - std::string sMessage = std::string("Duplicate object member token: ") + member.name; - throw ParseException(sMessage, tokenName.locBegin, tokenName.locEnd); - } - - bContinue = (tokenStream.EOS() == false && - tokenStream.Peek().nType == Token::TOKEN_NEXT_ELEMENT); - if (bContinue) - MatchExpectedToken(Token::TOKEN_NEXT_ELEMENT, tokenStream); - } - - MatchExpectedToken(Token::TOKEN_OBJECT_END, tokenStream); -} - - -inline void Reader::Parse(Array& array, Reader::TokenStream& tokenStream) -{ - MatchExpectedToken(Token::TOKEN_ARRAY_BEGIN, tokenStream); - - bool bContinue = (tokenStream.EOS() == false && - tokenStream.Peek().nType != Token::TOKEN_ARRAY_END); - while (bContinue) - { - // ...what's next? could be anything - Array::iterator itElement = array.Insert(UnknownElement()); - UnknownElement& element = *itElement; - Parse(element, tokenStream); - - bContinue = (tokenStream.EOS() == false && - tokenStream.Peek().nType == Token::TOKEN_NEXT_ELEMENT); - if (bContinue) - MatchExpectedToken(Token::TOKEN_NEXT_ELEMENT, tokenStream); - } - - MatchExpectedToken(Token::TOKEN_ARRAY_END, tokenStream); -} - - -inline void Reader::Parse(String& string, Reader::TokenStream& tokenStream) -{ - string = MatchExpectedToken(Token::TOKEN_STRING, tokenStream); -} - - -inline void Reader::Parse(Number& number, Reader::TokenStream& tokenStream) -{ - const Token& currentToken = tokenStream.Peek(); // might need this later for throwing exception - const std::string& sValue = MatchExpectedToken(Token::TOKEN_NUMBER, tokenStream); - - std::istringstream iStr(sValue); - double dValue; - iStr >> dValue; - - // did we consume all characters in the token? - if (iStr.eof() == false) - { - char c = iStr.peek(); - std::string sMessage = std::string("Unexpected character in NUMBER token: ") + c; - throw ParseException(sMessage, currentToken.locBegin, currentToken.locEnd); - } - - number = dValue; -} - - -inline void Reader::Parse(Boolean& boolean, Reader::TokenStream& tokenStream) -{ - const std::string& sValue = MatchExpectedToken(Token::TOKEN_BOOLEAN, tokenStream); - boolean = (sValue == "true" ? true : false); -} - - -inline void Reader::Parse(Null&, Reader::TokenStream& tokenStream) -{ - MatchExpectedToken(Token::TOKEN_NULL, tokenStream); -} - - -inline const std::string& Reader::MatchExpectedToken(Token::Type nExpected, Reader::TokenStream& tokenStream) -{ - const Token& token = tokenStream.Get(); - if (token.nType != nExpected) - { - std::string sMessage = std::string("Unexpected token: ") + token.sValue; - throw ParseException(sMessage, token.locBegin, token.locEnd); - } - - return token.sValue; -} - -} // End namespace diff --git a/src/libs/resiprocate/rutil/cajun/json/visitor.h b/src/libs/resiprocate/rutil/cajun/json/visitor.h deleted file mode 100644 index a06299d1..00000000 --- a/src/libs/resiprocate/rutil/cajun/json/visitor.h +++ /dev/null @@ -1,65 +0,0 @@ -/****************************************************************************** - -Copyright (c) 2009-2010, Terry Caton -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the projecct nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -******************************************************************************/ - -#pragma once - -#include "elements.h" - -namespace json -{ - - -class Visitor -{ -public: - virtual ~Visitor() {} - - virtual void Visit(Array& array) = 0; - virtual void Visit(Object& object) = 0; - virtual void Visit(Number& number) = 0; - virtual void Visit(String& string) = 0; - virtual void Visit(Boolean& boolean) = 0; - virtual void Visit(Null& null) = 0; -}; - -class ConstVisitor -{ -public: - virtual ~ConstVisitor() {} - - virtual void Visit(const Array& array) = 0; - virtual void Visit(const Object& object) = 0; - virtual void Visit(const Number& number) = 0; - virtual void Visit(const String& string) = 0; - virtual void Visit(const Boolean& boolean) = 0; - virtual void Visit(const Null& null) = 0; -}; - - -} // End namespace diff --git a/src/libs/resiprocate/rutil/cajun/json/writer.h b/src/libs/resiprocate/rutil/cajun/json/writer.h deleted file mode 100644 index 594d5418..00000000 --- a/src/libs/resiprocate/rutil/cajun/json/writer.h +++ /dev/null @@ -1,78 +0,0 @@ -/****************************************************************************** - -Copyright (c) 2009-2010, Terry Caton -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the projecct nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -******************************************************************************/ - -#pragma once - -#include "elements.h" -#include "visitor.h" - -namespace json -{ - -class Writer : private ConstVisitor -{ -public: - static void Write(const Object& object, std::ostream& ostr); - static void Write(const Array& array, std::ostream& ostr); - static void Write(const String& string, std::ostream& ostr); - static void Write(const Number& number, std::ostream& ostr); - static void Write(const Boolean& boolean, std::ostream& ostr); - static void Write(const Null& null, std::ostream& ostr); - static void Write(const UnknownElement& elementRoot, std::ostream& ostr); - -private: - Writer(std::ostream& ostr); - - template - static void Write_i(const ElementTypeT& element, std::ostream& ostr); - - void Write_i(const Object& object); - void Write_i(const Array& array); - void Write_i(const String& string); - void Write_i(const Number& number); - void Write_i(const Boolean& boolean); - void Write_i(const Null& null); - void Write_i(const UnknownElement& unknown); - - virtual void Visit(const Array& array); - virtual void Visit(const Object& object); - virtual void Visit(const Number& number); - virtual void Visit(const String& string); - virtual void Visit(const Boolean& boolean); - virtual void Visit(const Null& null); - - std::ostream& m_ostr; - int m_nTabDepth; -}; - - -} // End namespace - - -#include "writer.inl" \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/cajun/json/writer.inl b/src/libs/resiprocate/rutil/cajun/json/writer.inl deleted file mode 100644 index a474d624..00000000 --- a/src/libs/resiprocate/rutil/cajun/json/writer.inl +++ /dev/null @@ -1,178 +0,0 @@ -/****************************************************************************** - -Copyright (c) 2009-2010, Terry Caton -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the projecct nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -******************************************************************************/ - -#include "writer.h" -#include -#include - -/* - -TODO: -* better documentation -* unicode character encoding - -*/ - -namespace json -{ - - -inline void Writer::Write(const UnknownElement& elementRoot, std::ostream& ostr) { Write_i(elementRoot, ostr); } -inline void Writer::Write(const Object& object, std::ostream& ostr) { Write_i(object, ostr); } -inline void Writer::Write(const Array& array, std::ostream& ostr) { Write_i(array, ostr); } -inline void Writer::Write(const Number& number, std::ostream& ostr) { Write_i(number, ostr); } -inline void Writer::Write(const String& string, std::ostream& ostr) { Write_i(string, ostr); } -inline void Writer::Write(const Boolean& boolean, std::ostream& ostr) { Write_i(boolean, ostr); } -inline void Writer::Write(const Null& null, std::ostream& ostr) { Write_i(null, ostr); } - - -inline Writer::Writer(std::ostream& ostr) : - m_ostr(ostr), - m_nTabDepth(0) -{} - -template -void Writer::Write_i(const ElementTypeT& element, std::ostream& ostr) -{ - Writer writer(ostr); - writer.Write_i(element); - ostr.flush(); // all done -} - -inline void Writer::Write_i(const Array& array) -{ - if (array.Empty()) - m_ostr << "[]"; - else - { - m_ostr << '[' << std::endl; - ++m_nTabDepth; - - Array::const_iterator it(array.Begin()), - itEnd(array.End()); - while (it != itEnd) { - m_ostr << std::string(m_nTabDepth, '\t'); - - Write_i(*it); - - if (++it != itEnd) - m_ostr << ','; - m_ostr << std::endl; - } - - --m_nTabDepth; - m_ostr << std::string(m_nTabDepth, '\t') << ']'; - } -} - -inline void Writer::Write_i(const Object& object) -{ - if (object.Empty()) - m_ostr << "{}"; - else - { - m_ostr << '{' << std::endl; - ++m_nTabDepth; - - Object::const_iterator it(object.Begin()), - itEnd(object.End()); - while (it != itEnd) { - m_ostr << std::string(m_nTabDepth, '\t'); - - Write_i(it->name); - - m_ostr << " : "; - Write_i(it->element); - - if (++it != itEnd) - m_ostr << ','; - m_ostr << std::endl; - } - - --m_nTabDepth; - m_ostr << std::string(m_nTabDepth, '\t') << '}'; - } -} - -inline void Writer::Write_i(const Number& numberElement) -{ - m_ostr << std::setprecision(20) << numberElement.Value(); -} - -inline void Writer::Write_i(const Boolean& booleanElement) -{ - m_ostr << (booleanElement.Value() ? "true" : "false"); -} - -inline void Writer::Write_i(const String& stringElement) -{ - m_ostr << '"'; - - const std::string& s = stringElement.Value(); - std::string::const_iterator it(s.begin()), - itEnd(s.end()); - for (; it != itEnd; ++it) - { - switch (*it) - { - case '"': m_ostr << "\\\""; break; - case '\\': m_ostr << "\\\\"; break; - case '\b': m_ostr << "\\b"; break; - case '\f': m_ostr << "\\f"; break; - case '\n': m_ostr << "\\n"; break; - case '\r': m_ostr << "\\r"; break; - case '\t': m_ostr << "\\t"; break; - //case '\u': m_ostr << "\\u"; break; // uh... - default: m_ostr << *it; break; - } - } - - m_ostr << '"'; -} - -inline void Writer::Write_i(const Null& ) -{ - m_ostr << "null"; -} - -inline void Writer::Write_i(const UnknownElement& unknown) -{ - unknown.Accept(*this); -} - -inline void Writer::Visit(const Array& array) { Write_i(array); } -inline void Writer::Visit(const Object& object) { Write_i(object); } -inline void Writer::Visit(const Number& number) { Write_i(number); } -inline void Writer::Visit(const String& string) { Write_i(string); } -inline void Writer::Visit(const Boolean& boolean) { Write_i(boolean); } -inline void Writer::Visit(const Null& null) { Write_i(null); } - - - -} // End namespace diff --git a/src/libs/resiprocate/rutil/compat.hxx b/src/libs/resiprocate/rutil/compat.hxx index d0cbcde0..bd65d632 100644 --- a/src/libs/resiprocate/rutil/compat.hxx +++ b/src/libs/resiprocate/rutil/compat.hxx @@ -3,6 +3,8 @@ #ifdef HAVE_CONFIG_H #include "config.h" +#else +#define GPERF_SIZE_TYPE size_t #endif @@ -20,10 +22,6 @@ //#include //#endif -#ifdef TARGET_OS_MAC -# include -#endif - #include #ifndef WIN32 @@ -44,7 +42,9 @@ # ifndef __GNUC__ # pragma warning(disable : 4996) # endif +#ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN +#endif # include # include #undef WIN32_LEAN_AND_MEAN @@ -53,7 +53,41 @@ #ifdef UNDER_CE #include "wince/WceCompat.hxx" #endif // UNDER_CE + +#if defined(_MSC_VER) && _MSC_VER < 1900 +#include +#ifndef snprintf +#define snprintf c99_snprintf + +inline int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap) +{ + int count = -1; + + if (size != 0) + count = _vsnprintf_s(str, size, _TRUNCATE, format, ap); + if (count == -1) + count = _vscprintf(format, ap); + + return count; +} + +inline int c99_snprintf(char* str, size_t size, const char* format, ...) +{ + int count; + va_list ap; + + va_start(ap, format); + count = c99_vsnprintf(str, size, format, ap); + va_end(ap); + + return count; +} #endif +#endif // _MSC_VER + +#endif + +#define RESIP_MAX_SOCKADDR_SIZE 28 #if defined(__APPLE__) // .amr. If you get linker or type conflicts around UInt32, then use this define @@ -101,6 +135,40 @@ # define T_A 1 #endif +// Mac OS X: UInt32 definition conflicts with the Mac OS or iPhone OS SDK. +// If you've included either SDK then these will be defined. +// We could also check that __MACTYPES__ is not defined +#if !defined(TARGET_OS_MAC) && !defined(TARGET_OS_IPHONE) +typedef unsigned char UInt8; +typedef unsigned short UInt16; +typedef unsigned int UInt32; +typedef char Int8; +typedef short Int16; +typedef int Int32; +#else +// On Apple platforms, MacTypes.h should provide the types: +#include +typedef SInt8 Int8; +typedef SInt16 Int16; +typedef SInt32 Int32; +#endif + +#if defined( TARGET_OS_IPHONE ) +// TARGET_OS_IPHONE can be 0 or 1, so must also check the value +#if TARGET_OS_IPHONE +#define REQUIRE_SO_NOSIGPIPE +#endif +#endif + +#if defined( WIN32 ) + typedef signed __int64 Int64; + typedef unsigned __int64 UInt64; +#else + typedef signed long long Int64; + typedef unsigned long long UInt64; +#endif +//typedef struct { unsigned char octet[16]; } UInt128; + namespace resip { @@ -122,7 +190,10 @@ inline const _Tp& resipMin(const _Tp& __a, const _Tp& __b) { if (__b < __a) - return __b; + { + return __b; + } + return __a; } @@ -131,7 +202,10 @@ inline const _Tp& resipMax(const _Tp& __a, const _Tp& __b) { if (__a < __b) - return __b; + { + return __b; + } + return __a; } @@ -148,22 +222,49 @@ resipIntDiv(const _Tp1& __a, const _Tp2& __b) return __a/__b; } +#if defined(WORDS_BIGENDIAN) || defined(_BIG_ENDIAN) || defined( __BIG_ENDIAN__ ) || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) || defined(RESIP_BIG_ENDIAN) + +inline UInt64 +ntoh64(const UInt64 input) +{ + return input; +} + +inline UInt64 +hton64(const UInt64 input) +{ + return input; +} + +#else + +inline UInt64 +ntoh64(const UInt64 input) +{ + UInt64 rval; + UInt8 *data = (UInt8 *)&rval; + + data[0] = (UInt8)((input >> 56) & 0xFF); + data[1] = (UInt8)((input >> 48) & 0xFF); + data[2] = (UInt8)((input >> 40) & 0xFF); + data[3] = (UInt8)((input >> 32) & 0xFF); + data[4] = (UInt8)((input >> 24) & 0xFF); + data[5] = (UInt8)((input >> 16) & 0xFF); + data[6] = (UInt8)((input >> 8) & 0xFF); + data[7] = (UInt8)((input >> 0) & 0xFF); + + return rval; +} + +inline UInt64 +hton64(const UInt64 input) +{ + return (ntoh64(input)); } -// Mac OS X: UInt32 definition conflicts with the Mac OS or iPhone OS SDK. -// If you've included either SDK then these will be defined. -#if !defined(TARGET_OS_MAC) && !defined(TARGET_OS_IPHONE) -typedef unsigned char UInt8; -typedef unsigned short UInt16; -typedef unsigned long UInt32; #endif -#if defined( WIN32 ) - typedef unsigned __int64 UInt64; -#else - typedef unsigned long long UInt64; -#endif -//typedef struct { unsigned char octet[16]; } UInt128; +} //template "levels; ie REASONABLE and COMPLETE //reasonable allows most things such as partial template specialization, @@ -183,7 +284,7 @@ typedef unsigned long UInt32; #ifdef USE_IPV6 #ifndef IPPROTO_IPV6 #if(_WIN32_WINNT >= 0x0501) // Some versions of the windows SDK define IPPROTO_IPV6 differently - always enable IP v6 if USE_IPV6 and _WIN32_WINNT >= 0x0501 -# define IPPROTO_IPV6 ::IPPROTO_IPV6 +#define IPPROTO_IPV6 ::IPPROTO_IPV6 #else #ifdef _MSC_VER #define __STR2__(x) #x @@ -191,11 +292,7 @@ typedef unsigned long UInt32; #define __LOC__ __FILE__ "("__STR1__(__LINE__)"): " #pragma message (__LOC__ " IPv6 support requested, but IPPROTO_V6 undefined; this platform does not appear to support IPv6 ") #else -# ifndef __ANDROID_API__ -# warning IPv6 support requested, but IPPROTO_IPV6 undefined; this platform does not appear to support IPv6 -# else -# define IPPROTO_IPV6 ::IPPROTO_IPV6 -# endif +#warning IPv6 support requested, but IPPROTO_IPV6 undefined; this platform does not appear to support IPv6 #endif // .bwc. Don't do this; someone might have defined it for their own code. // #undef USE_IPV6 @@ -203,6 +300,10 @@ typedef unsigned long UInt32; #endif #endif +#ifndef IPPROTO_SCTP +#define IPPROTO_SCTP 132 +#endif + // !bwc! Some poking around seems to indicate that icc supports gcc's function // attributes, at least as far back as version 8. I have no idea what support is // like prior to that. As for SUNPRO, it uses gcc's frontend, so I would expect @@ -215,6 +316,37 @@ typedef unsigned long UInt32; #define RESIP_DEPRECATED(x) x #endif +// These used to live in resipfaststreams.hxx and may only be used there +#if (defined(WIN32) || defined(_WIN32_WCE)) + +#if (defined(_MSC_VER) && _MSC_VER >= 1400 ) +#define SNPRINTF_1(buffer,sizeofBuffer,count,format,var1) _snprintf_s(buffer,sizeofBuffer,_TRUNCATE,format,var1) +#define LTOA(value,string,sizeofstring,radix) _ltoa_s(value,string,sizeofstring,radix) +#define ULTOA(value,string,sizeofstring,radix) _ultoa_s(value,string,sizeofstring,radix) +#define I64TOA(value,string,sizeofstring,radix) _i64toa_s(value,string,sizeofstring,radix) +#define UI64TOA(value,string,sizeofstring,radix) _ui64toa_s(value,string,sizeofstring,radix) +#define GCVT(val,num,buffer,buffersize) _gcvt_s(buffer,buffersize,val,num) +#else +#define _TRUNCATE -1 +#define SNPRINTF_1(buffer,sizeofBuffer,count,format,var1) _snprintf(buffer,count,format,var1) +#define LTOA(value,string,sizeofstring,radix) _ltoa(value,string,radix) +#define ULTOA(value,string,sizeofstring,radix) _ultoa(value,string,radix) +#define I64TOA(value,string,sizeofstring,radix) _i64toa(value,string,radix) +#define UI64TOA(value,string,sizeofstring,radix) _ui64toa(value,string,radix) +#define GCVT(val,sigdigits,buffer,buffersize) _gcvt(val,sigdigits,buffer) +#endif + +#else //non-windows +#define _TRUNCATE -1 +#define SNPRINTF_1(buffer,sizeofBuffer,count,format,var1) snprintf(buffer,sizeofBuffer,format,var1) +#define LTOA(l,buffer,bufferlen,radix) SNPRINTF_1(buffer,bufferlen,bufferlen,"%li",l) +#define ULTOA(ul,buffer,bufferlen,radix) SNPRINTF_1(buffer,bufferlen,bufferlen,"%lu",ul) +#define I64TOA(value,string,sizeofstring,radix) SNPRINTF_1(string,sizeofstring,sizeofstring,"%lli",value) +#define UI64TOA(value,string,sizeofstring,radix) SNPRINTF_1(string,sizeofstring,sizeofstring,"%llu",value) +#define GCVT(f,sigdigits,buffer,bufferlen) SNPRINTF_1(buffer,bufferlen,bufferlen,"%f",f) +#define _CVTBUFSIZE 309+40 +#endif + #endif /* ==================================================================== diff --git a/src/libs/resiprocate/rutil/dns/AresDns.cxx b/src/libs/resiprocate/rutil/dns/AresDns.cxx index 403b6e5a..ec4aa71b 100644 --- a/src/libs/resiprocate/rutil/dns/AresDns.cxx +++ b/src/libs/resiprocate/rutil/dns/AresDns.cxx @@ -9,6 +9,7 @@ #include "rutil/dns/AresDns.hxx" #include "rutil/GenericIPAddress.hxx" +#include "rutil/Timer.hxx" #include "AresCompat.hxx" #if !defined(USE_CARES) @@ -45,31 +46,37 @@ namespace resip class AresDnsPollItem : public FdPollItemBase { public: - AresDnsPollItem(FdPollGrp *grp, int fd, AresDns& aresObj, + AresDnsPollItem(FdPollGrp *grp, int fd, int using_tcp, AresDns& aresObj, ares_channel chan, int server_idx) : FdPollItemBase(grp, fd, FPEM_Read), mAres(aresObj), - mChannel(chan), mFd(fd), mServerIdx(server_idx) + mChannel(chan), mFd(fd), mUsingTcp(using_tcp), mServerIdx(server_idx) { } virtual void processPollEvent(FdPollEventMask mask); void resetPollGrp(FdPollGrp *grp) { - if (mPollGrp) + if(mPollGrp) + { mPollGrp->delPollItem(mPollHandle); + } + mPollHandle = 0; mPollGrp = grp; - if (mPollGrp) - mPollHandle = mPollGrp->addPollItem(mFd, FPEM_Read, this); + if(mPollGrp) + { + mPollHandle = mPollGrp->addPollItem(mFd, FPEM_Read, this); + } } AresDns& mAres; ares_channel mChannel; int mFd; + int mUsingTcp; int mServerIdx; static void socket_poll_cb(void *cb_data, ares_channel channel, int server_idx, - int fd, ares_poll_action_t act); + int fd, int using_tcp, ares_poll_action_t act); }; }; @@ -77,7 +84,7 @@ class AresDnsPollItem : public FdPollItemBase void AresDnsPollItem::processPollEvent(FdPollEventMask mask) { - assert( (mask&(FPEM_Read|FPEM_Write))!= 0 ); + resip_assert( (mask&(FPEM_Read|FPEM_Write))!= 0 ); time_t nowSecs; time(&nowSecs); /// maybe nice if this was passed into us? @@ -95,40 +102,55 @@ AresDnsPollItem::processPollEvent(FdPollEventMask mask) void AresDnsPollItem::socket_poll_cb(void *cb_data, ares_channel channel, int server_idx, - int fd, ares_poll_action_t act) + int fd, int using_tcp, ares_poll_action_t act) { AresDns *ares = static_cast(cb_data); //assert( ares ); FdPollGrp *grp = ares->mPollGrp; //assert( grp ); - AresDnsPollItem *olditem = ares->mPollItems.at(server_idx); + AresDnsPollItem *olditem = using_tcp == 0 ? ares->mPollItems.at(server_idx).first : ares->mPollItems.at(server_idx).second; if ( olditem ) { - assert( olditem->mChannel==channel ); - assert( olditem->mServerIdx==server_idx ); + resip_assert( olditem->mChannel==channel ); + resip_assert( olditem->mServerIdx==server_idx ); + resip_assert( olditem->mUsingTcp==using_tcp ); } switch ( act ) { case ARES_POLLACTION_OPEN: - assert( olditem==NULL ); - assert( fd!=INVALID_SOCKET ); - ares->mPollItems[server_idx] = new AresDnsPollItem( grp, fd, *ares, channel, server_idx); + resip_assert( !olditem ); + resip_assert( fd!=INVALID_SOCKET ); + if (using_tcp == 0) + { + ares->mPollItems[server_idx].first = new AresDnsPollItem(grp, fd, using_tcp, *ares, channel, server_idx); + } + else + { + ares->mPollItems[server_idx].second = new AresDnsPollItem(grp, fd, using_tcp, *ares, channel, server_idx); + } break; case ARES_POLLACTION_CLOSE: - assert( olditem ); - ares->mPollItems[server_idx] = NULL; + resip_assert( olditem ); + if (using_tcp == 0) + { + ares->mPollItems[server_idx].first = NULL; + } + else + { + ares->mPollItems[server_idx].second = NULL; + } delete olditem; // destructor removes from poll break; case ARES_POLLACTION_WRITEON: - assert( olditem ); + resip_assert( olditem ); grp->modPollItem(olditem->mPollHandle, FPEM_Read|FPEM_Write); break; case ARES_POLLACTION_WRITEOFF: - assert( olditem ); + resip_assert( olditem ); grp->modPollItem(olditem->mPollHandle, FPEM_Read); break; default: - assert( 0 ); + resip_assert( 0 ); } } @@ -156,12 +178,15 @@ AresDns::setPollGrp(FdPollGrp *grp) mPollGrp->registerFdSetIOObserver(*this); } #else - for(std::vector::iterator i=mPollItems.begin(); - i!=mPollItems.end(); ++i) + for (PollItems::iterator i = mPollItems.begin(); i!=mPollItems.end(); ++i) { - if(*i) + if(i->first) { - (*i)->resetPollGrp(grp); + i->first->resetPollGrp(grp); + } + if (i->second) + { + i->second->resetPollGrp(grp); } } mPollGrp = grp; @@ -176,37 +201,57 @@ AresDns::init(const std::vector& additionalNameservers, unsigned int features) { mAdditionalNameservers = additionalNameservers; - mFeatures = features; + mSocketFunc = socketfunc; - int ret = internalInit(additionalNameservers, - socketfunc, - features, - &mChannel, - timeout, - tries); + return init(timeout, tries, features); +} - if (ret != Success) - return ret; +int +AresDns::init(int dnsTimeout, int dnsTries, unsigned int features) +{ + mFeatures = features; -#ifdef WIN32 - // For windows OSs it is uncommon to run a local DNS server. Therefor if there - // are no defined DNS servers in windows networking and ARES just returned the - // loopback address (ie. default localhost server / named) - // then put resip DNS resolution into hostfile lookup only mode - if(mChannel->nservers == 1 && - mChannel->servers[0].default_localhost_server) - { - // enable hostfile only lookup mode - mHostFileLookupOnlyMode = true; - } - else - { - // disable hostfile only lookup mode - mHostFileLookupOnlyMode = false; - } + int ret = internalInit(mAdditionalNameservers, + mSocketFunc, + features, + &mChannel, + dnsTimeout, + dnsTries); + + if (ret != Success) + return ret; + +#ifndef USE_CARES + if (mPollGrp) + { + // Ensure vector starts empty, since init may be called more than once + mPollItems.clear(); + // expand vector to hold {nservers} and init to NULLAr + mPollItems.insert(mPollItems.end(), mChannel->nservers, std::make_pair((AresDnsPollItem*)0, (AresDnsPollItem*)0)); + // tell ares to let us know when things change + ares_process_set_poll_cb(mChannel, AresDnsPollItem::socket_poll_cb, this); + } #endif - return Success; +#ifdef WIN32 + // For windows OSs it is uncommon to run a local DNS server. Therefor if there + // are no defined DNS servers in windows networking and ARES just returned the + // loopback address (ie. default localhost server / named) + // then put resip DNS resolution into hostfile lookup only mode + if (mChannel->nservers == 1 && + mChannel->servers[0].default_localhost_server) + { + // enable hostfile only lookup mode + mHostFileLookupOnlyMode = true; + } + else + { + // disable hostfile only lookup mode + mHostFileLookupOnlyMode = false; + } +#endif + + return Success; } int @@ -215,13 +260,13 @@ AresDns::internalInit(const std::vector& additionalNameservers unsigned int features, ares_channeldata** channel, int timeout, - int tries -) + int tries) { if(*channel) { #if defined(USE_ARES) - ares_destroy_suppress_callbacks(*channel); + // Sends ARES_EDESTRUCTION to callbacks so that all requests in progress fail + ares_destroy(*channel); #elif defined(USE_CARES) // Callbacks will be supressed by looking for the ARES_EDESTRUCTION // sentinel status @@ -353,10 +398,10 @@ AresDns::internalInit(const std::vector& additionalNameservers for (int i = 0; i < (*channel)->nservers; ++i) { #ifdef USE_IPV6 - if((*channel)->servers[i].family == AF_INET6) + if((*channel)->servers[i].family == AF_INET6) { InfoLog(<< " name server: " << DnsUtil::inet_ntop((*channel)->servers[i].addr6)); - } + } else #endif { @@ -367,24 +412,14 @@ AresDns::internalInit(const std::vector& additionalNameservers // In ares, we must manipulate these directly if (timeout > 0) { - mChannel->timeout = timeout; + (*channel)->timeout = timeout; } if (tries > 0) { - mChannel->tries = tries; + (*channel)->tries = tries; } -#ifndef USE_CARES - if ( mPollGrp ) - { - // expand vector to hold {nservers} and init to NULL - mPollItems.insert( mPollItems.end(), (*channel)->nservers, (AresDnsPollItem*)0); - // tell ares to let us know when things change - ares_process_set_poll_cb(mChannel, AresDnsPollItem::socket_poll_cb, this); - } -#endif - #elif defined(USE_CARES) { // Log which version of c-ares we're using @@ -441,11 +476,23 @@ bool AresDns::checkDnsChange() // Compare them one-by-one for (int i = 0; i < mChannel->nservers; ++i) { - if (mChannel->servers[i].addr.s_addr - != channel->servers[i].addr.s_addr) +#ifdef USE_IPV6 + if(channel->servers[i].family == AF_INET6) { - bRet = true; - break; + if(memcmp(&mChannel->servers[i].addr6, &channel->servers[i].addr6, sizeof(mChannel->servers[i].addr6)) != 0) + { + bRet = true; + break; + } + } + else +#endif + { + if (mChannel->servers[i].addr.s_addr != channel->servers[i].addr.s_addr) + { + bRet = true; + break; + } } } } @@ -525,7 +572,7 @@ AresDns::~AresDns() bool AresDns::hostFileLookup(const char* target, in_addr &addr) { - assert(target); + resip_assert(target); hostent *hostdata = 0; @@ -585,7 +632,9 @@ unsigned int AresDns::getTimeTillNextProcessMS() { struct timeval tv; - tv.tv_sec = 1; tv.tv_usec = 0; + unsigned maxSystemTime = resip::Timer::getMaxSystemTimeWaitMs(); + tv.tv_sec = maxSystemTime / 1000; + tv.tv_usec = 1000 * (maxSystemTime % 1000); ares_timeout(mChannel, NULL, &tv); return tv.tv_sec*1000 + tv.tv_usec / 1000; } @@ -604,16 +653,16 @@ void AresDns::processTimers() { #ifdef USE_CARES - return; + ares_process(mChannel, NULL, NULL); #else - assert( mPollGrp!=0 ); + resip_assert( mPollGrp!=0 ); time_t timeSecs; time(&timeSecs); ares_process_poll(mChannel, /*server*/-1, /*rd*/-1, /*wr*/-1, timeSecs); #endif } -void +void AresDns::process(FdSet& fdset) { process(fdset.read, fdset.write); diff --git a/src/libs/resiprocate/rutil/dns/AresDns.hxx b/src/libs/resiprocate/rutil/dns/AresDns.hxx index 11a57949..8921daf4 100644 --- a/src/libs/resiprocate/rutil/dns/AresDns.hxx +++ b/src/libs/resiprocate/rutil/dns/AresDns.hxx @@ -26,11 +26,13 @@ class AresDns : public ExternalDns, public FdSetIOObserver { friend class AresDnsPollItem; public: - AresDns() {mChannel = 0; mFeatures = 0; mPollGrp=NULL;} + AresDns() : mChannel(0), mSocketFunc(0), mFeatures(0), mPollGrp(NULL) { } virtual ~AresDns(); virtual int init(const std::vector& additionalNameservers, AfterSocketCreationFuncPtr socketfunc, int timeout=0, int tries=0, unsigned int features=0); + // reinitializes with the same additionalNameservers and AfterSocketCreationFuncPtr as last call to init + virtual int init(int dnsTimeout = 0, int dnsTries = 0, unsigned int features = 0); int internalInit(const std::vector& additionalNameservers, AfterSocketCreationFuncPtr socketfunc, unsigned int features=0, ares_channeldata** channel = 0, int timeout=0, int tries=0); @@ -72,11 +74,13 @@ class AresDns : public ExternalDns, public FdSetIOObserver static ExternalDnsHandler* getHandler(void* arg); struct ares_channeldata* mChannel; std::vector mAdditionalNameservers; + AfterSocketCreationFuncPtr mSocketFunc; unsigned int mFeatures; volatile static bool mHostFileLookupOnlyMode; FdPollGrp* mPollGrp; - std::vector mPollItems; + typedef std::vector > PollItems; + PollItems mPollItems; // first item is for UDP socket, 2nd is for TCP socket }; diff --git a/src/libs/resiprocate/rutil/dns/DnsAAAARecord.cxx b/src/libs/resiprocate/rutil/dns/DnsAAAARecord.cxx index 83a93963..6d70b460 100644 --- a/src/libs/resiprocate/rutil/dns/DnsAAAARecord.cxx +++ b/src/libs/resiprocate/rutil/dns/DnsAAAARecord.cxx @@ -35,7 +35,7 @@ DnsAAAARecord::DnsAAAARecord(const RROverlay& overlay) free(name); memcpy(&mAddr, overlay.data(), sizeof(in6_addr)); #else - assert(0); + resip_assert(0); #endif } @@ -44,7 +44,7 @@ bool DnsAAAARecord::isSameValue(const Data& value) const #ifdef USE_IPV6 return DnsUtil::inet_ntop(mAddr) == value; #else - assert(0); + resip_assert(0); return false; #endif } @@ -56,7 +56,7 @@ DnsAAAARecord::dump(EncodeStream& strm) const strm << mName << " (AAAA) --> " << DnsUtil::inet_ntop(mAddr); return strm; #else - assert(0); + resip_assert(0); strm << " (AAAA) --> ? (IPV6 is disabled in this library, what " "happened here?)"; return strm; diff --git a/src/libs/resiprocate/rutil/dns/DnsHostRecord.cxx b/src/libs/resiprocate/rutil/dns/DnsHostRecord.cxx index 631ead81..8d81e17d 100644 --- a/src/libs/resiprocate/rutil/dns/DnsHostRecord.cxx +++ b/src/libs/resiprocate/rutil/dns/DnsHostRecord.cxx @@ -30,7 +30,7 @@ DnsHostRecord::DnsHostRecord(const RROverlay& overlay) long len = 0; int status = ares_expand_name(overlay.data()-overlay.nameLength()-RRFIXEDSZ, overlay.msg(), overlay.msgLength(), &name, &len); (void)status; - assert(status == ARES_SUCCESS); // .kw. what should we do if bad? + resip_assert(status == ARES_SUCCESS); // .kw. what should we do if bad? mName = name; free(name); memcpy(&mAddr, overlay.data(), sizeof(in_addr)); diff --git a/src/libs/resiprocate/rutil/dns/DnsNaptrRecord.cxx b/src/libs/resiprocate/rutil/dns/DnsNaptrRecord.cxx index 5c2ff31c..0e7773d6 100644 --- a/src/libs/resiprocate/rutil/dns/DnsNaptrRecord.cxx +++ b/src/libs/resiprocate/rutil/dns/DnsNaptrRecord.cxx @@ -155,7 +155,7 @@ bool DnsNaptrRecord::isSameValue(const Data& value) const EncodeStream& DnsNaptrRecord::dump(EncodeStream& strm) const { - strm << mName << " (NAPTR)--> o=" << mOrder << " p=" << mPreference; + strm << mName << " (NAPTR)--> o=" << mOrder << " p=" << mPreference << " s=" << mService; return strm; } diff --git a/src/libs/resiprocate/rutil/dns/DnsStub.cxx b/src/libs/resiprocate/rutil/dns/DnsStub.cxx index 8f9bc12e..9c6f6b81 100644 --- a/src/libs/resiprocate/rutil/dns/DnsStub.cxx +++ b/src/libs/resiprocate/rutil/dns/DnsStub.cxx @@ -8,7 +8,7 @@ // release version messes time_t definition again #include #include -#include +#include "rutil/ResipAssert.h" #include "AresCompat.hxx" @@ -46,14 +46,14 @@ unsigned int DnsStub::mDnsFeatures = 0; void DnsResultSink::onLogDnsResult(const DNSResult& rr) { - DebugLog (<< rr); + DebugLog(<< "Host(A) Result: " << rr); } void DnsResultSink::onLogDnsResult(const DNSResult& rr) { #if defined(USE_IPV6) - DebugLog (<< rr); + DebugLog(<< "Host(AAAA) Result: " << rr); #else ErrLog(<< "Something called " "DnsResultSink::onLogDnsResult(const DNSResult& rr)" @@ -64,19 +64,19 @@ DnsResultSink::onLogDnsResult(const DNSResult& rr) void DnsResultSink::onLogDnsResult(const DNSResult& rr) { - DebugLog (<< rr); + DebugLog(<< "SRV Result: " << rr); } void DnsResultSink::onLogDnsResult(const DNSResult& rr) { - DebugLog (<< rr); + DebugLog(<< "NAPTR Result: " << rr); } void DnsResultSink::onLogDnsResult(const DNSResult& rr) { - DebugLog (<< rr); + DebugLog(<< "CNAME Result: " << rr); } DnsStub::DnsStub(const NameserverList& additional, @@ -97,7 +97,7 @@ DnsStub::DnsStub(const NameserverList& additional, { if (retCode == ExternalDns::BuildMismatch) { - assert(0); + resip_assert(0); throw DnsStubException("Library was not build w/ required capabilities(probably USE_IPV6 resip/ares mismatch", __FILE__,__LINE__); } @@ -161,6 +161,18 @@ DnsStub::processTimers() mDnsProvider->processTimers(); } +void +DnsStub::queueCommand(Command* command) +{ + mCommandFifo.add(command); + + // Wake up fifo reader + if (mAsyncProcessHandler) + { + mAsyncProcessHandler->handleProcessNotification(); + } +} + void DnsStub::cache(const Data& key, in_addr addr) @@ -381,7 +393,7 @@ DnsStub::setPollGrp(FdPollGrp* pollGrp) if(mPollGrp) { // unregister our select interruptor - //mPollGrp->delPollItem(mInterruptorHandle); + mPollGrp->delPollItem(mInterruptorHandle); mInterruptorHandle=0; } @@ -389,7 +401,7 @@ DnsStub::setPollGrp(FdPollGrp* pollGrp) if (mPollGrp) { - //mInterruptorHandle = mPollGrp->addPollItem(mSelectInterruptor.getReadSocket(), FPEM_Read, &mSelectInterruptor); + mInterruptorHandle = mPollGrp->addPollItem(mSelectInterruptor.getReadSocket(), FPEM_Read, &mSelectInterruptor); } mDnsProvider->setPollGrp(mPollGrp); @@ -408,7 +420,7 @@ DnsStub::Query::Query(DnsStub& stub, ResultTransform* transform, ResultConverter mSink(s), mFollowCname(followCname) { - assert(s); + resip_assert(s); } DnsStub::Query::~Query() @@ -485,7 +497,7 @@ DnsStub::Query::go() { if(mStub.mDnsProvider && mStub.mDnsProvider->hostFileLookupLookupOnlyMode()) { - assert(mRRType == T_A); + resip_assert(mRRType == T_A); StackLog (<< targetToQuery << " not cached. Doing hostfile lookup"); in_addr address; if (mStub.mDnsProvider->hostFileLookup(targetToQuery.c_str(), address)) @@ -601,11 +613,11 @@ DnsStub::Query::process(int status, const unsigned char* abuf, const int alen) case ARES_EBADFAMILY: ErrLog (<< "Bad lookup type " << mStub.errorMessage(status) << " for " << mTarget); // .bwc. This should not happen. If it does, we have code to fix. - assert(0); + resip_assert(0); break; default: ErrLog (<< "Unknown error " << mStub.errorMessage(status) << " for " << mTarget); - assert(0); + resip_assert(0); break; } @@ -776,12 +788,7 @@ void DnsStub::setEnumSuffixes(const std::vector& suffixes) { SetEnumSuffixesCommand* command = new SetEnumSuffixesCommand(*this, suffixes); - mCommandFifo.add(command); - - if (mAsyncProcessHandler) - { - mAsyncProcessHandler->handleProcessNotification(); - } + queueCommand(command); } const std::vector& @@ -800,12 +807,7 @@ void DnsStub::setEnumDomains(const std::map& domains) { SetEnumDomainsCommand* command = new SetEnumDomainsCommand(*this, domains); - mCommandFifo.add(command); - - if (mAsyncProcessHandler) - { - mAsyncProcessHandler->handleProcessNotification(); - } + queueCommand(command); } const std::map& @@ -824,12 +826,7 @@ void DnsStub::clearDnsCache() { ClearDnsCacheCommand* command = new ClearDnsCacheCommand(*this); - mCommandFifo.add(command); - - if (mAsyncProcessHandler) - { - mAsyncProcessHandler->handleProcessNotification(); - } + queueCommand(command); } void @@ -842,12 +839,7 @@ void DnsStub::logDnsCache() { LogDnsCacheCommand* command = new LogDnsCacheCommand(*this); - mCommandFifo.add(command); - - if (mAsyncProcessHandler) - { - mAsyncProcessHandler->handleProcessNotification(); - } + queueCommand(command); } void @@ -860,23 +852,37 @@ void DnsStub::getDnsCacheDump(std::pair key, GetDnsCacheDumpHandler* handler) { GetDnsCacheDumpCommand* command = new GetDnsCacheDumpCommand(*this, key, handler); - mCommandFifo.add(command); - - if (mAsyncProcessHandler) - { - mAsyncProcessHandler->handleProcessNotification(); - } + queueCommand(command); } void DnsStub::doGetDnsCacheDump(std::pair key, GetDnsCacheDumpHandler* handler) { - assert(handler != 0); + resip_assert(handler != 0); Data dnsCacheDump; mRRCache.getCacheDump(dnsCacheDump); handler->onDnsCacheDumpRetrieved(key, dnsCacheDump); } +void +DnsStub::reloadDnsServers() +{ + ReloadDnsServersCommand* command = new ReloadDnsServersCommand(*this); + queueCommand(command); +} + +void +DnsStub::doReloadDnsServers() +{ + bool changed = mDnsProvider->checkDnsChange(); + if (changed) + { + doClearDnsCache(); + + mDnsProvider->init(mDnsTimeout, mDnsTries, mDnsFeatures); + } +} + void DnsStub::setDnsCacheTTL(int ttl) { diff --git a/src/libs/resiprocate/rutil/dns/DnsStub.hxx b/src/libs/resiprocate/rutil/dns/DnsStub.hxx index 8d53f885..2928ea91 100644 --- a/src/libs/resiprocate/rutil/dns/DnsStub.hxx +++ b/src/libs/resiprocate/rutil/dns/DnsStub.hxx @@ -54,6 +54,10 @@ class DNSResult { for (typename std::vector::const_iterator i=records.begin(); i != records.end(); ++i) { + if (i != records.begin()) + { + strm << ", "; + } i->dump(strm); } } @@ -111,7 +115,14 @@ class DnsStub : public ExternalDnsHandler typedef std::vector NameserverList; static NameserverList EmptyNameserverList; - + + class Command + { + public: + virtual ~Command() {} + virtual void execute() = 0; + }; + class ResultTransform { public: @@ -147,15 +158,28 @@ class DnsStub : public ExternalDnsHandler void setResultTransform(ResultTransform*); void removeResultTransform(); + + /*! + @param enumSuffixes If the uri is enum searchable, this is the list of + enum suffixes (for example "e164.arpa") that will be used in + the attempt to resolve this uri. + */ void setEnumSuffixes(const std::vector& suffixes); const std::vector& getEnumSuffixes() const; + + /*! + @param enumDomains The ENUM possibility is only considered if + the URI domain part is one of these domains + */ void setEnumDomains(const std::map& domains); const std::map& getEnumDomains() const; + void clearDnsCache(); void logDnsCache(); void getDnsCacheDump(std::pair key, GetDnsCacheDumpHandler* handler); void setDnsCacheTTL(int ttl); void setDnsCacheSize(int size); + void reloadDnsServers(); bool checkDnsChange(); bool supportedType(int); @@ -168,16 +192,13 @@ class DnsStub : public ExternalDnsHandler // reserved for internal use, so do not use 0. If you'd like to blacklist // for different types of protocols, just pass in any integer other than // those used for pre-defined protocols. - // + // ?slg? Should we offer a non-queuing version of this - currently all resip lookup + // requests are from the DnsThread context anyway, so there is no need to queue + // the request to the fifo. template void lookup(const Data& target, int protocol, DnsResultSink* sink) { QueryCommand* command = new QueryCommand(target, protocol, sink, *this); - mCommandFifo.add(command); - - if (mAsyncProcessHandler) - { - mAsyncProcessHandler->handleProcessNotification(); - } + queueCommand(command); } virtual void handleDnsRaw(ExternalDnsRawResult); @@ -186,8 +207,10 @@ class DnsStub : public ExternalDnsHandler virtual unsigned int getTimeTillNextProcessMS(); virtual void buildFdSet(FdSet& fdset); void setPollGrp(FdPollGrp* pollGrp); - void processTimers(); + + virtual void queueCommand(Command* command); + private: void processFifo(); @@ -218,7 +241,7 @@ class DnsStub : public ExternalDnsHandler const DnsResourceRecordsByPtr& src, DnsResultSink* sink) { - assert(sink); + resip_assert(sink); DNSResult result; for (unsigned int i = 0; i < src.size(); ++i) { @@ -280,14 +303,6 @@ class DnsStub : public ExternalDnsHandler private: - class Command - { - public: - virtual ~Command() {} - virtual void execute() = 0; - }; - - template class QueryCommand : public Command { @@ -413,6 +428,24 @@ class DnsStub : public ExternalDnsHandler GetDnsCacheDumpHandler* mHandler; }; + void doReloadDnsServers(); + + class ReloadDnsServersCommand : public Command + { + public: + ReloadDnsServersCommand(DnsStub& stub) + : mStub(stub) + {} + ~ReloadDnsServersCommand() {} + void execute() + { + mStub.doReloadDnsServers(); + } + + private: + DnsStub& mStub; + }; + SelectInterruptor mSelectInterruptor; FdPollItemHandle mInterruptorHandle; diff --git a/src/libs/resiprocate/rutil/dns/DnsThread.cxx b/src/libs/resiprocate/rutil/dns/DnsThread.cxx index d9034b68..1abb6fb0 100644 --- a/src/libs/resiprocate/rutil/dns/DnsThread.cxx +++ b/src/libs/resiprocate/rutil/dns/DnsThread.cxx @@ -30,8 +30,7 @@ DnsThread::thread() try { mDnsStub.processTimers(); - if (mPollGrp.get()) - mPollGrp->waitAndProcess(25); + mPollGrp->waitAndProcess(25); } catch(BaseException& e) { diff --git a/src/libs/resiprocate/rutil/dns/DnsThread.hxx b/src/libs/resiprocate/rutil/dns/DnsThread.hxx index c8d5f261..a318049a 100644 --- a/src/libs/resiprocate/rutil/dns/DnsThread.hxx +++ b/src/libs/resiprocate/rutil/dns/DnsThread.hxx @@ -22,7 +22,7 @@ class DnsThread : public ThreadIf protected: DnsStub& mDnsStub; - std::unique_ptr mPollGrp; + std::auto_ptr mPollGrp; }; // class DnsThread } // namespace resip diff --git a/src/libs/resiprocate/rutil/dns/ExternalDns.hxx b/src/libs/resiprocate/rutil/dns/ExternalDns.hxx index fbdaadb1..f6be0952 100644 --- a/src/libs/resiprocate/rutil/dns/ExternalDns.hxx +++ b/src/libs/resiprocate/rutil/dns/ExternalDns.hxx @@ -41,6 +41,9 @@ class ExternalDns int dnsTries = 0, unsigned int features = 0) = 0; // bit mask of Features + // reinitializes with the same additionalNameservers and AfterSocketCreationFuncPtr as last call to init + virtual int init(int dnsTimeout = 0, int dnsTries = 0, unsigned int features = 0) = 0; + //returns 'true' only is there are changes in the DNS server list virtual bool checkDnsChange() = 0; diff --git a/src/libs/resiprocate/rutil/dns/LocalDns.cxx b/src/libs/resiprocate/rutil/dns/LocalDns.cxx index 86e689ef..173c610d 100644 --- a/src/libs/resiprocate/rutil/dns/LocalDns.cxx +++ b/src/libs/resiprocate/rutil/dns/LocalDns.cxx @@ -101,7 +101,7 @@ void LocalDns::message(const char* file, unsigned char* buf, int& len) len = 0; ifstream fs; fs.open(file, ios_base::binary | ios_base::in); - assert(fs.is_open()); + resip_assert(fs.is_open()); unsigned char* p = buf; @@ -124,9 +124,9 @@ LocalDns::localCallback(void *arg, int status, unsigned char *abuf, int alen) unsigned char msg[1024]; int len = 0; map::iterator it = files.find(mTarget); - assert(it != files.end()); + resip_assert(it != files.end()); message(it->second.c_str(), msg, len); - assert(0 != len); + resip_assert(0 != len); getHandler(arg)->handleDnsRaw(makeRawResult(arg, 0, msg, len)); Payload* p = reinterpret_cast(arg); delete p; diff --git a/src/libs/resiprocate/rutil/dns/LocalDns.hxx b/src/libs/resiprocate/rutil/dns/LocalDns.hxx index 934c90fa..87a053dc 100644 --- a/src/libs/resiprocate/rutil/dns/LocalDns.hxx +++ b/src/libs/resiprocate/rutil/dns/LocalDns.hxx @@ -29,11 +29,11 @@ class LocalDns : public ExternalDns void lookup(const char* target, unsigned short type, ExternalDnsHandler* handler, void* userData); - virtual void lookupARecords(const char* /*target*/, ExternalDnsHandler* /*handler*/, void* /*userData*/) {} - virtual void lookupAAAARecords(const char* /*target*/, ExternalDnsHandler* /*handler*/, void* /*userData*/) {} - virtual void lookupNAPTR(const char* /*target*/, ExternalDnsHandler* /*handler*/, void* /*userData*/) {} - virtual void lookupSRV(const char* /*target*/, ExternalDnsHandler* /*handler*/, void* /*userData*/) {} - virtual char* errorMessage(long /*errorCode*/) + virtual void lookupARecords(const char* target, ExternalDnsHandler* handler, void* userData) {} + virtual void lookupAAAARecords(const char* target, ExternalDnsHandler* handler, void* userData) {} + virtual void lookupNAPTR(const char* target, ExternalDnsHandler* handler, void* userData) {} + virtual void lookupSRV(const char* target, ExternalDnsHandler* handler, void* userData) {} + virtual char* errorMessage(long errorCode) { const char* msg = "Local Dns"; diff --git a/src/libs/resiprocate/rutil/dns/RRCache.cxx b/src/libs/resiprocate/rutil/dns/RRCache.cxx index 0e20f3d0..bc920f33 100644 --- a/src/libs/resiprocate/rutil/dns/RRCache.cxx +++ b/src/libs/resiprocate/rutil/dns/RRCache.cxx @@ -27,7 +27,7 @@ #include #include #include -#include +#include "rutil/ResipAssert.h" #include "rutil/BaseException.hxx" #include "rutil/Data.hxx" #include "rutil/Timer.hxx" @@ -96,7 +96,7 @@ RRCache::updateCache(const Data& target, { Data domain = (*begin).domain(); FactoryMap::iterator it = mFactoryMap.find(rrType); - assert(it != mFactoryMap.end()); + resip_assert(it != mFactoryMap.end()); RRList* key = new RRList(domain, rrType); RRSet::iterator lb = mRRSet.lower_bound(key); if (lb != mRRSet.end() && @@ -153,7 +153,7 @@ RRCache::lookup(const Data& target, Result& records, int& status) { - records.empty(); + records.clear(); status = 0; RRList* key = new RRList(target, type); RRSet::iterator it = mRRSet.find(key); @@ -212,11 +212,11 @@ RRCache::getTTL(const RROverlay& overlay) char* name = 0; long len = 0; int status = ares_expand_name(overlay.data(), overlay.msg(), overlay.msgLength(), &name, &len); - assert( status == ARES_SUCCESS ); + resip_assert( status == ARES_SUCCESS ); const unsigned char* pPos = overlay.data() + len; free(name); name = 0; status = ares_expand_name(pPos, overlay.msg(), overlay.msgLength(), &name, &len); - assert( status == ARES_SUCCESS ); + resip_assert( status == ARES_SUCCESS ); free(name); pPos += len; pPos += 16; // skip four 32 bit entities. @@ -229,7 +229,7 @@ RRCache::purge() if (mRRSet.size() < mSize) return; RRList* lst = *(mLruHead->begin()); RRSet::iterator it = mRRSet.find(lst); - assert(it != mRRSet.end()); + resip_assert(it != mRRSet.end()); lst->remove(); delete *it; mRRSet.erase(it); @@ -238,19 +238,39 @@ RRCache::purge() void RRCache::logCache() { - for (std::set::iterator it = mRRSet.begin(); it != mRRSet.end(); it++) + UInt64 now = Timer::getTimeSecs(); + for (std::set::iterator it = mRRSet.begin(); it != mRRSet.end(); ) { - (*it)->log(); + if (now >= (*it)->absoluteExpiry()) + { + delete *it; + mRRSet.erase(it++); + } + else + { + (*it)->log(); + ++it; + } } } void RRCache::getCacheDump(Data& dnsCacheDump) { + UInt64 now = Timer::getTimeSecs(); DataStream strm(dnsCacheDump); - for (std::set::iterator it = mRRSet.begin(); it != mRRSet.end(); it++) + for (std::set::iterator it = mRRSet.begin(); it != mRRSet.end(); ) { - (*it)->encodeRRList(strm); + if (now >= (*it)->absoluteExpiry()) + { + delete *it; + mRRSet.erase(it++); + } + else + { + (*it)->encodeRRList(strm); + ++it; + } } strm.flush(); } diff --git a/src/libs/resiprocate/rutil/dns/RRCache.hxx b/src/libs/resiprocate/rutil/dns/RRCache.hxx index 0971eebb..2bc56f1e 100644 --- a/src/libs/resiprocate/rutil/dns/RRCache.hxx +++ b/src/libs/resiprocate/rutil/dns/RRCache.hxx @@ -67,7 +67,7 @@ class RRCache } else { - return lhs->key() < rhs->key(); + return (Data(lhs->key())).lowercase() < (Data(rhs->key())).lowercase(); } } }; diff --git a/src/libs/resiprocate/rutil/dns/RRList.cxx b/src/libs/resiprocate/rutil/dns/RRList.cxx index e63a9dcc..edafd499 100644 --- a/src/libs/resiprocate/rutil/dns/RRList.cxx +++ b/src/libs/resiprocate/rutil/dns/RRList.cxx @@ -157,7 +157,7 @@ RRList::encodeRecordItem(RRList::RecordItem& item, EncodeStream& strm) case T_CNAME: { DnsCnameRecord* record = dynamic_cast(item.record); - assert(record); + resip_assert(record); strm << "CNAME: " << record->name() << " -> " << record->cname(); break; } @@ -165,7 +165,7 @@ RRList::encodeRecordItem(RRList::RecordItem& item, EncodeStream& strm) case T_NAPTR: { DnsNaptrRecord* record = dynamic_cast(item.record); - assert(record); + resip_assert(record); strm << "NAPTR: " << record->name() << " -> repl=" << record->replacement() << " service=" << record->service() << " order=" << record->order() << " pref=" << record->preference() << " flags=" << record->flags() << " regexp=" << record->regexp().regexp(); @@ -175,7 +175,7 @@ RRList::encodeRecordItem(RRList::RecordItem& item, EncodeStream& strm) case T_SRV: { DnsSrvRecord* record = dynamic_cast(item.record); - assert(record); + resip_assert(record); strm << "SRV: " << record->name() << " -> " << record->target() << ":" << record->port() << " priority=" << record->priority() << " weight=" << record->weight(); break; @@ -185,7 +185,7 @@ RRList::encodeRecordItem(RRList::RecordItem& item, EncodeStream& strm) case T_AAAA: { DnsAAAARecord* record = dynamic_cast(item.record); - assert(record); + resip_assert(record); strm << "AAAA(Host): " << record->name() << " -> " << DnsUtil::inet_ntop(record->v6Address()); break; } @@ -194,7 +194,7 @@ RRList::encodeRecordItem(RRList::RecordItem& item, EncodeStream& strm) case T_A: { DnsHostRecord* record = dynamic_cast(item.record); - assert(record); + resip_assert(record); strm << "A(Host): " << record->name() << " -> " << record->host(); break; } diff --git a/src/libs/resiprocate/rutil/dns/RRVip.cxx b/src/libs/resiprocate/rutil/dns/RRVip.cxx index 3a2257ee..6547b533 100644 --- a/src/libs/resiprocate/rutil/dns/RRVip.cxx +++ b/src/libs/resiprocate/rutil/dns/RRVip.cxx @@ -77,7 +77,7 @@ void RRVip::vip(const Data& target, else { TransformFactoryMap::iterator it = mFactories.find(rrType); - assert(it != mFactories.end()); + resip_assert(it != mFactories.end()); Transform* transform = it->second->createTransform(vip); mTransforms.insert(TransformMap::value_type(key, transform)); } diff --git a/src/libs/resiprocate/rutil/fixupGperf b/src/libs/resiprocate/rutil/fixupGperf old mode 100644 new mode 100755 diff --git a/src/libs/resiprocate/rutil/hep/HepAgent.cxx b/src/libs/resiprocate/rutil/hep/HepAgent.cxx new file mode 100644 index 00000000..2846d464 --- /dev/null +++ b/src/libs/resiprocate/rutil/hep/HepAgent.cxx @@ -0,0 +1,138 @@ +#if defined(HAVE_CONFIG_H) +#include "config.h" +#endif + +#include + +#include "rutil/hep/ResipHep.hxx" +#include "rutil/hep/HepAgent.hxx" +#include "rutil/DataStream.hxx" +#include "rutil/Logger.hxx" + +using namespace resip; +using namespace std; + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +HepAgent::HepAgent(const Data &captureHost, int capturePort, int captureAgentID) + : mCaptureHost(captureHost), mCapturePort(capturePort), mCaptureAgentID(captureAgentID) +{ +#ifdef USE_IPV6 + struct sockaddr_in6 myaddr; + memset(&myaddr, 0, sizeof(myaddr)); + myaddr.sin6_family=AF_INET6; + myaddr.sin6_addr = in6addr_any; // FIXME - make it configurable + myaddr.sin6_port=0; // FIXME - make it configurable + + mSocket = ::socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP); + + int no = 0; +#if !defined(WIN32) + ::setsockopt(mSocket, IPPROTO_IPV6, IPV6_V6ONLY, &no, sizeof(no)); +#else + ::setsockopt(mSocket, IPPROTO_IPV6, IPV6_V6ONLY, (const char*)&no, sizeof(no)); +#endif + +#else + struct sockaddr_in myaddr; + memset(&myaddr, 0, sizeof(myaddr)); + myaddr.sin_family=AF_INET; + myaddr.sin_addr.s_addr=INADDR_ANY; // FIXME - make it configurable + myaddr.sin_port=0; // FIXME - make it configurable + + mSocket = ::socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); +#endif + + if(mSocket < 0) + { + ErrLog(<<"Failed to create socket"); + throw std::runtime_error("Failed to create socket"); + } + + // make it non-blocking + // FIXME - HEP messages are lost if the transmit buffer fills up + // Messages should be queued and sent as part of the main loop + if(!makeSocketNonBlocking(mSocket)) + { + ErrLog(<<"Failed to set O_NONBLOCK"); + throw std::runtime_error("Failed to set O_NONBLOCK"); + } + + if(::bind(mSocket, ( struct sockaddr *) &myaddr, sizeof(myaddr)) < 0) { + ErrLog(<<"bind failed"); + throw std::runtime_error("bind failed"); + } + + // create destination Tuple + struct addrinfo *rset; + if(getaddrinfo(mCaptureHost.c_str(), 0, 0, &rset) != 0) + { + ErrLog(<<"getaddrinfo failed"); + throw std::runtime_error("getaddrinfo failed"); + } + if(rset == 0) + { + ErrLog(<<"no results from getaddrinfo"); + throw std::runtime_error("no results from getaddrinfo"); + } + const struct addrinfo& dest = rset[0]; + switch(dest.ai_family) + { + case AF_INET: + memcpy(&mDestination.v4Address, dest.ai_addr, dest.ai_addrlen); + mDestination.v4Address.sin_port = htons(mCapturePort); + break; +#ifdef IPPROTO_IPV6 + case AF_INET6: + memcpy(&mDestination.v6Address, dest.ai_addr, dest.ai_addrlen); + mDestination.v6Address.sin6_port = htons(mCapturePort); + break; +#endif + default: + ErrLog(<<"unsupported address family"); + throw std::runtime_error("unsupported address family"); + } + freeaddrinfo(rset); + InfoLog(<<"HEP capture agent ready to send to " << mDestination); +} + +HepAgent::~HepAgent() +{ +} + +/* ==================================================================== + * + * Copyright 2016 Daniel Pocock http://danielpocock.com All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ diff --git a/src/libs/resiprocate/rutil/hep/HepAgent.hxx b/src/libs/resiprocate/rutil/hep/HepAgent.hxx new file mode 100644 index 00000000..32a0f6a3 --- /dev/null +++ b/src/libs/resiprocate/rutil/hep/HepAgent.hxx @@ -0,0 +1,284 @@ +#if !defined(RESIP_HEPAGENT_HXX) +#define RESIP_HEPAGENT_HXX + +#include "rutil/Data.hxx" +#include "rutil/GenericIPAddress.hxx" +#include "rutil/Socket.hxx" +#include "rutil/TransportType.hxx" +#include "rutil/hep/ResipHep.hxx" +#include "rutil/DataStream.hxx" +#include "rutil/Logger.hxx" + +#define RESIPROCATE_SUBSYSTEM Subsystem::TRANSPORT + +namespace resip +{ + +class HepAgent +{ + public: + typedef enum + { + SIP = 1, + RTCP_JSON = 5 + } HEPEventType; + + HepAgent(const Data &captureHost, int capturePort, int captureAgentID); + virtual ~HepAgent(); + template + void sendToHOMER(const TransportType type, const GenericIPAddress& source, const GenericIPAddress& destination, const HEPEventType eventType, const T& msg, const Data& correlationId) + { + struct hep_generic *hg; + hep_chunk_ip4_t src_ip4, dst_ip4; + hep_chunk_t payload_chunk; + +#ifdef USE_IPV6 + hep_chunk_ip6_t src_ip6, dst_ip6; +#endif + + char *data = new char[sizeof(struct hep_generic)]; + Data buf(Data::Take, data, sizeof(struct hep_generic)); + hg = (struct hep_generic *)buf.data(); + DebugLog(<< "buf.size() == " << buf.size()); + DataStream stream(buf); + + memset(hg, 0, sizeof(struct hep_generic)); + + /* header set */ + memcpy(hg->header.id, "\x48\x45\x50\x33", 4); + + Data chunk; + + /* IP proto */ + hg->ip_family.chunk.vendor_id = htons(0x0000); + hg->ip_family.chunk.type_id = htons(0x0001); + hg->ip_family.chunk.length = htons(sizeof(hg->ip_family)); + unsigned int sourcePort = 0; + unsigned int destinationPort = 0; + switch(source.address.sa_family) + { + case AF_INET: + { + hg->ip_family.data = AF_INET; + src_ip4.chunk.vendor_id = htons(0x0000); + src_ip4.chunk.type_id = htons(0x0003); + const struct sockaddr_in& src_sa = source.v4Address; + memcpy(&src_ip4.data, &src_sa.sin_addr.s_addr, sizeof(src_sa.sin_addr.s_addr)); + src_ip4.chunk.length = htons(sizeof(src_ip4)); + chunk = Data(Data::Borrow, (char *)&src_ip4, sizeof(hep_chunk_ip4_t)); + stream << chunk; + sourcePort = ntohs(src_sa.sin_port); + + dst_ip4.chunk.vendor_id = htons(0x0000); + dst_ip4.chunk.type_id = htons(0x0004); + const struct sockaddr_in& dst_sa = destination.v4Address; + memcpy(&dst_ip4.data, &dst_sa.sin_addr.s_addr, sizeof(dst_sa.sin_addr.s_addr)); + dst_ip4.chunk.length = htons(sizeof(dst_ip4)); + chunk = Data(Data::Borrow, (char *)&dst_ip4, sizeof(hep_chunk_ip4_t)); + stream << chunk; + destinationPort = ntohs(dst_sa.sin_port); + + break; + } +#ifdef USE_IPV6 + case AF_INET6: + { + hg->ip_family.data = AF_INET6; + src_ip6.chunk.vendor_id = htons(0x0000); + src_ip6.chunk.type_id = htons(0x0005); + const struct sockaddr_in6& src_sa6 = source.v6Address; + memcpy(&src_ip6.data, &src_sa6.sin6_addr, sizeof(src_sa6.sin6_addr)); + src_ip6.chunk.length = htons(sizeof(src_ip6)); + chunk = Data(Data::Borrow, (char *)&src_ip6, sizeof(hep_chunk_ip6_t)); + stream << chunk; + sourcePort = ntohs(src_sa6.sin6_port); + + dst_ip6.chunk.vendor_id = htons(0x0000); + dst_ip6.chunk.type_id = htons(0x0006); + const struct sockaddr_in6& dst_sa6 = destination.v6Address; + memcpy(&dst_ip6.data, &dst_sa6.sin6_addr, sizeof(dst_sa6.sin6_addr)); + dst_ip6.chunk.length = htons(sizeof(dst_ip6)); + chunk = Data(Data::Borrow, (char *)&dst_ip6, sizeof(hep_chunk_ip6_t)); + stream << chunk; + destinationPort = ntohs(dst_sa6.sin6_port); + break; + } +#endif + { + default: + ErrLog(<<"unhandled address family"); + return; + } + } + stream.flush(); + DebugLog(<< "buf.size() == " << buf.size()); + hg = (struct hep_generic *)buf.data(); + + /* PROTOCOL */ + switch(type) + { + case TLS: + hg->ip_proto.data = IPPROTO_IDP; // FIXME + break; + case TCP: + hg->ip_proto.data = IPPROTO_TCP; + break; + case UDP: + hg->ip_proto.data = IPPROTO_UDP; + break; +#if !defined(WIN32) || (defined(WIN32) && (_WIN32_WINNT >= 0x0600)) + case SCTP: + hg->ip_proto.data = IPPROTO_SCTP; + break; +#endif + case WS: + case WSS: + hg->ip_proto.data = IPPROTO_TCP; // FIXME + break; + default: + ErrLog(<<"unhandled TransportType"); + return; + } + /* Proto ID */ + hg->ip_proto.chunk.vendor_id = htons(0x0000); + hg->ip_proto.chunk.type_id = htons(0x0002); + hg->ip_proto.chunk.length = htons(sizeof(hg->ip_proto)); + + /* SRC PORT */ + hg->src_port.chunk.vendor_id = htons(0x0000); + hg->src_port.chunk.type_id = htons(0x0007); + hg->src_port.data = htons(sourcePort); + hg->src_port.chunk.length = htons(sizeof(hg->src_port)); + + /* DST PORT */ + hg->dst_port.chunk.vendor_id = htons(0x0000); + hg->dst_port.chunk.type_id = htons(0x0008); + hg->dst_port.data = htons(destinationPort); + hg->dst_port.chunk.length = htons(sizeof(hg->dst_port)); + + UInt64 now = hepUnixTimestamp(); + + /* TIMESTAMP SEC */ + hg->time_sec.chunk.vendor_id = htons(0x0000); + hg->time_sec.chunk.type_id = htons(0x0009); + hg->time_sec.chunk.length = htons(sizeof(hg->time_sec)); + hg->time_sec.data = htonl(now / 1000000LL); + + /* TIMESTAMP USEC */ + hg->time_usec.chunk.vendor_id = htons(0x0000); + hg->time_usec.chunk.type_id = htons(0x000a); + hg->time_usec.data = htonl(now % 1000000LL); + hg->time_usec.chunk.length = htons(sizeof(hg->time_usec)); + + /* Protocol TYPE */ + hg->proto_t.chunk.vendor_id = htons(0x0000); + hg->proto_t.chunk.type_id = htons(0x000b); + hg->proto_t.data = eventType; + hg->proto_t.chunk.length = htons(sizeof(hg->proto_t)); + + /* Capture ID */ + hg->capt_id.chunk.vendor_id = htons(0x0000); + hg->capt_id.chunk.type_id = htons(0x000c); + hg->capt_id.data = htons(mCaptureAgentID); + hg->capt_id.chunk.length = htons(sizeof(hg->capt_id)); + + stream.flush(); + + /* Correlation ID */ + if(!correlationId.empty()) + { + StackLog(<<"adding correlation ID: " << correlationId); + hep_chunk_t correlation_chunk; + correlation_chunk.vendor_id = htons(0x0000); + correlation_chunk.type_id = htons(0x0011); + correlation_chunk.length = htons(sizeof(correlation_chunk) + correlationId.size()); + chunk = Data(Data::Borrow, (char *)&correlation_chunk, sizeof(correlation_chunk)); + stream << chunk; + stream << correlationId; + stream.flush(); + } + + Data::size_type payloadChunkOffset = buf.size(); + payload_chunk.vendor_id = htons(0x0000); + payload_chunk.type_id = htons(0x000f); + chunk = Data(Data::Borrow, (char *)&payload_chunk, sizeof(payload_chunk)); + stream << chunk; + stream.flush(); + Data::size_type beforePayload = buf.size(); + DebugLog(<< "buf.size() == " << buf.size()); + stream << msg; + stream.flush(); + Data::size_type afterPayload = buf.size(); + DebugLog(<< "Final buf.size() == " << buf.size()); + hep_chunk_t *_payload_chunk = (hep_chunk_t *)(buf.data() + payloadChunkOffset); + _payload_chunk->length = htons(sizeof(payload_chunk) + afterPayload - beforePayload); + hg = (struct hep_generic *)buf.data(); + hg->header.length = htons(afterPayload); + + if(sendto(mSocket, buf.data(), buf.size(), 0, &mDestination.address, mDestination.length()) < 0) + { + int e = getErrno(); +#if defined(WIN32) + ErrLog(<< "sending to HOMER " << mDestination << " failed (" << e << ")"); +#else + ErrLog(<< "sending to HOMER " << mDestination << " failed (" << e << "): " << strerror(e)); +#endif + } + else + { + DebugLog(<< "packet sent to HOMER " << mDestination); + } + } + + private: + Data mCaptureHost; + int mCapturePort; + int mCaptureAgentID; + GenericIPAddress mDestination; + Socket mSocket; +}; + + +} + +#undef RESIPROCATE_SUBSYSTEM + +#endif + + +/* ==================================================================== + * + * Copyright 2016 Daniel Pocock http://danielpocock.com All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. Neither the name of the author(s) nor the names of any contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * ==================================================================== + * + * + */ diff --git a/src/libs/resiprocate/rutil/hep/ResipHep.cxx b/src/libs/resiprocate/rutil/hep/ResipHep.cxx new file mode 100644 index 00000000..33109053 --- /dev/null +++ b/src/libs/resiprocate/rutil/hep/ResipHep.cxx @@ -0,0 +1,93 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "rutil/hep/ResipHep.hxx" + +#include "rutil/ResipAssert.h" + +// Under Windows we use FILETIME, whose epoch is 1601-01-01 00:00:00 UTC. +// To obtain Unix timestamp we must calculate difference with Unix epoc, +// that is 1970-01-01 00:00:00 UTC. +// In this way we obtain: ((1970 - 1601) * 365 + 89) * 24 * 60 * 60 * 1000 * 1000, +// where 89 is the number of leap year days between 1601 and 1970: +// (1970 - 1601) / 4 excluding 1700, 1800, and 1900. +#define EPOCH_DIFFERENCE 11644473600000000LL + +// Returns microseconds since Unix epoch time (UTC) +UInt64 hepUnixTimestamp() +{ + resip_assert(sizeof(UInt64) == 64/8); + + UInt64 time = 0; + +#if defined(WIN32) || defined(UNDER_CE) + FILETIME ft; + +#ifdef UNDER_CE + SYSTEMTIME st; + ::GetSystemTime(&st); + ::SystemTimeToFileTime(&st, &ft); +#else // UNDER_CE + ::GetSystemTimeAsFileTime(&ft); +#endif // UNDER_CE + + ULARGE_INTEGER li; + li.LowPart = ft.dwLowDateTime; + li.HighPart = ft.dwHighDateTime; + + // divide by 10 to convert 100-nanoseconds to microseconds, + // then subtract EPOCH_DIFFERENCE to obtain microseconds + // from Unix epoch time + time = (li.QuadPart / 10) - EPOCH_DIFFERENCE; + +#else // #if defined(WIN32) || defined(UNDER_CE) + + struct timeval now; + gettimeofday(&now , NULL); + + time = now.tv_sec; + time = time * 1000000; + time += now.tv_usec; + +#endif // #if defined(WIN32) || defined(UNDER_CE) + + return time; +} + +/* ==================================================================== +* +* Copyright 2016 Dario Bozzali - IFM Infomaster All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in +* the documentation and/or other materials provided with the +* distribution. +* +* 3. Neither the name of the author(s) nor the names of any contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +* +* ==================================================================== +* +* +*/ diff --git a/src/libs/resiprocate/rutil/hep/ResipHep.hxx b/src/libs/resiprocate/rutil/hep/ResipHep.hxx new file mode 100644 index 00000000..6a126bec --- /dev/null +++ b/src/libs/resiprocate/rutil/hep/ResipHep.hxx @@ -0,0 +1,171 @@ +#if !defined(RESIP_HEP_HXX) +#define RESIP_HEP_HXX + +#if defined(_WIN32) +#include "rutil/msvc/stdint.h" +typedef uint8_t u_int8_t; +typedef uint16_t u_int16_t; +typedef uint32_t u_int32_t; +#include +#include +#else +#include +#ifdef USE_IPV6 +#include +#endif /* USE_IPV6 */ +#endif + +#include "rutil/compat.hxx" + +#ifdef _MSC_VER +#define PACKED_STRUCT( __StructDeclaration__ ) __pragma( pack(push, 1) ) __StructDeclaration__ __pragma( pack(pop) ) +#elif defined(__GNUC__) +#define PACKED_STRUCT( __StructDeclaration__ ) __StructDeclaration__ __attribute__((__packed__)) +#else +#define PACKED_STRUCT( __StructDeclaration__ ) __StructDeclaration__ +#endif + +/* HEPv3 types */ + +PACKED_STRUCT(struct hep_chunk{ + u_int16_t vendor_id; + u_int16_t type_id; + u_int16_t length; +}); + +typedef struct hep_chunk hep_chunk_t; + +PACKED_STRUCT(struct hep_chunk_uint8 { + hep_chunk_t chunk; + u_int8_t data; +}); + +typedef struct hep_chunk_uint8 hep_chunk_uint8_t; + +PACKED_STRUCT(struct hep_chunk_uint16 { + hep_chunk_t chunk; + u_int16_t data; +}); + +typedef struct hep_chunk_uint16 hep_chunk_uint16_t; + +PACKED_STRUCT(struct hep_chunk_uint32 { + hep_chunk_t chunk; + u_int32_t data; +}); + +typedef struct hep_chunk_uint32 hep_chunk_uint32_t; + +PACKED_STRUCT(struct hep_chunk_str { + hep_chunk_t chunk; + char *data; +}); + +typedef struct hep_chunk_str hep_chunk_str_t; + +PACKED_STRUCT(struct hep_chunk_ip4 { + hep_chunk_t chunk; + struct in_addr data; +}); + +typedef struct hep_chunk_ip4 hep_chunk_ip4_t; + +#ifdef USE_IPV6 +PACKED_STRUCT(struct hep_chunk_ip6 { + hep_chunk_t chunk; + struct in6_addr data; +}); + +typedef struct hep_chunk_ip6 hep_chunk_ip6_t; +#endif // USE_IPV6 + +PACKED_STRUCT(struct hep_ctrl { + char id[4]; + u_int16_t length; +}); + +typedef struct hep_ctrl hep_ctrl_t; + +PACKED_STRUCT(struct hep_chunk_payload { + hep_chunk_t chunk; + char *data; +}); + +typedef struct hep_chunk_payload hep_chunk_payload_t; + +/* Structure of HEP */ + +PACKED_STRUCT(struct hep_generic { + hep_ctrl_t header; + hep_chunk_uint8_t ip_family; + hep_chunk_uint8_t ip_proto; + hep_chunk_uint16_t src_port; + hep_chunk_uint16_t dst_port; + hep_chunk_uint32_t time_sec; + hep_chunk_uint32_t time_usec; + hep_chunk_uint8_t proto_t; + hep_chunk_uint32_t capt_id; +}); + +typedef struct hep_generic hep_generic_t; + +/* Ethernet / IP / UDP header IPv4 */ +const int udp_payload_offset = 14 + 20 + 8; + +struct hep_hdr { + u_int8_t hp_v; /* version */ + u_int8_t hp_l; /* length */ + u_int8_t hp_f; /* family */ + u_int8_t hp_p; /* protocol */ + u_int16_t hp_sport; /* source port */ + u_int16_t hp_dport; /* destination port */ +}; + +struct hep_timehdr { + u_int32_t tv_sec; /* seconds */ + u_int32_t tv_usec; /* useconds */ + u_int16_t captid; /* Capture ID node */ +}; + +struct hep_iphdr { + struct in_addr hp_src; + struct in_addr hp_dst; /* source and dest address */ +}; + +#ifdef USE_IPV6 +struct hep_ip6hdr { + struct in6_addr hp6_src; /* source address */ + struct in6_addr hp6_dst; /* destination address */ +}; +#endif // USE_IPV6 + +UInt64 hepUnixTimestamp(); + +#endif // RESIP_HEP_HXX + +/* ==================================================================== +* +* Copyright(c) 2010 - 2016 +* +* All rights reserved. +* +* Redistribution and use in source and binary forms are permitted +* provided that the above copyright notice and this paragraph are +* duplicated in all such forms and that any documentation, +* advertising materials, and other materials related to such +* distribution and use acknowledge that the software was developed +* by the .The name of the SIPCAPTURE may not be used to +* endorse or promote products derived from this software without specific +* prior written permission. +* +* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +* +* ==================================================================== +* +* Contributor(s): +* +* Dario Bozzali - IFM Infomaster +* +*/ diff --git a/src/libs/resiprocate/rutil/msvc/inttypes.h b/src/libs/resiprocate/rutil/msvc/inttypes.h new file mode 100644 index 00000000..ac7e32b6 --- /dev/null +++ b/src/libs/resiprocate/rutil/msvc/inttypes.h @@ -0,0 +1,306 @@ +// ISO C9x compliant inttypes.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2013 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the product nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_INTTYPES_H_ // [ +#define _MSC_INTTYPES_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include "stdint.h" + +// 7.8 Format conversion of integer types + +typedef struct { + intmax_t quot; + intmax_t rem; +} imaxdiv_t; + +// 7.8.1 Macros for format specifiers + +#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 + +// The fprintf macros for signed integers are: +#define PRId8 "d" +#define PRIi8 "i" +#define PRIdLEAST8 "d" +#define PRIiLEAST8 "i" +#define PRIdFAST8 "d" +#define PRIiFAST8 "i" + +#define PRId16 "hd" +#define PRIi16 "hi" +#define PRIdLEAST16 "hd" +#define PRIiLEAST16 "hi" +#define PRIdFAST16 "hd" +#define PRIiFAST16 "hi" + +#define PRId32 "I32d" +#define PRIi32 "I32i" +#define PRIdLEAST32 "I32d" +#define PRIiLEAST32 "I32i" +#define PRIdFAST32 "I32d" +#define PRIiFAST32 "I32i" + +#define PRId64 "I64d" +#define PRIi64 "I64i" +#define PRIdLEAST64 "I64d" +#define PRIiLEAST64 "I64i" +#define PRIdFAST64 "I64d" +#define PRIiFAST64 "I64i" + +#define PRIdMAX "I64d" +#define PRIiMAX "I64i" + +#define PRIdPTR "Id" +#define PRIiPTR "Ii" + +// The fprintf macros for unsigned integers are: +#define PRIo8 "o" +#define PRIu8 "u" +#define PRIx8 "x" +#define PRIX8 "X" +#define PRIoLEAST8 "o" +#define PRIuLEAST8 "u" +#define PRIxLEAST8 "x" +#define PRIXLEAST8 "X" +#define PRIoFAST8 "o" +#define PRIuFAST8 "u" +#define PRIxFAST8 "x" +#define PRIXFAST8 "X" + +#define PRIo16 "ho" +#define PRIu16 "hu" +#define PRIx16 "hx" +#define PRIX16 "hX" +#define PRIoLEAST16 "ho" +#define PRIuLEAST16 "hu" +#define PRIxLEAST16 "hx" +#define PRIXLEAST16 "hX" +#define PRIoFAST16 "ho" +#define PRIuFAST16 "hu" +#define PRIxFAST16 "hx" +#define PRIXFAST16 "hX" + +#define PRIo32 "I32o" +#define PRIu32 "I32u" +#define PRIx32 "I32x" +#define PRIX32 "I32X" +#define PRIoLEAST32 "I32o" +#define PRIuLEAST32 "I32u" +#define PRIxLEAST32 "I32x" +#define PRIXLEAST32 "I32X" +#define PRIoFAST32 "I32o" +#define PRIuFAST32 "I32u" +#define PRIxFAST32 "I32x" +#define PRIXFAST32 "I32X" + +#define PRIo64 "I64o" +#define PRIu64 "I64u" +#define PRIx64 "I64x" +#define PRIX64 "I64X" +#define PRIoLEAST64 "I64o" +#define PRIuLEAST64 "I64u" +#define PRIxLEAST64 "I64x" +#define PRIXLEAST64 "I64X" +#define PRIoFAST64 "I64o" +#define PRIuFAST64 "I64u" +#define PRIxFAST64 "I64x" +#define PRIXFAST64 "I64X" + +#define PRIoMAX "I64o" +#define PRIuMAX "I64u" +#define PRIxMAX "I64x" +#define PRIXMAX "I64X" + +#define PRIoPTR "Io" +#define PRIuPTR "Iu" +#define PRIxPTR "Ix" +#define PRIXPTR "IX" + +// The fscanf macros for signed integers are: +#define SCNd8 "d" +#define SCNi8 "i" +#define SCNdLEAST8 "d" +#define SCNiLEAST8 "i" +#define SCNdFAST8 "d" +#define SCNiFAST8 "i" + +#define SCNd16 "hd" +#define SCNi16 "hi" +#define SCNdLEAST16 "hd" +#define SCNiLEAST16 "hi" +#define SCNdFAST16 "hd" +#define SCNiFAST16 "hi" + +#define SCNd32 "ld" +#define SCNi32 "li" +#define SCNdLEAST32 "ld" +#define SCNiLEAST32 "li" +#define SCNdFAST32 "ld" +#define SCNiFAST32 "li" + +#define SCNd64 "I64d" +#define SCNi64 "I64i" +#define SCNdLEAST64 "I64d" +#define SCNiLEAST64 "I64i" +#define SCNdFAST64 "I64d" +#define SCNiFAST64 "I64i" + +#define SCNdMAX "I64d" +#define SCNiMAX "I64i" + +#ifdef _WIN64 // [ +# define SCNdPTR "I64d" +# define SCNiPTR "I64i" +#else // _WIN64 ][ +# define SCNdPTR "ld" +# define SCNiPTR "li" +#endif // _WIN64 ] + +// The fscanf macros for unsigned integers are: +#define SCNo8 "o" +#define SCNu8 "u" +#define SCNx8 "x" +#define SCNX8 "X" +#define SCNoLEAST8 "o" +#define SCNuLEAST8 "u" +#define SCNxLEAST8 "x" +#define SCNXLEAST8 "X" +#define SCNoFAST8 "o" +#define SCNuFAST8 "u" +#define SCNxFAST8 "x" +#define SCNXFAST8 "X" + +#define SCNo16 "ho" +#define SCNu16 "hu" +#define SCNx16 "hx" +#define SCNX16 "hX" +#define SCNoLEAST16 "ho" +#define SCNuLEAST16 "hu" +#define SCNxLEAST16 "hx" +#define SCNXLEAST16 "hX" +#define SCNoFAST16 "ho" +#define SCNuFAST16 "hu" +#define SCNxFAST16 "hx" +#define SCNXFAST16 "hX" + +#define SCNo32 "lo" +#define SCNu32 "lu" +#define SCNx32 "lx" +#define SCNX32 "lX" +#define SCNoLEAST32 "lo" +#define SCNuLEAST32 "lu" +#define SCNxLEAST32 "lx" +#define SCNXLEAST32 "lX" +#define SCNoFAST32 "lo" +#define SCNuFAST32 "lu" +#define SCNxFAST32 "lx" +#define SCNXFAST32 "lX" + +#define SCNo64 "I64o" +#define SCNu64 "I64u" +#define SCNx64 "I64x" +#define SCNX64 "I64X" +#define SCNoLEAST64 "I64o" +#define SCNuLEAST64 "I64u" +#define SCNxLEAST64 "I64x" +#define SCNXLEAST64 "I64X" +#define SCNoFAST64 "I64o" +#define SCNuFAST64 "I64u" +#define SCNxFAST64 "I64x" +#define SCNXFAST64 "I64X" + +#define SCNoMAX "I64o" +#define SCNuMAX "I64u" +#define SCNxMAX "I64x" +#define SCNXMAX "I64X" + +#ifdef _WIN64 // [ +# define SCNoPTR "I64o" +# define SCNuPTR "I64u" +# define SCNxPTR "I64x" +# define SCNXPTR "I64X" +#else // _WIN64 ][ +# define SCNoPTR "lo" +# define SCNuPTR "lu" +# define SCNxPTR "lx" +# define SCNXPTR "lX" +#endif // _WIN64 ] + +#endif // __STDC_FORMAT_MACROS ] + +// 7.8.2 Functions for greatest-width integer types + +// 7.8.2.1 The imaxabs function +#define imaxabs _abs64 + +// 7.8.2.2 The imaxdiv function + +// This is modified version of div() function from Microsoft's div.c found +// in %MSVC.NET%\crt\src\div.c +#ifdef STATIC_IMAXDIV // [ +static +#else // STATIC_IMAXDIV ][ +_inline +#endif // STATIC_IMAXDIV ] +imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) +{ + imaxdiv_t result; + + result.quot = numer / denom; + result.rem = numer % denom; + + if (numer < 0 && result.rem > 0) { + // did division wrong; must fix up + ++result.quot; + result.rem -= denom; + } + + return result; +} + +// 7.8.2.3 The strtoimax and strtoumax functions +#define strtoimax _strtoi64 +#define strtoumax _strtoui64 + +// 7.8.2.4 The wcstoimax and wcstoumax functions +#define wcstoimax _wcstoi64 +#define wcstoumax _wcstoui64 + + +#endif // _MSC_INTTYPES_H_ ] diff --git a/src/libs/resiprocate/rutil/msvc/stdint.h b/src/libs/resiprocate/rutil/msvc/stdint.h new file mode 100644 index 00000000..4fe0ef9a --- /dev/null +++ b/src/libs/resiprocate/rutil/msvc/stdint.h @@ -0,0 +1,259 @@ +// ISO C9x compliant stdint.h for Microsoft Visual Studio +// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 +// +// Copyright (c) 2006-2013 Alexander Chemeris +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// 3. Neither the name of the product nor the names of its contributors may +// be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _MSC_VER // [ +#error "Use this header only with Microsoft Visual C++ compilers!" +#endif // _MSC_VER ] + +#ifndef _MSC_STDINT_H_ // [ +#define _MSC_STDINT_H_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#if _MSC_VER >= 1600 // [ +#include +#else // ] _MSC_VER >= 1600 [ + +#include + +// For Visual Studio 6 in C++ mode and for many Visual Studio versions when +// compiling for ARM we should wrap include with 'extern "C++" {}' +// or compiler give many errors like this: +// error C2733: second C linkage of overloaded function 'wmemchr' not allowed +#ifdef __cplusplus +extern "C" { +#endif +# include +#ifdef __cplusplus +} +#endif + +// Define _W64 macros to mark types changing their size, like intptr_t. +#ifndef _W64 +# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +# define _W64 __w64 +# else +# define _W64 +# endif +#endif + + +// 7.18.1 Integer types + +// 7.18.1.1 Exact-width integer types + +// Visual Studio 6 and Embedded Visual C++ 4 doesn't +// realize that, e.g. char has the same size as __int8 +// so we give up on __intX for them. +#if (_MSC_VER < 1300) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; +#else + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; +#endif +typedef signed __int64 int64_t; +typedef unsigned __int64 uint64_t; + + +// 7.18.1.2 Minimum-width integer types +typedef int8_t int_least8_t; +typedef int16_t int_least16_t; +typedef int32_t int_least32_t; +typedef int64_t int_least64_t; +typedef uint8_t uint_least8_t; +typedef uint16_t uint_least16_t; +typedef uint32_t uint_least32_t; +typedef uint64_t uint_least64_t; + +// 7.18.1.3 Fastest minimum-width integer types +typedef int8_t int_fast8_t; +typedef int16_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef int64_t int_fast64_t; +typedef uint8_t uint_fast8_t; +typedef uint16_t uint_fast16_t; +typedef uint32_t uint_fast32_t; +typedef uint64_t uint_fast64_t; + +// 7.18.1.4 Integer types capable of holding object pointers +#ifdef _WIN64 // [ + typedef signed __int64 intptr_t; + typedef unsigned __int64 uintptr_t; +#else // _WIN64 ][ + typedef _W64 signed int intptr_t; + typedef _W64 unsigned int uintptr_t; +#endif // _WIN64 ] + +// 7.18.1.5 Greatest-width integer types +typedef int64_t intmax_t; +typedef uint64_t uintmax_t; + + +// 7.18.2 Limits of specified-width integer types + +#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 + +// 7.18.2.1 Limits of exact-width integer types +#define INT8_MIN ((int8_t)_I8_MIN) +#define INT8_MAX _I8_MAX +#define INT16_MIN ((int16_t)_I16_MIN) +#define INT16_MAX _I16_MAX +#define INT32_MIN ((int32_t)_I32_MIN) +#define INT32_MAX _I32_MAX +#define INT64_MIN ((int64_t)_I64_MIN) +#define INT64_MAX _I64_MAX +#define UINT8_MAX _UI8_MAX +#define UINT16_MAX _UI16_MAX +#define UINT32_MAX _UI32_MAX +#define UINT64_MAX _UI64_MAX + +// 7.18.2.2 Limits of minimum-width integer types +#define INT_LEAST8_MIN INT8_MIN +#define INT_LEAST8_MAX INT8_MAX +#define INT_LEAST16_MIN INT16_MIN +#define INT_LEAST16_MAX INT16_MAX +#define INT_LEAST32_MIN INT32_MIN +#define INT_LEAST32_MAX INT32_MAX +#define INT_LEAST64_MIN INT64_MIN +#define INT_LEAST64_MAX INT64_MAX +#define UINT_LEAST8_MAX UINT8_MAX +#define UINT_LEAST16_MAX UINT16_MAX +#define UINT_LEAST32_MAX UINT32_MAX +#define UINT_LEAST64_MAX UINT64_MAX + +// 7.18.2.3 Limits of fastest minimum-width integer types +#define INT_FAST8_MIN INT8_MIN +#define INT_FAST8_MAX INT8_MAX +#define INT_FAST16_MIN INT16_MIN +#define INT_FAST16_MAX INT16_MAX +#define INT_FAST32_MIN INT32_MIN +#define INT_FAST32_MAX INT32_MAX +#define INT_FAST64_MIN INT64_MIN +#define INT_FAST64_MAX INT64_MAX +#define UINT_FAST8_MAX UINT8_MAX +#define UINT_FAST16_MAX UINT16_MAX +#define UINT_FAST32_MAX UINT32_MAX +#define UINT_FAST64_MAX UINT64_MAX + +// 7.18.2.4 Limits of integer types capable of holding object pointers +#ifdef _WIN64 // [ +# define INTPTR_MIN INT64_MIN +# define INTPTR_MAX INT64_MAX +# define UINTPTR_MAX UINT64_MAX +#else // _WIN64 ][ +# define INTPTR_MIN INT32_MIN +# define INTPTR_MAX INT32_MAX +# define UINTPTR_MAX UINT32_MAX +#endif // _WIN64 ] + +// 7.18.2.5 Limits of greatest-width integer types +#define INTMAX_MIN INT64_MIN +#define INTMAX_MAX INT64_MAX +#define UINTMAX_MAX UINT64_MAX + +// 7.18.3 Limits of other integer types + +#ifdef _WIN64 // [ +# define PTRDIFF_MIN _I64_MIN +# define PTRDIFF_MAX _I64_MAX +#else // _WIN64 ][ +# define PTRDIFF_MIN _I32_MIN +# define PTRDIFF_MAX _I32_MAX +#endif // _WIN64 ] + +#define SIG_ATOMIC_MIN INT_MIN +#define SIG_ATOMIC_MAX INT_MAX + +#ifndef SIZE_MAX // [ +# ifdef _WIN64 // [ +# define SIZE_MAX _UI64_MAX +# else // _WIN64 ][ +# define SIZE_MAX _UI32_MAX +# endif // _WIN64 ] +#endif // SIZE_MAX ] + +// WCHAR_MIN and WCHAR_MAX are also defined in +#ifndef WCHAR_MIN // [ +# define WCHAR_MIN 0 +#endif // WCHAR_MIN ] +#ifndef WCHAR_MAX // [ +# define WCHAR_MAX _UI16_MAX +#endif // WCHAR_MAX ] + +#define WINT_MIN 0 +#define WINT_MAX _UI16_MAX + +#endif // __STDC_LIMIT_MACROS ] + + +// 7.18.4 Limits of other integer types + +#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 + +// 7.18.4.1 Macros for minimum-width integer constants + +#define INT8_C(val) val##i8 +#define INT16_C(val) val##i16 +#define INT32_C(val) val##i32 +#define INT64_C(val) val##i64 + +#define UINT8_C(val) val##ui8 +#define UINT16_C(val) val##ui16 +#define UINT32_C(val) val##ui32 +#define UINT64_C(val) val##ui64 + +// 7.18.4.2 Macros for greatest-width integer constants +// These #ifndef's are needed to prevent collisions with . +// Check out Issue 9 for the details. +#ifndef INTMAX_C // [ +# define INTMAX_C INT64_C +#endif // INTMAX_C ] +#ifndef UINTMAX_C // [ +# define UINTMAX_C UINT64_C +#endif // UINTMAX_C ] + +#endif // __STDC_CONSTANT_MACROS ] + +#endif // _MSC_VER >= 1600 ] + +#endif // _MSC_STDINT_H_ ] diff --git a/src/libs/resiprocate/rutil/resipfaststreams.hxx b/src/libs/resiprocate/rutil/resipfaststreams.hxx index be5603c7..f613f5d0 100644 --- a/src/libs/resiprocate/rutil/resipfaststreams.hxx +++ b/src/libs/resiprocate/rutil/resipfaststreams.hxx @@ -15,7 +15,7 @@ #include //for std::endl, std::cerr, etc. #include //for snprintf -#include +#include "rutil/ResipAssert.h" #include "rutil/compat.hxx" namespace resip @@ -59,41 +59,6 @@ class ResipBasicIOStream bool eof_; }; - -#if (defined(WIN32) || defined(_WIN32_WCE)) - -#if (defined(_MSC_VER) && _MSC_VER >= 1400 ) -#define SNPRINTF_1(buffer,sizeofBuffer,count,format,var1) _snprintf_s(buffer,sizeofBuffer,_TRUNCATE,format,var1) -#define LTOA(value,string,sizeofstring,radix) _ltoa_s(value,string,sizeofstring,radix) -#define ULTOA(value,string,sizeofstring,radix) _ultoa_s(value,string,sizeofstring,radix) -#define I64TOA(value,string,sizeofstring,radix) _i64toa_s(value,string,sizeofstring,radix) -#define UI64TOA(value,string,sizeofstring,radix) _ui64toa_s(value,string,sizeofstring,radix) -#define GCVT(val,num,buffer,buffersize) _gcvt_s(buffer,buffersize,val,num) -#else -# ifndef _TRUNCATE -# define _TRUNCATE -1 -# endif -# define SNPRINTF_1(buffer,sizeofBuffer,count,format,var1) _snprintf(buffer,count,format,var1) -# define LTOA(value,string,sizeofstring,radix) _ltoa(value,string,radix) -# define ULTOA(value,string,sizeofstring,radix) _ultoa(value,string,radix) -# define I64TOA(value,string,sizeofstring,radix) _i64toa(value,string,radix) -# define UI64TOA(value,string,sizeofstring,radix) _ui64toa(value,string,radix) -# define GCVT(val,sigdigits,buffer,buffersize) _gcvt(val,sigdigits,buffer) -#endif - -#else //non-windows -# ifndef _TRUNCATE -# define _TRUNCATE -1 -# endif -# define SNPRINTF_1(buffer,sizeofBuffer,count,format,var1) snprintf(buffer,sizeofBuffer,format,var1) -# define LTOA(l,buffer,bufferlen,radix) SNPRINTF_1(buffer,bufferlen,bufferlen,"%li",l) -# define ULTOA(ul,buffer,bufferlen,radix) SNPRINTF_1(buffer,bufferlen,bufferlen,"%lu",ul) -# define I64TOA(value,string,sizeofstring,radix) SNPRINTF_1(string,sizeofstring,sizeofstring,"%ll",value) -# define UI64TOA(value,string,sizeofstring,radix) SNPRINTF_1(string,sizeofstring,sizeofstring,"%llu",value) -# define GCVT(f,sigdigits,buffer,bufferlen) SNPRINTF_1(buffer,bufferlen,bufferlen,"%f",f) -# define _CVTBUFSIZE 309+40 -#endif - /** std::ostream replacement. */ class ResipFastOStream : public ResipBasicIOStream @@ -155,42 +120,57 @@ class ResipFastOStream : public ResipBasicIOStream ResipFastOStream& operator<<(bool b) { //int i = (b == true) ? (1):(0); - *this<<(static_cast(b)); + *this<<(static_cast(b)); return *this; } - ResipFastOStream& operator<<(short s) + ResipFastOStream& operator<<(Int16 i) { - *this<<(static_cast(s)); + *this<<(static_cast(i)); return *this; } - ResipFastOStream& operator<<(unsigned short us) + ResipFastOStream& operator<<(UInt16 ui) { - *this<<(static_cast(us)); + *this<<(static_cast(ui)); return *this; } - ResipFastOStream& operator<<(int i) + ResipFastOStream& operator<<(Int32 l) { - *this<<(static_cast(i)); + if (!buf_) + { + return *this; + } + char buf[33]; + //snprintf(buf,33,"%" PRId32,l); + LTOA((long int)l,buf,33,10); + size_t count = strlen(buf); + if (buf_->writebuf(buf,count) < count) + { + good_ = false; + } + return *this; } -#ifdef _W64 - //for size_t - ResipFastOStream& operator<<(_W64 unsigned int ui) + ResipFastOStream& operator<<(UInt32 ul) { - *this<<(static_cast(ui)); + if (!buf_) + { + return *this; + } + char buf[33]; + //snprintf(buf,33,"%" PRIu32,ul); + ULTOA((unsigned long int)ul,buf,33,10); + size_t count = strlen(buf); + if (buf_->writebuf(buf,count) < count) + { + good_ = false; + } + return *this; } -#else - ResipFastOStream& operator<<(unsigned int ui) - { - *this<<(static_cast(ui)); - return *this; - } -#endif ResipFastOStream& operator<<(long l) { @@ -198,8 +178,10 @@ class ResipFastOStream : public ResipBasicIOStream { return *this; } - char buf[33]; - LTOA(l,buf,33,10); + + char buf[66]; + LTOA(l,buf,66,10); + size_t count = strlen(buf); if (buf_->writebuf(buf,count) < count) { @@ -215,8 +197,10 @@ class ResipFastOStream : public ResipBasicIOStream { return *this; } - char buf[33]; - ULTOA(ul,buf,33,10); + + char buf[66]; + ULTOA(ul,buf,66,10); + size_t count = strlen(buf); if (buf_->writebuf(buf,count) < count) { @@ -226,15 +210,17 @@ class ResipFastOStream : public ResipBasicIOStream return *this; } -#ifdef WIN32 - ResipFastOStream& operator<<(__int64 i64) + ResipFastOStream& operator<<(Int64 i64) { if (!buf_) { return *this; } + char buf[66]; + //snprintf(buf,66,"%" PRId64,i64); I64TOA(i64,buf,66,10); + size_t count = strlen(buf); if (buf_->writebuf(buf,count) < count) { @@ -244,24 +230,6 @@ class ResipFastOStream : public ResipBasicIOStream return *this; } - ResipFastOStream& operator<<(unsigned __int64 ui64) - { - if (!buf_) - { - return *this; - } - - char buf[66]; - UI64TOA(ui64,buf,66,10); - size_t count = strlen(buf); - if (buf_->writebuf(buf,count) < count) - { - good_ = false; - } - - return *this; - } -#else ResipFastOStream& operator<<(UInt64 ui64) { if (!buf_) @@ -270,6 +238,7 @@ class ResipFastOStream : public ResipBasicIOStream } char buf[66]; + //snprintf(buf,66,"%" PRIu64,ui64); UI64TOA(ui64,buf,66,10); size_t count = strlen(buf); @@ -280,7 +249,6 @@ class ResipFastOStream : public ResipBasicIOStream return *this; } -#endif ResipFastOStream& operator<<(float f) { @@ -358,7 +326,7 @@ class ResipFastOStream : public ResipBasicIOStream } else { - assert(0); + resip_assert(0); } return *this; } @@ -483,7 +451,7 @@ class ResipStdBuf : public ResipStreamBuf } return count; } - virtual size_t readbuf(char * /*buf*/, size_t /*count*/) + virtual size_t readbuf(char *buf, size_t count) { return 0; } diff --git a/src/libs/resiprocate/rutil/rutil.pro b/src/libs/resiprocate/rutil/rutil.pro deleted file mode 100644 index 55c6c8dd..00000000 --- a/src/libs/resiprocate/rutil/rutil.pro +++ /dev/null @@ -1,157 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2010-11-29T21:30:22 -# -#------------------------------------------------- - -QT -= core gui - -TARGET = rutil -TEMPLATE = lib -CONFIG += staticlib -INCLUDEPATH += ../ ../contrib/ares ../../contrib/ares -DEFINES += USE_ARES USE_IPV6 _WIN32_WINNT=0x0501 - -win32 { - DESTDIR = ../../../Libs/compiled/win -} - -SOURCES += \ - FileSystem.cxx \ - DnsUtil.cxx \ - DataStream.cxx \ - Data.cxx \ - CountStream.cxx \ - Condition.cxx \ - Coders.cxx \ - BaseException.cxx \ - AbstractFifo.cxx \ - Log.cxx \ - Lock.cxx \ - HeapInstanceCounter.cxx \ - resipfaststreams.cxx \ - RecursiveMutex.cxx \ - Random.cxx \ - RADIUSDigestAuthenticator.cxx \ - Poll.cxx \ - ParseException.cxx \ - ParseBuffer.cxx \ - Mutex.cxx \ - MD5Stream.cxx \ - vmd5.cxx \ - TransportType.cxx \ - Timer.cxx \ - Time.cxx \ - ThreadIf.cxx \ - SysLogStream.cxx \ - SysLogBuf.cxx \ - Subsystem.cxx \ - Socket.cxx \ - RWMutex.cxx \ - dns/RRVip.cxx \ - dns/RROverlay.cxx \ - dns/RRList.cxx \ - dns/RRCache.cxx \ - dns/QueryTypes.cxx \ - dns/LocalDns.cxx \ - dns/ExternalDnsFactory.cxx \ - dns/DnsStub.cxx \ - dns/DnsSrvRecord.cxx \ - dns/DnsResourceRecord.cxx \ - dns/DnsNaptrRecord.cxx \ - dns/DnsHostRecord.cxx \ - dns/DnsCnameRecord.cxx \ - dns/DnsAAAARecord.cxx \ - dns/AresDns.cxx \ - ssl/SHA1Stream.cxx \ - ssl/OpenSSLInit.cxx \ - stun/Udp.cxx \ - stun/Stun.cxx \ - ssl/SHA1Stream.cxx \ - ssl/OpenSSLInit.cxx - -HEADERS += \ - FiniteFifo.hxx \ - FileSystem.hxx \ - Fifo.hxx \ - DnsUtil.hxx \ - DataStream.hxx \ - DataException.hxx \ - Data.hxx \ - CountStream.hxx \ - Condition.hxx \ - compat.hxx \ - Coders.hxx \ - CircularBuffer.hxx \ - BaseException.hxx \ - AsyncProcessHandler.hxx \ - AsyncID.hxx \ - AbstractFifo.hxx \ - Logger.hxx \ - Log.hxx \ - Lockable.hxx \ - Lock.hxx \ - IntrusiveListElement.hxx \ - Inserter.hxx \ - HeapInstanceCounter.hxx \ - HashMap.hxx \ - GenericTimerQueue.hxx \ - GenericIPAddress.hxx \ - resipfaststreams.hxx \ - RecursiveMutex.hxx \ - Random.hxx \ - RADIUSDigestAuthenticator.hxx \ - Poll.hxx \ - ParseException.hxx \ - ParseBuffer.hxx \ - Mutex.hxx \ - MD5Stream.hxx \ - vthread.hxx \ - vmd5.hxx \ - TransportType.hxx \ - Timer.hxx \ - TimeLimitFifo.hxx \ - Time.hxx \ - ThreadIf.hxx \ - SysLogStream.hxx \ - SysLogBuf.hxx \ - Subsystem.hxx \ - Socket.hxx \ - SharedPtr.hxx \ - SharedCount.hxx \ - RWMutex.hxx \ - dns/RRVip.hxx \ - dns/RROverlay.hxx \ - dns/RRList.hxx \ - dns/RRFactory.hxx \ - dns/RRCache.hxx \ - dns/QueryTypes.hxx \ - dns/LocalDns.hxx \ - dns/ExternalDnsFactory.hxx \ - dns/ExternalDns.hxx \ - dns/DnsStub.hxx \ - dns/DnsSrvRecord.hxx \ - dns/DnsResourceRecord.hxx \ - dns/DnsNaptrRecord.hxx \ - dns/DnsHostRecord.hxx \ - dns/DnsHandler.hxx \ - dns/DnsCnameRecord.hxx \ - dns/DnsAAAARecord.hxx \ - dns/AresDns.hxx \ - dns/AresCompat.hxx \ - ssl/SHA1Stream.hxx \ - ssl/OpenSSLInit.hxx \ - stun/Udp.hxx \ - stun/Stun.hxx \ - ssl/SHA1Stream.hxx \ - ssl/OpenSSLInit.hxx -unix:!symbian { - maemo5 { - target.path = /opt/usr/lib - } else { - target.path = /usr/local/lib - } - INSTALLS += target -} - - diff --git a/src/libs/resiprocate/rutil/rutil_10_0.vcxproj.filters b/src/libs/resiprocate/rutil/rutil_10_0.vcxproj.filters deleted file mode 100644 index a0f3d90e..00000000 --- a/src/libs/resiprocate/rutil/rutil_10_0.vcxproj.filters +++ /dev/null @@ -1,456 +0,0 @@ - - - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - - \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/rutil_12_0.vcxproj b/src/libs/resiprocate/rutil/rutil_12_0.vcxproj new file mode 100644 index 00000000..8e838ca1 --- /dev/null +++ b/src/libs/resiprocate/rutil/rutil_12_0.vcxproj @@ -0,0 +1,604 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + SSL-Debug-MT + Win32 + + + SSL-Debug-MT + x64 + + + SSL-Debug + Win32 + + + SSL-Debug + x64 + + + SSL-Release-MT + Win32 + + + SSL-Release-MT + x64 + + + SSL-Release + Win32 + + + SSL-Release + x64 + + + + rutil + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + rutil + Win32Proj + + + + StaticLibrary + MultiByte + v120 + + + StaticLibrary + MultiByte + v120 + + + StaticLibrary + MultiByte + v120 + + + StaticLibrary + MultiByte + v120 + + + StaticLibrary + MultiByte + v120 + + + StaticLibrary + MultiByte + v120 + + + StaticLibrary + MultiByte + v120 + + + StaticLibrary + MultiByte + v120 + + + StaticLibrary + MultiByte + v120 + + + StaticLibrary + MultiByte + v120 + + + StaticLibrary + MultiByte + v120 + + + StaticLibrary + MultiByte + v120 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.21006.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + + + + + + Disabled + $(ProjectDir)dns/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + + + Level3 + EditAndContinue + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + Disabled + $(ProjectDir)dns/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;NO_IPHLPAPI;LEAK_CHECK;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + $(ProjectDir)dns/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + $(ProjectDir)dns/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/opensslx64/include;%(AdditionalIncludeDirectories) + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + ProgramDatabase + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/opensslx64/include;%(AdditionalIncludeDirectories) + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + Disabled + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;LEAK_CHECK;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + + + Level3 + EditAndContinue + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + Disabled + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;LEAK_CHECK;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + + + Level3 + EditAndContinue + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + Disabled + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/opensslx64/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;LEAK_CHECK;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + Disabled + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/opensslx64/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;LEAK_CHECK;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + true + true + + + + + + + + + + + + + + + true + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {ce7cf5e0-cad1-49d6-95d1-143ded7b226e} + + + + + + diff --git a/src/libs/resiprocate/rutil/rutil_10_0.vcxproj b/src/libs/resiprocate/rutil/rutil_14_0.vcxproj similarity index 63% rename from src/libs/resiprocate/rutil/rutil_10_0.vcxproj rename to src/libs/resiprocate/rutil/rutil_14_0.vcxproj index 5599030c..10ed17e8 100644 --- a/src/libs/resiprocate/rutil/rutil_10_0.vcxproj +++ b/src/libs/resiprocate/rutil/rutil_14_0.vcxproj @@ -17,6 +17,14 @@ Release x64 + + SSL-Debug-MT + Win32 + + + SSL-Debug-MT + x64 + SSL-Debug Win32 @@ -25,6 +33,14 @@ SSL-Debug x64 + + SSL-Release-MT + Win32 + + + SSL-Release-MT + x64 + SSL-Release Win32 @@ -46,21 +62,41 @@ MultiByte v140 + + StaticLibrary + MultiByte + v140 + StaticLibrary MultiByte v140 + + StaticLibrary + MultiByte + v140 + StaticLibrary MultiByte v140 + + StaticLibrary + MultiByte + v140 + StaticLibrary MultiByte v140 + + StaticLibrary + MultiByte + v140 + StaticLibrary MultiByte @@ -88,18 +124,34 @@ + + + + + + + + + + + + + + + + @@ -119,22 +171,30 @@ <_ProjectFileVersion>10.0.21006.1 - Debug\ - Debug\ - Debug\ - Debug\ - Release\ - Release\ - Release\ - Release\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ - $(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ AllRules.ruleset AllRules.ruleset @@ -148,23 +208,35 @@ AllRules.ruleset + AllRules.ruleset AllRules.ruleset + AllRules.ruleset + + + + AllRules.ruleset + AllRules.ruleset AllRules.ruleset + AllRules.ruleset + + + + Disabled - $(ProjectDir)/../contrib/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions) + $(ProjectDir)dns/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL @@ -181,8 +253,8 @@ Disabled - $(ProjectDir)/../contrib/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;NO_IPHLPAPI;LEAK_CHECK;%(PreprocessorDefinitions) + $(ProjectDir)dns/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;NO_IPHLPAPI;LEAK_CHECK;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL true @@ -197,8 +269,8 @@ - $(ProjectDir)/../contrib/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) + $(ProjectDir)dns/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) MultiThreadedDLL true @@ -212,8 +284,8 @@ - $(ProjectDir)/../contrib/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) + $(ProjectDir)dns/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) MultiThreadedDLL true @@ -227,8 +299,8 @@ - $(ProjectDir)/../contrib/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions) + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions) MultiThreadedDLL true @@ -240,16 +312,46 @@ $(OutDir)$(TargetName)$(TargetExt) + + + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + - $(ProjectDir)/../contrib/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions) + WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions) MultiThreadedDLL true Level3 ProgramDatabase + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/opensslx64/include;%(AdditionalIncludeDirectories) + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + ProgramDatabase + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/opensslx64/include;%(AdditionalIncludeDirectories) $(OutDir)$(TargetName)$(TargetExt) @@ -258,8 +360,8 @@ Disabled - $(ProjectDir)/../contrib/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;LEAK_CHECK;%(PreprocessorDefinitions) + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;LEAK_CHECK;%(PreprocessorDefinitions) true EnableFastChecks MultiThreadedDebugDLL @@ -273,11 +375,29 @@ $(OutDir)$(TargetName)$(TargetExt) + + + Disabled + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;LEAK_CHECK;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + + + Level3 + EditAndContinue + + + $(OutDir)$(TargetName)$(TargetExt) + + Disabled - $(ProjectDir)/../contrib/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;%(AdditionalIncludeDirectories) - _SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS;WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;LEAK_CHECK;%(PreprocessorDefinitions) + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/opensslx64/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;LEAK_CHECK;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebugDLL true @@ -290,6 +410,23 @@ $(OutDir)$(TargetName)$(TargetExt) + + + Disabled + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/opensslx64/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;LEAK_CHECK;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + @@ -312,7 +449,10 @@ + + + @@ -322,6 +462,7 @@ + true true @@ -399,6 +540,8 @@ + + @@ -413,6 +556,7 @@ + @@ -420,6 +564,7 @@ + @@ -449,16 +594,8 @@ - - - - + {ce7cf5e0-cad1-49d6-95d1-143ded7b226e} - true - true - false - true - false diff --git a/src/libs/resiprocate/rutil/rutil_15_0.vcxproj b/src/libs/resiprocate/rutil/rutil_15_0.vcxproj new file mode 100644 index 00000000..7a2d514c --- /dev/null +++ b/src/libs/resiprocate/rutil/rutil_15_0.vcxproj @@ -0,0 +1,605 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + SSL-Debug-MT + Win32 + + + SSL-Debug-MT + x64 + + + SSL-Debug + Win32 + + + SSL-Debug + x64 + + + SSL-Release-MT + Win32 + + + SSL-Release-MT + x64 + + + SSL-Release + Win32 + + + SSL-Release + x64 + + + + rutil + {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} + rutil + Win32Proj + 10.0.17134.0 + + + + StaticLibrary + MultiByte + v141 + + + StaticLibrary + MultiByte + v141 + + + StaticLibrary + MultiByte + v141 + + + StaticLibrary + MultiByte + v141 + + + StaticLibrary + MultiByte + v141 + + + StaticLibrary + MultiByte + v141 + + + StaticLibrary + MultiByte + v141 + + + StaticLibrary + MultiByte + v141 + + + StaticLibrary + MultiByte + v141 + + + StaticLibrary + MultiByte + v141 + + + StaticLibrary + MultiByte + v141 + + + StaticLibrary + MultiByte + v141 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>10.0.21006.1 + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + + + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + + + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + AllRules.ruleset + + + + + + + + + + + + Disabled + $(ProjectDir)dns/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + + + Level3 + EditAndContinue + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + Disabled + $(ProjectDir)dns/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;NO_IPHLPAPI;LEAK_CHECK;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + $(ProjectDir)dns/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + $(ProjectDir)dns/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions) + MultiThreadedDLL + true + + + Level3 + ProgramDatabase + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/opensslx64/include;%(AdditionalIncludeDirectories) + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions) + MultiThreaded + true + + + Level3 + ProgramDatabase + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/opensslx64/include;%(AdditionalIncludeDirectories) + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + Disabled + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;LEAK_CHECK;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebugDLL + true + + + Level3 + EditAndContinue + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + Disabled + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../contrib/openssl/inc32;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;LEAK_CHECK;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + true + + + Level3 + EditAndContinue + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + Disabled + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/opensslx64/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;LEAK_CHECK;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebugDLL + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + Disabled + $(ProjectDir)dns/ares;$(ProjectDir)../;$(ProjectDir)../contrib/opensslx64/include;%(AdditionalIncludeDirectories) + WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;LEAK_CHECK;%(PreprocessorDefinitions) + EnableFastChecks + MultiThreadedDebug + true + + + Level3 + ProgramDatabase + + + $(OutDir)$(TargetName)$(TargetExt) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + true + true + true + + + + + + + + + + + + + + + true + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {ce7cf5e0-cad1-49d6-95d1-143ded7b226e} + + + + + + \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/rutil_7_1.vcproj b/src/libs/resiprocate/rutil/rutil_7_1.vcproj deleted file mode 100644 index 3d8808f9..00000000 --- a/src/libs/resiprocate/rutil/rutil_7_1.vcproj +++ /dev/null @@ -1,642 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/libs/resiprocate/rutil/rutil_8_0.vcproj b/src/libs/resiprocate/rutil/rutil_8_0.vcproj deleted file mode 100644 index 51cbca82..00000000 --- a/src/libs/resiprocate/rutil/rutil_8_0.vcproj +++ /dev/null @@ -1,909 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/libs/resiprocate/rutil/rutil_9_0.vcproj b/src/libs/resiprocate/rutil/rutil_9_0.vcproj deleted file mode 100644 index dd66b5dd..00000000 --- a/src/libs/resiprocate/rutil/rutil_9_0.vcproj +++ /dev/null @@ -1,918 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/libs/resiprocate/rutil/rutil_9_0.vcxproj b/src/libs/resiprocate/rutil/rutil_9_0.vcxproj deleted file mode 100644 index 45d5c9be..00000000 --- a/src/libs/resiprocate/rutil/rutil_9_0.vcxproj +++ /dev/null @@ -1,315 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - SSL-Debug - Win32 - - - SSL-Release - Win32 - - - - rutil - {3D0E5CEB-93DC-4FDB-918B-D08FA369E106} - rutil - Win32Proj - - - - StaticLibrary - v120 - MultiByte - - - StaticLibrary - v120 - MultiByte - - - StaticLibrary - v120 - MultiByte - - - StaticLibrary - v120 - MultiByte - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>12.0.21005.1 - - - $(SolutionDir)\output\$(Platform)\$(Configuration)\$(ProjectName)\ - $(SolutionDir)\intermediate\$(Platform)\$(Configuration)\$(ProjectName)\ - - - $(SolutionDir)\output\$(Platform)\$(Configuration)\$(ProjectName)\ - $(SolutionDir)\intermediate\$(Platform)\$(Configuration)\$(ProjectName)\ - - - $(Configuration)\ - $(Configuration)\ - - - $(Configuration)\ - $(Configuration)\ - - - - /MP %(AdditionalOptions) - Disabled - $(ProjectDir)dns/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;LEAK_CHECK;%(PreprocessorDefinitions) - false - EnableFastChecks - MultiThreadedDebugDLL - true - - Level3 - EditAndContinue - - - $(OutDir)rutil.lib - - - - - /MP %(AdditionalOptions) - $(ProjectDir)dns/ares;$(ProjectDir)../;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - Level3 - ProgramDatabase - - - $(OutDir)rutil.lib - - - - - /MP %(AdditionalOptions) - $(ProjectDir)../contrib/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../../openssl/include - WIN32;NDEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;%(PreprocessorDefinitions) - MultiThreadedDLL - true - - Level3 - ProgramDatabase - - - $(OutDir)rutil.lib - - - - - /MP %(AdditionalOptions) - Disabled - $(ProjectDir)../contrib/ares;$(ProjectDir)../;$(ProjectDir)../contrib/openssl/include;$(ProjectDir)../../openssl/include - WIN32;_DEBUG;_LIB;USE_ARES;USE_IPV6;USE_SSL;LEAK_CHECK;%(PreprocessorDefinitions) - false - EnableFastChecks - MultiThreadedDebugDLL - true - - Level3 - EditAndContinue - - - $(OutDir)rutil.lib - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - true - - - - - - - - - - - - - - - - - - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/rutil_9_0.vcxproj.filters b/src/libs/resiprocate/rutil/rutil_9_0.vcxproj.filters deleted file mode 100644 index edb73325..00000000 --- a/src/libs/resiprocate/rutil/rutil_9_0.vcxproj.filters +++ /dev/null @@ -1,462 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hpp;hxx;hm;inl;inc;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - - \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/rutil_9_0.vcxproj.user b/src/libs/resiprocate/rutil/rutil_9_0.vcxproj.user deleted file mode 100644 index abe8dd89..00000000 --- a/src/libs/resiprocate/rutil/rutil_9_0.vcxproj.user +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/src/libs/resiprocate/rutil/ssl/OpenSSLInit.cxx b/src/libs/resiprocate/rutil/ssl/OpenSSLInit.cxx index 5dd433f1..d42486f9 100644 --- a/src/libs/resiprocate/rutil/ssl/OpenSSLInit.cxx +++ b/src/libs/resiprocate/rutil/ssl/OpenSSLInit.cxx @@ -10,7 +10,10 @@ #include "rutil/ssl/OpenSSLInit.hxx" +#include +#if !defined(LIBRESSL_VERSION_NUMBER) #include +#endif #include #include #include @@ -19,6 +22,15 @@ #define OPENSSL_THREAD_DEFINES #include +#if defined(WIN32) && defined(_MSC_VER) && (_MSC_VER >= 1900) +// OpenSSL builds use an older version of visual studio that require the following definition +// Also will need to link with legacy_stdio_definitions.lib. It's possible that future build of +// SL's windows OpenSSL binaries will be built with VS2015 and will not require this, however it shouldn't +// hurt to be here. +// http://stackoverflow.com/questions/30412951/unresolved-external-symbol-imp-fprintf-and-imp-iob-func-sdl2 +extern "C" { FILE __iob_func[3] = { *stdin,*stdout,*stderr }; } +#endif + #define RESIPROCATE_SUBSYSTEM Subsystem::SIP using namespace resip; @@ -57,29 +69,42 @@ OpenSSLInit::OpenSSLInit() CRYPTO_set_dynlock_lock_callback(::resip_OpenSSLInit_dynLockFunction); #endif -#if 0 - CRYPTO_malloc_debug_init(); +#if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) + CRYPTO_malloc_debug_init(); CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); - CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); +#else + CRYPTO_set_mem_debug(1); #endif + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); + SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); - assert(EVP_des_ede3_cbc()); - mInitialized = true; + resip_assert(EVP_des_ede3_cbc()); + mInitialized = true; } OpenSSLInit::~OpenSSLInit() { - mInitialized = false; - ERR_free_strings();// Clean up data allocated during SSL_load_error_strings - ERR_remove_state(0);// free thread error queue - CRYPTO_cleanup_all_ex_data(); - EVP_cleanup();// Clean up data allocated during OpenSSL_add_all_algorithms + mInitialized = false; +#if OPENSSL_VERSION_NUMBER < 0x10000000L + ERR_remove_state(0);// free thread error queue +#elif OPENSSL_VERSION_NUMBER < 0x10100000L + ERR_remove_thread_state(NULL);// free thread error queue +#endif + EVP_cleanup();// Clean up data allocated during OpenSSL_add_all_algorithms + CRYPTO_cleanup_all_ex_data(); + ERR_free_strings();// Clean up data allocated during SSL_load_error_strings + + // Warning: Unable to free compression methods on OpenSSL < 1.0.2 + // For now we don't even try to free for older versions, see discussion in Debian bug #848652 + // https://bugs.debian.org/848652 + // No need to free for OpenSSL 1.1.0 and later, the library manages the memory by itself. +#if OPENSSL_VERSION_NUMBER >= 0x10002000L && OPENSSL_VERSION_NUMBER < 0x10100000L + SSL_COMP_free_compression_methods(); +#endif - //!dcm! We know we have a leak; see BaseSecurity::~BaseSecurity for - //!details. // CRYPTO_mem_leaks_fp(stderr); delete [] mMutexes; @@ -103,10 +128,10 @@ unsigned long resip_OpenSSLInit_threadIdFunction() { #if defined(WIN32) - assert(0); + resip_assert(0); #else #ifndef _POSIX_THREADS - assert(0); + resip_assert(0); #endif unsigned long ret; ret= (unsigned long)pthread_self(); diff --git a/src/libs/resiprocate/rutil/ssl/OpenSSLInit.hxx b/src/libs/resiprocate/rutil/ssl/OpenSSLInit.hxx index 235cfbd9..f9b0c23e 100644 --- a/src/libs/resiprocate/rutil/ssl/OpenSSLInit.hxx +++ b/src/libs/resiprocate/rutil/ssl/OpenSSLInit.hxx @@ -8,7 +8,7 @@ #include "rutil/Mutex.hxx" #include "rutil/RWMutex.hxx" #include "rutil/Data.hxx" -#include +#include "rutil/ResipAssert.h" #include // This will not be built or installed if USE_SSL is not defined; if you are diff --git a/src/libs/resiprocate/rutil/ssl/SHA1Stream.cxx b/src/libs/resiprocate/rutil/ssl/SHA1Stream.cxx index 09f7727d..b431d857 100644 --- a/src/libs/resiprocate/rutil/ssl/SHA1Stream.cxx +++ b/src/libs/resiprocate/rutil/ssl/SHA1Stream.cxx @@ -1,4 +1,4 @@ -#include +#include "rutil/ResipAssert.h" #if defined(HAVE_CONFIG_H) #include "config.h" @@ -59,7 +59,7 @@ SHA1Buffer::overflow(int c) Data SHA1Buffer::getHex() { - assert(mBlown == false); + resip_assert(mBlown == false); SHA1_Final((unsigned char*)&mBuf[0], mContext.get()); mBlown = true; Data digest(Data::Share, (const char*)&mBuf[0], mBuf.size()); @@ -69,9 +69,9 @@ SHA1Buffer::getHex() Data SHA1Buffer::getBin(unsigned int bits) { - assert(mBlown == false); - assert (bits % 8 == 0); - assert (bits / 8 <= mBuf.size()); + resip_assert(mBlown == false); + resip_assert (bits % 8 == 0); + resip_assert (bits / 8 <= mBuf.size()); SHA1_Final((unsigned char*)&mBuf[0], mContext.get()); mBlown = true; return Data(&mBuf[20-bits/8], bits / 8); diff --git a/src/libs/resiprocate/rutil/ssl/SHA1Stream.hxx b/src/libs/resiprocate/rutil/ssl/SHA1Stream.hxx index 37314d0e..efad6339 100644 --- a/src/libs/resiprocate/rutil/ssl/SHA1Stream.hxx +++ b/src/libs/resiprocate/rutil/ssl/SHA1Stream.hxx @@ -56,7 +56,7 @@ class SHA1Buffer : public std::streambuf // this adds overhead, two additional new/delete. // could get rid of the overhead if, sizeof(SHA_CTX) and SHA_DIGEST_LENGTH are known and FIXED. // could use pimpl to get rid of one new/delete pair. - std::unique_ptr mContext; + std::auto_ptr mContext; std::vector mBuf; bool mBlown; }; diff --git a/src/libs/resiprocate/rutil/stun/Stun.cxx b/src/libs/resiprocate/rutil/stun/Stun.cxx index 64dbd484..7b79dbed 100644 --- a/src/libs/resiprocate/rutil/stun/Stun.cxx +++ b/src/libs/resiprocate/rutil/stun/Stun.cxx @@ -2,7 +2,7 @@ #include "config.h" #endif -#include +#include "rutil/ResipAssert.h" #include #include #include @@ -628,7 +628,7 @@ encodeXorOnly(char* ptr) static char* encodeAtrString(char* ptr, UInt16 type, const StunAtrString& atr) { - assert(atr.sizeValue % 4 == 0); + resip_assert(atr.sizeValue % 4 == 0); ptr = encode16(ptr, type); ptr = encode16(ptr, atr.sizeValue); @@ -654,7 +654,7 @@ stunEncodeMessage( const StunMessage& msg, const StunAtrString& password, bool verbose) { - assert(bufLen >= sizeof(StunMsgHdr)); + resip_assert(bufLen >= sizeof(StunMsgHdr)); char* ptr = buf; if (verbose) clog << "Encoding stun message: " << endl; @@ -801,7 +801,7 @@ int stunRand() { // return 32 bits of random stuff - assert( sizeof(int) == 4 ); + resip_assert( sizeof(int) == 4 ); static bool init=false; if ( !init ) { @@ -810,7 +810,7 @@ stunRand() UInt64 tick; #if defined(WIN32) -#if !defined(UNDER_CE) && !defined(__GNUC__) && !defined(_WIN64) +#if !defined(UNDER_CE) && !defined(__GNUC__) && !defined(_WIN64) && !defined(_M_ARM) volatile unsigned int lowtick=0,hightick=0; __asm { @@ -826,7 +826,7 @@ stunRand() #endif #elif defined(__GNUC__) && ( defined(__i686__) || defined(__i386__) || defined(__x86_64__) ) asm("rdtsc" : "=A" (tick)); -#elif defined (__SUNPRO_CC) || defined( __sparc__ ) +#elif defined (__SUNPRO_CC) || (defined(__sun) && defined(__SVR4)) tick = gethrtime(); #elif defined(__APPLE__) || defined(__MACH__) int fd=open("/dev/random",O_RDONLY); @@ -848,7 +848,7 @@ stunRand() } #ifdef WIN32 - assert( RAND_MAX == 0x7fff ); + resip_assert( RAND_MAX == 0x7fff ); int r1 = rand(); int r2 = rand(); @@ -880,6 +880,7 @@ stunRandomPort() void computeHmac(char* hmac, const char* input, int length, const char* key, int sizeKey) { + // !slg! TODO - use newly added rutil/SHA1.hxx class - will need to add new method to it to support this strncpy(hmac,"hmac-not-implemented",20); } #else @@ -899,7 +900,7 @@ computeHmac(char* hmac, const char* input, int length, const char* key, int size key, sizeKey, reinterpret_cast(input), length, reinterpret_cast(hmac), &resultSize); - assert(resultSize == 20); + resip_assert(resultSize == 20); } #endif @@ -938,9 +939,9 @@ stunCreateUserName(const StunAddress4& source, StunAtrString* username) UInt32(source.addr), UInt32(stunRand()), UInt32(lotime)); - assert( strlen(buffer) < 1024 ); + resip_assert( strlen(buffer) < 1024 ); - assert(strlen(buffer) + 41 < STUN_MAX_STRING); + resip_assert(strlen(buffer) + 41 < STUN_MAX_STRING); char hmac[20]; char key[] = "Jason"; @@ -952,8 +953,8 @@ stunCreateUserName(const StunAddress4& source, StunAtrString* username) strcat(buffer,hmacHex); int l = (int)strlen(buffer); - assert( l+1 < STUN_MAX_STRING ); - assert( l%4 == 0 ); + resip_assert( l+1 < STUN_MAX_STRING ); + resip_assert( l%4 == 0 ); username->sizeValue = l; memcpy(username->value,buffer,l); @@ -1128,11 +1129,16 @@ stunParseHostName( char* peerName, struct hostent* h; #ifdef WIN32 - assert( strlen(host) >= 1 ); + resip_assert( strlen(host) >= 1 ); if ( isdigit( host[0] ) ) { // assume it is a ip address - unsigned long a = inet_addr(host); +#if defined(_MSC_VER) && _MSC_VER >= 1800 /* removing compilation warning in VS2013+ */ + unsigned long a = 0; + inet_pton(AF_INET, host, &a); +#else + unsigned long a = inet_addr(host); +#endif //cerr << "a=0x" << hex << a << dec << endl; ip = ntohl( a ); @@ -1146,7 +1152,7 @@ stunParseHostName( char* peerName, { int err = getErrno(); std::cerr << "error was " << err << std::endl; - assert( err != WSANOTINITIALISED ); + resip_assert( err != WSANOTINITIALISED ); ip = ntohl( 0x7F000001L ); @@ -1184,7 +1190,7 @@ stunParseHostName( char* peerName, bool stunParseServerName( char* name, StunAddress4& addr) { - assert(name); + resip_assert(name); // TODO - put in DNS SRV stuff. @@ -1326,7 +1332,7 @@ stunServerProcessMsg( char* buf, "1234", 4, reinterpret_cast(buf), bufLen-20-4, hmac, &hmacSize); - assert(hmacSize == 20); + resip_assert(hmacSize == 20); #endif if (memcmp(buf, hmac, 20) != 0) @@ -1338,7 +1344,7 @@ stunServerProcessMsg( char* buf, // need to compute this later after message is filled in resp->hasMessageIntegrity = true; - assert(req.hasUsername); + resip_assert(req.hasUsername); resp->hasUsername = true; resp->username = req.username; // copy username in } @@ -1416,8 +1422,8 @@ stunServerProcessMsg( char* buf, { // copy username in resp->hasUsername = true; - assert( req.username.sizeValue % 4 == 0 ); - assert( req.username.sizeValue < STUN_MAX_STRING ); + resip_assert( req.username.sizeValue % 4 == 0 ); + resip_assert( req.username.sizeValue < STUN_MAX_STRING ); memcpy( resp->username.value, req.username.value, req.username.sizeValue ); resp->username.sizeValue = req.username.sizeValue; } @@ -1427,9 +1433,9 @@ stunServerProcessMsg( char* buf, resp->hasServerName = true; const char serverName[] = "Vovida.org " STUN_VERSION; // must pad to mult of 4 - assert( sizeof(serverName) < STUN_MAX_STRING ); + resip_assert( sizeof(serverName) < STUN_MAX_STRING ); //cerr << "sizeof serverName is " << sizeof(serverName) << endl; - assert( sizeof(serverName)%4 == 0 ); + resip_assert( sizeof(serverName)%4 == 0 ); memcpy( resp->serverName.value, serverName, sizeof(serverName)); resp->serverName.sizeValue = sizeof(serverName); } @@ -1444,7 +1450,7 @@ stunServerProcessMsg( char* buf, if (req.hasUsername && (req.username.sizeValue > 64 ) ) { UInt32 source; - assert( sizeof(int) == sizeof(UInt32) ); + resip_assert( sizeof(int) == sizeof(UInt32) ); sscanf(req.username.value, "%x", &source); resp->hasReflectedFrom = true; @@ -1462,7 +1468,7 @@ stunServerProcessMsg( char* buf, return false; } - assert(0); + resip_assert(0); return false; } @@ -1470,9 +1476,9 @@ bool stunInitServer(StunServerInfo& info, const StunAddress4& myAddr, const StunAddress4& altAddr, int startMediaPort, bool verbose ) { - assert( myAddr.port != 0 ); - assert( altAddr.port!= 0 ); - assert( myAddr.addr != 0 ); + resip_assert( myAddr.port != 0 ); + resip_assert( altAddr.port!= 0 ); + resip_assert( myAddr.addr != 0 ); //assert( altAddr.addr != 0 ); info.myAddr = myAddr; @@ -1802,8 +1808,8 @@ stunServerProcess(StunServerInfo& info, bool verbose) if ( ok ) { - assert( dest.addr != 0 ); - assert( dest.port != 0 ); + resip_assert( dest.addr != 0 ); + resip_assert( dest.port != 0 ); resip::Socket sendFd; @@ -1917,14 +1923,14 @@ stunBuildReqSimple( StunMessage* msg, const StunAtrString& username, bool changePort, bool changeIp, unsigned int id ) { - assert( msg ); + resip_assert( msg ); memset( msg , 0 , sizeof(*msg) ); msg->msgHdr.msgType = BindRequestMsg; for ( int i=0; i<16; i=i+4 ) { - assert(i+3<16); + resip_assert(i+3<16); int r = stunRand(); msg->msgHdr.id.octet[i+0]= r>>0; msg->msgHdr.id.octet[i+1]= r>>8; @@ -1954,16 +1960,16 @@ stunSendTest( resip::Socket myFd, StunAddress4& dest, const StunAtrString& username, const StunAtrString& password, int testNum, bool verbose ) { - assert( dest.addr != 0 ); - assert( dest.port != 0 ); + resip_assert( dest.addr != 0 ); + resip_assert( dest.port != 0 ); bool changePort=false; bool changeIP=false; - bool discard=false; switch (testNum) { case 1: + case 5: case 10: case 11: break; @@ -1977,12 +1983,9 @@ stunSendTest( resip::Socket myFd, StunAddress4& dest, case 4: changeIP=true; break; - case 5: - discard=true; - break; default: cerr << "Test " << testNum <<" is unknown\n"; - assert(0); + resip_assert(0); } StunMessage req; @@ -2022,8 +2025,8 @@ stunGetUserNameAndPassword( const StunAddress4& dest, bool stunTest( StunAddress4& dest, int testNum, bool verbose, StunAddress4* sAddr, unsigned long timeoutMs ) { - assert( dest.addr != 0 ); - assert( dest.port != 0 ); + resip_assert( dest.addr != 0 ); + resip_assert( dest.port != 0 ); int port = stunRandomPort(); UInt32 interfaceIp=0; @@ -2115,8 +2118,8 @@ stunNatType( StunAddress4& dest, StunAddress4* sAddr // NIC to use ) { - assert( dest.addr != 0 ); - assert( dest.port != 0 ); + resip_assert( dest.addr != 0 ); + resip_assert( dest.port != 0 ); if ( hairpin ) { @@ -2141,12 +2144,11 @@ stunNatType( StunAddress4& dest, return StunTypeFailure; } - assert( myFd1 != INVALID_SOCKET ); - assert( myFd2 != INVALID_SOCKET ); + resip_assert( myFd1 != INVALID_SOCKET ); + resip_assert( myFd2 != INVALID_SOCKET ); bool respTestI=false; bool isNat=true; - StunAddress4 testIchangedAddr; StunAddress4 testImappedAddr; bool respTestI2=false; bool mappedIpSame = true; @@ -2238,7 +2240,7 @@ stunNatType( StunAddress4& dest, else { //if (verbose) clog << "-----------------------------------------" << endl; - assert( err>0 ); + resip_assert( err>0 ); // data is avialbe on some fd for ( int i=0; i<2; i++) @@ -2286,8 +2288,6 @@ stunNatType( StunAddress4& dest, if ( !respTestI ) { - testIchangedAddr.addr = resp.changedAddress.ipv4.addr; - testIchangedAddr.port = resp.changedAddress.ipv4.port; testImappedAddr.addr = resp.mappedAddress.ipv4.addr; testImappedAddr.port = resp.mappedAddress.ipv4.port; @@ -2486,9 +2486,9 @@ stunOpenSocket( StunAddress4& dest, StunAddress4* mapAddr, int port, StunAddress4* srcAddr, bool verbose ) { - assert( dest.addr != 0 ); - assert( dest.port != 0 ); - assert( mapAddr ); + resip_assert( dest.addr != 0 ); + resip_assert( dest.port != 0 ); + resip_assert( mapAddr ); if ( port == 0 ) { @@ -2535,7 +2535,6 @@ stunOpenSocket( StunAddress4& dest, StunAddress4* mapAddr, } StunAddress4 mappedAddr = resp.mappedAddress.ipv4; - StunAddress4 changedAddr = resp.changedAddress.ipv4; //clog << "--- stunOpenSocket --- " << endl; //clog << "\treq id=" << req.id << endl; @@ -2554,9 +2553,9 @@ stunOpenSocketPair( StunAddress4& dest, StunAddress4* mapAddr, int port, StunAddress4* srcAddr, bool verbose ) { - assert( dest.addr!= 0 ); - assert( dest.port != 0 ); - assert( mapAddr ); + resip_assert( dest.addr!= 0 ); + resip_assert( dest.port != 0 ); + resip_assert( mapAddr ); const int NUM=3; @@ -2630,7 +2629,6 @@ stunOpenSocketPair( StunAddress4& dest, StunAddress4* mapAddr, } mappedAddr[i] = resp.mappedAddress.ipv4; - StunAddress4 changedAddr = resp.changedAddress.ipv4; } if (verbose) diff --git a/src/libs/resiprocate/rutil/stun/Udp.cxx b/src/libs/resiprocate/rutil/stun/Udp.cxx index e1356e0a..7976bf5b 100644 --- a/src/libs/resiprocate/rutil/stun/Udp.cxx +++ b/src/libs/resiprocate/rutil/stun/Udp.cxx @@ -1,4 +1,4 @@ -#include +#include "rutil/ResipAssert.h" #include #include #include @@ -108,7 +108,7 @@ openPort( unsigned short port, unsigned int interfaceIp, bool verbose ) clog << "Opened port " << port << " with fd " << fd << endl; } - assert( fd != INVALID_SOCKET ); + resip_assert( fd != INVALID_SOCKET ); return fd; } @@ -119,10 +119,10 @@ getMessage( resip::Socket fd, char* buf, int* len, UInt32* srcIp, unsigned short* srcPort, bool verbose) { - assert( fd != INVALID_SOCKET ); + resip_assert( fd != INVALID_SOCKET ); int originalSize = *len; - assert( originalSize > 0 ); + resip_assert( originalSize > 0 ); struct sockaddr_in from; int fromLen = sizeof(from); @@ -188,20 +188,20 @@ sendMessage( resip::Socket fd, char* buf, int l, unsigned int dstIp, unsigned short dstPort, bool verbose) { - assert( fd != INVALID_SOCKET ); + resip_assert( fd != INVALID_SOCKET ); int s; if ( dstPort == 0 ) { // sending on a connected port - assert( dstIp == 0 ); + resip_assert( dstIp == 0 ); s = send(fd,buf,l,0); } else { - assert( dstIp != 0 ); - assert( dstPort != 0 ); + resip_assert( dstIp != 0 ); + resip_assert( dstPort != 0 ); struct sockaddr_in to; int toLen = sizeof(to); diff --git a/src/libs/resiprocate/rutil/stun/Udp.hxx b/src/libs/resiprocate/rutil/stun/Udp.hxx index 5ef6efa7..635f3e65 100644 --- a/src/libs/resiprocate/rutil/stun/Udp.hxx +++ b/src/libs/resiprocate/rutil/stun/Udp.hxx @@ -9,7 +9,10 @@ typedef int socklen_t; # endif # else - typedef int socklen_t; +// GNU HURD also defines __MACH__ but does not require this typedef +# ifndef __GNU__ + typedef int socklen_t; +# endif # endif #endif diff --git a/src/libs/resiprocate/rutil/vmd5.cxx b/src/libs/resiprocate/rutil/vmd5.cxx index b95de654..30984765 100644 --- a/src/libs/resiprocate/rutil/vmd5.cxx +++ b/src/libs/resiprocate/rutil/vmd5.cxx @@ -31,7 +31,7 @@ /* Add _BIG_ENDIAN for Solaris */ /* Add _BIG_ENDIAN__ for MAC OSX */ -#if defined(WORDS_BIGENDIAN) || defined(_BIG_ENDIAN) || defined( __BIG_ENDIAN__ ) +#if defined(WORDS_BIGENDIAN) || defined(_BIG_ENDIAN) || defined( __BIG_ENDIAN__ ) || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) || defined(RESIP_BIG_ENDIAN) void resip::byteSwap(u_int32_t *buf, unsigned words) { @@ -167,7 +167,7 @@ resip::MD5Final(md5byte digest[16], struct MD5Context *ctx) void resip::MD5Transform(u_int32_t buf[4], u_int32_t const in[16]) { - register u_int32_t a, b, c, d; + u_int32_t a, b, c, d; a = buf[0]; b = buf[1];