SDN - Lync Link LDL->LDM

Auf dieser Seite beschreibe ich genauer, was zwischen dem LDL und dem LDM übertragen wird. Da die Verbindung per HTTP ohne SSL möglich ist kann der Verkehr sehr einfach mitgeschnitten werden. Zudem kann ich mir mit einem eigenen HTTP-Service auch die Daten abholen ohne auf den LDM angewiesen zu sein.

There is an short english version available at SDN Live View

LDM Verbindung

Beim Setup haben sie eine URL eingeben müssen, an die der LDL erfasste Daten sendet. Natürlich protokolliert der LDL einige Daten auch in Textdateien, die durch die eigenen DLLs per Default täglich bzw. bei 10MByte Dateigröße eine neue Datei schreiben. Diese Dateien können Sie natürlich auswerten.

Achtung:
Die Protokolldateien werden nicht automatisch nach Ablauf einer Zeit gelöscht. Sie sollten ihre Server überwachen, um Engpässe bei der Festplattenkapazität zu erkennen und vielleicht die alten Dateien auch löschen, z.B.: durch einen geplanten Task

Interessanter ist aber die Schnittstelle, mit der der LDL die Daten zum LDM sendet. Diese "Verbindung" ist für den Einsatz als SDN-Datenlieferant sinnvoll um die Daten mehrere Frontend Server zu einem zentralen Knoten zu senden, der diese dann zusammenfasst und dann weiter gibt. Ich habe aber gar nicht erst diesen LDM installiert, sondern mit einem kleinen PowerShell-Skript einen HTTP-Listener gestartet, der die Verbindungen des LDL angenommen und ausgegeben hat.

Initial Download

Mit der SDN 2.1 hat Microsoft die Kommunikation zwischen LDL und LDM etwas "verbessert", indem die Verbindung z.B.: per SSL mit Client Zertifikat gesichert Senden kann. Größte Änderung ist aber, dass der LDL nun beim Start erst mal eine Konfiguration vom LDM herunter laden will. Es reicht also nicht mehr auf die HTTP-POST zu warten, sondern auch einen GET zu unterstützen. Hier der Auszug aus dem WireShark gegen den LDM:

POST /LDL/GetConfiguration HTTP/1.1
Content-Type: text/xml
Accept: text/xml
Host: nawsyslog:9333
Content-Length: 122
Expect: 100-continue
Connection: Keep-Alive

HTTP/1.1 100 Continue

<GetConfiguration Version="1.0">
  <Pool />
  <FrontEnd>NAWLYNC001</FrontEnd>
  <CurrentVersion />
</GetConfiguration>POST /LDL/RequestMessage HTTP/1.1
Content-Type: text/xml
Accept: text/xml
Host: nawsyslog:9333
Content-Length: 3103
Expect: 100-continue

[12394 bytes missing in capture file]HTTP/1.1 100 Continue

 

 

 

StartOrUpdate

Der LDL sendet jede Aktivität, die z.B. ein INVITE oder BYE zu einer Audio- oder Video-Konferenz ist, per HTTP-POST an die angegebene URL. Und das muss gar kein IIS oder der LDM sein, sondern kann auch ein andere Programm sein. Der Post enthält eine einfache XML-Struktur. Der Start eines Calls ist etwas aufwändiger da neben den Call-Daten auch die SDP-Endpunkte mit übergeben werden.

