Skip to content
This repository

Make sure TXT records are in same order as setup on mdns announce #1684

Merged
merged 2 commits into from over 1 year ago

2 participants

Joakim Plate Memphiz
Joakim Plate
Collaborator

The txtvers record in TXT records is often required to be the first record. So allow this in our API.

elupus added some commits
Joakim Plate elupus zeroconf: maintain txt record order when publishing service 25629fc
Joakim Plate elupus zeroconf/osx: maintain txt field order on publish
OSX create the txt records using a dictionary, so to maintain
order, we use a custom hash function that put all elements
in the same hash bucket.
f78ada6
Memphiz
Owner

Looks good and straight forward.

Memphiz
Owner

@elupus - if you want that in - push that button...

Joakim Plate elupus merged commit c2a21de into from
Joakim Plate
Collaborator

Suppose it won't hurt.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 2 unique commits by 1 author.

Oct 26, 2012
Joakim Plate elupus zeroconf: maintain txt record order when publishing service 25629fc
Joakim Plate elupus zeroconf/osx: maintain txt field order on publish
OSX create the txt records using a dictionary, so to maintain
order, we use a custom hash function that put all elements
in the same hash bucket.
f78ada6
This page is out of date. Refresh to see the latest.
16 xbmc/Application.cpp
@@ -1514,7 +1514,7 @@ bool CApplication::StartWebServer()
1514 1514 bool started = false;
1515 1515 if (m_WebServer.Start(webPort, g_guiSettings.GetString("services.webserverusername"), g_guiSettings.GetString("services.webserverpassword")))
1516 1516 {
1517   - std::map<std::string, std::string> txt;
  1517 + std::vector<std::pair<std::string, std::string> > txt;
1518 1518 started = true;
1519 1519 // publish web frontend and API services
1520 1520 #ifdef HAS_WEB_INTERFACE
@@ -1564,19 +1564,19 @@ bool CApplication::StartAirplayServer()
1564 1564 if (CAirPlayServer::StartServer(listenPort, true))
1565 1565 {
1566 1566 CAirPlayServer::SetCredentials(usePassword, password);
1567   - std::map<std::string, std::string> txt;
  1567 + std::vector<std::pair<std::string, std::string> > txt;
1568 1568 CNetworkInterface* iface = g_application.getNetwork().GetFirstConnectedInterface();
1569 1569 if (iface)
1570 1570 {
1571   - txt["deviceid"] = iface->GetMacAddress();
  1571 + txt.push_back(std::make_pair("deviceid", iface->GetMacAddress()));
1572 1572 }
1573 1573 else
1574 1574 {
1575   - txt["deviceid"] = "FF:FF:FF:FF:FF:F2";
  1575 + txt.push_back(std::make_pair("deviceid", "FF:FF:FF:FF:FF:F2"));
1576 1576 }
1577   - txt["features"] = "0x77";
1578   - txt["model"] = "AppleTV2,1";
1579   - txt["srcvers"] = AIRPLAY_SERVER_VERSION_STR;
  1577 + txt.push_back(std::make_pair("features", "0x77"));
  1578 + txt.push_back(std::make_pair("model", "AppleTV2,1"));
  1579 + txt.push_back(std::make_pair("srcvers", AIRPLAY_SERVER_VERSION_STR));
1580 1580 CZeroconf::GetInstance()->PublishService("servers.airplay", "_airplay._tcp", g_infoManager.GetLabel(SYSTEM_FRIENDLY_NAME), listenPort, txt);
1581 1581 ret = true;
1582 1582 }
@@ -1620,7 +1620,7 @@ bool CApplication::StartJSONRPCServer()
1620 1620 {
1621 1621 if (CTCPServer::StartServer(g_advancedSettings.m_jsonTcpPort, g_guiSettings.GetBool("services.esallinterfaces")))
1622 1622 {
1623   - std::map<std::string, std::string> txt;
  1623 + std::vector<std::pair<std::string, std::string> > txt;
1624 1624 CZeroconf::GetInstance()->PublishService("servers.jsonrpc-tpc", "_xbmc-jsonrpc._tcp", g_infoManager.GetLabel(SYSTEM_FRIENDLY_NAME), g_advancedSettings.m_jsonTcpPort, txt);
1625 1625 return true;
1626 1626 }
32 xbmc/network/AirTunesServer.cpp
@@ -503,22 +503,22 @@ bool CAirTunesServer::StartServer(int port, bool nonlocal, bool usePassword, con
503 503 CStdString appName;
504 504 appName.Format("%s@%s", m_macAddress.c_str(), g_infoManager.GetLabel(SYSTEM_FRIENDLY_NAME).c_str());
505 505
506   - std::map<std::string, std::string> txt;
507   - txt["cn"] = "0,1";
508   - txt["ch"] = "2";
509   - txt["ek"] = "1";
510   - txt["et"] = "0,1";
511   - txt["sv"] = "false";
512   - txt["tp"] = "UDP";
513   - txt["sm"] = "false";
514   - txt["ss"] = "16";
515   - txt["sr"] = "44100";
516   - txt["pw"] = "false";
517   - txt["vn"] = "3";
518   - txt["da"] = "true";
519   - txt["vs"] = "130.14";
520   - txt["md"] = "0,1,2";
521   - txt["txtvers"] = "1";
  506 + std::vector<std::pair<std::string, std::string> > txt;
  507 + txt.push_back(std::make_pair("txtvers", "1"));
  508 + txt.push_back(std::make_pair("cn", "0,1"));
  509 + txt.push_back(std::make_pair("ch", "2"));
  510 + txt.push_back(std::make_pair("ek", "1"));
  511 + txt.push_back(std::make_pair("et", "0,1"));
  512 + txt.push_back(std::make_pair("sv", "false"));
  513 + txt.push_back(std::make_pair("tp", "UDP"));
  514 + txt.push_back(std::make_pair("sm", "false"));
  515 + txt.push_back(std::make_pair("ss", "16"));
  516 + txt.push_back(std::make_pair("sr", "44100"));
  517 + txt.push_back(std::make_pair("pw", "false"));
  518 + txt.push_back(std::make_pair("vn", "3"));
  519 + txt.push_back(std::make_pair("da", "true"));
  520 + txt.push_back(std::make_pair("vs", "130.14"));
  521 + txt.push_back(std::make_pair("md", "0,1,2"));
522 522
523 523 CZeroconf::GetInstance()->PublishService("servers.airtunes", "_raop._tcp", appName, port, txt);
524 524 }
2  xbmc/network/EventServer.cpp
@@ -155,7 +155,7 @@ void CEventServer::Run()
155 155 CAddress any_addr;
156 156 CSocketListener listener;
157 157 int packetSize = 0;
158   - std::map<std::string, std::string> txt;
  158 + std::vector<std::pair<std::string, std::string> > txt;
159 159
160 160 CLog::Log(LOGNOTICE, "ES: Starting UDP Event server on %s:%d", any_addr.Address(), m_iPort);
161 161
4 xbmc/network/Zeroconf.cpp
@@ -43,7 +43,7 @@
43 43 //should be optimized away
44 44 class CZeroconfDummy : public CZeroconf
45 45 {
46   - virtual bool doPublishService(const std::string&, const std::string&, const std::string&, unsigned int, std::map<std::string, std::string>)
  46 + virtual bool doPublishService(const std::string&, const std::string&, const std::string&, unsigned int, const std::vector<std::pair<std::string, std::string> >&)
47 47 {
48 48 return false;
49 49 }
@@ -68,7 +68,7 @@ bool CZeroconf::PublishService(const std::string& fcr_identifier,
68 68 const std::string& fcr_type,
69 69 const std::string& fcr_name,
70 70 unsigned int f_port,
71   - std::map<std::string, std::string> txt)
  71 + const std::vector<std::pair<std::string, std::string> >& txt)
72 72 {
73 73 CSingleLock lock(*mp_crit_sec);
74 74 CZeroconf::PublishInfo info = {fcr_type, fcr_name, f_port, txt};
7 xbmc/network/Zeroconf.h
@@ -22,6 +22,7 @@
22 22
23 23 #include <string>
24 24 #include <map>
  25 +#include <vector>
25 26 #include "utils/Job.h"
26 27
27 28 class CCriticalSection;
@@ -49,7 +50,7 @@ class CZeroconf
49 50 const std::string& fcr_type,
50 51 const std::string& fcr_name,
51 52 unsigned int f_port,
52   - std::map<std::string, std::string> txt);
  53 + const std::vector<std::pair<std::string, std::string> >& txt);
53 54
54 55 ///removes the specified service
55 56 ///returns false if fcr_identifier does not exist
@@ -86,7 +87,7 @@ class CZeroconf
86 87 const std::string& fcr_type,
87 88 const std::string& fcr_name,
88 89 unsigned int f_port,
89   - std::map<std::string, std::string> txt) = 0;
  90 + const std::vector<std::pair<std::string, std::string> >& txt) = 0;
