1 20 21 package org.jacorb.orb.iiop; 22 23 import java.io.BufferedOutputStream ; 24 import java.io.IOException ; 25 import java.util.ArrayList ; 26 import java.util.Iterator ; 27 import java.util.List ; 28 29 import org.apache.avalon.framework.configuration.*; 30 31 import org.jacorb.orb.CDRInputStream; 32 import org.jacorb.orb.IIOPAddress; 33 import org.jacorb.orb.factory.SocketFactory; 34 import org.jacorb.orb.giop.TransportManager; 35 36 import org.omg.CSIIOP.*; 37 import org.omg.SSLIOP.*; 38 import org.omg.CORBA.*; 39 40 41 50 51 public class ClientIIOPConnection 52 extends IIOPConnection 53 implements Configurable 54 { 55 private int timeout = 0; 57 58 private int ssl_port = -1; 59 private int noOfRetries = 5; 60 private int retryInterval = 0; 61 private boolean doSupportSSL = false; 62 private TransportManager transportManager; 63 64 public static int openTransports = 0; 67 68 private Exception exception = null; 70 71 public ClientIIOPConnection() 72 { 73 use_ssl = false; 74 } 75 76 public void configure(Configuration configuration) 77 throws ConfigurationException 78 { 79 super.configure(configuration); 80 82 timeout = 83 configuration.getAttributeAsInteger("jacorb.connection.client.idle_timeout",0 ); 84 noOfRetries = 85 configuration.getAttributeAsInteger("jacorb.retries", 5); 86 retryInterval = 87 configuration.getAttributeAsInteger("jacorb.retry_interval",500); 88 doSupportSSL = 89 configuration.getAttribute("jacorb.security.support_ssl","off").equals("on"); 90 transportManager = 91 this.configuration.getORB().getTransportManager(); 92 93 } 94 95 public ClientIIOPConnection (ClientIIOPConnection other) 96 { 97 super (other); 98 this.timeout = other.timeout; 99 this.ssl_port = other.ssl_port; 100 } 101 102 111 public synchronized void connect(org.omg.ETF.Profile server_profile, long time_out) 112 { 113 if( ! connected ) 114 { 115 if (server_profile instanceof IIOPProfile) 116 { 117 this.profile = (IIOPProfile) server_profile; 118 } 119 else 120 { 121 throw new org.omg.CORBA.BAD_PARAM 122 ( "attempt to connect an IIOP connection " 123 + "to a non-IIOP profile: " + server_profile.getClass()); 124 } 125 126 checkSSL(); 127 128 int retries = noOfRetries; 129 while( retries >= 0 ) 130 { 131 try 132 { 133 createSocket(time_out); 134 135 if( timeout != 0 ) 136 { 137 138 socket.setSoTimeout( timeout ); 139 } 140 141 in_stream = 142 socket.getInputStream(); 143 144 out_stream = 145 new BufferedOutputStream ( socket.getOutputStream()); 146 147 if (logger.isInfoEnabled()) 148 { 149 logger.info("Connected to " + connection_info + 150 " from local port " + 151 socket.getLocalPort() + 152 ( this.isSSL() ? " via SSL" : "" )); 153 } 154 155 connected = true; 156 157 ++openTransports; 159 160 return; 161 } 162 catch ( IOException c ) 163 { 164 if (logger.isDebugEnabled()) 165 logger.debug("Exception", c ); 166 167 retries--; 170 if( retries >= 0 ) 171 { 172 if (logger.isInfoEnabled()) 173 logger.info("Retrying to connect to " + 174 connection_info ); 175 try 176 { 177 Thread.sleep( retryInterval ); 178 } 179 catch( InterruptedException i ) 180 { 181 } 182 } 183 } 184 catch (TIMEOUT e) 185 { 186 profile = null; 188 use_ssl = false; 189 ssl_port = -1; 190 throw e; 191 } 192 193 } 194 195 if( retries < 0 ) 196 { 197 profile = null; 198 use_ssl = false; 199 ssl_port = -1; 200 throw new org.omg.CORBA.TRANSIENT 201 ( "Retries exceeded, couldn't reconnect to " + 202 connection_info ); 203 } 204 } 205 } 206 207 212 private void createSocket(long time_out) 213 throws IOException 214 { 215 List addressList = new ArrayList (); 216 addressList.add(((IIOPProfile)profile).getAddress()); 217 addressList.addAll(((IIOPProfile)profile).getAlternateAddresses()); 218 219 Iterator addressIterator = addressList.iterator(); 220 221 exception = null; 222 socket = null; 223 while (socket == null && addressIterator.hasNext()) 224 { 225 try 226 { 227 IIOPAddress address = (IIOPAddress)addressIterator.next(); 228 229 final SocketFactory factory = 230 (use_ssl) ? transportManager.getSSLSocketFactory() : 231 transportManager.getSocketFactory(); 232 233 final String ipAddress = address.getIP(); 234 final int port = (use_ssl) ? ssl_port : address.getPort(); 235 connection_info = ipAddress + ":" + port; 236 237 if (logger.isDebugEnabled()) 238 { 239 logger.debug("Trying to connect to " + connection_info + " with timeout=" + time_out); 240 } 241 exception = null; 242 socket = null; 243 244 if( time_out > 0 ) 245 { 246 final ClientIIOPConnection self = this; 252 Thread thread = new Thread ( new Runnable () 253 { 254 public void run() 255 { 256 try 257 { 258 socket = factory.createSocket(ipAddress, port); 259 } 260 catch (Exception e) 261 { 262 exception = e; 263 } 264 finally 265 { 266 synchronized (self) 267 { 268 self.notify(); 269 } 270 } 271 } 272 } ); 273 thread.setDaemon(true); 274 try 275 { 276 synchronized (self) 277 { 278 thread.start(); 279 self.wait(time_out); 280 } 281 } 282 catch (InterruptedException _ex) 283 { } 284 285 if (socket == null) 286 { 287 if (exception == null) 288 { 289 if (logger.isDebugEnabled()) 290 { 291 logger.debug("connect to " + connection_info + 292 " with timeout=" + time_out + " timed out"); 293 } 294 thread.interrupt(); 295 exception = 296 new TIMEOUT("connection timeout of " + time_out + " milliseconds expired"); 297 } 298 else 299 { 300 if (logger.isDebugEnabled()) 301 { 302 logger.debug("connect to " + connection_info + " with timeout=" 303 + time_out + " raised exception: " + exception.toString()); 304 } 305 } 306 } 307 } 308 else 309 { 310 socket = factory.createSocket(ipAddress, port); 312 } 313 } 314 catch (Exception e) 315 { 316 exception = e; 317 } 318 } 319 320 if (exception != null) 321 { 322 if( exception instanceof IOException ) 323 { 324 throw (IOException )exception; 325 } 326 else if( exception instanceof org.omg.CORBA.TIMEOUT ) 327 { 328 throw (org.omg.CORBA.TIMEOUT )exception; 329 } 330 else 331 { 332 throw new IOException ( "Unexpected exception occured: " + exception.toString() ); 335 } 336 } 337 } 338 339 340 public synchronized void close() 341 { 342 try 343 { 344 if (connected && socket != null) 345 { 346 socket.close (); 347 348 if( in_stream != null ) 351 { 352 in_stream.close(); 353 } 354 if( out_stream != null ) 355 { 356 out_stream.close(); 357 } 358 359 --openTransports; 361 } 362 363 connected = false; 364 } 365 catch (IOException ex) 366 { 367 throw to_COMM_FAILURE (ex); 368 } 369 370 if (logger.isInfoEnabled()) 371 { 372 logger.info("Client-side TCP transport to " + 373 connection_info + " closed."); 374 } 375 } 376 377 378 379 380 385 private void checkSSL() 386 { 387 CompoundSecMechList sas 388 = (CompoundSecMechList)((IIOPProfile)profile).getComponent 389 (TAG_CSI_SEC_MECH_LIST.value, 390 CompoundSecMechListHelper.class); 391 392 TLS_SEC_TRANS tls = null; 393 if (sas != null && sas.mechanism_list[0].transport_mech.tag == TAG_TLS_SEC_TRANS.value) { 394 try 395 { 396 byte[] tagData = sas.mechanism_list[0].transport_mech.component_data; 397 CDRInputStream in = new CDRInputStream( (org.omg.CORBA.ORB )null, tagData ); 398 in.openEncapsulatedArray(); 399 tls = TLS_SEC_TRANSHelper.read( in ); 400 } 401 catch ( Exception ex ) 402 { 403 logger.warn("Error parsing TLS_SEC_TRANS: "+ex); 404 } 405 } 406 407 SSL ssl = (SSL)((IIOPProfile)profile).getComponent 408 (TAG_SSL_SEC_TRANS.value, 409 SSLHelper.class); 410 416 423 int minimum_options = 426 Integrity.value | 427 Confidentiality.value | 428 DetectReplay.value | 429 DetectMisordering.value | 430 EstablishTrustInTarget.value | 431 EstablishTrustInClient.value; 432 433 int client_required = 0; 434 int client_supported = 0; 435 436 if( doSupportSSL ) 438 { 439 client_required = 440 configuration.getAttributeAsInteger("jacorb.security.ssl.client.required_options", 16); 441 client_supported = 442 configuration.getAttributeAsInteger("jacorb.security.ssl.client.supported_options",16); 443 } 444 445 if( tls != null && ((tls.target_supports & minimum_options) != 0) && doSupportSSL && ((client_supported & minimum_options) != 0 )&& ( ((tls.target_requires & minimum_options) != 0) || ((client_required & minimum_options) != 0))) { 452 if (logger.isDebugEnabled()) 453 { 454 logger.debug("Selecting TLS for connection"); 455 } 456 457 use_ssl = true; 458 ssl_port = tls.addresses[0].port; 459 if (ssl_port < 0) ssl_port += 65536; 460 } 461 else if( ssl != null && ((ssl.target_supports & minimum_options) != 0) && doSupportSSL && ((client_supported & minimum_options) != 0 )&& ( ((ssl.target_requires & minimum_options) != 0) || ((client_required & minimum_options) != 0))) { 468 if (logger.isDebugEnabled()) 469 { 470 logger.debug("Selecting SSL for connection"); 471 } 472 473 use_ssl = true; 474 ssl_port = ssl.port; 475 if (ssl_port < 0) 476 ssl_port += 65536; 477 } 478 else if( doSupportSSL && ((client_required & minimum_options) != 0)) { 484 throw new org.omg.CORBA.NO_PERMISSION ( "Client-side policy requires SSL/TLS, but server doesn't support it" ); 485 } 486 else 487 { 488 use_ssl = false; 489 ssl_port = -1; 490 } 491 } 492 } 493 | Popular Tags |