[UDP mit BNetEx] DeNIC-Domainabfrage per IRIS DCHK

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

Justus

Betreff: [UDP mit BNetEx] DeNIC-Domainabfrage per IRIS DCHK

BeitragDi, Dez 15, 2009 20:34
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo.
Ich habe ein Problem.

Worum geht es?

Ich möchte über BlitzMax eine DCHK-Abfrage starten. Das ist ein relativ neuer Dienst, der bisher nur von der DeNIC, der Vergabestelle für .de-Domains, angeboten wird. Er dient dazu abzufragen, ob eine Domain bereits registriert oder noch frei ist.
Dabei ist mir wichtig, dass es mit BlitzMax selbst umgesetzt wird. Ich könnte natürlich den bereits existierenden C-Code von http://dchk.pfp.de/ benutzen, aber das ist nicht das Ziel.

Wie sollte es theoretisch funktionieren?

Die Abfrage basiert auf einem bestimmten Protokoll, das ist definiert in RFC 4993.
Das läuft über UDP ab und hat dadurch den Vorteil, dass man den TCP-Header spart, einfach seinen Request zur DeNIC schickt und wartet bis was zurückkommt. Hat aber den Nachteil, dass man nicht weiß ob der Request überhaupt angekommen ist.

Das XML, in dem steht um welche Domain es bei der Abfrage geht usw. gehört zum IRIS-Protokoll, das wiederum ist definiert im RFC 3981.

Das Basis-Protokoll

Zuerst wird der Payload-Descriptor gesendet, quasi Zusatzinformationen zur Payload ("Traglast", also das XML). Dieser ist im Einzelnen:

  • Der Header: 8 Bits, alle sind 0.
  • Die Transaction-ID: Beliebiger Wert mit 16 Bit Länge, der in der Antwort wieder zurückgesendet wird, damit man weiß welcher Request und welche Antwort zusammengehören.
  • Die maximale Response-Length: Wie lang die Antwort des Servers sein darf. Auch der Wert besteht aus 16 Bit.
  • Die Authority-Length: Wie lang der Authority String ist. 8 Bits.
  • Die Authority: Welcher Server für die Domain verantwortlich ist. Müsste eigentlich "dchk" sein.


Danach wird das XML geschickt.

Alles muss in genau einem UDP-Paket geschickt werden und darf nicht länger als 4000 Byte sein. Standardport ist 715.

Mein Code

BlitzMax: [AUSKLAPPEN]
SuperStrict

Import Vertex.BNetEx

Global stream:TUDPStream
Global request:String

Try

stream = New TUDPStream

If Not stream.Init() Then Throw("Can't create socket")

stream.SetRemoteIP(TNetwork.GetHostIp("dchk.denic.de"))

stream.SetRemotePort(715)
Stream.SetLocalPort(715)

' Payload header, see http://tools.ietf.org/html/rfc4993#section-3.1.3
request :+ %00000000

' Transaction ID
request :+ %1010101010101010

' Maximum Response Size
request :+ %0000111110100000

request :+ %00000100

request :+ "dchk"

request :+ "<request xmlns="+Chr(34)+"urn:ietf:params:xml:ns:iris1"+Chr(34)+" xmlns:xsi="+Chr(34)+"http://www.w3.org/2001/XMLSchema-instance"+Chr(34)+" xsi:schemaLocation="+Chr(34)+"urn:ietf:params:xml:ns:iris1 iris.xsd"+Chr(34)+"><searchSet><lookupEntity registryType="+Chr(34)+"urn:ietf:params:xml:ns:dchk1"+Chr(34)+" entityClass="+Chr(34)+"domain-name"+Chr(34)+" entityName="+Chr(34)+"denic.de"+Chr(34)+" /></searchSet></request>"


stream.WriteLine(request)
Print request

Print(Stream.SendMsg()+" Bytes sent")

Catch Exception:Object

Print("Error")