<LyncDiagnostics Version="1.0">
  <ConnectionInfo>
    <FrontEnd>lync2013fe</FrontEnd>
    <CallId>42f4929eebd749c8a8b527c3f3c86f03</CallId>
    <CSEQ>2</CSEQ>
    <ConversationId>Ac8yT0wswlLEZPQYTDid8nAvVkEZEg==</ConversationId>
    <TimeStamp>2014-02-25T17:30:38.5184126Z</TimeStamp>
  </ConnectionInfo>
  <StartOrUpdate Type="audio">
    <From>
      <Id>804d667da3</Id>
      <EPId>ccdcf5ebc1</EPId>
      <URI>sip:326C204F36B2541B@msxfaq.net</URI>
      <IP>10.1.1.25</IP>
      <Port>23504</Port>
    </From>
    <To>
      <Id>81c96ba5</Id>
      <EPId>5E9B554402</EPId>
      <URI>sip:206939D5E70607C6@msxfaq.net;gruu;opaque=srvr:microsoft.rtc.applications.testbot</URI>
      <Contact>sip:206939D5E70607C6@msxfaq.net;gruu;opaque=srvr:microsoft.rtc.applications.testbot</Contact>
      <IP>10.1.1.21</IP>
      <Port>49884</Port>
    </To>
    <Properties>
      <Protocol>UDP</Protocol>
      <EstimatedBandwidth Codec="G722/8000">
        <Low>46100</Low>
        <High>100600</High>
      </EstimatedBandwidth>
      <EstimatedBandwidth Codec="G7221/16000">
        <Low>128000</Low>
        <High>223600</High>
      </EstimatedBandwidth>
      <EstimatedBandwidth Codec="SIREN/16000">
        <Low>46100</Low>
        <High>52600</High>
      </EstimatedBandwidth>
      <EstimatedBandwidth Codec="PCMU/8000">
        <Low>64800</Low>
        <High>97000</High>
      </EstimatedBandwidth>
      <EstimatedBandwidth Codec="PCMA/8000">
        <Low>64800</Low>
        <High>97000</High>
      </EstimatedBandwidth>
      <EstimatedBandwidth Codec="AAL2-G726-32/8000" />
      <EstimatedBandwidth Codec="CN/8000" />
      <EstimatedBandwidth Codec="CN/16000" />
      <EstimatedBandwidth Codec="RED/8000" />
      <EstimatedBandwidth Codec="telephone-event/8000" />
    </Properties>
  </StartOrUpdate>
  <StartOrUpdate Type="audio">
....
  </StartOrUpdate>
</LyncDiagnostics>

Der Datensatz enthält eine Information über alle Codec, die die beiden Parteien nutzen können. Welcher genutzt wird, wird natürlich später innerhalb des RTP-Datenstroms variabel entschieden. Der Knoten "StartOrUpdate" ist zweimal enthalten, da jede Richtung getrennt betrachtet wird. Wenn noch Video dazu kommt, dann können auch drei oder mehr Instanzen vorhanden sein.

Ended

Das Ende eines Calls ist dagegen überschaubar kurz:

<LyncDiagnostics Version="1.0">
  <ConnectionInfo>
    <FrontEnd>lync2013fe</FrontEnd>
    <CallId>373de56c178052948ba70814e97afe4c</CallId>
    <CSEQ>3</CSEQ>
    <TimeStamp>2014-02-25T17:56:49.017824Z</TimeStamp>
  </ConnectionInfo>
  <Ended>
    <EndPoint>
      <Id>8de45d648e</Id>
      <EPId>ccdcf5ebc1</EPId>
      <URI>sip:FB051BCCFF88FAD68E3BE528C9D8FE08@msxfaq.net</URI>
    </EndPoint>
    <EndPoint>
      <Id>6e1e52882d</Id>
      <EPId>5E9B554402</EPId>
      <URI>sip:FB051BCCFF88FAD68E3BE528C9D8FE08@msxfaq.net;
           gruu;opaque=srvr:microsoft.rtc.applications.testbot:wss8fws0aznmk1miznzaad8x</URI>
    </EndPoint>
  </Ended>
</LyncDiagnostics>

Error

Zusätzlich habe ich auch verschiedene "Error"-Meldungen gefunden, mit denen der LDL Fehler weiter gibt.

<LyncDiagnostics Version="1.0">
  <ConnectionInfo>
    <FrontEnd>lync2013fe</FrontEnd>
    <CallId>d9aff9d99e1a4fe19507c0698ae5f3cd</CallId>
    <CSEQ>1</CSEQ>
    <TimeStamp>2014-02-25T17:56:12.7332588Z</TimeStamp>
  </ConnectionInfo>
  <Error>
    <EndPoint>
      <Id>5af2ea2db6</Id>
      <EPId>ccdcf5ebc1</EPId>
      <URI>sip:1FBFFBD1E76D4F7E60DEF1CA1B0C7248@msxfaq.net</URI>
    </EndPoint>
    <EndPoint>
      <Id>E3FF980F002E85A2F242657513CD1EA8</Id>
      <URI>sip:1FBFFBD1E76D4F7E60DEF1CA1B0C7248@msxfaq.net;gruu;opaque=app:locationprofile:get;default</URI>
    </EndPoint>
    <Properties>
      <ResponseCode Code="403">Location profile only available when UC enabled.</ResponseCode>
      <MSDiagnostics>2;reason="See response code and reason phrase";
           AppUri="http://www.microsoft.com/LCS/TranslationService";source="lync2013fe.msxfaq.net"</MSDiagnostics>
    </Properties>
  </Error>
