I have an iPad application which opens a socket connection to a server in Intranet using socket libraries in C . While starting the application, if the iPad is not connected to the same network (i.e. can not resolve the Domain Name of the server), I expect it to establish a VPN connection automatically. But socket calls and getaddrinfo() methods in the application can not do this. They just fail to connect to the server without trying to open the VPN connection.
With Safari, browsing to the address "http://..." works fine and succesfully starts the VPN. If I make a similar HTTP request in the beginning of the application by using the code below, I can make it start the VPN connection. But sending an additional http request is the best solution for me. VPN should start whenever iPad needs to resolve the domain name, without any dependency for the protocol or remote port number.
NSString* urlForVPN = #"http://..";
NSURLRequest * urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:urlForVPN] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:10.0];
[NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error];
On Apple developer site it says "Avoid Resolving DNS Names Before Connecting to a Host. The preferred way to connect to a host is with an API that accepts a DNS name, such as CFHost or CFNetService" (https://developer.apple.com/library/ios/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/CommonPitfalls/CommonPitfalls.html). Accordingly, I was hoping that the following code should start VPN while trying to resolve the server name, but it does not work either. It just fails to get the IP address. I had to manually switch on the VPN to make it connect to the server.
NSString* hostname = #"myserver";
CFHostRef hostRef = CFHostCreateWithName(kCFAllocatorDefault, (CFStringRef)hostname);
BOOL isSuccess = CFHostStartInfoResolution(hostRef, kCFHostAddresses, nil);
How can I make an application understand that it needs to start the VPN?
Does "VPN on-demand" work only for URL connections?
From what I have come to understand through articles as well as first-hand reach, VPN-on-Demand will only trigger when you use Apple libraries that utilize WebKit (NSURLSession, NSURLConnection, etc.).
Therefore socket-based network requests are unable to trigger Apple's On-Demand VPN.
The documentation that appears support this is found here:
https://developer.apple.com/library/prerelease/ios/documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/CommonPitfalls/CommonPitfalls.html#//apple_ref/doc/uid/TP40010220-CH4-SW2
For those stumbling with this problem, using POSIX sockets will not trigger on-demand VPNs because those rules match by domain and those sockets don't have the domain info.
One workaround is to launch a dummy request through the usual NSURLSession / NSURLConnection to the correct domain to just trigger the VPN.
You might also want to get the reachability status and check for the "kSCNetworkReachabilityFlagsTransientConnection" which empirically turns to be there when a VPN connection is available (because many modern VPNs are based on ppp). These way you could detect when the VPN turns off in order to launch another dummy request.
Related
I was curious on why a client cannot directly to a machine running webrtc server but can do that via turn server. Both turn & webrtc are in same VPC of AWS.
Could be a lot of things.
Assuming you have the TURN configuration file correct, and as you are noting both AWS instances have public IPs, then it's possible that on the instance with the TURN server, you do not have all the firewall ports opened needed related to the TURN server: https://stackoverflow.com/a/59212004/8201657
Or, maybe it's a DNS issue and the domain of your TURN server is unknown to your peer, so it is not able to access it.
Or, maybe you are attempting to connect via WebRTC but not securely. WebRTC requires a secure connnection (https).
I have developed a WebRTC based application along with Kurento-Media-Server.
Problems with this application is:
It works but only on open network (i.e. if run on a network without firewall).
When in firewall it runs sometimes (once out of 10 attempts).
I have tried several things with the firewall, I have disabled all kind of incoming/outgoing traffic. I have created a port-forwarding for my application as well as Kurento-media server.
I am not sure how much useful this information might be but I am deploying my
application on the same physical box along with Kurento-Media-Server. I have configured google's STUN server on my client.js, I have also configured same STUN servers on kurento using code. I haven't configured TURN server.
Just confirming this, signaling server can be behind firewall along with rest of the application, correct?
I am not sure what to look for now, any help in this area would be great.
EDIT-1
From this link I learned that my current network on which my isn't working it has issues with plain websocket connection, it doesn't allow it, it only allows secure Websocket connections.
EDIT-2
Image of netscan:
In my phone network where my app works fine I see all greens in Websocket's "plain" column.
EDIT-3 Solved
Finally found the problem, We were using a router for testing and development and I found that the router had issues, I used LAN cable on the same router and everything worked fine. Calls from application were working just fine. Firewall related details help in configuring the firewall later on.
Based on your problem description it seems all the UDP traffic is not open in your firewall. WebRTC media run on UDP ports.As you mentioned it works one out of 10 times whch means only few UDP ports are open in your firewall.You are lucky when traffic comes via tose ports.You can open port-range in your firewall and configure the same in kurento-media-server config.Your job should be done.
Even if you configure TURN server you need to open certain ports for outgoing and incoming UDP traffic.For TURN server default port is 3478 or 8443 for sending data towards it but for incoming traffic you need to configure port-range on your TURN server and open those ports in your firewall. Always remember TURN server is assured way to connect but it's always costly.
I'm posting data from my app to my server using NSURLSession when a button is pressed. I can successfully send the data to my server and insert into a database, for the first two occasions, but any time after that, the request times out.
I've tried: changing session configuration (connections per host, timeoutInterval etc), session configuration types, changing the way the data is posted.
Has anyone seen this sort of behaviour before and know how I can fix this issue?
Or is it a server issue? I thought my server was down initially. I couldn't connect to it, nor load certain pages. However, it was only down for me. After rebooting my modem, I could connect back to the server. I didn't have any issues connecting to phpMyAdmin.
If the problem was reproducible after a reboot of the router, then I would look into whether Apple's captive portal test servers were down at the time.
Otherwise, my suspicion is that it is a network problem rather than anything specific to your app.
It is quite possible that the pages you were loading successfully were coming from cache.
Because you said that rebooting your modem fixed the problem, that likely means that your modem stopped responding to either DHCP requests or DNS lookups (either for your domain or for one of the captive portal test domains).
It is also possible that you have a packet loss problem, and that it gets worse the longer your router has been up and running. This could cause some requests to complete and others to fail.
Occasionally, I've seen weird behavior vaguely similar to this when ICMP is getting blocked too aggressively.
I've also seen this when a stateful firewall loses its mind and forgets the state.
This can also be caused by keeping HTTP/HTTPS connections alive past the point at which the server gives up and drops the connection, if your firewall is blocking the packet that tells you that the connection was closed by the remote end.
But without a packet trace, there's no way to be certain. To get one:
If your network code is running on OS X, you can just do this with tcpdump on your network interface.
If you are doing this on iOS, you can do this by connecting your computer via wired Ethernet, enabling network sharing over Wi-Fi, pointing tcpdump at the bridge interface, and pointing your iPhone at that Wi-Fi network.
Either way, that will tell you if there are requests going out that never come back, and more importantly, what type of requests they are, and who is responsible for replying to them. Once you have that information, if the source of the problem isn't obvious, post a link to the packet trace and we'll add more suggestions.
I am consuming a web service in .NET application with WCF client.
The Endpoint's address of the service is over port 4338, and it is over HTTPS, secured with WS-Security standard.
So the address is something like :
https://[servername]:4338/[servicename]/
I was not able to communicate to the service with just running the application.
it gave me the following error :
Could not connect to [servername]:4338
TCP error code 10060: A connection
attempt failed because the connected
party did not properly respond after a
period of time, or established
connection failed because connected
host has failed to respond
[servername]:4338
But when I run Fiddler to investigate the http communication, the application start to work, and I will be able to communicate to the service.
As well, I want to add that I have a different service on the same web server that hosts the first service, and that second service's address is hosted on port 8080, and I am able to communicate with it with WCF client (without running Fiddler).
So, I googled and I found that it might be related to the proxy settings. Do you know what the problem is, and how can I solve it?
Thanks
Fiddler acts as an Internet proxy server. In general, any symptom of the form: "it works when I use Fiddler" means "it works when there's a (different) proxy server".
Check your proxy server settings. In particular, as empi suggested, try it in a browser. If it works there, it could be due to the fact that the browser has the proxy settings configured, and that you do not have them configured for WCF.
If you have proxy set in Internet Explorer, it may cause the problem. What happens when you open https://[servername]:4338/[servicename]/ in Internet Explorer?
Thanks empi for the reply.
I found the answer.
Actually in our company we have a proxy settings through "Automatic configuration script"
and depends on the web sites we are targeting internally, the script will point us to the proper proxy.
So, from the script I got the proper proxy address.
and in my .NET application I added this code
WebRequest.DefaultWebProxy = new WebProxy("http://xx.xx.xx.xx:8080");
and that fixed the problem
So WCF client was not detecting the setting of the automatic script.
and this is the reason it worked when I run Fiddler, because Fiddler listen to the http communication, and send it again through the settings.
So I've gone ahead and set up my ShoutCast server DNAS and set my DSP in Winamp on my host computer. The server listens on port 8000, so per some instructions I installed an output plugin for winamp (Shoutcast DSP) and used 8000 and the password to connect. Server accepts the connection.
Now, what the heck do I do now? My host computer is SSL secured and the DNAS server is installed within the secure web directory (if that matters). My desired end result is that I want to listen to my ShoutCast setup at home (host computer) from any computer.
I try browsing to my ip address and port 8000 (without using HTTPS) and it comes back with nothing. If I browse with HTTPS://my.server.com:8000, I get Error code: ssl_error_rx_record_too_long)
Have I completely missed something, or am I just a total moron?
Thanks.
SHOUTcast doesn't support SSL. The service on port 8000 is an unencrypted server for HTTP and ICY (the rather pointless SHOUTcast native streaming protocol, which is almost but not quite HTTP). The ssl_error_rx_record_too_long error is characteristic of trying to access a non-HTTPS service as HTTPS.
You should be able to connect to 8000 with your web browser and get the DNAS status page. If, on the other hand, you connect to that port with a media player, it'll return the direct MP3 stream. (Unfortunately, in an incredibly boneheaded piece of design, the way SHOUTcast decides which to respond with is by sniffing your User-Agent header for something beginning with Mozilla, so if you're using an alternative browser or blocking your UA you'll not be able to get the status, and if the stream's down you might just get nothing.)
To listen to a SHOUTcast server through SSL you would need to set up a proxy on another port that forwarded HTTPS requests to local HTTP requests; it'd also have to be a streaming-capable proxy, and you might need some hacks to stop ICY breaking it.
Probably easier, you could set up an SSH forwarded port from your client to the server. That would also be the only way to allow the DJ to connect to SHOUTcast with encryption, since the DJ protocol isn't HTTP compatible at all. Obviously SSH tunnels are no good for random public listeners though.
You could also try Icecast, an alternative to SHOUTcast that I believe has some SSL support (and also uses plain HTTP streaming instead of ICY).