Print(" " + Exception.ToString())

End Try

Repeat
If Stream.RecvAvail() Then
While Stream.RecvMsg() ; Wend

If Stream.Size() > 0 Then
Print("Message from:")
Print(" - IP = " + TNetwork.StringIP(Stream.GetMsgIP()))
Print(" - Port = " + Stream.GetMsgPort())
While Not Stream.Eof()
Print(">"+Stream.ReadLine())
Wend
EndIf
EndIf
Forever


Mein Problem

Der Request müsste eigentlich so richtig sein und er verbindet sich auch erfolgreich, aber es kommt einfach keine Antwort und ich weiß nicht, warum nicht. Habe ich in den RFCs etwas falsch gelesen oder schicke ich es einfach falsch oder antwortet er und ich empfange es nicht richtig?

Vielen Dank für eure Hilfe!

Tankbuster

BeitragDi, Dez 15, 2009 20:54
Antworten mit Zitat
Benutzer-Profile anzeigen
Es kann eventuell sein, dass dein Router den Port blockiert?
Portforwarding hilft Wink

Generell kann es sein, dass Teile des UDP-Paketes verloren gehen, wenn dieses zu groß wird. Allerdings passiert sowas generell sehr selten.

Das UDP-"Paket" kann aus mehreren Ethernet- oder IP-"Paketen" bestehen. Eventuell kommen diese immer in der falschen Reihenfolge an, so dass die Nachricht verfälscht wird und dadurch zerstört wird.

Diese 2 Punkte sind aber so unwahrscheinlich, dass ich den Fehler bei der Weiterleitung deines Routers suchen würde Wink

Ob dein Code jetzt 100% richtig ist kann ich nicht beurteilen. Dafür fehlen mir die BMax Kenntnisse Razz
Twitter
Download Jewel Snake!
Windows|Android

Justus

BeitragDi, Dez 15, 2009 21:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Danke für deine Antwort, Tankbuster, aber am Portforwarding liegt es leider nicht, habe es mit gezieltem Forwarding eingeschaltet getestet.

Generell (Tip von DarkCorner) braucht man das aber ohnehin meistens nicht extra einzurichten, weil er Pakete von IPs an die man gerade etwas geschickt hat, automatisch durchwinkt.

Tankbuster

BeitragDi, Dez 15, 2009 22:21
Antworten mit Zitat
Benutzer-Profile anzeigen
Das hier verwirrt mich:
Zitat:
request :+ %00000000
request :+ %1010101010101010


Ich weiß ja nicht ob es in BMax möglich ist, sowas zu machen. request ist ja als String deklariert, kann man dann einfach 1 oder 2 Bytes reinquetschen?

In Blitz3D funktioniert das nicht:
Code: [AUSKLAPPEN]
Local lol$=""
lol$=lol$+%10000000
Print lol$

Ergebnis: 128
Twitter
Download Jewel Snake!
Windows|Android

Justus

BeitragDi, Dez 15, 2009 23:01
Antworten mit Zitat
Benutzer-Profile anzeigen
Ist das nicht so wie es funktionieren soll? Bei mir kommt das entsprechende raus:
Zitat:
043690400013dchk.denic.de<request xmlns="urn:ietf:params:xml:ns:iris1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:ietf:params:xml:ns:iris1 iris.xsd"><searchSet><lookupEntity registryType="urn:ietf:params:xml:ns:dchk1" entityClass="domain-name" entityName="denic.de" /></searchSet></request>

Ob ich das jetzt als String behandle oder nicht ist doch egal, oder? Nur die Darstellung bei mir ist anders, die Bytes die ankommen aber dieselben, dachte ich. Nicht?

Tankbuster

BeitragDi, Dez 15, 2009 23:41
Antworten mit Zitat
Benutzer-Profile anzeigen
Ha, das ist der Fehler.
Die Bytes sind nämlich nicht gleich.


