JAIN-SIP getting request source IP address and port - jain-sip

Is there a way of getting the IP address/port of an incoming request? (I don't want the data in the message, but I'd like information from the SIP stack itself, and preferably also the listening point the request had been received on.)
So far I have not find any solution by parsing the Javadocs.

Pending you are using http://java.net/projects/jsip
Cast RequestEvent to gov.nist.javax.sip.RequestEventExt in
public void processRequest(RequestEvent requestEvent) {
RequestEventExt requestEventExt = (RequestEventExt) requestEvent;
requestEventExt.getRemoteIpAddress();
requestEventExt.getRemotePort();
}
Best Regards
Jean

Related

how Channel.isActive() works in netty?

I'm using netty 4.x, and I finally find it calls
public boolean isActive() {
SocketChannel ch = javaChannel();
return ch.isOpen() && ch.isConnected();
}
can I use it to check whether the connection between client and server is readable/writeable?
If the answer is yes, then I believe isActive use sth. like heartbeat to check the status of the client. but when I grab the tcp packets I can't find any packets work as heartbeat through wireshark filter tcp.port==12093(it's my server port).
any suggestion is helps.
Channel.isActive() works by looking up the querying the underlying socket to see if it is connected.
So if we want to know how it works we should dig a little deeper, if you are using netty with tcp connections, you are almost sure you are using the java nio sockets.
From io.netty.channel.socket.nio.NioSocketChannel:
#Override
public boolean isActive() {
SocketChannel ch = javaChannel();
return ch.isOpen() && ch.isConnected();
}
Both of the above methods aren't that interesting, and are simply boolean flags set to the correct value by native code.
However, since isActive() just returns those boolean flags, you cannot be sure that the connection is still working at the moment you call the function, the best way would be to change your protocol to include some kind of ping message, for example IRC has a ping command, or FTP has the NOOB command.
When sending a ping message, you must make sure that it leaves enough headroom for partial network dropout, for example if your computer is connected through WIFI, there will be some packet loss. However, the native tcp layer in the operating system should handle these packet loss combined with resending for you, but it may mean that after you send a ping message, it may take up to a full minute before isActive() will return false.
If you want to add automatic ping messages to your protocol, it may be wise to look into the IdleStateHandler and the WriteTimeoutHandler.

UDP Listen, Send Receive (Simple, Client and Server on same app)

