Logo ROOT  
Reference Guide
TServerSocket.cxx
Go to the documentation of this file.
1// @(#)root/net:$Id$
2// Author: Fons Rademakers 18/12/96
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12//////////////////////////////////////////////////////////////////////////
13// //
14// TServerSocket //
15// //
16// This class implements server sockets. A server socket waits for //
17// requests to come in over the network. It performs some operation //
18// based on that request and then possibly returns a full duplex socket //
19// to the requester. The actual work is done via the TSystem class //
20// (either TUnixSystem or TWinNTSystem). //
21// //
22//////////////////////////////////////////////////////////////////////////
23
24#include "TServerSocket.h"
25#include "TSocket.h"
26#include "TSystem.h"
27#include "TROOT.h"
28#include "TError.h"
29#include <string>
30#include "TVirtualMutex.h"
31
32// Hook to server authentication wrapper
35
36// Defaul options for accept
38
40
42
43////////////////////////////////////////////////////////////////////////////////
44/// Kind of macro to parse input options
45/// Modify opt according to modifier mod.
46
47static void SetAuthOpt(UChar_t &opt, UChar_t mod)
48{
50
51 if (!mod) return;
52
53 if ((mod & kSrvAuth)) opt |= kSrvAuth;
54 if ((mod & kSrvNoAuth)) opt &= ~kSrvAuth;
55}
56
57////////////////////////////////////////////////////////////////////////////////
58/// Create a server socket object for a named service. Set reuse to true
59/// to force reuse of the server socket (i.e. do not wait for the time
60/// out to pass). Using backlog one can set the desirable queue length
61/// for pending connections.
62/// Use tcpwindowsize to specify the size of the receive buffer, it has
63/// to be specified here to make sure the window scale option is set (for
64/// tcpwindowsize > 65KB and for platforms supporting window scaling).
65/// Use IsValid() to check the validity of the
66/// server socket. In case server socket is not valid use GetErrorCode()
67/// to obtain the specific error value. These values are:
68/// 0 = no error (socket is valid)
69/// -1 = low level socket() call failed
70/// -2 = low level bind() call failed
71/// -3 = low level listen() call failed
72/// Every valid server socket is added to the TROOT sockets list which
73/// will make sure that any open sockets are properly closed on
74/// program termination.
75
76TServerSocket::TServerSocket(const char *service, Bool_t reuse, Int_t backlog,
77 Int_t tcpwindowsize)
78{
81
82 SetName("ServerSocket");
83
84 fSecContext = 0;
85 fSecContexts = new TList;
86
87 // If this is a local path, try announcing a UNIX socket service
89 if (service && (!gSystem->AccessPathName(service) ||
90#ifndef WIN32
91 service[0] == '/')) {
92#else
93 service[0] == '/' || (service[1] == ':' && service[2] == '/'))) {
94#endif
96 fService = "unix:";
97 fService += service;
98 fSocket = gSystem->AnnounceUnixService(service, backlog);
99 if (fSocket >= 0) {
101 gROOT->GetListOfSockets()->Add(this);
102 }
103 } else {
104 // TCP / UDP socket
105 fService = service;
106 int port = gSystem->GetServiceByName(service);
107 if (port != -1) {
108 fSocket = gSystem->AnnounceTcpService(port, reuse, backlog, tcpwindowsize);
109 if (fSocket >= 0) {
111 gROOT->GetListOfSockets()->Add(this);
112 }
113 } else {
114 fSocket = -1;
115 }
116 }
117}
118
119////////////////////////////////////////////////////////////////////////////////
120/// Create a server socket object on a specified port. Set reuse to true
121/// to force reuse of the server socket (i.e. do not wait for the time
122/// out to pass). Using backlog one can set the desirable queue length
123/// for pending connections. If port is 0 a port scan will be done to
124/// find a free port. This option is mutual exlusive with the reuse option.
125/// Use tcpwindowsize to specify the size of the receive buffer, it has
126/// to be specified here to make sure the window scale option is set (for
127/// tcpwindowsize > 65KB and for platforms supporting window scaling).
128/// Use IsValid() to check the validity of the
129/// server socket. In case server socket is not valid use GetErrorCode()
130/// to obtain the specific error value. These values are:
131/// 0 = no error (socket is valid)
132/// -1 = low level socket() call failed
133/// -2 = low level bind() call failed
134/// -3 = low level listen() call failed
135/// Every valid server socket is added to the TROOT sockets list which
136/// will make sure that any open sockets are properly closed on
137/// program termination.
138
140 Int_t tcpwindowsize)
141{
144
145 SetName("ServerSocket");
146
147 fSecContext = 0;
148 fSecContexts = new TList;
151
152 fSocket = gSystem->AnnounceTcpService(port, reuse, backlog, tcpwindowsize);
153 if (fSocket >= 0) {
155 gROOT->GetListOfSockets()->Add(this);
156 }
157}
158
159////////////////////////////////////////////////////////////////////////////////
160/// Destructor: cleanup authentication stuff (if any) and close
161
163{
165 if (fSecContexts) {
166 if (fgSrvAuthClupHook) {
167 // Cleanup the security contexts
168 (*fgSrvAuthClupHook)(fSecContexts);
169 }
170 // Remove the list
173 fSecContexts = 0;
174 }
175
176 Close();
177}
178
179////////////////////////////////////////////////////////////////////////////////
180/// Accept a connection on a server socket. Returns a full-duplex
181/// communication TSocket object. If no pending connections are
182/// present on the queue and nonblocking mode has not been enabled
183/// with SetOption(kNoBlock,1) the call blocks until a connection is
184/// present. The returned socket must be deleted by the user. The socket
185/// is also added to the TROOT sockets list which will make sure that
186/// any open sockets are properly closed on program termination.
187/// In case of error 0 is returned and in case non-blocking I/O is
188/// enabled and no connections are available -1 is returned.
189///
190/// The opt can be used to require client authentication; valid options are
191///
192/// kSrvAuth = require client authentication
193/// kSrvNoAuth = force no client authentication
194///
195/// Example: use Opt = kSrvAuth to require client authentication.
196///
197/// Default options are taken from fgAcceptOpt and are initially
198/// equivalent to kSrvNoAuth; they can be changed with the static
199/// method TServerSocket::SetAcceptOptions(Opt).
200/// The active defaults can be visualized using the static method
201/// TServerSocket::ShowAcceptOptions().
202///
203
205{
206 if (fSocket == -1) { return 0; }
207
208 TSocket *socket = new TSocket;
209
211 if (soc == -1) { delete socket; return 0; }
212 if (soc == -2) { delete socket; return (TSocket*) -1; }
213
214 // Parse Opt
215 UChar_t acceptOpt = fgAcceptOpt;
216 SetAuthOpt(acceptOpt, opt);
217 Bool_t auth = (Bool_t)(acceptOpt & kSrvAuth);
218
219 socket->fSocket = soc;
220 socket->fSecContext = 0;
221 socket->fService = fService;
223 socket->fAddress = gSystem->GetPeerName(socket->fSocket);
224 if (socket->fSocket >= 0) {
226 gROOT->GetListOfSockets()->Add(socket);
227 }
228
229 // Perform authentication, if required
230 if (auth) {
231 if (!Authenticate(socket)) {
232 delete socket;
233 socket = 0;
234 }
235 }
236
237 return socket;
238}
239
240////////////////////////////////////////////////////////////////////////////////
241/// Return internet address of host to which the server socket is bound,
242/// i.e. the local host. In case of error TInetAddress::IsValid() returns
243/// kFALSE.
244
246{
247 if (fSocket != -1) {
248 if (fAddress.GetPort() == -1)
250 return fAddress;
251 }
252 return TInetAddress();
253}
254
255////////////////////////////////////////////////////////////////////////////////
256/// Get port # to which server socket is bound. In case of error returns -1.
257
259{
260 if (fSocket != -1) {
261 if (fAddress.GetPort() == -1)
263 return fAddress.GetPort();
264 }
265 return -1;
266}
267
268
269////////////////////////////////////////////////////////////////////////////////
270/// Return default options for Accept
271
273{
274 return fgAcceptOpt;
275}
276
277////////////////////////////////////////////////////////////////////////////////
278/// Set default options for Accept according to modifier 'mod'.
279/// Use:
280/// kSrvAuth require client authentication
281/// kSrvNoAuth do not require client authentication
282
284{
286}
287
288////////////////////////////////////////////////////////////////////////////////
289/// Print default options for Accept.
290
292{
293 ::Info("ShowAcceptOptions", "Use authentication: %s", (fgAcceptOpt & kSrvAuth) ? "yes" : "no");
294}
295
296////////////////////////////////////////////////////////////////////////////////
297/// Check authentication request from the client on new
298/// open connection
299
301{
302 if (!fgSrvAuthHook) {
304
305 // Load libraries needed for (server) authentication ...
306 TString srvlib = "libSrvAuth";
307 char *p = 0;
308 // The generic one
309 if ((p = gSystem->DynamicPathName(srvlib, kTRUE))) {
310 delete[] p;
311 if (gSystem->Load(srvlib) == -1) {
312 Error("Authenticate", "can't load %s",srvlib.Data());
313 return kFALSE;
314 }
315 } else {
316 Error("Authenticate", "can't locate %s",srvlib.Data());
317 return kFALSE;
318 }
319 //
320 // Locate SrvAuthenticate
321 Func_t f = gSystem->DynFindSymbol(srvlib,"SrvAuthenticate");
322 if (f)
324 else {
325 Error("Authenticate", "can't find SrvAuthenticate");
326 return kFALSE;
327 }
328 //
329 // Locate SrvAuthCleanup
330 f = gSystem->DynFindSymbol(srvlib,"SrvAuthCleanup");
331 if (f)
333 else {
334 Warning("Authenticate", "can't find SrvAuthCleanup");
335 }
336 }
337
338 TString confdir = TROOT::GetRootSys();
339 if (!confdir.Length()) {
340 Error("Authenticate", "config dir undefined");
341 return kFALSE;
342 }
343
344 // dir for temporary files
347 tmpdir = TString("/tmp");
348
349 // Get Host name
350 TString openhost(sock->GetInetAddress().GetHostName());
351 if (gDebug > 2)
352 Info("Authenticate","OpenHost = %s", openhost.Data());
353
354 // Run Authentication now
355 std::string user;
356 Int_t meth = -1;
357 Int_t auth = 0;
358 Int_t type = 0;
359 std::string ctkn = "";
360 if (fgSrvAuthHook)
361 auth = (*fgSrvAuthHook)(sock, confdir, tmpdir, user,
362 meth, type, ctkn, fSecContexts);
363
364 if (gDebug > 2)
365 Info("Authenticate","auth = %d, type= %d, ctkn= %s",
366 auth, type, ctkn.c_str());
367
368 return auth;
369}
#define SafeDelete(p)
Definition: RConfig.hxx:550
#define f(i)
Definition: RSha256.hxx:104
int Int_t
Definition: RtypesCore.h:41
unsigned char UChar_t
Definition: RtypesCore.h:34
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:365
R__EXTERN Int_t gDebug
Definition: Rtypes.h:91
#define R__ASSERT(e)
Definition: TError.h:96
int type
Definition: TGX11.cxx:120
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:59
#define gROOT
Definition: TROOT.h:415
static void SetAuthOpt(UChar_t &opt, UChar_t mod)
Kind of macro to parse input options Modify opt according to modifier mod.
TVirtualMutex * gSrvAuthenticateMutex
Int_t(* SrvClup_t)(TSeqCollection *)
Definition: TServerSocket.h:36
const UChar_t kSrvNoAuth
Definition: TServerSocket.h:40
const UChar_t kSrvAuth
Definition: TServerSocket.h:39
Int_t(* SrvAuth_t)(TSocket *sock, const char *, const char *, std::string &, Int_t &, Int_t &, std::string &, TSeqCollection *)
Definition: TServerSocket.h:33
@ kWritePermission
Definition: TSystem.h:47
R__EXTERN TSystem * gSystem
Definition: TSystem.h:560
#define R__LOCKGUARD2(mutex)
#define R__LOCKGUARD(mutex)
virtual void Delete(Option_t *option="")=0
Delete this object.
This class represents an Internet Protocol (IP) address.
Definition: TInetAddress.h:36
Int_t GetPort() const
Definition: TInetAddress.h:73
const char * GetHostName() const
Definition: TInetAddress.h:71
A doubly linked list.
Definition: TList.h:44
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:172
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
void ResetBit(UInt_t f)
Definition: TObject.h:171
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
static const TString & GetRootSys()
Get the rootsys directory in the installation. Static utility function.
Definition: TROOT.cxx:2925
static SrvAuth_t fgSrvAuthHook
Definition: TServerSocket.h:46
virtual Int_t GetLocalPort()
Get port # to which server socket is bound. In case of error returns -1.
static UChar_t fgAcceptOpt
Definition: TServerSocket.h:48
static void SetAcceptOptions(UChar_t Opt)
Set default options for Accept according to modifier 'mod'.
Bool_t Authenticate(TSocket *)
Check authentication request from the client on new open connection.
static SrvClup_t fgSrvAuthClupHook
Definition: TServerSocket.h:47
virtual ~TServerSocket()
Destructor: cleanup authentication stuff (if any) and close.
static void ShowAcceptOptions()
Print default options for Accept.
static UChar_t GetAcceptOptions()
Return default options for Accept.
virtual TSocket * Accept(UChar_t Opt=0)
Accept a connection on a server socket.
virtual TInetAddress GetLocalInetAddress()
Return internet address of host to which the server socket is bound, i.e.
TSeqCollection * fSecContexts
Definition: TServerSocket.h:45
TInetAddress fAddress
Definition: TSocket.h:59
Int_t fSocket
Definition: TSocket.h:69
TSocket()
Definition: TSocket.h:83
TString fService
Definition: TSocket.h:67
@ kIsUnix
Definition: TSocket.h:48
virtual void Close(Option_t *opt="")
Close the socket.
Definition: TSocket.cxx:388
TInetAddress GetInetAddress() const
Definition: TSocket.h:113
TSecContext * fSecContext
Definition: TSocket.h:65
Basic string class.
Definition: TString.h:131
Ssiz_t Length() const
Definition: TString.h:405
const char * Data() const
Definition: TString.h:364
virtual int GetServiceByName(const char *service)
Get port # of internet service.
Definition: TSystem.cxx:2363
virtual TInetAddress GetSockName(int sock)
Get Internet Protocol (IP) address of host and port #.
Definition: TSystem.cxx:2354
virtual Func_t DynFindSymbol(const char *module, const char *entry)
Find specific entry point in specified library.
Definition: TSystem.cxx:2046
virtual char * GetServiceByPort(int port)
Get name of internet service.
Definition: TSystem.cxx:2372
virtual int AcceptConnection(int sock)
Accept a connection.
Definition: TSystem.cxx:2426
virtual TInetAddress GetPeerName(int sock)
Get Internet Protocol (IP) address of remote host and port #.
Definition: TSystem.cxx:2345
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition: TSystem.cxx:1845
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition: TSystem.cxx:1287
virtual int AnnounceTcpService(int port, Bool_t reuse, int backlog, int tcpwindowsize=-1)
Announce TCP/IP service.
Definition: TSystem.cxx:2390
virtual int AnnounceUnixService(int port, int backlog)
Announce unix domain service.
Definition: TSystem.cxx:2408
virtual const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
Definition: TSystem.cxx:1473
char * DynamicPathName(const char *lib, Bool_t quiet=kFALSE)
Find a dynamic library called lib using the system search paths.
Definition: TSystem.cxx:2022
This class implements a mutex interface.
Definition: TVirtualMutex.h:34