Dein "request :+ %1010101010101010" wird z.B. zu dem String "43690"
Du siehst was..

bin(1010101010101010)=dez(43690)

Also wird einfach nur die Binärzahl dezimal in den String geschrieben. Das kann nicht richtig sein. Hier liegt der Fehler Wink

Um das zu umgehen könntest du es so machen:

Code: [AUSKLAPPEN]

'  "request :+ %1010101010101010" wird zu:
stream.WriteByte(10101010)
stream.WriteByte(10101010)


MFG: Tank
Twitter
Download Jewel Snake!
Windows|Android

DAK

BeitragDi, Dez 15, 2009 23:57
Antworten mit Zitat
Benutzer-Profile anzeigen
oder auch möglich is

request :+ chr(%10101010)+chr(%10101010)
Gewinner der 6. und der 68. BlitzCodeCompo

Justus

BeitragMi, Dez 16, 2009 23:10
Antworten mit Zitat
Benutzer-Profile anzeigen
Leider erreiche ich mit beiden Varianten kein funktionierendes Resultat, wenn ich den Code nach euren Vorgaben modifiziere. Kriegt ihr ein funktionierendes Beispiel hin?

Tankbuster

BeitragMi, Dez 16, 2009 23:19
Antworten mit Zitat
Benutzer-Profile anzeigen
Wenn dein Code stimmen sollte, müsste es so funktionieren.
Allerdings nur, wenn der Server auch sowas wie WriteLine erwartet. Es kann ja auch sein, dass er erst die Länge des Strings in einem Integer erwartet, danach den String, so wie in BB bei ReadString
Oder er sucht nach nullterminierten Strings, was deiner nicht ist, da er mit einem Zeilenumbruch endet, und dann wird er einfach als unkomplett bewertet und nicht bearbeitet Wink

Dazu müsste man sich aber die docs anschaun, und ich bin etwas lesefaul. Besonders wenn es so englisch-technisches Zeug betrifft.

BlitzMax: [AUSKLAPPEN]

SuperStrict

Import Vertex.BNetEx

Global stream:TUDPStream
Global request:String

Try

stream = New TUDPStream

If Not stream.Init() Then Throw("Can't create socket")

stream.SetRemoteIP(TNetwork.GetHostIp("dchk.denic.de"))

stream.SetRemotePort(715)
Stream.SetLocalPort(715)

' Payload header, see http://tools.ietf.org/html/rfc4993#section-3.1.3
stream.WriteByte(%00000000)

' Transaction ID
stream.WriteByte(%10101010)
stream.WriteByte(%10101010)

' Maximum Response Size
stream.WriteByte(%00001111)
stream.WriteByte(%10100000)

stream.WriteByte(%00000100)

request :+ "dchk"

request :+ "Chr(34)+"urn:ietf:params:xml:ns:iris1"+Chr(34)+" xmlns:xsi="+Chr(34)+"http://www.w3.org/2001/XMLSchema-instance"+Chr(34)+" xsi:schemaLocation="+Chr(34)+"urn:ietf:params:xml:ns:iris1 iris.xsd"+Chr(34)+">Chr(34)+"urn:ietf:params:xml:ns:dchk1"+Chr(34)+" entityClass="+Chr(34)+"domain-name"+Chr(34)+" entityName="+Chr(34)+"denic.de"+Chr(34)+" />"


stream.WriteLine(request)
Print request

Print(Stream.SendMsg()+" Bytes sent")

Catch Exception:Object

Print("Error")

Print(" " + Exception.ToString())

End Try

Repeat
If Stream.RecvAvail() Then
While Stream.RecvMsg() ; Wend

If Stream.Size() > 0 Then
Print("Message from:")
Print(" - IP = " + TNetwork.StringIP(Stream.GetMsgIP()))
Print(" - Port = " + Stream.GetMsgPort())
While Not Stream.Eof()
Print(">"+Stream.ReadLine())
Wend
EndIf
EndIf
Forever

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group