46da64277986f6c37a1b9d891e99368838a63736
[shibboleth/cpp-sp.git] / shibsp / remoting / impl / ListenerService.cpp
1 /**
2  * Licensed to the University Corporation for Advanced Internet
3  * Development, Inc. (UCAID) under one or more contributor license
4  * agreements. See the NOTICE file distributed with this work for
5  * additional information regarding copyright ownership.
6  *
7  * UCAID licenses this file to you under the Apache License,
8  * Version 2.0 (the "License"); you may not use this file except
9  * in compliance with the License. You may obtain a copy of the
10  * License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing,
15  * software distributed under the License is distributed on an
16  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
17  * either express or implied. See the License for the specific
18  * language governing permissions and limitations under the License.
19  */
20
21 /**
22  * ListenerService.cpp
23  *
24  * Interprocess remoting engine.
25  */
26
27 #include "internal.h"
28 #include "exceptions.h"
29 #include "ServiceProvider.h"
30 #include "remoting/ListenerService.h"
31
32 #include <xercesc/dom/DOM.hpp>
33
34 using namespace shibsp;
35 using namespace xmltooling;
36 using namespace xercesc;
37 using namespace std;
38
39 namespace shibsp {
40     SHIBSP_DLLLOCAL PluginManager<ListenerService,string,const DOMElement*>::Factory TCPListenerServiceFactory;
41 #ifndef WIN32
42     SHIBSP_DLLLOCAL PluginManager<ListenerService,string,const DOMElement*>::Factory UnixListenerServiceFactory;
43 #endif
44 };
45
46 void SHIBSP_API shibsp::registerListenerServices()
47 {
48     SPConfig& conf=SPConfig::getConfig();
49     conf.ListenerServiceManager.registerFactory(TCP_LISTENER_SERVICE, TCPListenerServiceFactory);
50 #ifndef WIN32
51     conf.ListenerServiceManager.registerFactory(UNIX_LISTENER_SERVICE, UnixListenerServiceFactory);
52 #endif
53 }
54
55 Remoted::Remoted()
56 {
57 }
58
59 Remoted::~Remoted()
60 {
61 }
62
63 ListenerService::ListenerService()
64 {
65 }
66
67 ListenerService::~ListenerService()
68 {
69 }
70
71 Remoted* ListenerService::regListener(const char* address, Remoted* listener)
72 {
73     Remoted* ret=nullptr;
74     map<string,Remoted*>::const_iterator i=m_listenerMap.find(address);
75     if (i!=m_listenerMap.end())
76         ret=i->second;
77     m_listenerMap[address]=listener;
78     Category::getInstance(SHIBSP_LOGCAT".Listener").info("registered remoted message endpoint (%s)",address);
79     return ret;
80 }
81
82 bool ListenerService::unregListener(const char* address, Remoted* current, Remoted* restore)
83 {
84     map<string,Remoted*>::const_iterator i=m_listenerMap.find(address);
85     if (i!=m_listenerMap.end() && i->second==current) {
86         if (restore)
87             m_listenerMap[address]=restore;
88         else
89             m_listenerMap.erase(address);
90         Category::getInstance(SHIBSP_LOGCAT".Listener").info("unregistered remoted message endpoint (%s)",address);
91         return true;
92     }
93     return false;
94 }
95
96 Remoted* ListenerService::lookup(const char *address) const
97 {
98     map<string,Remoted*>::const_iterator i=m_listenerMap.find(address);
99     return (i==m_listenerMap.end()) ? nullptr : i->second;
100 }
101
102 void ListenerService::receive(DDF &in, ostream& out)
103 {
104     if (!in.name())
105         throw ListenerException("Incoming message with no destination address rejected.");
106     else if (!strcmp("ping",in.name())) {
107         DDF outmsg=DDF(nullptr).integer(in.integer() + 1);
108         DDFJanitor jan(outmsg);
109         out << outmsg;
110     }
111
112     // Two stage lookup, on the listener itself, and the SP interface.
113     ServiceProvider* sp = SPConfig::getConfig().getServiceProvider();
114     Locker locker(sp);
115     Remoted* dest = lookup(in.name());
116     if (!dest) {
117         dest = sp->lookupListener(in.name());
118         if (!dest)
119             throw ListenerException("No destination registered for incoming message addressed to ($1).", params(1,in.name()));
120     }
121
122     dest->receive(in, out);
123 }
124
125 bool ListenerService::init(bool force)
126 {
127     return true;
128 }
129
130 void ListenerService::term()
131 {
132 }