Bind UDP server on specific ip address ERLANG - udp

I need to bind the UDP server to a specific IP address. Now I'm creating a UDP server like this
start_link(N,Param) ->
gen_server:start_link({local,?SERVER},?MODULE, [N,Param], []).
%% ------------------------------------------------------------------
%% gen_server Function Definitions
%% ------------------------------------------------------------------
%% opens UDP listening socket. May be sockets will be more than 1
init([N,ListenPort]) ->
Port=ListenPort+N-1,
inets:start(),
{ok,Socket}=gen_udp:open(Port,[{active,once},{reuseaddr,true},binary]),
{ok, #state{port=Port,socket=Socket,in=0,out=0}}.
Where PARAM is UDP server port.
I don't know how to bind it to some IP.
Could someone help me please?

Use the ip option, passing the address as a tuple:
{ok,Socket}=gen_udp:open(Port,[{active,once},{reuseaddr,true},binary,{ip,{127,0,0,1}}]),
If you have the IP address in string format, you can use inet:parse_address/1 to parse it into a tuple:
{ok, IpAddress} = inet:parse_address("127.0.0.1"),
{ok,Socket}=gen_udp:open(Port,[{active,once},{reuseaddr,true},binary,{ip,IpAddress}]),

Related

When receiving on UDP socket listening on ANY/0.0.0.0 address, to which local IP was the packet sent?

On my system I have multiple IP addressed. A UDP socket is listening to them all by binding to 0.0.0.0:5005.
Call recvfrom to wait for data.
In the response a sockaddr is filled with the address of the remote sender.
But how do I get to know which of my local IP the packet was sent to?
Is the a way to know?
Or do I need to explicitly open a socket for each IP address on the system?

Receive TCP with 2 IP Addresses - VB.Net

I'm making a chat program and i have a big problem : I have to make my computer listen more IP Adresses .
I mean that my computer will have to receive TCP data addressed to different IP at the same time .
Example :
the Computer 1 send "Hello 1" to the IP 192.168.1.103 and
the Computer 2 send "Hello 2" to the IP 192.168.56.1
My Computer (with IP : 192.168.58.1) have to receive both the messages ( i think that the only way to do that is to change continuosly my computer IP from 192.168.1.103 to 192.168.56.1 and the other way around)
Yes i know , it's a little hard ...
There's a more simple way to make this ?
As #tcarvin mentioned, UDP is more advisable. You can use UDP as the initial protocol for a TCP-IP connection and then operate the rest of the chat over TCP-IP after the connection is established.

STUN server address is incompatible | Error code=701:

I have installed the TURN server everything in the server code is working fine. no error in the log file. only a warning stating
0: WARNING: I cannot support STUN CHANGE_REQUEST functionality because only one IP address is provided
but the TURN server running on the server.
here is what shows when I check lsof -i :3478
turnserve 999 root 15u IPv4 446811411 0t0 TCP domain.com:stun (LISTEN)
turnserve 999 root 23u IPv4 446811417 0t0 TCP domain:stun (LISTEN)
turnserve 999 root 24u IPv4 446810998 0t0 UDP domain.com:stun
turnserve 999 root 25u IPv4 446810999 0t0 UDP domain.com:stun
when I check STUN in Trickle ICE it throws an errors
The server stun:xxx.xxx.xxx.xxx:3478 returned an error with code=701:
STUN server address is incompatible.
The server stun:xxx.xxx.xxx.xxx:3478 returned an error with code=701:
STUN allocate request timed out.
what's going wrong in this.
Thank you
I think that 701 error is a more generic connectivity error that Trickle ICE uses to indicate it didn't get a binding response back. Run stunclient your.stun.ip.address with the command line tools at www.stunprotocol.org to see if your STUN service is accessible from the outside world.
STUN technically requires being hosted on a device with two IP addresses and two ports. It's typically a command line parameter to specify which IP addresses the server should listen on. But most server implementations can operate on a host with a single IP address.
The second IP address and port on the server is used for STUN client filtering tests to detect what type of NAT is in effect. The client sends a binding request on the server's primary ip and port, but with a change request attribute to have the server respond from the alternate IP address or port. More often than not, this binding request with a change-request attribute fails since NATs will not forward traffic from the other IP/port.
The filtering test is useful for logging what type of NAT the client is on. So that failed connections can be debugged and that success/failure metrics can be correlated to NAT type.
Since most ICE implementations will exchange all available address candidates (local, mapped, and relay), the filtering test isn't very or useful to connectivity establishment.
I'm surprised Trickle ICE is giving you an error. I didn't think WebRTC ever used the changer-request attribute. I just did a Wireshark trace of a Trickle ICE session to stunserver.stunprotocol.org. I don't see the webrtc client setting the change-request attribute in either of the two binding requests it makes.
More details in RFC 5780 Section 3.2
In macOS, I just do so:
> brew install stuntman
when it done
> stunclient stunserver.stunprotocol.org
Binding test: success
Local address: 198.18.0.1:54898
Mapped address: 210.0.158.130:56750
To specify port, just like this:
> stunclient stunserver.stunprotocol.org 3478
Binding test: success
Local address: 198.18.0.1:63061
Mapped address: 210.0.158.130:37126
Have fun!

send UDP to client behind a nat using STUN

I want to test stun client/server and the send udp traffic from server side to client side.
I run stun client in a local machine, I get the following result.1.
Lenovo-Z50-70:~/iop-bb$ stun -v my_stun_server
STUN client version 0.96
Opened port 22948 with fd 3
Opened port 22949 with fd 4
Encoding stun message:
Encoding ChangeRequest: 0
About to send msg of len 28 to 212.227.107.179:3478
Encoding stun message:
Encoding ChangeRequest: 4
About to send msg of len 28 to 212.227.107.179:3478
Encoding stun message:
Encoding ChangeRequest: 2
About to send msg of len 28 to 212.227.107.179:3478
Received stun message: 88 bytes
MappedAddress = 41.224.250.29:22948
SourceAddress = 212.227.107.179:3478
ChangedAddress = 127.0.0.1:3479
XorMappedAddress = 41.224.250.29:22948
ServerName = Vovida.org 0.96
Received message of type 257 id=1
On the server side, I execute the following, echo "hello" | nc -w1 -u 41.224.250.29 22944.
But, in the client side I didn't receive the packet.
Any suggestion?
You would need to match the port on both sides and do a hole punching step after obtaining your public ip and port.
You ran a stun client listening on local port 22948 to the server (listening on port 3478). From that port you sent a stun binding request request to your server.
The server responded back with a response indicating that your public ip:port was
41.224.250.29 22948.
So now you know that your local ip (e.g. 192.168.1.2) maps to 41.224.250.29 and your local port 22948 maps to the public port 22948.
You could in theory start communicating between client port 22948 and server 3478, but 3478 is already in use by the server. You need to do a hole punching step using the same port you obtained from the STUN response.
The hole punching step with your other service goes like this. Client sends from port 22948 to server (port 9876 for example).
echo "hello there" | nc -p 22948 server 9876
The server could respond:
echo "I see you" | nc -p 9876 41.224.250.29 22948
On the server side, I execute the following, echo "hello" | nc -w1 -u 41.224.250.29 22944
Does this received any packet prior from that client or using the address "41.224.250.29 22944"? If not, client end NAT will not allow this incoming traffic unless it's a full-cone NAT. It's also important that client is using a socket which is ready to receive any packet from that external source. Basically, you have to make sure that binding is there for that external source.

enumerating ipv4 and ipv6 address of my cards using boost asio

I am trying to enumerate ipv4 and ipv6 addresses of all the network cards(I have 2 cards) my pc.
I am using the following code to do that.
using boost::asio::ip::tcp;
boost::asio::io_service io_service;
tcp::resolver resolver(io_service);
tcp::resolver::query query(boost::asio::ip::host_name(),"");
tcp::resolver::iterator it=resolver.resolve(query);
while(it!=tcp::resolver::iterator())
{
boost::asio::ip::address addr=(it++)->endpoint().address();
if(addr.is_v6())
{
std::cout<<"ipv6 address: ";
}
else
std::cout<<"ipv4 address: ";
std::cout<<addr.to_string()<<std::endl;
}
The code displays correct ipv4 addresses but not ipv6. Here is the output
ipv6 address: ::1
ipv4 address: 192.168.10.200
ipv4 address: 192.168.10.236
I have very minimum knowledge of ipv6. When I list the information about network interface using ipconfig/all I see that the actual ipv6 addresses are
fe80::226:5aff:fe14:5687%5
fe80::225:64ff:feb2:4f61%4
Can someone please guide me how to list the ipv6 addresses.
Thanks.
If the platform is Windows 7 SP1 the link-local interfaces are being skipped as they are tagged "SkipAsSource" by Windows which means that getaddrinfo will not return them and hence neither will Boost.
You can try to inspect the flag with the following command:
netsh int ipv6 show addresses level=verbose
Address fe80::e0:0:0:0%14 Parameters
---------------------------------------------------------
Interface Luid : Teredo Tunneling Pseudo-Interface
Scope Id : 0.14
Valid Lifetime : infinite
Preferred Lifetime : infinite
DAD State : Deprecated
Address Type : Other
Skip as Source : **true**