Okay, I want to send a UDP packet to an IP, and then receive it.
As I can't get it to work, I have to ask for assistance.
I want it to work on 1 app, meaning client and server is on the same application.
I currently got it working with Audio sending and receiving on the same app (using sample codes and stuff).
And the thing I can´t understand is just the UDP, and probably Sockets.
It seems simple, but I can´t get it to work.
So if I can get a very simple sample, like:
"UDP Send "hello" to IPofchoice"
"UDP receive "data" from IPofchoice"
Messagebox.show("decoded(data));
Well hope you get what I mean.
EDIT:
Here is my "example" which doesn´t work at all.
void VoiceChat_KeyPress(object sender, KeyPressEventArgs e)
void VoiceChat_KeyPress(object sender, KeyPressEventArgs e)
{
string text = "Hello";
byte[] send_buffer = Encoding.ASCII.GetBytes(text);
otherPartyIP = new IPEndPoint(IPAddress.Parse(txtCallToIP.Text), 1450);
udpClientKey.Send(send_buffer, send_buffer.Length, "127.0.0.1", 1450);
byte[] byteData = udpClientKey.Receive(ref otherPartyIP);
MessageBox.Show(otherPartyIP.Address.ToString());
MessageBox.Show(System.Text.Encoding.ASCII.GetString(byteData));
}
Where txtCallToIP.tex = the ip i write, which is 127.0.0.1 currently.
This i solved.
To have a client and server in UDP it´s very easy, though a bit dangerous, as you don´t know for sure if it´s working or not unless you test it (UDP just send and don´t care about anything else).
So basically to do it.
Client.Send(buffer,0,buffer.size,IPAdress,Port);
byte[] rec = Client.Receive(ref IPAdress);
To receive you must have bind it to an IP, so you can just bind it to listen to Any ipadress,
The port however needs to be set (i think), and you want to do that, as listening to everything there is, is not a good idea.
So ref IPAdress will be that listening IP and Port.
So it´s very easy to set up. And you can use the same UDPClient for both receiving and sending if you want, though it´s probably better to have 2 separate .

Get TCP address information in ZeroMQ

I want to connect clients to a server using ZeroMQ (java bindings, jzmq), but I need the TCP information badly, for example the TCP/IP address of a client request! The problem is, for being able to announce a service in the network I need to grab the TCP address of a request to be able to redirect clients to that service. The broker is a central "service registry" in that case. However, having ZeroMQ services on both sides, I do not see an option to retrieve that information.
What I do now, is to establish a dummy connection using a standard socket to the broker, after the connection is established I grab the IP address used for this connection and close the connection again. The IP address which has been retrieved is now being used for binding on it using a ZeroMQ socket on a random port.
I think this solution is the ugliest solution ever possible, so: What is a better solution to this problem?
Greetings.
0MQ doesn't provide the address of peers, for a number of reasons. It's also not that useful since what you really want is the endpoint to receive connections on, not the address the connection was made on.
What I usually do, and it's elegant enough, is pass bind a service to an ephemeral port, get a full connection endpoint ("tcp://ipaddress:port") and send that string in some way, either broadcast to peers, to a central registry, etc. along with my service name. Then, peers who want to connect back can take the service name, look up to find my endpoint, and connect back to me.
In ZMQ 4.x, you may get the string property "Peer-Address" or the "Identity" property. http://api.zeromq.org/4-2:zmq-msg-gets
The Identity is set in the other peer before connect(). http://api.zeromq.org/4-2:zmq-setsockopt#toc20
For example,
const char *identityString = "identity";
zmq::context_t context(1);
zmq::socket_t socket(context, ZMQ_REQ);
socket.setsockopt(ZMQ_IDENTITY, identityString, strlen(identityString));
socket.connect("tcp://127.0.0.1:5555");
Then the other side:
while(1)
{
zmq::message_t request;
if (socket.recv(&request, ZMQ_NOBLOCK))
{
const char* identity = request.gets("Identity");
const char* peerAddress = request.gets("Peer-Address");
printf("Received from %s %s\n", peerAddress, identity);
break;
}
}
I'm using CppZmq btw, you should be able to find the relevant calls easily.
Digging deeper into the libzmq code, I discovered that the library attaches to every message instance the file descriptor that it was received on.
This worked for me
int sockfd = zmq_msg_get(&msg, ZMQ_SRCFD);
sockaddr_in addr;
socklen_t asize = sizeof(addr);
getpeername(sockfd, (sockaddr*)&addr, &asize);
std::cout << inet_ntoa(addr.sin_addr) << ":" << addr.sin_port << std::endl;
Note that the FDs can and will be reused by other connections.
I'm working with version 4.2.1 of the api using the CZMQ binding and I found a solution for my case (ZMQ_STREAM). It works by setting an id before connecting.
The relevant socket option is "ZMQ_CONNECT_RID".
ZMQ api via zmq_setsockopt()
CZMQ api via zsock_set_connect_rid()
Some codes with redacted redacted ips.
const char endpoint1[] = "tcp://1.2.3.4:12345"
const char endpoint2[] = "tcp://5.6.7.8:12345"
zsock_t *stream = zsock_new(ZMQ_STREAM);
zsock_set_connect_rid(stream, endpoint1);
zsock_connect(stream, endpoint1);
zsock_set_connect_rid(stream, endpoint2);
zsock_connect(stream, endpoint2);
Then I get those 2 messages if there is a connection. First frame is the id and second frame is empty on connect/disconnect for ZMQ_STREAM sockets.
[Message1]
[019] tcp://1.2.3.4:12345
[000]
[Message2]
[019] tcp://5.6.7.8:12345
[000]
Another option is to use the zmq_socket_monitor() or czmq zmonitor. It was one of my first solution but I was looking for something lighter. I was able the get the endpoint that way without setting the id directly on the socket.
The zmonitor zactor make it possible to subscribe to socket events and then it sends a message with 3 frames:
[009] CONNECTED
[002] 14
[021] tcp://127.0.0.1:33445

send to port on server

If I open up a port on our server to listen out for incoming messages (ie - strings of text), how can i send those messages? are their any example codes out there that are useful?
I have downloaded a few sample projects but none seem to do i want.
what code is used to specify the ip address and port number?
Here you wil find exactly what you need.
It is a wrapper class called AsyncSocket; to connect you just send it the string with the ip and an int with the port.
It will do all the work on ints own.
To send info you just turn your string into NSData if I remember correctly.
It has a very easy to follow sample so you should be up and running in about 20 min.
Look up any tutorial text on networking.
For instance, there are a bunch of echo server implmentations at rosettacode.

Send XMPP (Smack) Message

Ok, the problem should be trivial but I can't get to the bottom of it.
I have two users A & B
Their JID's for this example will be A#123 and B#123 where 123 is the IP of the server.
I'm sending a message from A->B using the following code:
chat = chatmanager.createChat(username,
new MessageListener() {
public void processMessage(Chat chat, Message message) {}});
String sendUsername = username + "#123";
Message msgObj = new Message(sendUsername, Message.Type.chat);
msgObj.setBody(message);
chat.sendMessage(msgObj);
I've hardcoded the IP so that I'm 100% sure that I attach the "#123" at the end of the nickname so there are no incorrect JIDs.
So A#123 sends msgObj to B#123. This is how I understood XMPP messaging to work. That you can't send from A->B but it must be A#123 -> B#123.
However, my server seems to think otherwise. It continuously informs me of the following error:
2010.12.27 19:02:52 [org.jivesoftware.openfire.session.LocalOutgoingServerSession
.createOutgoingSession(LocalOutgoingServerSession.java:258)] Error trying to
connect to remote server: A(DNS lookup: A:5269)
java.net.UnknownHostException: A
In both A and B's roster on the Openfire server, they have each other as a contact with the proper JIDs (username#123).
Can anyone provide some insight? I'm lost.
Edit
I'm trying to use Wireshark to catch the XML sent to and from the Openfire server to determine if the recipient of the message is named properly (A#123 instead of A).
Upon using Wireshark, I received this as the XML being transferred:
\302\3469\223\341\3429\000\000\000\000\377\377
I have disabled SSL, I have connected un-securely. I'm not sure why I'm getting SSL type XML, is that what it is?
Turns out the answer to this problem was something that was just overlooked.
In the first line of code:
chat = chatmanager.createChat(username, new MessageListener() {
public void processMessage(Chat chat, Message message) {}
});
I didn't make the variable "username" have the proper IP extension. So it was merely "A" instead of "A#123"
Moving "sendUsername" to the top and Changing "username" to "sendUsername" makes everything work great :)
Silly mistake.
Using IP addresses is almost always more confusing than you think it is.
There's a good chance you have OpenFire misconfigured, so that the IP address isn't a valid hostname. Go into the admin console, under "System Properties", and make sure that the xmpp.domain property is set to your IP address.