MyServerSocketFactory.java 2.9 KB

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