90 91 //removes the service if published
91 92 virtual bool doRemoveService(const std::string& fcr_ident) = 0;
92 93
@@ -107,7 +108,7 @@ class CZeroconf
107 108 std::string type;
108 109 std::string name;
109 110 unsigned int port;
110   - std::map<std::string, std::string> txt;
  111 + std::vector<std::pair<std::string, std::string> > txt;
111 112 };
112 113
113 114 //protects data
4 xbmc/network/linux/ZeroconfAvahi.cpp
@@ -131,7 +131,7 @@ bool CZeroconfAvahi::doPublishService(const std::string& fcr_identifier,
131 131 const std::string& fcr_type,
132 132 const std::string& fcr_name,
133 133 unsigned int f_port,
134   - std::map<std::string, std::string> txt)
  134 + const std::vector<std::pair<std::string, std::string> >& txt)
135 135 {
136 136 CLog::Log(LOGDEBUG, "CZeroconfAvahi::doPublishService identifier: %s type: %s name:%s port:%i", fcr_identifier.c_str(), fcr_type.c_str(), fcr_name.c_str(), f_port);
137 137
@@ -145,7 +145,7 @@ bool CZeroconfAvahi::doPublishService(const std::string& fcr_identifier,
145 145
146 146 //txt records to AvahiStringList
147 147 AvahiStringList *txtList = NULL;
148   - for(std::map<std::string, std::string>::iterator it=txt.begin(); it!=txt.end(); it++)
  148 + for(std::vector<std::pair<std::string, std::string> >::const_iterator it=txt.begin(); it!=txt.end(); it++)
149 149 {
150 150 txtList = avahi_string_list_add_pair(txtList, it->first.c_str(), it->second.c_str());
151 151 }
3  xbmc/network/linux/ZeroconfAvahi.h
@@ -25,6 +25,7 @@
25 25
26 26 #include <memory>
27 27 #include <map>
  28 +#include <vector>
28 29 #include <string>
29 30 #include "network/Zeroconf.h"
30 31
@@ -47,7 +48,7 @@ class CZeroconfAvahi : public CZeroconf
47 48 const std::string& fcr_type,
48 49 const std::string& fcr_name,
49 50 unsigned int f_port,
50   - std::map<std::string, std::string> txt);
  51 + const std::vector<std::pair<std::string, std::string> >& txt);