</LyncDiagnostics>

Hier ein Beispiel einiger Fehler.

<MSDiagnostics>2;reason="See response code and reason phrase";
   AppUri="http://www.microsoft.com/LCS/TranslationService";source="lync2013fe.msxfaq.net"</MSDiagnostics>
<MSDiagnostics>11007;reason="QoE is not enabled";source="lync2013fe.msxfaq.net";appName="UdcAgent"</MSDiagnostics>
<MSDiagnostics>2019;reason="Report error service is not available";source="lync2013fe.msxfaq.net"</MSDiagnostics>

Auch das ist aus meiner Sicht ein klarer Hinweis, dass die SDN API durchaus schon länger von Microsoft für andere Zwecke verwendet wird. Denn was will ein WiFi-System mit den Informationen über Lync-Fehler?

QoE-Einträge

Zuletzt gibt es bei aktiviertem QoE-Server auch die Möglichkeit diese Informationen an den LDM zu übergeben. Ein Eintrag sieht z.B. wie folgt aus:

<LyncDiagnostics Version="1.0">
  <ConnectionInfo Originator="24c094104b">
    <FrontEnd>LYNC2013FE</FrontEnd>
    <CallId>03783e26f8dd494c8ea2e1991b9f90e4</CallId>
    <TimeStamp>2014-02-28T18:31:31.6464959Z</TimeStamp>
    <Connectivity>DIRECT</Connectivity>
    <StartTime>2014-02-28T18:29:46.0865Z</StartTime>
    <EndTime>2014-02-28T18:31:31.0354Z</EndTime>
    <AppliedBandwidthLimit>350000</AppliedBandwidthLimit>
    <DialogCategory>BeforeMedServer</DialogCategory>
  </ConnectionInfo>
  <QualityUpdate Type="video">
    <From>
      <Id>687f6ca677</Id>
      <URI>sip:user1@msxfaq.net</URI>
      <Contact>sip:user1@msxfaq.net;opaque=user:epid:-ey0-raqhv6boojczrk_jwaa;gruu</Contact>
      <IP>192.168.102.41</IP>
      <Port>6508</Port>
    </From>
    <To>
      <Id>24c094104b</Id>
      <URI>sip:user2@msxfaq.net</URI>
      <Contact>sip:user2@msxfaq.net;opaque=user:epid:v5mswjitsfyhyej4vldnkaaa;gruu</Contact>
      <IP>192.168.103.2</IP>
      <Port>33700</Port>
      <Relay>80.66.20.21</Relay>
      <RelayPort>51503</RelayPort>
      <Inside>True</Inside>
      <VPN>False</VPN>
      <Connection>Ethernet</Connection>
    </To>
    <Properties>
      <EstimatedBandwidth Codec="H264" />
      <PacketUtilization>1538</PacketUtilization>
      <PacketLossRate>0.001297973</PacketLossRate>
      <PacketLossRateMax>0.01317565</PacketLossRateMax>
      <JitterInterArrival>1</JitterInterArrival>
      <JitterInterArrivalMax>3</JitterInterArrivalMax>
      <VideoPacketLossRate Limit="0.1">0.001297973</VideoPacketLossRate>
      <RecvFrameRateAverage Limit="7">15.02539</RecvFrameRateAverage>
      <VideoLocalFrameLossPercentageAvg Limit="10">0.5873715</VideoLocalFrameLossPercentageAvg>
      <LocalFrameLossPercentageAvg>0.5873715</LocalFrameLossPercentageAvg>
      <BitRateMax>326694</BitRateMax>
      <BitRateAvg>168614</BitRateAvg>
    </Properties>
  </QualityUpdate>
