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