src/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelAcceptorImpl.java

Fri, 24 Sep 2010 22:42:14 -0700

author
skoppar
date
Fri, 24 Sep 2010 22:42:14 -0700
changeset 205
b2fff4b7e8cd
parent 158
91006f157c46
child 478
80161c61aa68
permissions
-rw-r--r--

6891766: Vulnerabilities in use of reflection in CORBA
Reviewed-by: hawtin

     1 /*
     2  * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package com.sun.corba.se.impl.transport;
    28 import java.io.IOException;
    29 import java.net.InetSocketAddress;
    30 import java.net.ServerSocket;
    31 import java.net.Socket;
    32 import java.nio.channels.SelectableChannel;
    33 import java.nio.channels.SelectionKey;
    34 import java.nio.channels.ServerSocketChannel;
    35 import java.nio.channels.SocketChannel;
    36 import java.util.Iterator;
    38 import com.sun.corba.se.pept.broker.Broker;
    39 import com.sun.corba.se.pept.encoding.InputObject;
    40 import com.sun.corba.se.pept.encoding.OutputObject;
    41 import com.sun.corba.se.pept.protocol.MessageMediator;
    42 import com.sun.corba.se.pept.transport.Acceptor;
    43 import com.sun.corba.se.pept.transport.Connection;
    44 import com.sun.corba.se.pept.transport.ContactInfo;
    45 import com.sun.corba.se.pept.transport.EventHandler;
    46 import com.sun.corba.se.pept.transport.InboundConnectionCache;
    47 import com.sun.corba.se.pept.transport.Selector;
    49 import com.sun.corba.se.spi.extension.RequestPartitioningPolicy;
    50 import com.sun.corba.se.spi.ior.IORTemplate;
    51 import com.sun.corba.se.spi.ior.TaggedProfileTemplate;
    52 import com.sun.corba.se.spi.ior.iiop.IIOPAddress ;
    53 import com.sun.corba.se.spi.ior.iiop.IIOPFactories;
    54 import com.sun.corba.se.spi.ior.iiop.IIOPProfileTemplate ;
    55 import com.sun.corba.se.spi.ior.iiop.GIOPVersion ;
    56 import com.sun.corba.se.spi.ior.iiop.AlternateIIOPAddressComponent;
    57 import com.sun.corba.se.spi.logging.CORBALogDomains;
    58 import com.sun.corba.se.spi.orb.ORB;
    59 import com.sun.corba.se.spi.orbutil.threadpool.Work;
    60 import com.sun.corba.se.spi.protocol.CorbaMessageMediator;
    61 import com.sun.corba.se.spi.transport.CorbaAcceptor;
    62 import com.sun.corba.se.spi.transport.CorbaConnection;
    63 import com.sun.corba.se.spi.transport.SocketInfo;
    64 import com.sun.corba.se.spi.transport.SocketOrChannelAcceptor;
    66 import com.sun.corba.se.impl.encoding.CDRInputObject;
    67 import com.sun.corba.se.impl.encoding.CDROutputObject;
    68 import com.sun.corba.se.impl.logging.ORBUtilSystemException;
    69 import com.sun.corba.se.impl.oa.poa.Policies; // REVISIT impl/poa specific
    70 import com.sun.corba.se.impl.orbutil.ORBConstants;
    71 import com.sun.corba.se.impl.orbutil.ORBUtility;
    73 // BEGIN Legacy support.
    74 import com.sun.corba.se.spi.legacy.connection.LegacyServerSocketEndPointInfo;
    75 // END Legacy support.
    77 /**
    78  * @author Harold Carr
    79  */
    80 public class SocketOrChannelAcceptorImpl
    81     extends
    82         EventHandlerBase
    83     implements
    84         CorbaAcceptor,
    85         SocketOrChannelAcceptor,
    86         Work,
    87         // BEGIN Legacy
    88         SocketInfo,
    89         LegacyServerSocketEndPointInfo
    90         // END Legacy
    91 {
    92     protected ServerSocketChannel serverSocketChannel;
    93     protected ServerSocket serverSocket;
    94     protected int port;
    95     protected long enqueueTime;
    96     protected boolean initialized;
    97     protected ORBUtilSystemException wrapper ;
    98     protected InboundConnectionCache connectionCache;
   100     // BEGIN Legacy
   101     protected String type = "";
   102     protected String name = "";
   103     protected String hostname;
   104     protected int locatorPort;
   105     // END Legacy
   107     public SocketOrChannelAcceptorImpl(ORB orb)
   108     {
   109         this.orb = orb;
   110         wrapper = ORBUtilSystemException.get( orb,
   111             CORBALogDomains.RPC_TRANSPORT ) ;
   113         setWork(this);
   114         initialized = false;
   116         // BEGIN Legacy support.
   117         this.hostname = orb.getORBData().getORBServerHost();
   118         this.name = LegacyServerSocketEndPointInfo.NO_NAME;
   119         this.locatorPort = -1;
   120         // END Legacy support.
   121     }
   123     public SocketOrChannelAcceptorImpl(ORB orb, int port)
   124     {
   125         this(orb);
   126         this.port = port;
   127     }
   129     // BEGIN Legacy support.
   130     public SocketOrChannelAcceptorImpl(ORB orb, int port,
   131                                        String name, String type)
   132     {
   133         this(orb, port);
   134         this.name = name;
   135         this.type = type;
   136     }
   137     // END Legacy support.
   139     ////////////////////////////////////////////////////
   140     //
   141     // pept.transport.Acceptor
   142     //
   144     public boolean initialize()
   145     {
   146         if (initialized) {
   147             return false;
   148         }
   149         if (orb.transportDebugFlag) {
   150             dprint(".initialize: " + this);
   151         }
   152         InetSocketAddress inetSocketAddress = null;
   153         try {
   154             if (orb.getORBData().getListenOnAllInterfaces().equals(ORBConstants.LISTEN_ON_ALL_INTERFACES)) {
   155                 inetSocketAddress = new InetSocketAddress(port);
   156             } else {
   157                 String host = orb.getORBData().getORBServerHost();
   158                 inetSocketAddress = new InetSocketAddress(host, port);
   159             }
   160             serverSocket = orb.getORBData().getSocketFactory()
   161                 .createServerSocket(type, inetSocketAddress);
   162             internalInitialize();
   163         } catch (Throwable t) {
   164             throw wrapper.createListenerFailed( t, Integer.toString(port) ) ;
   165         }
   166         initialized = true;
   167         return true;
   168     }
   170     protected void internalInitialize()
   171         throws Exception
   172     {
   173         // Determine the listening port (for the IOR).
   174         // This is important when using emphemeral ports (i.e.,
   175         // when the port value to the constructor is 0).
   177         port = serverSocket.getLocalPort();
   179         // Register with transport (also sets up monitoring).
   181         orb.getCorbaTransportManager().getInboundConnectionCache(this);
   183         // Finish configuation.
   185         serverSocketChannel = serverSocket.getChannel();
   187         if (serverSocketChannel != null) {
   188             setUseSelectThreadToWait(
   189                 orb.getORBData().acceptorSocketUseSelectThreadToWait());
   190             serverSocketChannel.configureBlocking(
   191                 ! orb.getORBData().acceptorSocketUseSelectThreadToWait());
   192         } else {
   193             // Configure to use listener and reader threads.
   194             setUseSelectThreadToWait(false);
   195         }
   196         setUseWorkerThreadForEvent(
   197             orb.getORBData().acceptorSocketUseWorkerThreadForEvent());
   199     }
   201     public boolean initialized()
   202     {
   203         return initialized;
   204     }
   206     public String getConnectionCacheType()
   207     {
   208         return this.getClass().toString();
   209     }
   211     public void setConnectionCache(InboundConnectionCache connectionCache)
   212     {
   213         this.connectionCache = connectionCache;
   214     }
   216     public InboundConnectionCache getConnectionCache()
   217     {
   218         return connectionCache;
   219     }
   221     public boolean shouldRegisterAcceptEvent()
   222     {
   223         return true;
   224     }
   226     public void accept()
   227     {
   228         try {
   229             SocketChannel socketChannel = null;
   230             Socket socket = null;
   231             if (serverSocketChannel == null) {
   232                 socket = serverSocket.accept();
   233             } else {
   234                 socketChannel = serverSocketChannel.accept();
   235                 socket = socketChannel.socket();
   236             }
   237             orb.getORBData().getSocketFactory()
   238                 .setAcceptedSocketOptions(this, serverSocket, socket);
   239             if (orb.transportDebugFlag) {
   240                 dprint(".accept: " +
   241                        (serverSocketChannel == null
   242                         ? serverSocket.toString()
   243                         : serverSocketChannel.toString()));
   244             }
   246             CorbaConnection connection =
   247                 new SocketOrChannelConnectionImpl(orb, this, socket);
   248             if (orb.transportDebugFlag) {
   249                 dprint(".accept: new: " + connection);
   250             }
   252             // NOTE: The connection MUST be put in the cache BEFORE being
   253             // registered with the selector.  Otherwise if the bytes
   254             // are read on the connection it will attempt a time stamp
   255             // but the cache will be null, resulting in NPE.
   256             getConnectionCache().put(this, connection);
   258             if (connection.shouldRegisterServerReadEvent()) {
   259                 Selector selector = orb.getTransportManager().getSelector(0);
   260                 selector.registerForEvent(connection.getEventHandler());
   261             }
   263             getConnectionCache().reclaim();
   265         } catch (IOException e) {
   266             if (orb.transportDebugFlag) {
   267                 dprint(".accept:", e);
   268             }
   269             orb.getTransportManager().getSelector(0).unregisterForEvent(this);
   270             // REVISIT - need to close - recreate - then register new one.
   271             orb.getTransportManager().getSelector(0).registerForEvent(this);
   272             // NOTE: if register cycling we do not want to shut down ORB
   273             // since local beans will still work.  Instead one will see
   274             // a growing log file to alert admin of problem.
   275         }
   276     }
   278     public void close ()
   279     {
   280         try {
   281             if (orb.transportDebugFlag) {
   282                 dprint(".close->:");
   283             }
   284             Selector selector = orb.getTransportManager().getSelector(0);
   285             selector.unregisterForEvent(this);
   286             if (serverSocketChannel != null) {
   287                 serverSocketChannel.close();
   288             }
   289             if (serverSocket != null) {
   290                 serverSocket.close();
   291             }
   292         } catch (IOException e) {
   293             if (orb.transportDebugFlag) {
   294                 dprint(".close:", e);
   295             }
   296         } finally {
   297             if (orb.transportDebugFlag) {
   298                 dprint(".close<-:");
   299             }
   300         }
   301     }
   303     public EventHandler getEventHandler()
   304     {
   305         return this;
   306     }
   308     ////////////////////////////////////////////////////
   309     //
   310     // CorbaAcceptor
   311     //
   313     public String getObjectAdapterId()
   314     {
   315         return null;
   316     }
   318     public String getObjectAdapterManagerId()
   319     {
   320         return null;
   321     }
   323     public void addToIORTemplate(IORTemplate iorTemplate,
   324                                  Policies policies,
   325                                  String codebase)
   326     {
   327         Iterator iterator = iorTemplate.iteratorById(
   328             org.omg.IOP.TAG_INTERNET_IOP.value);
   330         String hostname = orb.getORBData().getORBServerHost();
   332         if (iterator.hasNext()) {
   333             // REVISIT - how does this play with legacy ORBD port exchange?
   334             IIOPAddress iiopAddress =
   335                 IIOPFactories.makeIIOPAddress(orb, hostname, port);
   336             AlternateIIOPAddressComponent iiopAddressComponent =
   337                 IIOPFactories.makeAlternateIIOPAddressComponent(iiopAddress);
   339             while (iterator.hasNext()) {
   340                 TaggedProfileTemplate taggedProfileTemplate =
   341                     (TaggedProfileTemplate) iterator.next();
   342                 taggedProfileTemplate.add(iiopAddressComponent);
   343             }
   344         } else {
   345             GIOPVersion version = orb.getORBData().getGIOPVersion();
   346             int templatePort;
   347             if (policies.forceZeroPort()) {
   348                 templatePort = 0;
   349             } else if (policies.isTransient()) {
   350                 templatePort = port;
   351             } else {
   352                 templatePort = orb.getLegacyServerSocketManager()
   353                    .legacyGetPersistentServerPort(SocketInfo.IIOP_CLEAR_TEXT);
   354             }
   355             IIOPAddress addr =
   356                 IIOPFactories.makeIIOPAddress(orb, hostname, templatePort);
   357             IIOPProfileTemplate iiopProfile =
   358                 IIOPFactories.makeIIOPProfileTemplate(orb, version, addr);
   359             if (version.supportsIORIIOPProfileComponents()) {
   360                 iiopProfile.add(IIOPFactories.makeCodeSetsComponent(orb));
   361                 iiopProfile.add(IIOPFactories.makeMaxStreamFormatVersionComponent());
   362                 RequestPartitioningPolicy rpPolicy = (RequestPartitioningPolicy)
   363                     policies.get_effective_policy(
   364                                       ORBConstants.REQUEST_PARTITIONING_POLICY);
   365                 if (rpPolicy != null) {
   366                     iiopProfile.add(
   367                          IIOPFactories.makeRequestPartitioningComponent(
   368                              rpPolicy.getValue()));
   369                 }
   370                 if (codebase != null && codebase != "") {
   371                     iiopProfile.add(IIOPFactories. makeJavaCodebaseComponent(codebase));
   372                 }
   373                 if (orb.getORBData().isJavaSerializationEnabled()) {
   374                     iiopProfile.add(
   375                            IIOPFactories.makeJavaSerializationComponent());
   376                 }
   377             }
   378             iorTemplate.add(iiopProfile);
   379         }
   380     }
   382     public String getMonitoringName()
   383     {
   384         return "AcceptedConnections";
   385     }
   387     ////////////////////////////////////////////////////
   388     //
   389     // EventHandler methods
   390     //
   392     public SelectableChannel getChannel()
   393     {
   394         return serverSocketChannel;
   395     }
   397     public int getInterestOps()
   398     {
   399         return SelectionKey.OP_ACCEPT;
   400     }
   402     public Acceptor getAcceptor()
   403     {
   404         return this;
   405     }
   407     public Connection getConnection()
   408     {
   409         throw new RuntimeException("Should not happen.");
   410     }
   412     ////////////////////////////////////////////////////
   413     //
   414     // Work methods.
   415     //
   417     /* CONFLICT: with legacy below.
   418     public String getName()
   419     {
   420         return this.toString();
   421     }
   422     */
   424     public void doWork()
   425     {
   426         try {
   427             if (orb.transportDebugFlag) {
   428                 dprint(".doWork->: " + this);
   429             }
   430             if (selectionKey.isAcceptable()) {
   431                         accept();
   432             } else {
   433                 if (orb.transportDebugFlag) {
   434                     dprint(".doWork: ! selectionKey.isAcceptable: " + this);
   435                 }
   436             }
   437         } catch (SecurityException se) {
   438             if (orb.transportDebugFlag) {
   439                 dprint(".doWork: ignoring SecurityException: "
   440                        + se
   441                        + " " + this);
   442             }
   443             String permissionStr = ORBUtility.getClassSecurityInfo(getClass());
   444             wrapper.securityExceptionInAccept(se, permissionStr);
   445         } catch (Exception ex) {
   446             if (orb.transportDebugFlag) {
   447                 dprint(".doWork: ignoring Exception: "
   448                        + ex
   449                        + " " + this);
   450             }
   451             wrapper.exceptionInAccept(ex);
   452         } catch (Throwable t) {
   453             if (orb.transportDebugFlag) {
   454                 dprint(".doWork: ignoring Throwable: "
   455                        + t
   456                        + " " + this);
   457             }
   458         } finally {
   460             // IMPORTANT: To avoid bug (4953599), we force the
   461             // Thread that does the NIO select to also do the
   462             // enable/disable of Ops using SelectionKey.interestOps().
   463             // Otherwise, the SelectionKey.interestOps() may block
   464             // indefinitely.
   465             // NOTE: If "acceptorSocketUseWorkerThreadForEvent" is
   466             // set to to false in ParserTable.java, then this method,
   467             // doWork(), will get executed by the same thread
   468             // (SelectorThread) that does the NIO select.
   469             // If "acceptorSocketUseWorkerThreadForEvent" is set
   470             // to true, a WorkerThread will execute this method,
   471             // doWork(). Hence, the registering of the enabling of
   472             // the SelectionKey's interestOps is done here instead
   473             // of calling SelectionKey.interestOps(<interest op>).
   475             Selector selector = orb.getTransportManager().getSelector(0);
   476             selector.registerInterestOps(this);
   478             if (orb.transportDebugFlag) {
   479                 dprint(".doWork<-:" + this);
   480             }
   481         }
   482     }
   484     public void setEnqueueTime(long timeInMillis)
   485     {
   486         enqueueTime = timeInMillis;
   487     }
   489     public long getEnqueueTime()
   490     {
   491         return enqueueTime;
   492     }
   495     //
   496     // Factory methods.
   497     //
   499     // REVISIT: refactor into common base or delegate.
   500     public MessageMediator createMessageMediator(Broker broker,
   501                                                  Connection connection)
   502     {
   503         // REVISIT - no factoring so cheat to avoid code dup right now.
   504         // REVISIT **** COUPLING !!!!
   505         ContactInfo contactInfo = new SocketOrChannelContactInfoImpl();
   506         return contactInfo.createMessageMediator(broker, connection);
   507     }
   509     // REVISIT: refactor into common base or delegate.
   510     public MessageMediator finishCreatingMessageMediator(Broker broker,
   511                                                          Connection connection,
   512                                                          MessageMediator messageMediator)
   513     {
   514         // REVISIT - no factoring so cheat to avoid code dup right now.
   515         // REVISIT **** COUPLING !!!!
   516         ContactInfo contactInfo = new SocketOrChannelContactInfoImpl();
   517         return contactInfo.finishCreatingMessageMediator(broker,
   518                                           connection, messageMediator);
   519     }
   521     public InputObject createInputObject(Broker broker,
   522                                          MessageMediator messageMediator)
   523     {
   524         CorbaMessageMediator corbaMessageMediator = (CorbaMessageMediator)
   525             messageMediator;
   526         return new CDRInputObject((ORB)broker,
   527                                   (CorbaConnection)messageMediator.getConnection(),
   528                                   corbaMessageMediator.getDispatchBuffer(),
   529                                   corbaMessageMediator.getDispatchHeader());
   530     }
   532     public OutputObject createOutputObject(Broker broker,
   533                                            MessageMediator messageMediator)
   534     {
   535         CorbaMessageMediator corbaMessageMediator = (CorbaMessageMediator)
   536             messageMediator;
   537         return new CDROutputObject((ORB) broker, corbaMessageMediator,
   538                                    corbaMessageMediator.getReplyHeader(),
   539                                    corbaMessageMediator.getStreamFormatVersion());
   540     }
   542     ////////////////////////////////////////////////////
   543     //
   544     // SocketOrChannelAcceptor
   545     //
   547     public ServerSocket getServerSocket()
   548     {
   549         return serverSocket;
   550     }
   552     ////////////////////////////////////////////////////
   553     //
   554     // Implementation.
   555     //
   557     public String toString()
   558     {
   559         String sock;
   560         if (serverSocketChannel == null) {
   561             if (serverSocket == null) {
   562                 sock = "(not initialized)";
   563             } else {
   564                 sock = serverSocket.toString();
   565             }
   566         } else {
   567             sock = serverSocketChannel.toString();
   568         }
   570         return
   571             toStringName() +
   572             "["
   573             + sock + " "
   574             + type + " "
   575             + shouldUseSelectThreadToWait() + " "
   576             + shouldUseWorkerThreadForEvent()
   577             + "]" ;
   578     }
   580     protected String toStringName()
   581     {
   582         return "SocketOrChannelAcceptorImpl";
   583     }
   585     protected void dprint(String msg)
   586     {
   587         ORBUtility.dprint(toStringName(), msg);
   588     }
   590     protected void dprint(String msg, Throwable t)
   591     {
   592         dprint(msg);
   593         t.printStackTrace(System.out);
   594     }
   596     // BEGIN Legacy support
   597     ////////////////////////////////////////////////////
   598     //
   599     // LegacyServerSocketEndPointInfo and EndPointInfo
   600     //
   602     public String getType()
   603     {
   604         return type;
   605     }
   607     public String getHostName()
   608     {
   609         return hostname;
   610     }
   612     public String getHost()
   613     {
   614         return hostname;
   615     }
   617     public int getPort()
   618     {
   619         return port;
   620     }
   622     public int getLocatorPort()
   623     {
   624         return locatorPort;
   625     }
   627     public void setLocatorPort (int port)
   628     {
   629         locatorPort = port;
   630     }
   632     public String getName()
   633     {
   634         // Kluge alert:
   635         // Work and Legacy both define getName.
   636         // Try to make this behave best for most cases.
   637         String result =
   638             name.equals(LegacyServerSocketEndPointInfo.NO_NAME) ?
   639             this.toString() : name;
   640         return result;
   641     }
   642     // END Legacy support
   643 }
   645 // End of file.

mercurial