Mercurial > libervia-backend
comparison src/plugins/plugin_misc_ip.py @ 1555:eb8aae35085b
plugin ip: local ip cache + DNS error detection
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 02 Nov 2015 22:02:41 +0100 |
parents | 6fa9e8c02c34 |
children | ec3848916ee8 |
comparison
equal
deleted
inserted
replaced
1554:e281ed2c21db | 1555:eb8aae35085b |
---|---|
25 from twisted.web import client as webclient | 25 from twisted.web import client as webclient |
26 from twisted.internet import defer | 26 from twisted.internet import defer |
27 from twisted.internet import reactor | 27 from twisted.internet import reactor |
28 from twisted.internet import protocol | 28 from twisted.internet import protocol |
29 from twisted.internet import endpoints | 29 from twisted.internet import endpoints |
30 from twisted.internet import error as internet_error | |
30 import urlparse | 31 import urlparse |
31 try: | 32 try: |
32 import netifaces | 33 import netifaces |
33 except ImportError: | 34 except ImportError: |
34 log.warning(u"netifaces is not available, it help discovering IPs, you can install it on https://pypi.python.org/pypi/netifaces") | 35 log.warning(u"netifaces is not available, it help discovering IPs, you can install it on https://pypi.python.org/pypi/netifaces") |
90 log.debug(u"NAT port plugin not available") | 91 log.debug(u"NAT port plugin not available") |
91 self._nat = None | 92 self._nat = None |
92 | 93 |
93 # XXX: cache is kept until SàT is restarted | 94 # XXX: cache is kept until SàT is restarted |
94 # if IP may have changed, use self.refreshIP | 95 # if IP may have changed, use self.refreshIP |
95 self._ip_cache = None | 96 self._external_ip_cache = None |
97 self._local_ip_cache = None | |
96 | 98 |
97 def refreshIP(self): | 99 def refreshIP(self): |
98 # FIXME: use a trigger instead ? | 100 # FIXME: use a trigger instead ? |
99 self._ip_cache = None | 101 self._external_ip_cache = None |
102 self._local_ip_cache = None | |
100 | 103 |
101 def _externalAllowed(self, profile): | 104 def _externalAllowed(self, profile): |
102 """Return value of parameter with autorisation of user to do external requests | 105 """Return value of parameter with autorisation of user to do external requests |
103 | 106 |
104 if parameter is not set, a dialog is shown to use to get its confirmation, and parameted is set according to answer | 107 if parameter is not set, a dialog is shown to use to get its confirmation, and parameted is set according to answer |
110 if allow_get_ip is None: | 113 if allow_get_ip is None: |
111 # we don't have autorisation from user yet to use get_ip, we ask him | 114 # we don't have autorisation from user yet to use get_ip, we ask him |
112 def setParam(allowed): | 115 def setParam(allowed): |
113 # FIXME: we need to use boolConst as setParam only manage str/unicode | 116 # FIXME: we need to use boolConst as setParam only manage str/unicode |
114 # need to be fixed when params will be refactored | 117 # need to be fixed when params will be refactored |
115 self.host.memory.setParam(GET_IP_NAME, C.boolConst(allow_get_ip), GET_IP_CATEGORY) | 118 self.host.memory.setParam(GET_IP_NAME, C.boolConst(allowed), GET_IP_CATEGORY) |
116 return allowed | 119 return allowed |
117 d = xml_tools.deferConfirm(self.host, _(GET_IP_CONFIRM), _(GET_IP_CONFIRM_TITLE), profile=profile) | 120 d = xml_tools.deferConfirm(self.host, _(GET_IP_CONFIRM), _(GET_IP_CONFIRM_TITLE), profile=profile) |
118 d.addCallback(setParam) | 121 d.addCallback(setParam) |
119 return d | 122 return d |
120 | 123 |
144 | 147 |
145 def _getIPFromExternal(self, ext_url): | 148 def _getIPFromExternal(self, ext_url): |
146 """Get local IP by doing a connection on an external url | 149 """Get local IP by doing a connection on an external url |
147 | 150 |
148 @param ext_utl(str): url to connect to | 151 @param ext_utl(str): url to connect to |
149 @return (defer.Deferred): return local IP | 152 @return (D(str)): return local IP |
150 """ | 153 """ |
151 url = urlparse.urlparse(ext_url) | 154 url = urlparse.urlparse(ext_url) |
152 port = url.port | 155 port = url.port |
153 if port is None: | 156 if port is None: |
154 if url.scheme=='http': | 157 if url.scheme=='http': |
180 @return (deferred): list of lan IP addresses | 183 @return (deferred): list of lan IP addresses |
181 or empty list if it can't be discovered | 184 or empty list if it can't be discovered |
182 if there are several addresses, the one used with the server is put first | 185 if there are several addresses, the one used with the server is put first |
183 """ | 186 """ |
184 # TODO: manage permission requesting (e.g. for UMTS link) | 187 # TODO: manage permission requesting (e.g. for UMTS link) |
188 if self._local_ip_cache is not None: | |
189 defer.returnValue(self._local_ip_cache) | |
185 client = self.host.getClient(profile) | 190 client = self.host.getClient(profile) |
186 addresses = [] | 191 addresses = [] |
187 | 192 |
188 # we first try our luck with netifaces | 193 # we first try our luck with netifaces |
189 if netifaces is not None: | 194 if netifaces is not None: |
219 allow_get_ip = yield self._externalAllowed(profile) | 224 allow_get_ip = yield self._externalAllowed(profile) |
220 | 225 |
221 if not allow_get_ip: | 226 if not allow_get_ip: |
222 defer.returnValue(addresses) | 227 defer.returnValue(addresses) |
223 | 228 |
224 ip_tuple = yield self._getIPFromExternal(GET_IP_PAGE) | 229 try: |
230 ip_tuple = yield self._getIPFromExternal(GET_IP_PAGE) | |
231 except Exception as internet_error.DNSLookupError: | |
232 log.warning(u"Can't access Domain Name System") | |
233 defer.returnValue(addresses) | |
225 self._insertFirst(addresses, ip_tuple.local) | 234 self._insertFirst(addresses, ip_tuple.local) |
226 defer.returnValue(addresses) | 235 defer.returnValue(addresses) |
227 | 236 |
228 | 237 |
229 @defer.inlineCallbacks | 238 @defer.inlineCallbacks |
231 """Try to discover external IP | 240 """Try to discover external IP |
232 | 241 |
233 @param profile: %(doc_profile)s | 242 @param profile: %(doc_profile)s |
234 @return (deferred): external IP address or None if it can't be discovered | 243 @return (deferred): external IP address or None if it can't be discovered |
235 """ | 244 """ |
236 if self._ip_cache is not None: | 245 if self._external_ip_cache is not None: |
237 defer.returnValue(self._ip_cache) | 246 defer.returnValue(self._external_ip_cache) |
238 | 247 |
239 # we first try with NAT-Port | 248 # we first try with NAT-Port |
240 if self._nat is not None: | 249 if self._nat is not None: |
241 nat_ip = yield self._nat.getIP() | 250 nat_ip = yield self._nat.getIP() |
242 if nat_ip is not None: | 251 if nat_ip is not None: |
252 self._external_ip_cache = nat_ip | |
243 defer.returnValue(nat_ip) | 253 defer.returnValue(nat_ip) |
244 | 254 |
245 # then by requesting external website | 255 # then by requesting external website |
246 allow_get_ip = yield self._externalAllowed(profile) | 256 allow_get_ip = yield self._externalAllowed(profile) |
247 ip = webclient.getPage(GET_IP_PAGE) if allow_get_ip else None | 257 try: |
258 ip = (yield webclient.getPage(GET_IP_PAGE)) if allow_get_ip else None | |
259 except internet_error.DNSLookupError: | |
260 log.warning(u"Can't access Domain Name System") | |
261 ip = None | |
262 else: | |
263 self._external_ip_cache = ip | |
248 defer.returnValue(ip) | 264 defer.returnValue(ip) |