Skip to content

Commit a25ad12

Browse files
committed
begin prototyping mdns
1 parent a428dac commit a25ad12

File tree

3 files changed

+138
-0
lines changed

3 files changed

+138
-0
lines changed

source/utils/misc.brs

+4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import "pkg:/source/utils/config.brs"
2+
import "pkg:/source/utils/resolver/resolver.brs"
23

34
function isNodeEvent(msg, field as string) as boolean
45
return type(msg) = "roSGNodeEvent" and msg.getField() = field
@@ -233,6 +234,9 @@ function urlCandidates(input as string)
233234
host = url[2]
234235
port = url[3]
235236
path = url[4]
237+
238+
host = resolve(host) ' /source/utils/resolver/resolver.brs
239+
236240
protoCandidates = []
237241
supportedProtos = ["http:", "https:"] ' appending colons because the regex does
238242
if proto = "none:" ' the user did not declare a protocol

source/utils/resolver/resolver.brs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
import "pkg:/source/utils/resolver/resolvers/local.brs"
3+
4+
' takes a string like "domain.tld",
5+
' determines if a stub resolver exists for tld
6+
' if it does, it attempts to resolve and return an ip
7+
' if resolution fails or no stub resolver exists,
8+
' returns the arguemnt it received.
9+
' we get around the tls problem with .local, since most interfaces
10+
' on the roku do not accept custom tls directives in 12.0
11+
' such as the Poster, the agent that fetches bif files, etc.
12+
' this means there is no way that the user has domain which both
13+
' requires one of these resolvers and has a globally
14+
' signed certificate. later, perhaps we can implement a custom
15+
' httpAgent and do our own per-resolver verification.
16+
function resolve(dn as string) as string
17+
parts = dn.tokenize(".")
18+
domain = parts[0]
19+
tld = parts[1]
20+
if tld = "local"
21+
localResolve(domain)
22+
end if
23+
return dn
24+
end function
+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
function localResolve(dn as string) as string
2+
print ".local resolver received domain " dn
3+
sendQuery(dn)
4+
ts = CreateObject("roTimespan")
5+
while ts.totalSeconds() < 10
6+
msg = Wait(5000, m.mdns.port)
7+
if msg <> invalid
8+
print "Message: "
9+
print msg
10+
ProcessMDNSResponse(msg)
11+
exit while
12+
end if
13+
end while
14+
return ""
15+
end function
16+
17+
function processMdnsResponse(message)
18+
if Type(message) = "roSocketEvent"
19+
if message.GetSocketId() = m.mdns.socket.GetId()
20+
print "The status of the socket: " m.mdns.socket.eSuccess()
21+
if m.mdns.socket.IsReadable()
22+
response = CreateObject("roByteArray")
23+
r = m.mdns.socket.Receive(response, 0, 4096)
24+
print "Received MDNS response packet: "
25+
print response
26+
print r
27+
else
28+
print "m.mdns.socket is not readable"
29+
end if
30+
else
31+
print "message is not from m.mdns.socket"
32+
end if
33+
else
34+
print "message is not an roSocketEvent"
35+
end if
36+
return ""
37+
end function
38+
39+
function rdRightShift(num as integer, count = 1 as integer) as integer
40+
mult = 2 ^ count
41+
summand = 1
42+
total = 0
43+
for i = count to 31
44+
if num and summand * mult
45+
total = total + summand
46+
end if
47+
summand = summand * 2
48+
end for
49+
return total
50+
end function
51+
52+
function rdINTtoHEX(num as integer) as object
53+
ba = CreateObject("roByteArray")
54+
ba.setresize(4, false)
55+
ba[0] = rdRightShift(num, 24)
56+
ba[1] = rdRightShift(num, 16)
57+
ba[2] = rdRightShift(num, 8)
58+
ba[3] = num ' truncates
59+
return ba.toHexString().Right(2)
60+
end function
61+
62+
sub printTests()
63+
print rdINTtoHEX(183)
64+
end sub
65+
66+
function strToHex(name as string) as object
67+
ba = CreateObject("roByteArray")
68+
ba.FromAsciiString(name)
69+
return ba.toHexString()
70+
end function
71+
72+
function createPacket(name as string)
73+
firstPart = "000000000001000000000000"
74+
secondPart = rdINTtoHEX(len(name)) + strToHex(name)
75+
lastPart = "056c6f63616c0000010001"
76+
packet = CreateObject("roByteArray")
77+
packet.fromHexString(firstPart + secondPart + lastPart)
78+
return packet
79+
end function
80+
81+
sub sendQuery(name)
82+
m.mdns = {
83+
port: CreateObject("roMessagePort"),
84+
address: CreateObject("roSocketAddress"),
85+
group: CreateObject("roSocketAddress"),
86+
socket: CreateObject("roDatagramSocket"),
87+
urlTransfer: CreateObject("roUrlTransfer")
88+
}
89+
90+
m.mdns.address.SetAddress("224.0.0.251:5353")
91+
m.mdns.group.SetAddress("224.0.0.251:5353")
92+
93+
print "Succesfully joined group:" m.mdns.socket.JoinGroup(m.mdns.group)
94+
m.mdns.socket.SetBroadcast(false)
95+
m.mdns.socket.setaddress(m.mdns.address)
96+
m.mdns.socket.NotifyReadable(true)
97+
print "THE MULTICAST TTL: " m.mdns.socket.getMulticastTTL()
98+
m.mdns.socket.SetMessagePort(m.mdns.port)
99+
m.mdns.urlTransfer.SetPort(m.mdns.port)
100+
'm.mdns.socket.SetBroadcast(true)
101+
'print "Broadcast enabled: " m.mdns.socket.GetBroadcast()
102+
'print "Multicastloop: " m.mdns.socket.GetMulticastLoop()
103+
m.mdns.socket.SetSendToAddress(m.mdns.address)
104+
105+
mdnsQueryPacket = createPacket(name)
106+
groupJoinPacket = CreateObject("roByteArray")
107+
groupJoinPacket.fromHexString("1100eeff00000000")
108+
m.mdns.socket.Send(groupJoinPacket, 0, mdnsQueryPacket.count())
109+
m.mdns.socket.Send(mdnsQueryPacket, 0, mdnsQueryPacket.count())
110+
end sub

0 commit comments

Comments
 (0)