MyServerSocketFactory.java 2.9 KB

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