MyServerSocketFactory.java 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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. /**
  11. * Server Socket Factory using the porthack.
  12. * @author Mihai Plasoianu
  13. */
  14. public class MyServerSocketFactory extends ServerSocketFactory {
  15. /**
  16. * This method creates and returns a ServerSocket. A custom SocketImpl is
  17. * injected into the ServerSocket.
  18. */
  19. @Override
  20. public ServerSocket createServerSocket(int port) throws IOException {
  21. FileDescriptor fd = new PrivilegedPort(port).bindAndGetFD();
  22. ServerSocket socket = new ServerSocket();
  23. try {
  24. SocketImpl impl = getImpl(socket);
  25. injectFD(fd, impl);
  26. injectImpl(impl, socket);
  27. setBound(socket);
  28. } catch (Exception e) {
  29. e.printStackTrace();
  30. }
  31. return socket;
  32. }
  33. /**
  34. * Extracts the SocketImpl out of a ServerSocket.
  35. */
  36. private SocketImpl getImpl(ServerSocket socket) throws Exception {
  37. Field implField = socket.getClass().getDeclaredField("impl");
  38. implField.setAccessible(true);
  39. return (SocketImpl) implField.get(socket);
  40. }
  41. /**
  42. * Injects a FileDescriptor into a SocketImpl.
  43. */
  44. private void injectFD(FileDescriptor fd, SocketImpl impl) throws Exception {
  45. Class<?> plainServerSocketImplClazz = impl.getClass();
  46. Class<?> plainSocketImplClazz = plainServerSocketImplClazz
  47. .getSuperclass();
  48. Class<?> socketImplClazz = plainSocketImplClazz.getSuperclass();
  49. Field fdField = socketImplClazz.getDeclaredField("fd");
  50. fdField.setAccessible(true);
  51. fdField.set(impl, fd);
  52. }
  53. /**
  54. * Injects a SocketImpl into a ServerSocket.
  55. */
  56. private void injectImpl(SocketImpl impl, ServerSocket socket)
  57. throws Exception {
  58. Field implField = socket.getClass().getDeclaredField("impl");
  59. implField.setAccessible(true);
  60. implField.set(socket, impl);
  61. }
  62. /**
  63. * Sets the isBound Field of a ServerSocket to true.
  64. */
  65. private void setBound(ServerSocket socket) throws Exception {
  66. Field boundField = socket.getClass().getDeclaredField("isBound");
  67. boundField.setAccessible(true);
  68. boundField.set(socket, true);
  69. }
  70. /**
  71. * Must override.
  72. */
  73. @Override
  74. public ServerSocket createServerSocket(int port, int backlog)
  75. throws IOException {
  76. return createServerSocket(port);
  77. }
  78. /**
  79. * Must override.
  80. */
  81. @Override
  82. public ServerSocket createServerSocket(int port, int backlog,
  83. InetAddress iAddress) throws IOException {
  84. return createServerSocket(port);
  85. }
  86. }