Guest User

Untitled

a guest
Jun 20th, 2018
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.08 KB | None | 0 0
  1. Index: repy/repy_constants.py
  2. ===================================================================
  3. --- repy/repy_constants.py (revision 2326)
  4. +++ repy/repy_constants.py (working copy)
  5. @@ -32,3 +32,14 @@
  6. CPU_POLLING_FREQ_LINUX = .1 # Linux
  7. CPU_POLLING_FREQ_WIN = .1 # Windows
  8. CPU_POLLING_FREQ_WINCE = .5 # Mobile devices are pretty slow
  9. +
  10. +
  11. +# These IP addresses are used to resolve our external IP address
  12. +# We attempt to connect to these IP addresses, and then check our local IP
  13. +# These addresses were choosen since they have been historically very stable
  14. +# They are from public universities
  15. +STABLE_PUBLIC_IPS = ["18.7.22.69", # M.I.T
  16. + "171.67.216.8", # Stanford
  17. + "169.229.131.81", # Berkley
  18. + "140.142.12.202"] # Univ. of Washington
  19. +
  20. Index: repy/emulcomm.py
  21. ===================================================================
  22. --- repy/emulcomm.py (revision 2326)
  23. +++ repy/emulcomm.py (working copy)
  24. @@ -37,6 +37,9 @@
  25. # Armon: Used for decoding the error messages
  26. import errno
  27.  
  28. +# Armon: Used for getting the constant IP values for resolving our external IP
  29. +import repy_constants
  30. +
  31. # The architecture is that I have a thread which "polls" all of the sockets
  32. # that are being listened on using select. If a connection
  33. # oriented socket has a connection pending, or a message-based socket has a
  34. @@ -711,56 +714,75 @@
  35. # Return the first allowed ip, there is always at least 1 element (loopback)
  36. return allowediplist[0]
  37.  
  38. - # Open a connectionless socket
  39. - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  40. + # Initialize these to None, so we can detect a failure
  41. + myip = None
  42. +
  43. + # It's possible on some platforms (Windows Mobile) that the IP will be
  44. + # 0.0.0.0 even when I have a public IP and the external IP is up. However, if
  45. + # I get a real connection with SOCK_STREAM, then I should get the real
  46. + # answer.
  47. + for conn_type in [socket.SOCK_DGRAM, socket.SOCK_STREAM]:
  48. +
  49. + # Try each stable IP
  50. + for ip_addr in repy_constants.STABLE_PUBLIC_IPS:
  51. + try:
  52. + # Try to resolve using the current connection type and
  53. + # stable IP, using port 80 since some platforms panic
  54. + # when given 0 (FreeBSD)
  55. + myip = resolve_local_ip(conn_type, ip_addr, 80)
  56. + except Exception, e:
  57. + pass
  58. + else:
  59. + # Return immediately if the IP address is good
  60. + if myip != None and myip != '' and myip != "0.0.0.0":
  61. + return myip
  62.  
  63. - # Tell it to connect to google (we assume that the DNS entry for this works)
  64. - # however, using port 0 causes some issues on FreeBSD! I choose port 80
  65. - # instead...
  66. - try:
  67. - s.connect(('google.com', 80))
  68. - except Exception, e:
  69. - # I reraise the exception from here because exceptions raised by connect
  70. - # are treated as "from a string" which confuses the traceback printer
  71. - # unless I re-raise it here (then it lists my line which is culled)
  72. - raise e
  73.  
  74. - # and the IP of the interface this connects on is the first item of the tuple
  75. - (myip, localport) = s.getsockname()
  76. + # Since we haven't returned yet, we must have failed.
  77. + # Raise an exception, we must not be connected to the internet
  78. + raise Exception("Cannot detect a connection to the Internet.")
  79. +
  80. +
  81. +
  82. +def resolve_local_ip(connection_type, external_ip, external_port=80):
  83. + """
  84. + <Purpose>
  85. + Resolve the local ip used when connecting outbound to an external ip.
  86.  
  87. - s.close()
  88. + <Arguments>
  89. + connection_type:
  90. + The type of connection to attempt. See socket.socket().
  91. +
  92. + external_ip:
  93. + The external IP to attempt to connect to.
  94. +
  95. + external_port:
  96. + The port on the remote host to attempt to connect to.
  97. +
  98. + <Exceptions>
  99. + As with socket.socket(), socketobj.connect(), etc.
  100. +
  101. + <Returns>
  102. + The locally assigned IP for the connection.
  103. + """
  104. + # Open a socket
  105. + s = socket.socket(socket.AF_INET, connection_type)
  106.  
  107. + try:
  108. + s.connect((external_ip, external_port))
  109.  
  110. - if myip == '' or myip == '0.0.0.0':
  111. - # It's possible on some platforms (Windows Mobile) that the IP will be
  112. - # 0.0.0.0 even when I have a public IP and google is up. However, if
  113. - # I get a real connection with SOCK_STREAM, then I should get the real
  114. - # answer.
  115. - # I'll do much the same as before, only using SOCK_STREAM, which
  116. - # unfortunately will actually connect
  117. - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  118. - try:
  119. - s.connect(('google.com', 80))
  120. - except Exception, e:
  121. - raise e
  122. - (myip, localport) = s.getsockname()
  123. -
  124. + # Get the local connection information for this socket
  125. + (myip, localport) = s.getsockname()
  126. +
  127. + # Always close the socket
  128. + finally:
  129. s.close()
  130. -
  131. - if myip == '' or myip == '0.0.0.0':
  132. - # hmm, SOCK_STREAM failed too. Let's raise an exception...
  133. - raise Exception, "Cannot get external IP despite successful name resolution. Sockets do not seem to behave properly"
  134.  
  135. -
  136. return myip
  137.  
  138.  
  139.  
  140.  
  141. -
  142. -
  143. -
  144. -
Add Comment
Please, Sign In to add comment