51 52
52 53 virtual bool doRemoveService(const std::string& fcr_ident);
53 54
15 xbmc/network/osx/ZeroconfOSX.cpp
@@ -38,13 +38,18 @@ CZeroconfOSX::~CZeroconfOSX()
38 38 doStop();
39 39 }
40 40
  41 +CFHashCode CFHashNullVersion (CFTypeRef cf)
  42 +{
  43 + return 0;
  44 +}
  45 +
41 46
42 47 //methods to implement for concrete implementations
43 48 bool CZeroconfOSX::doPublishService(const std::string& fcr_identifier,
44 49 const std::string& fcr_type,
45 50 const std::string& fcr_name,
46 51 unsigned int f_port,
47   - std::map<std::string, std::string> txt)
  52 + const std::vector<std::pair<std::string, std::string> >& txt)
48 53 {
49 54 CLog::Log(LOGDEBUG, "CZeroconfOSX::doPublishService identifier: %s type: %s name:%s port:%i", fcr_identifier.c_str(),
50 55 fcr_type.c_str(), fcr_name.c_str(), f_port);
@@ -71,10 +76,14 @@ bool CZeroconfOSX::doPublishService(const std::string& fcr_identifier,
71 76 //add txt records
72 77 if(!txt.empty())
73 78 {
  79 +
  80 + CFDictionaryKeyCallBacks key_cb = kCFTypeDictionaryKeyCallBacks;
  81 + key_cb.hash = CFHashNullVersion;
  82 +
74 83 //txt map to dictionary
75 84 CFDataRef txtData = NULL;
76   - CFMutableDictionaryRef txtDict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
77   - for(std::map<std::string, std::string>::const_iterator it = txt.begin(); it != txt.end(); ++it)
  85 + CFMutableDictionaryRef txtDict = CFDictionaryCreateMutable(NULL, 0, &key_cb, &kCFTypeDictionaryValueCallBacks);
  86 + for(std::vector<std::pair<std::string, std::string> >::const_iterator it = txt.begin(); it != txt.end(); ++it)
78 87 {
79 88 CFStringRef key = CFStringCreateWithCString (NULL,
80 89 it->first.c_str(),
3  xbmc/network/osx/ZeroconfOSX.h
@@ -20,6 +20,7 @@
20 20 */
21 21
22 22 #include <memory>
  23 +#include <vector>
23 24
24 25 #include "network/Zeroconf.h"
25 26 #include "threads/CriticalSection.h"
@@ -42,7 +43,7 @@ class CZeroconfOSX : public CZeroconf
42 43 const std::string& fcr_type,
43 44 const std::string& fcr_name,
44 45 unsigned int f_port,
45   - std::map<std::string, std::string> txt);
  46 + const std::vector<std::pair<std::string, std::string> >& txt);
46 47
47 48 bool doRemoveService(const std::string& fcr_ident);
48 49
4 xbmc/network/windows/ZeroconfWIN.cpp
@@ -62,7 +62,7 @@ bool CZeroconfWIN::doPublishService(const std::string& fcr_identifier,
62 62 const std::string& fcr_type,
63 63 const std::string& fcr_name,
64 64 unsigned int f_port,
65   - std::map<std::string, std::string> txt)
  65 + const std::vector<std::pair<std::string, std::string> >& txt)
66 66 {
67 67 DNSServiceRef netService = NULL;
68 68 TXTRecordRef txtRecord;
@@ -87,7 +87,7 @@ bool CZeroconfWIN::doPublishService(const std::string& fcr_identifier,
87 87 //add txt records
88 88 if(!txt.empty())
89 89 {
90   - for(std::map<std::string, std::string>::const_iterator it = txt.begin(); it != txt.end(); ++it)
  90 + for(std::vector<std::pair<std::string, std::string> >::const_iterator it = txt.begin(); it != txt.end(); ++it)
91 91 {
92 92 CLog::Log(LOGDEBUG, "ZeroconfWIN: key:%s, value:%s",it->first.c_str(),it->second.c_str());
93 93 uint8_t txtLen = (uint8_t)strlen(it->second.c_str());
2  xbmc/network/windows/ZeroconfWIN.h
@@ -36,7 +36,7 @@ class CZeroconfWIN : public CZeroconf
36 36 const std::string& fcr_type,
37 37 const std::string& fcr_name,
38 38 unsigned int f_port,
39   - std::map<std::string, std::string> txt);
  39 + const std::vector<std::pair<std::string, std::string> >& txt);
40 40
41 41 bool doRemoveService(const std::string& fcr_ident);
42 42

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.