</LyncDiagnostics>

Bislang habe ich aber nur Video-Daten gesehen.

Netmon

Zusätzlich habe ich die Verbindung zwischen dem LDL und dem LDM mit Netmon betrachtet und interessante Ergebnisse erhalten, die ich mit meinem kleinen HTTP-Server nicht so einfach einsammeln konnte.

Das erste auffällige Verhalten ist die "Gesprächigkeit". Der LDL scheint jede Sekunde einen TCP KeepAlive an den LDM zu senden. War der Grund dafür ist, konnte ich noch nicht ermitteln. Eventuell prüft der LDL so die Erreichbarkeit des LDM um im Fehlerfahl sofort auf einen Backup LDM umzuschalten.

Dann sehen Sie hier natürlich einen erfolgreichen Request: Auch der kann genauer betrachtet werden. Zuerst der bekannte Request

Als Antwort kommt aber nicht nur ein 200OK sondern auch eine kleine XML-Rumpfdatei mit einem Counter

Der Wert in "Count" zählt mit jeder Anfrage weiter hoch. Ich vermute einfach mal, dass der LDL diesen Wert nutzt, um die Vollständigkeit der Meldungen zu überprüfen. Ich konnte aber noch nicht sehen, ob der LDL auch einen "Resend" macht.

Im Post wird eine Sequenznummer mit gesendet, auf die der LDM auch die passende Antwort liefert. Wird der LDM aber kurz gestartet, dann hat sich der LDL nach ca. 50 Sekunden gefangen und auf den ersten Request wieder mit "Count = 1" gestartet. im nächsten POST hat der LDL dann seinerseits den CSEQ-Counter wieder auf 2 gesetzt, so dass dann das Pärchen wieder synchron gelaufen sind.

Im Gegensatz zum QoE-Server, der die Daten bei Lync 2010 per MSMQ und bei Lync 2013 per LySS relativ verzögert bekommt, nutzt die SDN-API die direkte Kommunikation aber scheint nichts zu puffern. Eine gewisse ungenauigkeit wird dabei wohl in Kauf genommen.

Stabilität

Microsoft bezeichnet diese Programme als SDN API, wobei es aus meiner Sicht keine "richtige" API ist. Man kann sie aber auch für eigene Zwecke verwenden. Allerdings ist mir in dem Zuge auch das ein oder andere aufgefallen. Es kann sein, dass es an der TestUmgebung lag oder PowerShell als Listener einfach nicht geeignet war. Aber folgende Probleme habe ich beobachtet.

  • Keine Calls über Mediation Server/MediaBypass
    ein Anruf vom Lync Client zu meinem Mobiltelefon wurde NICHT gemeldet.
  • Fängt sich nicht mehr, wenn TCP Listener kurz weg war
    Der LDL verbindet sich per TCP mit einem Webservice. Wenn der Dienst kurz nicht da ist, dann meldet der LDL dies in seinem Log aber bislang musste ich den Dienst neu starten, damit er sich wieder verbindet.
  • Keine regelmäßigen Updates
    Ich konnte bislang nicht sehen, dass die Statusmeldungen auch immer wieder mit einem "Refresh" geliefert werden. Wenn man als ein "End" verpasst, weil die nächste Station offline ist, dann bleibt so ein Call gefühlt ewig bestehen. Gleiches gilt wenn der "Start" verpasst wird. SDN - Lync Dialog Manager löst dies scheinbar durch eigene Timouts.
  • Kein Edge
    Wenn ein Teilnehmer per Edge angebunden ist, habe ich noch nichts gesehen, dass entsprechende Meldungen generiert werden.
  • Kein Skype oder Federation
    Ebenso betrifft dies wohl Personen über Federation. Selbst wenn ich intern von Lync zu Skype eine Audioverbindung nutze, die auch komplett intern bleibt, wird kein Datensatz erzeugt
  • Bekommt nicht alle Calls zuverlässig mit ?
    Selbst die Calls, die vom LDL gesehen werden sollten, scheinen nicht immer vollständig zu sein. Ich hoffe mehrmals sehen, dass ein Call nicht gemeldet wurde.

Weitere Links