udp: determine local port?
Alex Tweedly
alex at tweedly.net
Thu Jul 6 17:13:36 EDT 2006
John Craig wrote:
> Is it possible for rev to determine the local port used to send udp data?
>
I don't know of a way to do this directly - certainly nothing I can see
in the docs, and haven't seen it done.
There is a pretty nasty (but generally effective) way to do it ..... see
below. But before you get to that, I have to ask *why* you want to know
this. I can think of lots of possible reasons - but most of them aren't
good reasons. Generally, you don't need to know which local port has
been used - the handler specified in the "open" statement receives a
message when any reply arrives, without needing to know the port number.
There are good reasons to want it, but all the ones I can think of are
pretty esoteric (e.g. to punch a hole through a firewall). So I am
curious why you want this, in case we can suggest a better way.
Icky work-around.
All major OSes (afaik) allocate local ports serially, so you can pretty
much determine what was allocated by
- accept udp packets on some loopback interface (e.g. 127.0.0.1:9876)
- open a "connection" to this interface, send a packet to the
connection, close the connection
- give message processing a chance to happen
- open the socket you *really* wanted
- open a "connection" to this interface, send a packet to the
connection, close the connection
- give message processing a chance to happen again
Each time the loopback receives a packet, it can look at the incoming
socket info (which contains the return port number)
These *should* differ by two (assuming the OS allocated serially, and
nothing else got in the way).
If they differ by something other than 2 - try again !?!
Here's some code I tried out just to check if that does actually work,
and it does seem to ...
> --> all handlers
>
> on mouseUp
> -- use a 192.168.1.1 address (i.e. NOT same machine) to avoid
> error of no-one accepting on this port
> put "opened" && getUDPLOcalSocket("191.168.1.1:4567", myCallBack)
> & cr after msg
> -- put "before write " && the opensockets & cr after msg
> -- write "one" && cr to socket "127.0.0.1:4567"
> -- put "after write " && the opensockets & cr after msg
> end mouseUp
>
> on myCallBack
> -- will only be called if there is, e.g., an echo server on the
> "real" socket
> -- and if the above three lines are uncommented ...
> put "real call back handler ---------" & cr & paramCount() & cr
> after msg
> repeat with i = 1 to paramCount()
> put i && ":" && param(i) & cr after msg
> end repeat
> put "end real call back handler ---------" & cr after msg
> end myCallback
>
> local lIncomingSocketList
> local lLoopBackSocket = "127.0.0.1:9876"
> function getUDPLocalSocket pSocket, pCallBack
> -- first zero the accumulator
> put empty into lIncomingSocketList
> -- and close the socket (if it's alreadyh open, would re-use same
> local port number
> close socket pSocket
> -- set up the loopback, write to and close
> accept datagram connections on port "9876" with message loopBack
> open datagram socket lLoopBackSocket with message loopBack
> write " " to socket lLoopBackSocket
> close socket lLoopBackSocket
> -- MUST give that a chance to happen !
> wait 5 millisecs with messages
>
> open datagram socket pSocket with message pCallBack
>
> -- repeat the loopback open/write/close/allow messages
> open datagram socket lLoopBackSocket with message loopBack
> write " " to socket lLoopBackSocket
> close socket lLoopBackSocket
> wait 5 millisecs with messages
> -- and now can return the list - should have two port numbers 2 apart
> return lIncomingSocketList
> end getUDPLocalSocket
>
> on loopBack pSock
> put pSock & comma after lIncomingSocketList
> put "lopback" && pSock &cr after msg
> end loopBack
>
> on socketError p
> put "error" && p after msg
> end socketError
--
Alex Tweedly http://www.tweedly.net
--
No virus found in this outgoing message.
Checked by AVG Free Edition.
Version: 7.1.394 / Virus Database: 268.9.8/380 - Release Date: 30/06/2006
More information about the use-livecode
mailing list