diff --git a/hplip-mdns-retry-query.patch b/hplip-mdns-retry-query.patch new file mode 100644 index 0000000..bde0179 --- /dev/null +++ b/hplip-mdns-retry-query.patch @@ -0,0 +1,86 @@ +diff --git a/protocol/discovery/mdns.c b/protocol/discovery/mdns.c +index 92e153a..75ef0ea 100644 +--- a/protocol/discovery/mdns.c ++++ b/protocol/discovery/mdns.c +@@ -436,7 +436,7 @@ static int mdns_read_single_response(int udp_socket, char *recvbuffer, int recvb + FD_SET(udp_socket, &master); + maxfd = udp_socket; + tmo.tv_sec = 0; +- tmo.tv_usec = 300000; ++ tmo.tv_usec = 10000; + + readfd = master; + ret = select(maxfd + 1, &readfd, NULL, NULL, &tmo); +@@ -549,6 +549,34 @@ static void mdns_rr_cleanup(DNS_RECORD *rr) + } + } + ++static DNS_RECORD* send_and_receive(struct mdns_socket *mdns_sock, ++ const char *name, ++ int query_type, int read_mode) ++{ ++ /* wait up to ~1s */ ++ const useconds_t DELTA_T = 251000; ++ const int RETRIES = 8; ++ int retry = RETRIES; ++ DNS_RECORD *rr_list; ++ ++ while (retry) { ++ if (mdns_send_query(mdns_sock, name, query_type) == MDNS_STATUS_OK) { ++ rr_list = mdns_read_responses(mdns_sock->socket, read_mode, name); ++ if (rr_list != NULL) { ++ DBG("send_and_receive: got response after %d retries\n", ++ RETRIES - retry); ++ return rr_list; ++ } ++ } ++ /* MDNS servers delay responses. If the server just responded ++ * to some query (maybe an earlier one we sent), we may need to wait. */ ++ --retry; ++ usleep(DELTA_T); ++ } ++ BUG("send_and_receive: no response after %d retries\n", RETRIES); ++ return NULL; ++} ++ + int mdns_probe_nw_scanners(char* uris_buf, int buf_size, int *count) + { + int n = 0, bytes_read = 0; +@@ -562,11 +590,7 @@ int mdns_probe_nw_scanners(char* uris_buf, int buf_size, int *count) + if (mdns_open_socket(&mdns_sock) != MDNS_STATUS_OK) + goto bugout; + +- /* Send dns query */ +- mdns_send_query(&mdns_sock, scanner_name, QTYPE_PTR); +- +- /* Read Responses */ +- rr_list = mdns_read_responses(mdns_sock.socket, MODE_READ_ALL, scanner_name); ++ rr_list = send_and_receive(&mdns_sock, scanner_name, QTYPE_PTR, MODE_READ_ALL); + + /* Update URIs buffer */ + bytes_read = mdns_update_uris(rr_list, uris_buf, buf_size, count); +@@ -598,10 +622,8 @@ int mdns_lookup(char* hostname, unsigned char* ip) + + /* Send dns query */ + sprintf(fqdn, "%s.local", hostname); +- mdns_send_query(&mdns_sock, fqdn, QTYPE_A); + +- /* Read Responses */ +- rr_list = mdns_read_responses(mdns_sock.socket, MODE_READ_SINGLE, fqdn); ++ rr_list = send_and_receive(&mdns_sock, fqdn, QTYPE_A, MODE_READ_SINGLE); + + /* Update IP Address buffer */ + if(rr_list) +diff --git a/protocol/discovery/mdns.h b/protocol/discovery/mdns.h +index 34066fb..56d8847 100644 +--- a/protocol/discovery/mdns.h ++++ b/protocol/discovery/mdns.h +@@ -102,5 +102,8 @@ static int mdns_parse_respponse(unsigned char *Response, DNS_RECORD *rr); + static void mdns_rr_cleanup(DNS_RECORD *rr); + static DNS_RECORD *mdns_read_responses(int udp_socket, int mode, const char *question); + static unsigned char* mdns_readMDL(unsigned char *p, unsigned char *normalized_mdl, int len); ++static DNS_RECORD* send_and_receive(struct mdns_socket *mdns_sock, const char *name, ++ int query_type, int read_mode); ++static int get_ipv4_address(const char *iface, struct in_addr *addr); + #endif // _DISCOVERY_MDNS_H + diff --git a/hplip-mdns.patch b/hplip-mdns.patch new file mode 100644 index 0000000..49370de --- /dev/null +++ b/hplip-mdns.patch @@ -0,0 +1,553 @@ +diff --git a/base/mdns.py b/base/mdns.py +index 03bdb92..11d08b8 100644 +--- a/base/mdns.py ++++ b/base/mdns.py +@@ -35,6 +35,17 @@ from .g import * + from . import utils + from .sixext import BytesIO, to_bytes_utf8, to_bytes_latin, to_string_latin + ++if hasattr(socket, "if_nameindex"): ++ if_nameindex = socket.if_nameindex ++else: ++ def _if_nameindex(): ++ """"Poor man's if_nameindex for Python 2.""" ++ import os ++ sysdir = "/sys/class/net" ++ return sorted([ (int(open("%s/%s/ifindex" % (sysdir, iface), "r").read(), 0), iface) ++ for iface in os.listdir(sysdir) ]) ++ if_nameindex = _if_nameindex ++ + MAX_ANSWERS_PER_PACKET = 24 + + QTYPE_A = 1 +@@ -45,6 +56,8 @@ QTYPE_PTR = 12 + + QCLASS_IN = 1 + ++MCAST_ADDR='224.0.0.251' ++ + # Caller needs to ensure, data should be in string format. + def read_utf8(offset, data, l): + return offset+l, data[offset:offset+l] +@@ -188,11 +201,6 @@ def createSocketsWithsetOption(ttl=4): + s=None + try: + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) +- x = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) +- x.connect(('1.2.3.4', 56)) +- intf = x.getsockname()[0] +- x.close() +- + s.setblocking(0) + ttl = struct.pack('B', ttl) + except socket.error: +@@ -209,14 +217,42 @@ def createSocketsWithsetOption(ttl=4): + + try: + s.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_TTL, ttl) +- s.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, socket.inet_aton(intf) + socket.inet_aton('0.0.0.0')) + s.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_LOOP ,1) + except Exception as e: + log.error("Unable to setup multicast socket for mDNS: %s" % e) + if s: + s.close() + return None +- return s ++ ++ ifaces = [] ++ for idx, name in if_nameindex(): ++ mreqn = struct.pack("=4sii", socket.inet_aton(MCAST_ADDR), ++ socket.ntohl(socket.INADDR_ANY), idx) ++ try: ++ s.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, mreqn) ++ except Exception as e: ++ log.debug("Failed to join multicast group on interface %s: %s" % ++ (name, e)) ++ else: ++ log.debug("Joined multicast group on interface %s" % name) ++ ifaces.append((idx, name)) ++ ++ if len(ifaces) == 0: ++ log.error("failed to join multicast group on any interface") ++ s.close() ++ return None ++ ++ return (s, ifaces) ++ ++def closeSocket(s): ++ for idx, name in if_nameindex(): ++ mreqn = struct.pack("=4sii", socket.inet_aton(MCAST_ADDR), ++ socket.ntohl(socket.INADDR_ANY), idx) ++ try: ++ s.setsockopt(socket.SOL_IP, socket.IP_DROP_MEMBERSHIP, mreqn) ++ except Exception: ++ pass ++ s.close() + + def updateReceivedData(data, answers): + update_spinner() +@@ -299,13 +335,22 @@ def updateReceivedData(data, answers): + break + return y, answers + ++def send_packets(s, answers, name, mcast_addr, mcast_port): ++ for p in create_outgoing_packets(answers): ++ log.debug("Outgoing on %s: (%d)" % (name, len(p))) ++ log.log_data(p, width=16) ++ try: ++ s.sendto(p, 0, (mcast_addr, mcast_port)) ++ except socket.error as e: ++ log.debug("Unable to send broadcast DNS packet on %s: %s" % (name, e)) ++ raise + + def detectNetworkDevices(ttl=4, timeout=10): +- mcast_addr, mcast_port ='224.0.0.251', 5353 ++ mcast_addr, mcast_port =MCAST_ADDR, 5353 + found_devices = {} + answers = [] + +- s = createSocketsWithsetOption(ttl) ++ s, ifaces = createSocketsWithsetOption(ttl) + if not s: + return {} + +@@ -321,14 +366,24 @@ def detectNetworkDevices(ttl=4, timeout=10): + break + + if now >= next: +- try: +- for p in create_outgoing_packets(answers): +- log.debug("Outgoing: (%d)" % len(p)) +- log.log_data(p, width=16) +- s.sendto(p, 0, (mcast_addr, mcast_port)) ++ good = [] ++ for idx, name in ifaces: ++ mreqn = struct.pack("=4sii", socket.inet_aton(mcast_addr), ++ socket.ntohl(socket.INADDR_ANY), idx) ++ try: ++ s.setsockopt(socket.SOL_IP, socket.IP_MULTICAST_IF, mreqn) ++ except socket.error as e: ++ log.debug("failed to set IP_MULTICAST_IF on %s" % name) ++ continue ++ try: ++ send_packets(s, answers, name, mcast_addr, mcast_port) ++ except socket.error: ++ continue ++ else: ++ good.append((idx, name)) + +- except socket.error as e: +- log.error("Unable to send broadcast DNS packet: %s" % e) ++ if len(good) == 0: ++ log.error("Failed to send MDNS packet on any interface") + + next += delay + delay *= 2 +@@ -347,7 +402,5 @@ def detectNetworkDevices(ttl=4, timeout=10): + found_devices[y['ip']] = y + + log.debug("Found %d devices" % len(found_devices)) +- s.close() ++ closeSocket(s) + return found_devices +- +- +diff --git a/protocol/discovery/mdns.c b/protocol/discovery/mdns.c +index 3324d2a..92e153a 100644 +--- a/protocol/discovery/mdns.c ++++ b/protocol/discovery/mdns.c +@@ -1,3 +1,4 @@ ++ + /***************************************************************************** + mdns.c - mDNS related calls + +@@ -29,14 +30,17 @@ + #endif + + #include ++#include + #include + #include + #include + #include + #include + #include ++#include + #include "mdns.h" + #include ++#include + + /* Convert "www.google.com" to "3www6google3com". */ + static int mdns_convert_name_to_dns(const char *name, int name_size, char *dns_name) +@@ -71,14 +75,50 @@ static int mdns_convert_name_to_dns(const char *name, int name_size, char *dns_n + return x; /* return length DOES include null termination */ + } + ++#define MREQN_INIT(_mr, index) do { \ ++ (&(_mr))->imr_multiaddr.s_addr = inet_addr("224.0.0.251"); \ ++ (&(_mr))->imr_address.s_addr = htonl(INADDR_ANY); \ ++ (&(_mr))->imr_ifindex = (index); \ ++ } while(0) ++ ++struct mdns_socket { ++ int socket; ++ struct if_nameindex *idx; ++ struct if_nameindex **good; ++}; ++#define MDNS_SOCKET_INIT { .socket = -1, .idx = NULL, .good = NULL, } ++ ++static int get_ipv4_address(const char *iface, struct in_addr *addr) ++{ ++ int s, r; ++ struct ifreq ifr; ++ ++ memset(&ifr, 0, sizeof(ifr)); ++ strncpy(ifr.ifr_name, iface, IFNAMSIZ-1); ++ ++ s = socket(AF_INET, SOCK_DGRAM, 0); ++ r = ioctl(s, SIOCGIFADDR, &ifr); ++ close(s); ++ ++ if (r == -1) { ++ DBG("error in SIOCGIFADDR for %s: %m\n", iface); ++ return MDNS_STATUS_ERROR; ++ } ++ ++ if (addr != NULL) ++ memcpy(addr, &((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr, ++ sizeof(*addr)); ++ return MDNS_STATUS_OK; ++} + +-static int mdns_open_socket(int *psocket) ++static int mdns_open_socket(struct mdns_socket *mdns_sock) + { + int stat = MDNS_STATUS_ERROR; +- int udp_socket = -1, yes = 1; ++ int udp_socket = -1, yes = 1, ifaces; + char loop = 0, ttl = 255; + struct sockaddr_in recv_addr , addr; +- struct ip_mreq mreq; ++ struct ip_mreqn mreqn; ++ struct if_nameindex *idx; + + DBG("mdns_open_socket entry.\n"); + +@@ -120,24 +160,86 @@ static int mdns_open_socket(int *psocket) + goto bugout; + } + +- /* Join the .local multicast group */ +- mreq.imr_multiaddr.s_addr = inet_addr("224.0.0.251"); +- mreq.imr_interface.s_addr = htonl(INADDR_ANY); +- if (setsockopt(udp_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(struct ip_mreq)) == -1) { +- BUG("unable to add to multicast group: %m\n"); +- close(udp_socket); ++ mdns_sock->idx = if_nameindex(); ++ if (mdns_sock->idx == NULL) { ++ BUG("if_nameindex failed: %m\n"); ++ goto bugout; ++ } ++ ++ for (idx = mdns_sock->idx, ifaces = 0; ++ idx && (idx->if_index != 0 || idx->if_name != NULL); idx++) { ++ ifaces ++; ++ } ++ ++ mdns_sock->good = calloc(ifaces, sizeof(struct if_nameindex*)); ++ if (mdns_sock->good == NULL) ++ goto bugout; ++ ++ for (idx = mdns_sock->idx, ifaces = 0; ++ idx && (idx->if_index != 0 || idx->if_name != NULL); idx++) { ++ ++ /* Skip lo and interfaces without IPv4 address */ ++ if (!strcmp(idx->if_name, "lo")) ++ continue; ++ if (get_ipv4_address(idx->if_name, NULL) == MDNS_STATUS_ERROR) ++ continue; ++ ++ /* Join the multicast group on each local interface */ ++ MREQN_INIT(mreqn, idx->if_index); ++ if (setsockopt(udp_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreqn, ++ sizeof(struct ip_mreqn)) == -1) { ++ BUG("unable to add to multicast group for %s: %m\n", idx->if_name); ++ } else { ++ mdns_sock->good[ifaces++] = idx; ++ DBG("added multicast group on interface %s\n", idx->if_name); ++ } ++ } ++ ++ if (ifaces == 0) { ++ BUG("no interfaces for multicast found\n"); + goto bugout; + } + +- *psocket = udp_socket; +- DBG("pSocket = [%d]: %m\n", *psocket); ++ mdns_sock->socket = udp_socket; ++ DBG("Socket = [%d]: %m\n", mdns_sock->socket); + stat = MDNS_STATUS_OK; + + bugout: ++ if (stat != MDNS_STATUS_OK) ++ mdns_close_socket(mdns_sock); + return stat; + } + +-static void mdns_create_query_packet(char* fqdn, int query_type, char* querybuf, int *length) ++static void mdns_close_socket(struct mdns_socket *mdns_sock) ++{ ++ int i; ++ struct if_nameindex *idx; ++ struct ip_mreqn mreqn; ++ if (mdns_sock->socket != -1) { ++ for (i = 0; mdns_sock->good[i]; i++) { ++ idx = mdns_sock->good[i]; ++ MREQN_INIT(mreqn, idx->if_index); ++ if (setsockopt(mdns_sock->socket, IPPROTO_IP, IP_DROP_MEMBERSHIP, ++ &mreqn, sizeof(struct ip_mreqn)) == -1) { ++ BUG("unable to drop multicast group for %s: %m\n", idx->if_name); ++ }; ++ } ++ close(mdns_sock->socket); ++ mdns_sock->socket = -1; ++ } ++ ++ if (mdns_sock->idx != NULL) { ++ if_freenameindex(mdns_sock->idx); ++ mdns_sock->idx = NULL; ++ } ++ ++ if (mdns_sock->good != NULL) { ++ free(mdns_sock->good); ++ mdns_sock->good = NULL; ++ } ++} ++ ++static void mdns_create_query_packet(const char* fqdn, int query_type, char* querybuf, int *length) + { + int n = 0; + char header[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; +@@ -157,14 +259,14 @@ static void mdns_create_query_packet(char* fqdn, int query_type, char* querybuf, + *length = n; + } + +-static int mdns_send_query(int udp_socket, char *fqdn, int query_type) ++static int mdns_send_query(struct mdns_socket *mdns_sock, const char *fqdn, int query_type) + { + char querybuf[256] = {0,}; +- int length = 0; ++ int length = 0, i, success; + int stat = MDNS_STATUS_OK; + struct sockaddr_in send_addr; + +- DBG("mdns_send_query entry. send socket=%d len=%d\n", udp_socket, length); ++ DBG("mdns_send_query entry. send socket=%d len=%d\n", mdns_sock->socket, length); + + mdns_create_query_packet(fqdn, query_type, querybuf, &length); + +@@ -172,8 +274,26 @@ static int mdns_send_query(int udp_socket, char *fqdn, int query_type) + send_addr.sin_family = AF_INET; + send_addr.sin_addr.s_addr = inet_addr("224.0.0.251"); + send_addr.sin_port = htons(5353); +- if (sendto(udp_socket, querybuf, length, 0, (struct sockaddr *) &send_addr, sizeof(send_addr)) < 0) +- stat = MDNS_STATUS_ERROR; ++ ++ for (i = 0, success = 0; mdns_sock->good[i]; i++) { ++ struct if_nameindex *idx; ++ struct ip_mreqn mreqn; ++ idx = mdns_sock->good[i]; ++ MREQN_INIT(mreqn, idx->if_index); ++ if (setsockopt(mdns_sock->socket, IPPROTO_IP, IP_MULTICAST_IF, &mreqn, sizeof(mreqn)) ++ == -1) { ++ DBG("failed to set IP_MULTICAST_IF to %s\n", idx->if_name); ++ continue; ++ } ++ if (sendto(mdns_sock->socket, querybuf, length, 0, ++ (struct sockaddr *) &send_addr, sizeof(send_addr))< 0) { ++ DBG("failed to send on %s\n", idx->if_name); ++ } else ++ success++; ++ } ++ ++ if (success == 0) ++ stat = MDNS_STATUS_ERROR; + + DBG("mdns_send_query returning with status(%d)...\n", stat); + return stat; +@@ -252,7 +372,7 @@ static void mdns_read_header(char *Response, DNS_PKT_HEADER *h) + + } + +-static void mdns_parse_respponse(unsigned char *Response, DNS_RECORD *rr) ++static int mdns_parse_respponse(unsigned char *Response, DNS_RECORD *rr) + { + unsigned char *p = Response; + unsigned short type = 0, data_len = 0; +@@ -263,6 +383,11 @@ static void mdns_parse_respponse(unsigned char *Response, DNS_RECORD *rr) + mdns_read_header(Response, &h); + p += MDNS_HEADER_SIZE; + ++ if (h.answers + h.additionals <= 0) { ++ DBG("mdns_parse_respponse: no answers"); ++ return MDNS_STATUS_ERROR; ++ } ++ + for (i = 0; i < h.questions; i++) + { + p += mdns_readName(Response, p, rr->name); +@@ -295,6 +420,7 @@ static void mdns_parse_respponse(unsigned char *Response, DNS_RECORD *rr) + } + + DBG("mdns_parse_respponse returning MDL = %s, IP = %s\n",rr->mdl, rr->ip); ++ return MDNS_STATUS_OK; + } + + static int mdns_read_single_response(int udp_socket, char *recvbuffer, int recvbufsize) +@@ -328,7 +454,7 @@ static int mdns_read_single_response(int udp_socket, char *recvbuffer, int recvb + return ret; + } + +-static DNS_RECORD *mdns_read_responses(int udp_socket, int mode) ++static DNS_RECORD *mdns_read_responses(int udp_socket, int mode, const char *question) + { + int retries = 3, ret = 0; + char recvbuffer[MAX_MDNS_RESPONSE_LEN] = { 0, }; +@@ -351,17 +477,22 @@ static DNS_RECORD *mdns_read_responses(int udp_socket, int mode) + temp = (DNS_RECORD *)malloc(sizeof(DNS_RECORD)); + if(temp) + { +- temp->next = NULL; +- if(head == NULL) +- rr = head = temp; +- else +- { +- rr->next = temp; +- rr = rr->next; +- } +- +- memset(rr, 0, sizeof(DNS_RECORD)); +- mdns_parse_respponse(recvbuffer, rr); ++ memset(temp, 0, sizeof(DNS_RECORD)); ++ if (mdns_parse_respponse(recvbuffer, temp) == MDNS_STATUS_OK && ++ (mode == MODE_READ_ALL || question == NULL || ++ !strncmp(question, temp->name, sizeof(temp->name)-1))) { ++ if(head == NULL) ++ rr = head = temp; ++ else ++ { ++ rr->next = temp; ++ rr = rr->next; ++ } ++ } else { ++ DBG("Parse error or wrong MDNS name"); ++ free(temp); ++ continue; ++ } + + if(mode == MODE_READ_SINGLE) + break; +@@ -421,28 +552,28 @@ static void mdns_rr_cleanup(DNS_RECORD *rr) + int mdns_probe_nw_scanners(char* uris_buf, int buf_size, int *count) + { + int n = 0, bytes_read = 0; +- int udp_socket = 0; ++ struct mdns_socket mdns_sock = MDNS_SOCKET_INIT; + int stat = MDNS_STATUS_ERROR; + DNS_RECORD *rr_list = NULL; ++ const char scanner_name[] = "_scanner._tcp.local"; + + DBG("mdns_probe_nw_scanners entry.\n"); + /* Open UDP socket */ +- if (mdns_open_socket(&udp_socket) != MDNS_STATUS_OK) ++ if (mdns_open_socket(&mdns_sock) != MDNS_STATUS_OK) + goto bugout; + + /* Send dns query */ +- mdns_send_query(udp_socket, "_scanner._tcp.local", QTYPE_PTR); ++ mdns_send_query(&mdns_sock, scanner_name, QTYPE_PTR); + + /* Read Responses */ +- rr_list = mdns_read_responses(udp_socket, MODE_READ_ALL); ++ rr_list = mdns_read_responses(mdns_sock.socket, MODE_READ_ALL, scanner_name); + + /* Update URIs buffer */ + bytes_read = mdns_update_uris(rr_list, uris_buf, buf_size, count); + DBG("mdns_probe_nw_scanners returned with bytes_read = [%d].\n",bytes_read); + + bugout: +- if (udp_socket >= 0) +- close(udp_socket); ++ mdns_close_socket(&mdns_sock); + + mdns_rr_cleanup(rr_list); + +@@ -455,22 +586,22 @@ bugout: + */ + int mdns_lookup(char* hostname, unsigned char* ip) + { +- int udp_socket = 0; ++ struct mdns_socket mdns_sock = MDNS_SOCKET_INIT; + int stat = MDNS_STATUS_ERROR; + char fqdn[MAX_NAME_LENGTH] = {0}; + DNS_RECORD *rr_list = NULL; + + DBG("mdns_probe_nw_scanners entry.\n"); + /* Open UDP socket */ +- if (mdns_open_socket(&udp_socket) != MDNS_STATUS_OK) ++ if (mdns_open_socket(&mdns_sock) != MDNS_STATUS_OK) + goto bugout; + + /* Send dns query */ + sprintf(fqdn, "%s.local", hostname); +- mdns_send_query(udp_socket, fqdn, QTYPE_A); ++ mdns_send_query(&mdns_sock, fqdn, QTYPE_A); + + /* Read Responses */ +- rr_list = mdns_read_responses(udp_socket, MODE_READ_SINGLE); ++ rr_list = mdns_read_responses(mdns_sock.socket, MODE_READ_SINGLE, fqdn); + + /* Update IP Address buffer */ + if(rr_list) +@@ -481,8 +612,7 @@ int mdns_lookup(char* hostname, unsigned char* ip) + } + + bugout: +- if (udp_socket >= 0) +- close(udp_socket); ++ mdns_close_socket(&mdns_sock); + + mdns_rr_cleanup(rr_list); + return stat; +diff --git a/protocol/discovery/mdns.h b/protocol/discovery/mdns.h +index 8fccc82..34066fb 100644 +--- a/protocol/discovery/mdns.h ++++ b/protocol/discovery/mdns.h +@@ -86,19 +86,21 @@ typedef struct _DNS_PKT_HEADER + int mdns_probe_nw_scanners(char* buf, int buf_size, int *count); + int mdns_lookup(char* hostname, unsigned char* ip); + ++struct mdns_socket; + + /*Helper Function Prototypes*/ + static int mdns_convert_name_to_dns(const char *name, int name_size, char *dns_name); + static int mdns_read_single_response(int udp_socket, char *recvbuffer, int recvbufsize); +-static int mdns_open_socket(int *psocket); +-static int mdns_send_query(int udp_socket, char *fqdn, int query_type); ++static int mdns_open_socket(struct mdns_socket *mdns_sock); ++static void mdns_close_socket(struct mdns_socket *mdns_sock); ++static int mdns_send_query(struct mdns_socket *mdns_sock, const char *fqdn, int query_type); + static int mdns_readName(unsigned char* start, unsigned char *p, char *buf); + static int mdns_update_uris(DNS_RECORD *rr, char* uris_buf, int buf_size, int *count); +-static void mdns_create_query_packet(char* fqdn, int query_type, char* dnsquery, int *length); ++static void mdns_create_query_packet(const char* fqdn, int query_type, char* dnsquery, int *length); + static void mdns_read_header(char *Response, DNS_PKT_HEADER *h); +-static void mdns_parse_respponse(unsigned char *Response, DNS_RECORD *rr); ++static int mdns_parse_respponse(unsigned char *Response, DNS_RECORD *rr); + static void mdns_rr_cleanup(DNS_RECORD *rr); +-static DNS_RECORD *mdns_read_responses(int udp_socket, int mode); ++static DNS_RECORD *mdns_read_responses(int udp_socket, int mode, const char *question); + static unsigned char* mdns_readMDL(unsigned char *p, unsigned char *normalized_mdl, int len); + #endif // _DISCOVERY_MDNS_H + diff --git a/hplip.changes b/hplip.changes index a811496..d746369 100644 --- a/hplip.changes +++ b/hplip.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Fri Aug 26 15:13:30 UTC 2016 - martin.wilck@suse.com + +- Fixed device communication/detection problems with mdns/Bonjour + * added hplip-mdns.patch (MDNS send/receive on every iterface) + * added hplip-mdns-retry-query.patch (MDNS retry) + See https://bugs.launchpad.net/hplip/+bug/1616861 + ------------------------------------------------------------------- Mon Jun 6 07:06:46 UTC 2016 - jweberhofer@weberhofer.at diff --git a/hplip.spec b/hplip.spec index f46336e..56f5c00 100644 --- a/hplip.spec +++ b/hplip.spec @@ -56,6 +56,10 @@ Patch107: hplip-udev-rules-in-usr.patch # Patch108 add_missing_includes_and_define_GNU_SOURCE.patch adds missing '#include <...>' # and missing '#define _GNU_SOURCE' see https://bugs.launchpad.net/hplip/+bug/1456590 Patch108: add_missing_includes_and_define_GNU_SOURCE.patch +# Patch200 fixes device communication and detection via MDNS in some network setups: +Patch200: hplip-mdns.patch +# Patch201 makes MDNS lookups more robust by retrying queries: +Patch201: hplip-mdns-retry-query.patch # HPLIP's Python module cupsext.so has a build-time dependancy on the CUPS version: # It needs symbols (like ippFirstAttribute, ippNextAttribute, ippSetOperation etc) # that are defined only in libcups.so version > 1.5. For backward compatibility @@ -350,6 +354,8 @@ This sub-package is only required by developers. # Patch108 add_missing_includes_and_define_GNU_SOURCE.patch adds missing '#include <...>' # and missing '#define _GNU_SOURCE' see https://bugs.launchpad.net/hplip/+bug/1456590 %patch108 -p1 -b .add_missing_includes_and_define_GNU_SOURCE.orig +%patch200 -p1 -b .mdns +%patch201 -p1 -b .mdns-retry %build # If AUTOMAKE='automake --foreign' is not set, autoreconf (in fact automake) @@ -407,7 +413,8 @@ export CXXFLAGS="%{optflags} -fno-strict-aliasing" --with-drvdir=%{_libexecdir}/cups/driver \ --with-mimedir=%{_sysconfdir}/cups \ --with-docdir=%{_defaultdocdir}/%{name} \ - --with-htmldir==%{_defaultdocdir}/%{name} + --with-htmldir==%{_defaultdocdir}/%{name} \ + CFLAGS='%{optflags}' make %install