4

Bonjour API を使用してレコードを登録しました。今、出版したばかりのレコードの内容を知りたいです。「デーモンのデフォルトを使用する」ことを意味するNULLホスト名を指定して作成しましたが、それが何であるかを照会する簡単な方法が見つかりません!

avahi を使えば簡単です。 を呼び出しavahi_client_get_host_name()て、マシンのホスト名の開始値を取得します。

avahi と Bonjour の両方で、SRV レコードの値は登録の存続期間中に変更される可能性があります。登録が NULL ホスト名で行われた場合、レコードのホスト名は必要に応じて自動的に更新されます。ここで必要なのは、登録時にホスト名の初期値を取得する方法だけです。

私の Snow Leopard テスト マシンでは、デフォルトのマルチキャスト ホスト名がからのマシンの名前と同じではないgethostname(2)ことに注意してください。

私が考えることができる4つの解決策:

  1. 私のプロセスでホスト名を取得します。どこかにあるかもしれません。プロセスのメモリ ダンプを検索したstrings(3)ところ、アドレス空間でマルチキャスト ホスト名の 4 つのインスタンスが見つかりましたが、その名前が他の目的で使用されていることを考えると、これは偶然の一致である可能性があります。探している文字列がプロセスのどこかにあるとしても、それを正常に取得するための API が見つかりません。
  2. デーモンからホスト名を照会します。マッハポートを介して、それをフェッチするデーモンに送信できるクエリがあるかもしれません。API が見つかりません。関連するコードのチャンクは mDNSResponder の uDNS.c ファイルにあり、RPC インターフェイス経由で公開されていないようです。
  3. 登録したサービスを検索できました。ただし、これには多少のネットワーク トラフィックが含まれる可能性があるため、発生しないという保証がない限り、私はそうしたくありません。
  4. uDNS.c のロジックを再実装します。次の組み合わせからマシンのホスト名を取得します。

    • 動的 DNS 構成
    • 静的に構成されたマルチキャスト ホスト名
    • プライマリ インターフェイスの IPv4 アドレスの逆引き
    • gethostname(2)具体的には、または同等のものを使用しません

    そのロジックを再実装することは不可能に思えます。

現時点では、最初の SRV 登録の値を取得するためにルックアップを行う傾向がありますが、理想的ではないようです。正しい解決策は何ですか?

4

4 に答える 4

2

私はまさにこれをする必要がありました。ConvertDomainNameToCString マクロ (mDNSEmbeddedAPI.h に含まれています) を使用する必要があり、コア mDNS 構造にアクセスする必要があります。

登録された正確な Bonjour/Zeroconf ホスト名を取得する方法は次のとおりです。

char szHostname[512];
extern mDNS m;

ConvertDomainNameToCString(&m.MulticastHostname, szHostname);

これがお役に立てば幸いです。

于 2013-09-03T15:51:54.453 に答える
0

記録のために、私は (4) を使用し、マシンの構成を取得して、デーモンが使用しているホスト名を照会せずにまとめました。

static char* getBonjourDefaultHost()
{
  char* rv = 0;
#ifdef __APPLE__
  CFStringRef name = SCDynamicStoreCopyLocalHostName(NULL);
  if (name) {
    int len = CFStringGetLength(name);
    rv = new char[len*4+1];
    CFStringGetCString(name, rv, len*4+1, kCFStringEncodingUTF8);
    CFRelease(name);
  }
  // This fallback is completely incorrect, but why should we care...
  // Mac does something crazy like <sysctl hw.model>-<MAC address>.
  if (!rv)
    rv = GetHostname(); // using gethostname(2)

#elif defined(WIN32)
  CHAR tmp[256+1];
  ULONG namelength = sizeof(tmp);
  DynamicFn<BOOL (WINAPI*)(COMPUTER_NAME_FORMAT,LPSTR,LPDWORD)>
    GetComputerNameExA_("Kernel32", "GetComputerNameExA");
  if (!GetComputerNameExA_.isValid() ||
      !(*GetComputerNameExA_)(ComputerNamePhysicalDnsHostname, tmp, &namelength))
    tmp[0] = 0;
  // Roughly correct; there's some obscure string cleaning mDNSResponder does
  // to tidy up funny international strings.
  rv = tmp[0] ? strdup(tmp) : strdup("My Computer");

#elif defined(__sun)
  // This is exactly correct! What a relief.
  rv = GetHostName();

#else
#error Must add platform mDNS daemon scheme
#endif
  return rv;
}
于 2013-11-07T13:20:50.717 に答える
0

これはすでに回答されていることは知っていますが、回答の後半でPierzが言ったことに基づいて、SystemConfigurationフレームワークでそれを行う方法を調べました。

これは私が取り組んだことであり、他の誰かがこの時間をグーグルで節約できるかもしれないと考えました:Swiftの場合:

import SystemConfiguration

    let store = SCDynamicStoreCreate(nil, "ipmenu" as CFString, nil, nil )
    if let hostNames = SCDynamicStoreCopyValue(store, "Setup:/Network/HostNames" as CFString){
        if let hostName:String = (hostNames[kSCPropNetLocalHostName]) as? String {
            print("Host name:\(hostName)")
        }
    }
于 2020-10-21T22:07:02.800 に答える