1 26 27 28 package org.objectweb.jonathan.libs.resources.tcpip; 29 30 import java.io.EOFException ; 31 import java.io.IOException ; 32 import java.io.InputStream ; 33 import java.io.OutputStream ; 34 import java.net.ConnectException ; 35 import java.net.InetAddress ; 36 import java.net.ServerSocket ; 37 import java.net.Socket ; 38 import java.net.UnknownHostException ; 39 import java.net.NetworkInterface ; 40 import java.util.Enumeration ; 41 42 import org.objectweb.jonathan.apis.binding.ExportException; 43 import org.objectweb.jonathan.apis.kernel.InternalException; 44 import org.objectweb.jonathan.apis.kernel.JonathanException; 45 import org.objectweb.jonathan.apis.protocols.ip.IpConnection; 46 import org.objectweb.jonathan.apis.protocols.ip.IpSession; 47 import org.objectweb.jonathan.apis.protocols.ip.TcpIpConnectionMgr; 48 import org.objectweb.jonathan.apis.protocols.ip.TcpIpSrvConnectionFactory; 49 import org.objectweb.jonathan.apis.resources.Chunk; 50 51 import org.objectweb.util.monolog.api.BasicLevel; 52 53 56 public class IPv4ConnectionFactory implements TcpIpConnectionMgr { 57 58 static String default_localhost_name; 59 static String default_localhost_address; 60 static InetAddress default_localhost; 61 62 static { 63 try { 65 Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); 66 while (default_localhost == null && interfaces.hasMoreElements()) { 67 Enumeration addresses = 68 ((NetworkInterface )interfaces.nextElement()).getInetAddresses(); 69 while (default_localhost == null && addresses.hasMoreElements()) { 70 InetAddress address = (InetAddress )addresses.nextElement(); 71 if (!address.isLoopbackAddress() && address.isSiteLocalAddress()) { 72 default_localhost = address; 73 } 74 } 75 } 76 } catch (Exception ignored) { 77 if ((LoggerProvider.logger != null) 78 &&(LoggerProvider.logger.isLoggable(BasicLevel.WARN))) { 79 LoggerProvider.logger.log(BasicLevel.WARN,"Could not determine local host address."); 80 } 81 } 82 if (default_localhost != null) { 83 default_localhost_name = default_localhost.getHostName(); 84 default_localhost_address = default_localhost.getHostAddress(); 85 } 86 } 87 88 InetAddress localhost; 89 public String localhost_name; 90 91 94 public boolean verbose; 95 96 100 public boolean use_address_as_name; 101 102 105 public int SO_LINGER; 106 107 111 public int SO_TIMEOUT; 112 113 116 public boolean TCP_NODELAY; 117 118 121 public int backlog; 122 123 int max_retries; 124 125 126 127 132 public IPv4ConnectionFactory() throws JonathanException { 133 this(null,false,100,0,true,50,10,true); 134 } 135 136 137 149 public IPv4ConnectionFactory(String localhost_value, 150 boolean verbose, 151 int SO_LINGER, int SO_TIMEOUT, 152 boolean TCP_NODELAY, int backlog, 153 int max_retries, boolean use_address_as_name) 154 throws JonathanException { 155 156 this.verbose = verbose; 157 this.SO_LINGER = SO_LINGER; 158 this.SO_TIMEOUT = SO_TIMEOUT; 159 this.TCP_NODELAY = TCP_NODELAY; 160 this.backlog = backlog; 161 this.max_retries = max_retries; 162 if (max_retries <= 0) { 163 this.max_retries = 1; 164 } 165 this.use_address_as_name = use_address_as_name; 166 167 try{ 168 if (localhost_value != null && 169 (localhost_value.equals("localhost") || 170 localhost_value.equals("127.0.0.1"))) { 171 localhost_value = null; 172 } 173 if (localhost_value != null) { 174 localhost = InetAddress.getByName(localhost_value); 175 if (use_address_as_name) { 176 localhost_name = localhost.getHostAddress(); 177 } else { 178 localhost_name = localhost.getHostName(); 179 } 180 } else { 181 localhost = default_localhost; 182 if (use_address_as_name) { 183 localhost_name = default_localhost_address; 184 } else { 185 localhost_name = default_localhost_name; 186 } 187 } 188 } catch(UnknownHostException e){ 189 throw new JonathanException(e); 190 } 191 } 192 193 public void setVerbose(boolean verbose) { 194 this.verbose = verbose; 195 } 196 197 206 public IpConnection newCltConnection(String host,int port, 207 IpSession session) 208 throws JonathanException { 209 try { 210 if (host == null || host.equals("localhost") || host.equals("127.0.0.1")) { 211 host = default_localhost_name; 212 } 213 if ((LoggerProvider.bind_logger != null) 219 &&(LoggerProvider.bind_logger.isLoggable(BasicLevel.INFO))) { 220 LoggerProvider.bind_logger.log(BasicLevel.INFO,"Trying to connect to " + host + 221 " on port " + (port & 0xFFFF) + "."); 222 } 223 Socket socket = null; 225 for (int i = 0; i < max_retries; i++) { 226 try { 227 socket = new Socket (host,port & 0xFFFF); 228 break; 229 } catch (ConnectException e) { 230 if (i == (max_retries - 1)) { 231 throw new JonathanException(e); 232 } else if ((LoggerProvider.bind_logger != null) 238 &&(LoggerProvider.bind_logger.isLoggable(BasicLevel.INFO))) { 239 LoggerProvider.bind_logger.log(BasicLevel.INFO,"Re-trying to connect to " + host + 240 " on port " + (port & 0xFFFF) + "."); 241 } 242 } 244 } 245 if (SO_LINGER >= 0) { 246 socket.setSoLinger(true,SO_LINGER); 247 } 248 if (SO_TIMEOUT >= 0) { 249 socket.setSoTimeout(SO_TIMEOUT); 250 } 251 socket.setTcpNoDelay(TCP_NODELAY); 252 port = socket.getPort() & 0xFFFF ; 254 255 if ((LoggerProvider.bind_logger != null) 260 &&(LoggerProvider.bind_logger.isLoggable(BasicLevel.INFO))) { 261 LoggerProvider.bind_logger.log(BasicLevel.INFO,"Connected to " + socket); 262 } 263 return new Connection(socket,session,host,port); 265 } catch (IOException e) { 266 throw new JonathanException(e); 267 } 268 } 269 270 277 public TcpIpSrvConnectionFactory newSrvConnectionFactory(int port) 278 throws JonathanException { 279 return new SrvConnectionFactory(localhost,port,backlog); 280 } 281 282 291 public String getCanonicalHostName(String hostname) { 292 if (hostname != null && hostname.length() > 0) { 293 if (use_address_as_name) { 294 if (! Character.isDigit(hostname.charAt(0))) { 295 if (hostname.equals("localhost")) { 296 return default_localhost_address; 297 } else { 298 try { 299 return InetAddress.getByName(hostname).getHostAddress(); 300 } catch (Exception ignored) { 301 } 302 } 303 } else if (hostname.equals("127.0.0.1")) { 304 return default_localhost_address; 305 } 306 } else { 307 if (Character.isDigit(hostname.charAt(0))) { 308 if (hostname.equals("127.0.0.1")) { 309 return default_localhost_name; 310 } else { 311 try { 312 return InetAddress.getByName(hostname).getHostName(); 313 } catch (Exception ignored) { 314 } 315 } 316 } else if (hostname.equals("localhost")) { 317 return default_localhost_name; 318 } 319 } 320 } 321 return hostname; 322 } 323 324 334 protected Connection newSrvConnection(Socket socket,IpSession session, 335 String host, int port) 336 337 throws JonathanException { 338 return new Connection(socket,session,host,port); 339 } 340 341 344 class Connection implements IpConnection { 345 346 347 Socket socket; 348 String host; 349 int port; 350 InputStream is; 351 OutputStream os; 352 353 354 IpSession session; 355 356 365 protected Connection(Socket socket, IpSession session, 366 String host, int port) 367 368 throws JonathanException { 369 if (socket != null) { 370 try { 371 is = socket.getInputStream(); 372 os = socket.getOutputStream(); 373 } catch (IOException e) { 374 try { 375 socket.close(); 376 } catch (IOException ignored) { 377 } 378 throw new JonathanException(e); 379 } 380 } else { 381 throw new InternalException("Null socket to create connection"); 382 } 383 this.socket = socket; 384 this.session = session; 385 this.host = host; 386 this.port = port; 387 } 388 389 public int available() throws IOException { 390 return is.available(); 391 } 392 393 public void emit(Chunk c) throws IOException { 394 synchronized (os) { 395 if ((LoggerProvider.send_logger != null) 404 &&(LoggerProvider.send_logger.isLoggable(BasicLevel.DEBUG))) { 405 byte[] data = c.data; 406 int len = c.top - c.offset; 407 String str = "OUT: "; 408 for (int i = c.offset; i < len; i++) { 409 str = str + data[i] + " "; 410 } 411 LoggerProvider.send_logger.log(BasicLevel.DEBUG,str); 412 } 413 os.write(c.data,c.offset,c.top); 415 } 416 } 417 418 public void receive(Chunk c,int sz) throws IOException { 419 byte[] data = c.data; 420 int top = c.top; 421 while (sz > 0) { 425 int a = is.read(data,top,sz); 426 if ((LoggerProvider.receive_logger != null) 433 &&(LoggerProvider.receive_logger.isLoggable(BasicLevel.DEBUG))) { 434 String str = "IN: "; 435 for (int i = top; i < top + sz; i++) { 436 str = str + data[i] + " "; 437 } 438 LoggerProvider.receive_logger.log(BasicLevel.DEBUG,str); 439 } 440 if (a > 0) { 442 top += a; 443 sz -= a; 444 } else { 445 throw new EOFException (); 446 } 447 } 448 452 c.top = top; 453 } 454 455 456 460 public int getPort() { 461 return port; 462 } 463 464 468 public String getHostName() { 469 return host; 470 } 471 472 476 public IpSession getSession() { 477 return session; 478 } 479 480 484 public void setSession(IpSession session) { 485 this.session = session; 486 } 487 488 494 public synchronized void delete() { 495 if (socket != null) { 496 try { 497 if ((LoggerProvider.logger != null) 504 &&(LoggerProvider.logger.isLoggable(BasicLevel.INFO))) { 505 LoggerProvider.logger.log(BasicLevel.INFO,"Connection with host " + host + 506 " on port " + 507 (port & 0xFFFF) + " closed."); 508 } 509 socket.close(); 511 } catch (IOException ignored) {} 512 socket = null; 513 session = null; 514 } 515 } 516 517 521 public void release() { 522 delete(); 523 } 524 525 public String toString() { 526 return "IPv4Connection[" + socket + "]"; 527 } 528 529 } 530 531 class SrvConnectionFactory implements TcpIpSrvConnectionFactory { 532 int port; 533 String hostname; 534 ServerSocket server_socket; 535 536 SrvConnectionFactory(InetAddress localhost,int port,int backlog) 537 throws JonathanException { 538 if (use_address_as_name) { 539 this.hostname = localhost.getHostAddress(); 540 } else { 541 this.hostname = localhost.getHostName(); 542 } 543 try { 544 server_socket = new ServerSocket (port & 0xFFFF,backlog,localhost); 545 if (server_socket != null) { 546 this.port = server_socket.getLocalPort() & 0xFFFF; 547 if ((LoggerProvider.export_logger != null) 555 &&(LoggerProvider.export_logger.isLoggable(BasicLevel.INFO))) { 556 LoggerProvider.export_logger.log(BasicLevel.INFO,"Opened a server connection on host " + 557 hostname + " on port " + 558 (this.port & 0xFFFF)); 559 } 560 } else { 562 throw new ExportException("Can't create server socket."); 563 } 564 } catch (IOException e) { 565 throw new ExportException(e); 566 } 567 } 568 569 public IpConnection newSrvConnection(IpSession session) 570 throws JonathanException { 571 try { 572 ServerSocket current = null; 573 synchronized (this) { 574 if (server_socket != null) { 575 current = server_socket; 576 } else { 577 throw new ExportException("Server Connection Factory has been closed"); 578 } 579 } 580 581 Socket socket = current.accept(); 582 if (SO_LINGER >= 0) { 583 socket.setSoLinger(true,SO_LINGER); 584 } 585 if (SO_TIMEOUT >= 0) { 586 socket.setSoTimeout(SO_TIMEOUT); 587 } 588 socket.setTcpNoDelay(TCP_NODELAY); 589 int port = socket.getPort() & 0xFFFF; 590 String hostname = socket.getInetAddress().getHostName(); 591 if ((LoggerProvider.bind_logger != null) 599 &&(LoggerProvider.bind_logger.isLoggable(BasicLevel.INFO))) { 600 LoggerProvider.bind_logger.log(BasicLevel.INFO,"Accepted connection with host: " + 601 hostname + " on port: " + port); 602 } 603 return 605 IPv4ConnectionFactory.this.newSrvConnection(socket,session,hostname, 606 port); 607 } catch (IOException e) { 608 throw new ExportException(e); 609 } 610 } 611 612 public int getPort() { 613 return port; 614 } 615 616 public String getHostName() { 617 return hostname; 618 } 619 620 public synchronized void close() { 621 if (server_socket != null) { 622 try { 623 server_socket.close(); 624 } catch (IOException ignored) {} 625 server_socket = null; 626 } 627 } 628 } 629 } 630 631 632 633 634 | Popular Tags |