MyServerSocketFactory.java 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. package de.tudarmstadt.informatik.hostage.net;
  2. import java.io.FileDescriptor;
  3. import java.io.IOException;
  4. import java.lang.reflect.Field;
  5. import java.net.InetAddress;
  6. import java.net.ServerSocket;
  7. import java.net.SocketImpl;
  8. import javax.net.ServerSocketFactory;
  9. import de.tudarmstadt.informatik.hostage.system.PrivilegedPort;
  10. public class MyServerSocketFactory extends ServerSocketFactory {
  11. /**
  12. * This method creates and returns a ServerSocket. A custom SocketImpl is
  13. * injected into the ServerSocket.
  14. */
  15. @Override
  16. public ServerSocket createServerSocket(int port) throws IOException {
  17. FileDescriptor fd = new PrivilegedPort(port).bindAndGetFD();
  18. ServerSocket socket = new ServerSocket();
  19. try {
  20. SocketImpl impl = getImpl(socket);
  21. injectFD(fd, impl);
  22. injectImpl(impl, socket);
  23. setBound(socket);
  24. } catch (Exception e) {
  25. e.printStackTrace();
  26. }
  27. return socket;
  28. }
  29. /**
  30. * Extracts the SocketImpl out of a ServerSocket.
  31. */
  32. private SocketImpl getImpl(ServerSocket socket) throws Exception {
  33. Field implField = socket.getClass().getDeclaredField("impl");
  34. implField.setAccessible(true);
  35. return (SocketImpl) implField.get(socket);
  36. }
  37. /**
  38. * Injects a FileDescriptor into a SocketImpl.
  39. */
  40. private void injectFD(FileDescriptor fd, SocketImpl impl) throws Exception {
  41. Class<?> plainServerSocketImplClazz = impl.getClass();
  42. Class<?> plainSocketImplClazz = plainServerSocketImplClazz
  43. .getSuperclass();
  44. Class<?> socketImplClazz = plainSocketImplClazz.getSuperclass();
  45. Field fdField = socketImplClazz.getDeclaredField("fd");
  46. fdField.setAccessible(true);
  47. fdField.set(impl, fd);
  48. }
  49. /**
  50. * Injects a SocketImpl into a ServerSocket.
  51. */
  52. private void injectImpl(SocketImpl impl, ServerSocket socket)
  53. throws Exception {
  54. Field implField = socket.getClass().getDeclaredField("impl");
  55. implField.setAccessible(true);
  56. implField.set(socket, impl);
  57. }
  58. /**
  59. * Sets the isBound Field of a ServerSocket to true.
  60. */
  61. private void setBound(ServerSocket socket) throws Exception {
  62. Field boundField = socket.getClass().getDeclaredField("isBound");
  63. boundField.setAccessible(true);
  64. boundField.set(socket, true);
  65. }
  66. /**
  67. * Must override.
  68. */
  69. @Override
  70. public ServerSocket createServerSocket(int port, int backlog)
  71. throws IOException {
  72. return createServerSocket(port);
  73. }
  74. /**
  75. * Must override.
  76. */
  77. @Override
  78. public ServerSocket createServerSocket(int port, int backlog,
  79. InetAddress iAddress) throws IOException {
  80. return createServerSocket(port);
  81. }
  82. }