25 |
25 |
26 package java.net; |
26 package java.net; |
27 |
27 |
28 import jdk.internal.access.JavaNetSocketAccess; |
28 import jdk.internal.access.JavaNetSocketAccess; |
29 import jdk.internal.access.SharedSecrets; |
29 import jdk.internal.access.SharedSecrets; |
|
30 import sun.nio.ch.NioSocketImpl; |
30 |
31 |
31 import java.io.FileDescriptor; |
32 import java.io.FileDescriptor; |
32 import java.io.IOException; |
33 import java.io.IOException; |
33 import java.lang.reflect.Constructor; |
34 import java.lang.reflect.Constructor; |
34 import java.lang.reflect.InvocationTargetException; |
35 import java.lang.reflect.InvocationTargetException; |
540 * @since 1.1 |
541 * @since 1.1 |
541 * @revised 1.4 |
542 * @revised 1.4 |
542 * @spec JSR-51 |
543 * @spec JSR-51 |
543 */ |
544 */ |
544 protected final void implAccept(Socket s) throws IOException { |
545 protected final void implAccept(Socket s) throws IOException { |
545 SocketImpl si = null; |
546 SocketImpl impl = getImpl(); |
|
547 SocketImpl si = s.impl; |
|
548 |
|
549 // Socket does not have a SocketImpl |
|
550 if (si == null) { |
|
551 // create a SocketImpl and accept the connection |
|
552 si = Socket.createImpl(); |
|
553 impl.accept(si); |
|
554 |
|
555 try { |
|
556 // a custom impl has accepted the connection with a NIO SocketImpl |
|
557 if (!(impl instanceof NioSocketImpl) && (si instanceof NioSocketImpl)) { |
|
558 ((NioSocketImpl) si).postCustomAccept(); |
|
559 } |
|
560 } finally { |
|
561 securityCheckAccept(si); // closes si if permission check fails |
|
562 } |
|
563 |
|
564 // bind Socket to the SocketImpl and update socket state |
|
565 s.setImpl(si); |
|
566 s.postAccept(); |
|
567 return; |
|
568 } |
|
569 |
|
570 // ServerSocket or Socket is using NIO SocketImpl |
|
571 if (impl instanceof NioSocketImpl || si instanceof NioSocketImpl) { |
|
572 // not implemented |
|
573 if (impl instanceof NioSocketImpl && impl.getClass() != NioSocketImpl.class) |
|
574 throw new UnsupportedOperationException(); |
|
575 |
|
576 // accept connection via new SocketImpl |
|
577 NioSocketImpl nsi = new NioSocketImpl(false); |
|
578 impl.accept(nsi); |
|
579 securityCheckAccept(nsi); // closes si if permission check fails |
|
580 |
|
581 // copy state to the existing SocketImpl and update socket state |
|
582 nsi.copyTo(si); |
|
583 s.postAccept(); |
|
584 return; |
|
585 } |
|
586 |
|
587 // ServerSocket and Socket bound to custom SocketImpls |
|
588 s.impl = null; // break connection to impl |
|
589 boolean completed = false; |
546 try { |
590 try { |
547 if (s.impl == null) |
591 si.reset(); |
548 s.setImpl(); |
592 si.fd = new FileDescriptor(); |
549 else { |
593 si.address = new InetAddress(); |
550 s.impl.reset(); |
594 impl.accept(si); |
|
595 securityCheckAccept(si); // closes si if permission check fails |
|
596 completed = true; |
|
597 } finally { |
|
598 if (!completed) |
|
599 si.reset(); |
|
600 s.impl = si; // restore connection to impl |
|
601 } |
|
602 s.postAccept(); |
|
603 } |
|
604 |
|
605 /** |
|
606 * Invokes the security manager's checkAccept method. If the permission |
|
607 * check fails then it closes the SocketImpl. |
|
608 */ |
|
609 private void securityCheckAccept(SocketImpl si) throws IOException { |
|
610 SecurityManager sm = System.getSecurityManager(); |
|
611 if (sm != null) { |
|
612 try { |
|
613 sm.checkAccept(si.getInetAddress().getHostAddress(), si.getPort()); |
|
614 } catch (SecurityException se) { |
|
615 si.close(); |
|
616 throw se; |
551 } |
617 } |
552 si = s.impl; |
618 } |
553 s.impl = null; |
|
554 si.address = new InetAddress(); |
|
555 si.fd = new FileDescriptor(); |
|
556 getImpl().accept(si); |
|
557 SocketCleanable.register(si.fd); // raw fd has been set |
|
558 |
|
559 SecurityManager security = System.getSecurityManager(); |
|
560 if (security != null) { |
|
561 security.checkAccept(si.getInetAddress().getHostAddress(), |
|
562 si.getPort()); |
|
563 } |
|
564 } catch (IOException e) { |
|
565 if (si != null) |
|
566 si.reset(); |
|
567 s.impl = si; |
|
568 throw e; |
|
569 } catch (SecurityException e) { |
|
570 if (si != null) |
|
571 si.reset(); |
|
572 s.impl = si; |
|
573 throw e; |
|
574 } |
|
575 s.impl = si; |
|
576 s.postAccept(); |
|
577 } |
619 } |
578 |
620 |
579 /** |
621 /** |
580 * Closes this socket. |
622 * Closes this socket. |
581 * |
623 * |