Show More
@@ -34,7 +34,7 from __future__ import absolute_import, | |||
|
34 | 34 | - hostinfo |
|
35 | 35 | ignore unknown DNS record types |
|
36 | 36 | fixes to name decoding |
|
37 |
works alongside other processes using port 5353 (e.g. |
|
|
37 | works alongside other processes using port 5353 (e.g. Mac OS X) | |
|
38 | 38 | tested against Mac OS X 10.3.2's mDNSResponder |
|
39 | 39 | corrections to removal of list entries for service browser""" |
|
40 | 40 | |
@@ -228,7 +228,8 class DNSEntry(object): | |||
|
228 | 228 | def __eq__(self, other): |
|
229 | 229 | """Equality test on name, type, and class""" |
|
230 | 230 | if isinstance(other, DNSEntry): |
|
231 |
return self.name == other.name and self.type == other.type and |
|
|
231 | return (self.name == other.name and self.type == other.type and | |
|
232 | self.clazz == other.clazz) | |
|
232 | 233 | return 0 |
|
233 | 234 | |
|
234 | 235 | def __ne__(self, other): |
@@ -251,7 +252,8 class DNSEntry(object): | |||
|
251 | 252 | |
|
252 | 253 | def toString(self, hdr, other): |
|
253 | 254 | """String representation with additional information""" |
|
254 | result = "%s[%s,%s" % (hdr, self.getType(self.type), self.getClazz(self.clazz)) | |
|
255 | result = ("%s[%s,%s" % | |
|
256 | (hdr, self.getType(self.type), self.getClazz(self.clazz))) | |
|
255 | 257 | if self.unique: |
|
256 | 258 | result += "-unique," |
|
257 | 259 | else: |
@@ -273,7 +275,9 class DNSQuestion(DNSEntry): | |||
|
273 | 275 | |
|
274 | 276 | def answeredBy(self, rec): |
|
275 | 277 | """Returns true if the question is answered by the record""" |
|
276 | return self.clazz == rec.clazz and (self.type == rec.type or self.type == _TYPE_ANY) and self.name == rec.name | |
|
278 | return (self.clazz == rec.clazz and | |
|
279 | (self.type == rec.type or self.type == _TYPE_ANY) and | |
|
280 | self.name == rec.name) | |
|
277 | 281 | |
|
278 | 282 | def __repr__(self): |
|
279 | 283 | """String representation""" |
@@ -338,7 +342,8 class DNSRecord(DNSEntry): | |||
|
338 | 342 | |
|
339 | 343 | def toString(self, other): |
|
340 | 344 | """String representation with additional information""" |
|
341 | arg = "%s/%s,%s" % (self.ttl, self.getRemainingTTL(currentTimeMillis()), other) | |
|
345 | arg = ("%s/%s,%s" % | |
|
346 | (self.ttl, self.getRemainingTTL(currentTimeMillis()), other)) | |
|
342 | 347 | return DNSEntry.toString(self, "record", arg) |
|
343 | 348 | |
|
344 | 349 | class DNSAddress(DNSRecord): |
@@ -453,7 +458,10 class DNSService(DNSRecord): | |||
|
453 | 458 | def __eq__(self, other): |
|
454 | 459 | """Tests equality on priority, weight, port and server""" |
|
455 | 460 | if isinstance(other, DNSService): |
|
456 | return self.priority == other.priority and self.weight == other.weight and self.port == other.port and self.server == other.server | |
|
461 | return (self.priority == other.priority and | |
|
462 | self.weight == other.weight and | |
|
463 | self.port == other.port and | |
|
464 | self.server == other.server) | |
|
457 | 465 | return 0 |
|
458 | 466 | |
|
459 | 467 | def __repr__(self): |
@@ -498,7 +506,8 class DNSIncoming(object): | |||
|
498 | 506 | length = struct.calcsize(format) |
|
499 | 507 | for i in range(0, self.numQuestions): |
|
500 | 508 | name = self.readName() |
|
501 |
info = struct.unpack(format, |
|
|
509 | info = struct.unpack(format, | |
|
510 | self.data[self.offset:self.offset+length]) | |
|
502 | 511 | self.offset += length |
|
503 | 512 | |
|
504 | 513 | try: |
@@ -538,28 +547,39 class DNSIncoming(object): | |||
|
538 | 547 | return info[0] |
|
539 | 548 | |
|
540 | 549 | def readOthers(self): |
|
541 |
"""Reads |
|
|
550 | """Reads answers, authorities and additionals section of the packet""" | |
|
542 | 551 | format = '!HHiH' |
|
543 | 552 | length = struct.calcsize(format) |
|
544 | 553 | n = self.numAnswers + self.numAuthorities + self.numAdditionals |
|
545 | 554 | for i in range(0, n): |
|
546 | 555 | domain = self.readName() |
|
547 |
info = struct.unpack(format, |
|
|
556 | info = struct.unpack(format, | |
|
557 | self.data[self.offset:self.offset+length]) | |
|
548 | 558 | self.offset += length |
|
549 | 559 | |
|
550 | 560 | rec = None |
|
551 | 561 | if info[0] == _TYPE_A: |
|
552 |
rec = DNSAddress(domain, info[0], info[1], info[2], |
|
|
562 | rec = DNSAddress(domain, info[0], info[1], info[2], | |
|
563 | self.readString(4)) | |
|
553 | 564 | elif info[0] == _TYPE_CNAME or info[0] == _TYPE_PTR: |
|
554 |
rec = DNSPointer(domain, info[0], info[1], info[2], |
|
|
565 | rec = DNSPointer(domain, info[0], info[1], info[2], | |
|
566 | self.readName()) | |
|
555 | 567 | elif info[0] == _TYPE_TXT: |
|
556 |
rec = DNSText(domain, info[0], info[1], info[2], |
|
|
568 | rec = DNSText(domain, info[0], info[1], info[2], | |
|
569 | self.readString(info[3])) | |
|
557 | 570 | elif info[0] == _TYPE_SRV: |
|
558 | rec = DNSService(domain, info[0], info[1], info[2], self.readUnsignedShort(), self.readUnsignedShort(), self.readUnsignedShort(), self.readName()) | |
|
571 | rec = DNSService(domain, info[0], info[1], info[2], | |
|
572 | self.readUnsignedShort(), | |
|
573 | self.readUnsignedShort(), | |
|
574 | self.readUnsignedShort(), | |
|
575 | self.readName()) | |
|
559 | 576 | elif info[0] == _TYPE_HINFO: |
|
560 |
rec = DNSHinfo(domain, info[0], info[1], info[2], |
|
|
577 | rec = DNSHinfo(domain, info[0], info[1], info[2], | |
|
578 | self.readCharacterString(), | |
|
579 | self.readCharacterString()) | |
|
561 | 580 | elif info[0] == _TYPE_AAAA: |
|
562 |
rec = DNSAddress(domain, info[0], info[1], info[2], |
|
|
581 | rec = DNSAddress(domain, info[0], info[1], info[2], | |
|
582 | self.readString(16)) | |
|
563 | 583 | else: |
|
564 | 584 | # Try to ignore types we don't know about |
|
565 | 585 | # this may mean the rest of the name is |
@@ -972,7 +992,8 class ServiceBrowser(threading.Thread): | |||
|
972 | 992 | |
|
973 | 993 | self.done = 0 |
|
974 | 994 | |
|
975 |
self.zeroconf.addListener(self, DNSQuestion(self.type, _TYPE_PTR, |
|
|
995 | self.zeroconf.addListener(self, DNSQuestion(self.type, _TYPE_PTR, | |
|
996 | _CLASS_IN)) | |
|
976 | 997 | self.start() |
|
977 | 998 | |
|
978 | 999 | def updateRecord(self, zeroconf, now, record): |
@@ -987,13 +1008,15 class ServiceBrowser(threading.Thread): | |||
|
987 | 1008 | oldrecord.resetTTL(record) |
|
988 | 1009 | else: |
|
989 | 1010 | del(self.services[record.alias.lower()]) |
|
990 | callback = lambda x: self.listener.removeService(x, self.type, record.alias) | |
|
1011 | callback = (lambda x: | |
|
1012 | self.listener.removeService(x, self.type, record.alias)) | |
|
991 | 1013 | self.list.append(callback) |
|
992 | 1014 | return |
|
993 | 1015 | except Exception: |
|
994 | 1016 | if not expired: |
|
995 | 1017 | self.services[record.alias.lower()] = record |
|
996 | callback = lambda x: self.listener.addService(x, self.type, record.alias) | |
|
1018 | callback = (lambda x: | |
|
1019 | self.listener.addService(x, self.type, record.alias)) | |
|
997 | 1020 | self.list.append(callback) |
|
998 | 1021 | |
|
999 | 1022 | expires = record.getExpirationTime(75) |
@@ -1034,7 +1057,8 class ServiceBrowser(threading.Thread): | |||
|
1034 | 1057 | class ServiceInfo(object): |
|
1035 | 1058 | """Service information""" |
|
1036 | 1059 | |
|
1037 |
def __init__(self, type, name, address=None, port=None, weight=0, |
|
|
1060 | def __init__(self, type, name, address=None, port=None, weight=0, | |
|
1061 | priority=0, properties=None, server=None): | |
|
1038 | 1062 | """Create a service description. |
|
1039 | 1063 | |
|
1040 | 1064 | type: fully qualified service type name |
@@ -1043,7 +1067,8 class ServiceInfo(object): | |||
|
1043 | 1067 | port: port that the service runs on |
|
1044 | 1068 | weight: weight of the service |
|
1045 | 1069 | priority: priority of the service |
|
1046 |
properties: dictionary of properties (or a string holding the bytes for |
|
|
1070 | properties: dictionary of properties (or a string holding the bytes for | |
|
1071 | the text field) | |
|
1047 | 1072 | server: fully qualified name for service host (defaults to name)""" |
|
1048 | 1073 | |
|
1049 | 1074 | if not name.endswith(type): |
@@ -1081,7 +1106,8 class ServiceInfo(object): | |||
|
1081 | 1106 | suffix = '' |
|
1082 | 1107 | list.append('='.join((key, suffix))) |
|
1083 | 1108 | for item in list: |
|
1084 |
result = ''.join((result, struct.pack('!c', chr(len(item))), |
|
|
1109 | result = ''.join((result, struct.pack('!c', chr(len(item))), | |
|
1110 | item)) | |
|
1085 | 1111 | self.text = result |
|
1086 | 1112 | else: |
|
1087 | 1113 | self.text = properties |
@@ -1175,7 +1201,9 class ServiceInfo(object): | |||
|
1175 | 1201 | self.weight = record.weight |
|
1176 | 1202 | self.priority = record.priority |
|
1177 | 1203 | #self.address = None |
|
1178 |
self.updateRecord(zeroconf, now, |
|
|
1204 | self.updateRecord(zeroconf, now, | |
|
1205 | zeroconf.cache.getByDetails(self.server, | |
|
1206 | _TYPE_A, _CLASS_IN)) | |
|
1179 | 1207 | elif record.type == _TYPE_TXT: |
|
1180 | 1208 | if record.name == self.name: |
|
1181 | 1209 | self.setText(record.text) |
@@ -1190,19 +1218,34 class ServiceInfo(object): | |||
|
1190 | 1218 | last = now + timeout |
|
1191 | 1219 | result = 0 |
|
1192 | 1220 | try: |
|
1193 |
zeroconf.addListener(self, DNSQuestion(self.name, _TYPE_ANY, |
|
|
1194 | while self.server is None or self.address is None or self.text is None: | |
|
1221 | zeroconf.addListener(self, DNSQuestion(self.name, _TYPE_ANY, | |
|
1222 | _CLASS_IN)) | |
|
1223 | while (self.server is None or self.address is None or | |
|
1224 | self.text is None): | |
|
1195 | 1225 | if last <= now: |
|
1196 | 1226 | return 0 |
|
1197 | 1227 | if next <= now: |
|
1198 | 1228 | out = DNSOutgoing(_FLAGS_QR_QUERY) |
|
1199 |
out.addQuestion(DNSQuestion(self.name, _TYPE_SRV, |
|
|
1200 | out.addAnswerAtTime(zeroconf.cache.getByDetails(self.name, _TYPE_SRV, _CLASS_IN), now) | |
|
1201 | out.addQuestion(DNSQuestion(self.name, _TYPE_TXT, _CLASS_IN)) | |
|
1202 |
|
|
|
1229 | out.addQuestion(DNSQuestion(self.name, _TYPE_SRV, | |
|
1230 | _CLASS_IN)) | |
|
1231 | out.addAnswerAtTime( | |
|
1232 | zeroconf.cache.getByDetails(self.name, | |
|
1233 | _TYPE_SRV, | |
|
1234 | _CLASS_IN), | |
|
1235 | now) | |
|
1236 | out.addQuestion(DNSQuestion(self.name, _TYPE_TXT, | |
|
1237 | _CLASS_IN)) | |
|
1238 | out.addAnswerAtTime( | |
|
1239 | zeroconf.cache.getByDetails(self.name, _TYPE_TXT, | |
|
1240 | _CLASS_IN), | |
|
1241 | now) | |
|
1203 | 1242 | if self.server is not None: |
|
1204 |
out.addQuestion( |
|
|
1205 |
|
|
|
1243 | out.addQuestion( | |
|
1244 | DNSQuestion(self.server, _TYPE_A, _CLASS_IN)) | |
|
1245 | out.addAnswerAtTime( | |
|
1246 | zeroconf.cache.getByDetails(self.server, _TYPE_A, | |
|
1247 | _CLASS_IN), | |
|
1248 | now) | |
|
1206 | 1249 | zeroconf.send(out) |
|
1207 | 1250 | next = now + delay |
|
1208 | 1251 | delay = delay * 2 |
@@ -1227,7 +1270,8 class ServiceInfo(object): | |||
|
1227 | 1270 | |
|
1228 | 1271 | def __repr__(self): |
|
1229 | 1272 | """String representation""" |
|
1230 | result = "service[%s,%s:%s," % (self.name, socket.inet_ntoa(self.getAddress()), self.port) | |
|
1273 | result = ("service[%s,%s:%s," % | |
|
1274 | (self.name, socket.inet_ntoa(self.getAddress()), self.port)) | |
|
1231 | 1275 | if self.text is None: |
|
1232 | 1276 | result += "None" |
|
1233 | 1277 | else: |
@@ -1276,7 +1320,8 class Zeroconf(object): | |||
|
1276 | 1320 | # Some versions of linux raise an exception even though |
|
1277 | 1321 | # SO_REUSEADDR and SO_REUSEPORT have been set, so ignore it |
|
1278 | 1322 | pass |
|
1279 |
self.socket.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, |
|
|
1323 | self.socket.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, | |
|
1324 | socket.inet_aton(_MDNS_ADDR) + socket.inet_aton('0.0.0.0')) | |
|
1280 | 1325 | |
|
1281 | 1326 | self.listeners = [] |
|
1282 | 1327 | self.browsers = [] |
@@ -1353,11 +1398,20 class Zeroconf(object): | |||
|
1353 | 1398 | now = currentTimeMillis() |
|
1354 | 1399 | continue |
|
1355 | 1400 | out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA) |
|
1356 |
out.addAnswerAtTime(DNSPointer(info.type, _TYPE_PTR, |
|
|
1357 | out.addAnswerAtTime(DNSService(info.name, _TYPE_SRV, _CLASS_IN, ttl, info.priority, info.weight, info.port, info.server), 0) | |
|
1358 | out.addAnswerAtTime(DNSText(info.name, _TYPE_TXT, _CLASS_IN, ttl, info.text), 0) | |
|
1401 | out.addAnswerAtTime(DNSPointer(info.type, _TYPE_PTR, | |
|
1402 | _CLASS_IN, ttl, info.name), 0) | |
|
1403 | out.addAnswerAtTime( | |
|
1404 | DNSService( | |
|
1405 | info.name, _TYPE_SRV, | |
|
1406 | _CLASS_IN, ttl, info.priority, info.weight, info.port, | |
|
1407 | info.server), | |
|
1408 | 0) | |
|
1409 | out.addAnswerAtTime( | |
|
1410 | DNSText(info.name, _TYPE_TXT, _CLASS_IN, ttl, info.text), | |
|
1411 | 0) | |
|
1359 | 1412 | if info.address: |
|
1360 |
out.addAnswerAtTime(DNSAddress(info.server, _TYPE_A, |
|
|
1413 | out.addAnswerAtTime(DNSAddress(info.server, _TYPE_A, | |
|
1414 | _CLASS_IN, ttl, info.address), 0) | |
|
1361 | 1415 | self.send(out) |
|
1362 | 1416 | i += 1 |
|
1363 | 1417 | nextTime += _REGISTER_TIME |
@@ -1381,11 +1435,18 class Zeroconf(object): | |||
|
1381 | 1435 | now = currentTimeMillis() |
|
1382 | 1436 | continue |
|
1383 | 1437 | out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA) |
|
1384 | out.addAnswerAtTime(DNSPointer(info.type, _TYPE_PTR, _CLASS_IN, 0, info.name), 0) | |
|
1385 |
|
|
|
1386 | out.addAnswerAtTime(DNSText(info.name, _TYPE_TXT, _CLASS_IN, 0, info.text), 0) | |
|
1438 | out.addAnswerAtTime( | |
|
1439 | DNSPointer(info.type, _TYPE_PTR, _CLASS_IN, 0, info.name), 0) | |
|
1440 | out.addAnswerAtTime( | |
|
1441 | DNSService(info.name, _TYPE_SRV, | |
|
1442 | _CLASS_IN, 0, info.priority, info.weight, info.port, | |
|
1443 | info.name), | |
|
1444 | 0) | |
|
1445 | out.addAnswerAtTime(DNSText(info.name, _TYPE_TXT, | |
|
1446 | _CLASS_IN, 0, info.text), 0) | |
|
1387 | 1447 | if info.address: |
|
1388 |
out.addAnswerAtTime(DNSAddress(info.server, _TYPE_A, |
|
|
1448 | out.addAnswerAtTime(DNSAddress(info.server, _TYPE_A, | |
|
1449 | _CLASS_IN, 0, info.address), 0) | |
|
1389 | 1450 | self.send(out) |
|
1390 | 1451 | i += 1 |
|
1391 | 1452 | nextTime += _UNREGISTER_TIME |
@@ -1403,11 +1464,18 class Zeroconf(object): | |||
|
1403 | 1464 | continue |
|
1404 | 1465 | out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA) |
|
1405 | 1466 | for info in self.services.values(): |
|
1406 |
out.addAnswerAtTime(DNSPointer(info.type, _TYPE_PTR, |
|
|
1407 | out.addAnswerAtTime(DNSService(info.name, _TYPE_SRV, _CLASS_IN, 0, info.priority, info.weight, info.port, info.server), 0) | |
|
1408 | out.addAnswerAtTime(DNSText(info.name, _TYPE_TXT, _CLASS_IN, 0, info.text), 0) | |
|
1467 | out.addAnswerAtTime(DNSPointer(info.type, _TYPE_PTR, | |
|
1468 | _CLASS_IN, 0, info.name), 0) | |
|
1469 | out.addAnswerAtTime( | |
|
1470 | DNSService(info.name, _TYPE_SRV, | |
|
1471 | _CLASS_IN, 0, info.priority, info.weight, | |
|
1472 | info.port, info.server), | |
|
1473 | 0) | |
|
1474 | out.addAnswerAtTime(DNSText(info.name, _TYPE_TXT, | |
|
1475 | _CLASS_IN, 0, info.text), 0) | |
|
1409 | 1476 | if info.address: |
|
1410 |
out.addAnswerAtTime(DNSAddress(info.server, _TYPE_A, |
|
|
1477 | out.addAnswerAtTime(DNSAddress(info.server, _TYPE_A, | |
|
1478 | _CLASS_IN, 0, info.address), 0) | |
|
1411 | 1479 | self.send(out) |
|
1412 | 1480 | i += 1 |
|
1413 | 1481 | nextTime += _UNREGISTER_TIME |
@@ -1420,9 +1488,11 class Zeroconf(object): | |||
|
1420 | 1488 | i = 0 |
|
1421 | 1489 | while i < 3: |
|
1422 | 1490 | for record in self.cache.entriesWithName(info.type): |
|
1423 |
if record.type == _TYPE_PTR and not record.isExpired(now) and |
|
|
1491 | if (record.type == _TYPE_PTR and not record.isExpired(now) and | |
|
1492 | record.alias == info.name): | |
|
1424 | 1493 | if (info.name.find('.') < 0): |
|
1425 | info.name = info.name + ".[" + info.address + ":" + info.port + "]." + info.type | |
|
1494 | info.name = ("%w.[%s:%d].%s" % | |
|
1495 | (info.name, info.address, info.port, info.type)) | |
|
1426 | 1496 | self.checkService(info) |
|
1427 | 1497 | return |
|
1428 | 1498 | raise NonUniqueNameException |
@@ -1433,7 +1503,8 class Zeroconf(object): | |||
|
1433 | 1503 | out = DNSOutgoing(_FLAGS_QR_QUERY | _FLAGS_AA) |
|
1434 | 1504 | self.debug = out |
|
1435 | 1505 | out.addQuestion(DNSQuestion(info.type, _TYPE_PTR, _CLASS_IN)) |
|
1436 |
out.addAuthoritativeAnswer(DNSPointer(info.type, _TYPE_PTR, |
|
|
1506 | out.addAuthoritativeAnswer(DNSPointer(info.type, _TYPE_PTR, | |
|
1507 | _CLASS_IN, _DNS_TTL, info.name)) | |
|
1437 | 1508 | self.send(out) |
|
1438 | 1509 | i += 1 |
|
1439 | 1510 | nextTime += _CHECK_TIME |
@@ -1502,12 +1573,17 class Zeroconf(object): | |||
|
1502 | 1573 | for stype in self.servicetypes.keys(): |
|
1503 | 1574 | if out is None: |
|
1504 | 1575 | out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA) |
|
1505 | out.addAnswer(msg, DNSPointer("_services._dns-sd._udp.local.", _TYPE_PTR, _CLASS_IN, _DNS_TTL, stype)) | |
|
1576 | out.addAnswer(msg, | |
|
1577 | DNSPointer( | |
|
1578 | "_services._dns-sd._udp.local.", | |
|
1579 | _TYPE_PTR, _CLASS_IN, | |
|
1580 | _DNS_TTL, stype)) | |
|
1506 | 1581 | for service in self.services.values(): |
|
1507 | 1582 | if question.name == service.type: |
|
1508 | 1583 | if out is None: |
|
1509 | 1584 | out = DNSOutgoing(_FLAGS_QR_RESPONSE | _FLAGS_AA) |
|
1510 |
out.addAnswer(msg, DNSPointer(service.type, _TYPE_PTR, |
|
|
1585 | out.addAnswer(msg, DNSPointer(service.type, _TYPE_PTR, | |
|
1586 | _CLASS_IN, _DNS_TTL, service.name)) | |
|
1511 | 1587 | else: |
|
1512 | 1588 | try: |
|
1513 | 1589 | if out is None: |
@@ -1517,17 +1593,31 class Zeroconf(object): | |||
|
1517 | 1593 | if question.type == _TYPE_A or question.type == _TYPE_ANY: |
|
1518 | 1594 | for service in self.services.values(): |
|
1519 | 1595 | if service.server == question.name.lower(): |
|
1520 | out.addAnswer(msg, DNSAddress(question.name, _TYPE_A, _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.address)) | |
|
1596 | out.addAnswer(msg, | |
|
1597 | DNSAddress(question.name, _TYPE_A, | |
|
1598 | _CLASS_IN | _CLASS_UNIQUE, | |
|
1599 | _DNS_TTL, service.address)) | |
|
1521 | 1600 | |
|
1522 | 1601 | service = self.services.get(question.name.lower(), None) |
|
1523 | 1602 | if not service: continue |
|
1524 | 1603 | |
|
1525 |
if question.type == _TYPE_SRV or |
|
|
1526 | out.addAnswer(msg, DNSService(question.name, _TYPE_SRV, _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.priority, service.weight, service.port, service.server)) | |
|
1527 | if question.type == _TYPE_TXT or question.type == _TYPE_ANY: | |
|
1528 | out.addAnswer(msg, DNSText(question.name, _TYPE_TXT, _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.text)) | |
|
1604 | if (question.type == _TYPE_SRV or | |
|
1605 | question.type == _TYPE_ANY): | |
|
1606 | out.addAnswer(msg, | |
|
1607 | DNSService(question.name, _TYPE_SRV, | |
|
1608 | _CLASS_IN | _CLASS_UNIQUE, | |
|
1609 | _DNS_TTL, service.priority, | |
|
1610 | service.weight, service.port, | |
|
1611 | service.server)) | |
|
1612 | if (question.type == _TYPE_TXT or | |
|
1613 | question.type == _TYPE_ANY): | |
|
1614 | out.addAnswer(msg, DNSText(question.name, _TYPE_TXT, | |
|
1615 | _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.text)) | |
|
1529 | 1616 | if question.type == _TYPE_SRV: |
|
1530 | out.addAdditionalAnswer(DNSAddress(service.server, _TYPE_A, _CLASS_IN | _CLASS_UNIQUE, _DNS_TTL, service.address)) | |
|
1617 | out.addAdditionalAnswer( | |
|
1618 | DNSAddress(service.server, _TYPE_A, | |
|
1619 | _CLASS_IN | _CLASS_UNIQUE, | |
|
1620 | _DNS_TTL, service.address)) | |
|
1531 | 1621 | except Exception: |
|
1532 | 1622 | traceback.print_exc() |
|
1533 | 1623 | |
@@ -1553,7 +1643,8 class Zeroconf(object): | |||
|
1553 | 1643 | self.notifyAll() |
|
1554 | 1644 | self.engine.notify() |
|
1555 | 1645 | self.unregisterAllServices() |
|
1556 |
self.socket.setsockopt(socket.SOL_IP, socket.IP_DROP_MEMBERSHIP, |
|
|
1646 | self.socket.setsockopt(socket.SOL_IP, socket.IP_DROP_MEMBERSHIP, | |
|
1647 | socket.inet_aton(_MDNS_ADDR) + socket.inet_aton('0.0.0.0')) | |
|
1557 | 1648 | self.socket.close() |
|
1558 | 1649 | |
|
1559 | 1650 | # Test a few module features, including service registration, service |
@@ -1564,15 +1655,20 if __name__ == '__main__': | |||
|
1564 | 1655 | r = Zeroconf() |
|
1565 | 1656 | print("1. Testing registration of a service...") |
|
1566 | 1657 | desc = {'version':'0.10','a':'test value', 'b':'another value'} |
|
1567 | info = ServiceInfo("_http._tcp.local.", "My Service Name._http._tcp.local.", socket.inet_aton("127.0.0.1"), 1234, 0, 0, desc) | |
|
1658 | info = ServiceInfo("_http._tcp.local.", | |
|
1659 | "My Service Name._http._tcp.local.", | |
|
1660 | socket.inet_aton("127.0.0.1"), 1234, 0, 0, desc) | |
|
1568 | 1661 | print(" Registering service...") |
|
1569 | 1662 | r.registerService(info) |
|
1570 | 1663 | print(" Registration done.") |
|
1571 | 1664 | print("2. Testing query of service information...") |
|
1572 | print(" Getting ZOE service:", str(r.getServiceInfo("_http._tcp.local.", "ZOE._http._tcp.local."))) | |
|
1665 | print(" Getting ZOE service:", | |
|
1666 | str(r.getServiceInfo("_http._tcp.local.", "ZOE._http._tcp.local."))) | |
|
1573 | 1667 | print(" Query done.") |
|
1574 | 1668 | print("3. Testing query of own service...") |
|
1575 | print(" Getting self:", str(r.getServiceInfo("_http._tcp.local.", "My Service Name._http._tcp.local."))) | |
|
1669 | print(" Getting self:", | |
|
1670 | str(r.getServiceInfo("_http._tcp.local.", | |
|
1671 | "My Service Name._http._tcp.local."))) | |
|
1576 | 1672 | print(" Query done.") |
|
1577 | 1673 | print("4. Testing unregister of service information...") |
|
1578 | 1674 | r.unregisterService(info) |
General Comments 0
You need to be logged in to leave comments.
Login now