1 : //=============================================================================
2 : // File <$/src/cpp/prod/CORBA/YASingleServerOrb.cpp>
3 : // This file is part of YaOrb : Yet Another Object Request Broker,
4 : // Copyright (c) 2000-2003, Marc Alff.
5 : //
6 : // This program is free software; you can redistribute it and/or
7 : // modify it under the terms of the GNU General Public License
8 : // as published by the Free Software Foundation; either version 2
9 : // of the License, or (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License
17 : // along with this program; if not, write to the Free Software
18 : // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 : //
20 : //=============================================================================
21 :
22 : // Portability
23 : #include "yaorb/config.h"
24 : #include "src/cpp/prod/port/port_time.h"
25 : #include "src/cpp/prod/port/port_stdc.h"
26 : #include "src/cpp/prod/port/port_socket.h"
27 : #include "src/cpp/prod/port/port_unistd.h"
28 :
29 : #include <sys/types.h>
30 : #include <sys/select.h>
31 : #include <rpc/types.h>
32 : #include <stdio.h>
33 :
34 : #include <yaorb/CORBA.h>
35 : #include <yaorb/YAORB.h>
36 :
37 : #include "src/cpp/prod/CORBA/YASingleServerOrb.h"
38 : #include "src/cpp/prod/CORBA/YAConnection.h"
39 : #include "src/cpp/prod/boot/boot.h"
40 : #include "src/cpp/prod/tool/DEVELOPMENT.h"
41 : #include "src/cpp/prod/tool/Assert.h"
42 : #include "src/cpp/prod/protocol/iop/iop.h"
43 : #include "src/cpp/prod/protocol/giop/message_header.h"
44 : #include "src/cpp/prod/protocol/giop/request_header_12.h"
45 : #include "src/cpp/prod/protocol/cdr/cdr_memory.h"
46 : #include "src/cpp/prod/poa/YaObjectKey.h"
47 :
48 : // Max number of pending connect request on the _listning socket.
49 : const int NUMBER_OF_CONNECTIONS = 5 ;
50 :
51 : //==============================================================================
52 : // YASingleServerORB : Server ORB, single process.
53 : //==============================================================================
54 :
55 1 : YASingleServerOrb::YASingleServerOrb(const String & confFileName)
56 : : YAServerOrb(confFileName),
57 1 : _connections()
58 : {
59 0 : }
60 :
61 0 : YASingleServerOrb::~YASingleServerOrb()
62 : {
63 0 : }
64 :
65 : CORBA::Boolean
66 16 : YASingleServerOrb::workPending(void)
67 : {
68 : int rc ;
69 : fd_set readFDS ;
70 : fd_set writeFDS ;
71 : fd_set exceptFDS ;
72 : struct timeval delay ;
73 : int soc ;
74 : int maxFD = 0 ;
75 :
76 : // See if a new connection request is pending
77 16 : FD_ZERO(& readFDS) ;
78 16 : FD_SET(_listningSocket, & readFDS) ;
79 16 : maxFD = _listningSocket ;
80 :
81 : YAConnectionLstIt it(_connections) ;
82 : YAConnection *con = NULL ;
83 :
84 36 : while (it.GetNext())
85 : {
86 : con = it.GetItem() ;
87 :
88 : // For each connection, see if a new request is pending.
89 4 : soc = con->GetSocket() ;
90 4 : FD_SET(soc, & readFDS) ;
91 :
92 4 : if (soc > maxFD)
93 : {
94 : maxFD = soc ;
95 : }
96 : }
97 :
98 16 : FD_ZERO(& writeFDS) ;
99 16 : FD_ZERO(& exceptFDS) ;
100 16 : delay.tv_sec = 0 ;
101 16 : delay.tv_usec = 0 ;
102 16 : maxFD ++ ;
103 :
104 16 : fprintf(stderr, "YASingleServerORB::workPending before select\n") ;
105 16 : fflush(stderr) ;
106 :
107 16 : rc = select(maxFD, & readFDS, & writeFDS, & exceptFDS, & delay) ;
108 :
109 16 : fprintf(stderr, "YASingleServerORB::workPending after select\n") ;
110 16 : fflush(stderr) ;
111 :
112 : if (rc >0)
113 : {
114 : return true ;
115 : }
116 : else
117 : {
118 : return false ;
119 : }
120 : }
121 :
122 4 : void YASingleServerOrb::performWork(void)
123 : {
124 : int rc ;
125 : fd_set readFDS ;
126 : fd_set writeFDS ;
127 : fd_set exceptFDS ;
128 : struct timeval delay ;
129 : int soc ;
130 : int maxFD = 0 ;
131 :
132 : // See if a new connection request is pending
133 4 : FD_ZERO(& readFDS) ;
134 4 : FD_SET(_listningSocket, & readFDS) ;
135 4 : maxFD = _listningSocket ;
136 :
137 4 : YAConnectionLstIt it(_connections) ;
138 : YAConnection *con = NULL ;
139 :
140 12 : while (it.GetNext())
141 : {
142 : con = it.GetItem() ;
143 :
144 : // For each connection, see if a new request is pending.
145 4 : soc = con->GetSocket() ;
146 4 : FD_SET(soc, & readFDS) ;
147 :
148 4 : if (soc > maxFD)
149 : {
150 : maxFD = soc ;
151 : }
152 : }
153 :
154 4 : FD_ZERO(& writeFDS) ;
155 4 : FD_ZERO(& exceptFDS) ;
156 4 : delay.tv_sec = 0 ;
157 4 : delay.tv_usec = 0 ;
158 4 : maxFD ++ ;
159 :
160 4 : fprintf(stderr, "YASingleServerORB::performWork before select\n") ;
161 4 : fflush(stderr) ;
162 :
163 4 : rc = select(maxFD, & readFDS, & writeFDS, & exceptFDS, & delay) ;
164 :
165 4 : fprintf(stderr, "YASingleServerORB::performWork after select\n") ;
166 4 : fflush(stderr) ;
167 :
168 4 : if (rc < 0)
169 : {
170 0 : perror("select") ;
171 0 : NON_DEV("Error in select") ;
172 : }
173 :
174 4 : if (rc == 0)
175 : {
176 : return ;
177 : }
178 :
179 : YAConnectionLstIt it2(_connections) ;
180 :
181 8 : while (it2.GetNext())
182 : {
183 : con = it2.GetItem() ;
184 :
185 : // For each connection, process pending requests
186 4 : soc = con->GetSocket() ;
187 4 : if (FD_ISSET(soc, & readFDS))
188 : {
189 4 : handleExistingConnection(con) ;
190 : }
191 : }
192 :
193 : // Process pending connection requests
194 4 : if (FD_ISSET(_listningSocket, & readFDS))
195 : {
196 : YAConnection *server = NULL ;
197 : int connectedSoc ;
198 : struct sockaddr_in con ;
199 2 : socklen_t len = sizeof(con) ;
200 :
201 : connectedSoc = accept(
202 : _listningSocket,
203 : (struct sockaddr*) & con,
204 2 : & len) ;
205 2 : if (connectedSoc<0)
206 : {
207 0 : perror("accept") ;
208 0 : NON_DEV("accept failed") ;
209 : }
210 :
211 2 : server = new YAConnection(connectedSoc) ;
212 2 : handleNewConnection(server) ;
213 : }
214 : }
215 :
216 1 : void YASingleServerOrb::shutdown(CORBA::Boolean waitForCompletion)
217 : {
218 1 : _state = OrbState_Shutdown ;
219 :
220 1 : NON_DEV("shutdown : wait flag") ;
221 : }
222 :
223 1 : void YASingleServerOrb::run(void)
224 : {
225 18 : for (; _state == OrbState_Running ;)
226 : {
227 16 : if (workPending() == true)
228 : {
229 4 : performWork() ;
230 : }
231 : else
232 : {
233 12 : sleep(10) ;
234 : }
235 : }
236 : }
237 :
238 : void
239 2 : YASingleServerOrb::handleNewConnection(YAConnection *con)
240 : {
241 : _connections.addTail(con) ;
242 : }
243 :
244 : void
245 4 : YASingleServerOrb::handleExistingConnection(YAConnection *con)
246 : {
247 4 : Buffer request ;
248 4 : Buffer reply ;
249 : bool mustDrop = false ;
250 : bool mustReply = true ;
251 : bool mustProcess = true ;
252 :
253 4 : Com *com = con->GetCom() ;
254 :
255 : try
256 : {
257 4 : com->ReadBuffer(request) ;
258 : }
259 0 : catch (CORBA::MARSHAL & ex)
260 : {
261 : // Client sent a buggous GIOP Header
262 : mustDrop = true ;
263 : mustProcess = false ;
264 : }
265 2 : catch (CORBA::COMM_FAILURE & ex)
266 : {
267 : mustDrop = true ;
268 : mustReply = false ;
269 : mustProcess = false ;
270 : }
271 :
272 2 : if (mustReply == true)
273 : {
274 2 : if (mustProcess == true)
275 : {
276 2 : handleRequest(request, reply) ;
277 : }
278 : else
279 : {
280 0 : NON_DEV("error reply GIOP 1.2") ;
281 : }
282 :
283 : try
284 : {
285 2 : com->WriteBuffer(reply) ;
286 : }
287 2 : catch (...)
288 : {
289 2 : NON_DEV("Reply failed") ;
290 : }
291 : }
292 :
293 2 : if (mustDrop == true)
294 : {
295 2 : dropConnection(con) ;
296 0 : }
297 : }
298 :
299 : void
300 : YASingleServerOrb::dropConnection(
301 2 : YAConnection *con)
302 : {
303 : _connections.removeObject(con) ;
304 2 : con->Close() ;
305 2 : delete con ;
306 : }
307 :
308 : void
309 : YASingleServerOrb::handleRequest(
310 : Buffer & request,
311 2 : Buffer & reply)
312 : {
313 : CORBA::Octet *data = NULL ;
314 : unsigned int size = 0 ;
315 :
316 2 : data = request.GetData() ;
317 2 : size = request.GetSize() ;
318 :
319 2 : GIOPMessage giop ;
320 2 : CDRMemory cdrs(data, size, YAORB::CDR_READ) ;
321 2 : CORBA::Octet version_major = 0 ;
322 : CORBA::Octet version_minor = 0 ;
323 :
324 : try
325 : {
326 2 : giop.cdr_header(& cdrs) ;
327 2 : GIOPMessageHeader & header = giop.GetHeader() ;
328 :
329 2 : version_major = header.GetMajor() ;
330 2 : version_minor = header.GetMinor() ;
331 : }
332 0 : catch (CORBA::SystemException & ex)
333 : {
334 0 : NON_DEV("reply with error in GIOP 1.2") ;
335 : }
336 :
337 : try
338 : {
339 2 : giop.cdr_body(& cdrs) ;
340 : }
341 0 : catch (CORBA::SystemException & ex)
342 : {
343 0 : NON_DEV("reply with error in sender GIOP version") ;
344 : }
345 :
346 2 : if (version_major != 1)
347 : {
348 0 : NON_DEV("major") ;
349 : }
350 :
351 2 : switch(version_minor)
352 : {
353 : case 0 :
354 : {
355 0 : handleRequest10(giop, & cdrs, reply) ;
356 : break ;
357 : }
358 : case 1 :
359 : {
360 0 : handleRequest11(giop, & cdrs, reply) ;
361 : break ;
362 : }
363 : case 2 :
364 : {
365 2 : handleRequest12(giop, & cdrs, reply) ;
366 : break ;
367 : }
368 : default :
369 : {
370 0 : handleRequest1X(giop, & cdrs, reply) ;
371 : break ;
372 : }
373 0 : }
374 : }
375 :
376 : void
377 : YASingleServerOrb::handleRequest10(
378 : GIOPMessage & giop,
379 : YAORB::CDR *cdrs,
380 0 : Buffer & reply)
381 : {
382 0 : NON_DEV("request 1.0") ;
383 : }
384 :
385 : void
386 : YASingleServerOrb::handleRequest11(
387 : GIOPMessage & giop,
388 : YAORB::CDR *cdrs,
389 0 : Buffer & reply)
390 : {
391 0 : NON_DEV("request 1.1") ;
392 : }
393 :
394 : void
395 : YASingleServerOrb::handleRequest12(
396 : GIOPMessage & giop,
397 : YAORB::CDR *cdrs,
398 2 : Buffer & reply)
399 : {
400 2 : GIOPMessageHeader & header = giop.GetHeader() ;
401 2 : GIOP_12_MessageType_e msgType = header.GetGIOP12MessageType() ;
402 :
403 2 : switch(msgType)
404 : {
405 : case GIOPRequest_type :
406 : {
407 2 : dispatchRequest12(giop, cdrs, reply) ;
408 : break ;
409 : }
410 : case GIOPReply_type :
411 : {
412 0 : NON_DEV("reply 1.2") ;
413 : break ;
414 : }
415 : case GIOPCancelRequest_type :
416 : {
417 0 : NON_DEV("cancel request 1.2") ;
418 : break ;
419 : }
420 : case GIOPLocateRequest_type :
421 : {
422 0 : NON_DEV("locate request 1.2") ;
423 : break ;
424 : }
425 : case GIOPLocateReply_type :
426 : {
427 0 : NON_DEV("locate reply 1.2") ;
428 : break ;
429 : }
430 : case GIOPCloseConnection_type :
431 : {
432 0 : NON_DEV("close connection 1.2") ;
433 : break ;
434 : }
435 : case GIOPMessageError_type :
436 : {
437 0 : NON_DEV("message error 1.2") ;
438 : break ;
439 : }
440 : case GIOPFragment_type :
441 : {
442 0 : NON_DEV("fragment 1.2") ;
443 : break ;
444 : }
445 : }
446 : }
447 :
448 : void
449 : YASingleServerOrb::handleRequest1X(
450 : GIOPMessage & giop,
451 : YAORB::CDR *cdrs,
452 0 : Buffer & reply)
453 : {
454 0 : NON_DEV("request 1.X") ;
455 : }
456 :
457 : void
458 : YASingleServerOrb::dispatchRequest12(
459 : GIOPMessage & giop,
460 : YAORB::CDR *cdrs,
461 2 : Buffer & reply)
462 : {
463 2 : GIOP12RequestHeader * req = giop.GetRequest() ;
464 :
465 2 : CORBA::ULong reqId = req->GetRequestId() ;
466 2 : CORBA::Octet reqFlags = req->GetResponseFlags() ;
467 2 : const TargetAddress & reqTarget = req->GetTarget() ;
468 2 : const char* reqOperation = req->GetOperation() ;
469 :
470 2 : fprintf(stderr, "ReqId = %d\n", reqId) ;
471 2 : fprintf(stderr, "ReqFlags = %d\n", reqFlags) ;
472 2 : fprintf(stderr, "ReqOperation = %s\n", reqOperation) ;
473 :
474 : // PortableServer::ServantBase *servant = NULL ;
475 : // const YAORB::RepositoryID *repId = NULL ;
476 : YaObjectKey *objectKey = NULL ;
477 2 : objectKey = findObjectKey(reqTarget) ;
478 :
479 2 : PortableServer::POA_ptr poa = PortableServer::POA::_nil() ;
480 :
481 2 : if (objectKey != NULL)
482 : {
483 2 : const char * poaName = objectKey->GetPoaName() ;
484 :
485 2 : fprintf(stderr, "PoaName = %s\n", poaName) ;
486 :
487 2 : poa = findPOA(poaName) ;
488 : }
489 :
490 :
491 2 : NON_DEV("request 1.2") ;
492 : }
493 :
494 : PortableServer::POA_ptr
495 : YASingleServerOrb::findPOA(
496 2 : const char* poaName)
497 : {
498 2 : PortableServer::POA_ptr result = PortableServer::POA::_nil() ;
499 :
500 2 : int len = strlen(poaName) ;
501 4 : char * parseBuf = new char[len+1] ;
502 2 : strcpy(parseBuf, poaName) ;
503 2 : char* tmp = NULL ;
504 : char * tok = NULL ;
505 :
506 2 : tok = strtok_r(parseBuf, "/", & tmp) ;
507 :
508 2 : if (strcmp(tok, "RootPOA") == 0)
509 : {
510 2 : result = _rootPOA ;
511 :
512 2 : tok = strtok_r(NULL, "/", & tmp) ;
513 :
514 4 : while (tok != NULL)
515 : {
516 2 : if ( CORBA::is_nil(result) == false)
517 : {
518 : result = result->find_POA(
519 : tok, // find the child POA
520 2 : false) ; // do not activate it
521 : }
522 :
523 2 : tok = strtok_r(NULL, "/", & tmp) ;
524 : }
525 : }
526 :
527 2 : delete [] parseBuf ;
528 :
529 : return result ;
530 : }
531 :
532 : YaObjectKey *
533 : YASingleServerOrb::findObjectKey(
534 2 : const TargetAddress & target)
535 : {
536 : YaObjectKey * key = NULL ;
537 :
538 2 : switch(target.GetAddressingDisposition())
539 : {
540 : case KeyAddr :
541 : {
542 : GIOPEncapsulation *encap = NULL ;
543 :
544 2 : encap = target.GetObjectKey() ;
545 2 : key = new YaObjectKey() ;
546 2 : key->read(*encap) ;
547 2 : break ;
548 : }
549 : case ProfileAddr :
550 : {
551 0 : NON_DEV("find key in profile") ;
552 0 : break ;
553 : }
554 : case ReferenceAddr :
555 : {
556 0 : NON_DEV("find key in reference") ;
557 : break ;
558 : }
559 : }
560 :
561 : return key ;
562 : }
563 :
|