#include <shib/shib-threads.h>
#include <log4cpp/Category.hh>
-#ifdef USE_OUR_ONCRPC
-# define svc_fdset onc_svc_fdset
-#else
+// Deal with inadequate Sun RPC libraries
+
+#if !HAVE_DECL_SVCFD_CREATE
extern "C" SVCXPRT* svcfd_create(int, u_int, u_int);
#endif
+#ifndef HAVE_WORKING_SVC_DESTROY
+struct tcp_conn { /* kept in xprt->xp_p1 */
+ enum xprt_stat strm_stat;
+ u_long x_id;
+ XDR xdrs;
+ char verf_body[MAX_AUTH_BYTES];
+};
+#endif
+
using namespace std;
using namespace saml;
using namespace shibboleth;
using namespace log4cpp;
namespace {
- map<Thread*,int> children;
+ map<IListener::ShibSocket,Thread*> children;
Mutex* child_lock = NULL;
CondWait* child_wait = NULL;
bool running;
return NULL;
}
-SharChild::SharChild(IListener::ShibSocket& s, const Iterator<ShibRPCProtocols>& protos) : sock(s), lock(NULL), child(NULL)
+SharChild::SharChild(IListener::ShibSocket& s, const Iterator<ShibRPCProtocols>& protos) : sock(s), child(NULL)
{
protos.reset();
while (protos.hasNext())
v_protos.push_back(protos.next());
- // Create the lock and then lock this child
- lock = Mutex::create();
- Lock tl(lock);
-
// Create the child thread
child = Thread::create(shar_client_thread, (void*)this);
child->detach();
-
- // Lock the children map and add this child
- Lock cl(child_lock);
- children[child] = 1;
}
SharChild::~SharChild()
{
- // Lock this object
- lock->lock();
-
- // Then lock the children map, remove this thread, signal waiters, and return
+ // Then lock the children map, remove this socket/thread, signal waiters, and return
child_lock->lock();
- children.erase(child);
+ children.erase(sock);
child_lock->unlock();
child_wait->signal();
- lock->unlock();
- delete lock;
delete child;
}
void SharChild::run()
{
- if (SHARUtils::shar_create_svc(sock, v_protos) != 0)
+ // Before starting up, make sure we fully "own" this socket.
+ child_lock->lock();
+ while (children.find(sock)!=children.end())
+ child_wait->wait(child_lock);
+ children[sock] = child;
+ child_lock->unlock();
+
+ if (!svc_create())
return;
fd_set readfds;
FD_SET(sock, &readfds);
tv.tv_sec = 1;
- switch (select (sock+1, &readfds, 0, 0, &tv)) {
-
+ switch (select(sock+1, &readfds, 0, 0, &tv)) {
+#ifdef WIN32
+ case SOCKET_ERROR:
+#else
case -1:
+#endif
if (errno == EINTR) continue;
SHARUtils::log_error();
+ Category::getInstance("SHAR.SharChild").error("select() on incoming request socket (%u) returned error",sock);
return;
case 0:
break;
default:
- svc_getreqset (&readfds);
+ svc_getreqset(&readfds);
}
}
+}
+
+bool SharChild::svc_create()
+{
+ /* Wrap an RPC Service around the new connection socket. */
+ SVCXPRT* transp = svcfd_create(sock, 0, 0);
+ if (!transp) {
+ NDC ndc("svc_create");
+ Category::getInstance("SHAR.SharChild").error("cannot create RPC listener");
+ return false;
+ }
- if (running) {
- ShibTargetConfig::getConfig().getINI()->getListener()->close(sock);
+ /* Register the SHIBRPC RPC Program */
+ Iterator<ShibRPCProtocols> i(v_protos);
+ while (i.hasNext()) {
+ const ShibRPCProtocols& p=i.next();
+ if (!svc_register (transp, p.prog, p.vers, p.dispatch, 0)) {
+#ifdef HAVE_WORKING_SVC_DESTROY
+ svc_destroy(transp);
+#else
+ /* we have to inline svc_destroy because we can't pass in the xprt variable */
+ struct tcp_conn *cd = (struct tcp_conn *)transp->xp_p1;
+ xprt_unregister(transp);
+ close(transp->xp_sock);
+ if (transp->xp_port != 0) {
+ /* a rendezvouser socket */
+ transp->xp_port = 0;
+ } else {
+ /* an actual connection socket */
+ XDR_DESTROY(&(cd->xdrs));
+ }
+ mem_free((caddr_t)cd, sizeof(struct tcp_conn));
+ mem_free((caddr_t)transp, sizeof(SVCXPRT));
+#endif
+ NDC ndc("svc_create");
+ Category::getInstance("SHAR.SharChild").error("cannot register RPC program");
+ return false;
+ }
}
+ return true;
}
void SHARUtils::log_error()
#endif
}
-int SHARUtils::shar_create_svc(IListener::ShibSocket& sock, const Iterator<ShibRPCProtocols>& protos)
-{
- NDC ndc("shar_create_svc");
-
- /* Wrap an RPC Service around the new connection socket */
- SVCXPRT* svc = svcfd_create (sock, 0, 0);
- if (!svc) {
- Category::getInstance("SHAR.SHARUtils").error("cannot create RPC listener");
- return -1;
- }
-
- /* Register the SHIBRPC RPC Program */
- while (protos.hasNext()) {
- const ShibRPCProtocols& p=protos.next();
- if (!svc_register (svc, p.prog, p.vers, p.dispatch, 0)) {
- svc_destroy(svc);
- ShibTargetConfig::getConfig().getINI()->getListener()->close(sock);
- Category::getInstance("SHAR.SHARUtils").error("cannot register RPC program");
- return -2;
- }
- }
- return 0;
-}
-
void SHARUtils::init()
{
child_lock = Mutex::create();
delete child_lock;
child_lock = NULL;
}
-
--- /dev/null
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifndef _MAC
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,2,1,0
+ PRODUCTVERSION 1,2,1,0
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "\0"
+ VALUE "CompanyName", "UCAID\0"
+ VALUE "FileDescription", "Shibboleth Attribute Requester Service\0"
+ VALUE "FileVersion", "1, 2, 1, 0\0"
+ VALUE "InternalName", "shar\0"
+ VALUE "LegalCopyright", "Copyright © 2004 UCAID\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "shar.exe\0"
+ VALUE "PrivateBuild", "\0"
+ VALUE "ProductName", "Shibboleth 1.2.1\0"
+ VALUE "ProductVersion", "1, 2, 1, 0\0"
+ VALUE "SpecialBuild", "\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // !_MAC
+
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+