Personal Project

Monday, July 25, 2016

How to setup a TURN Server for your WebRTC application ?

Get Started 
Developing a WebRTC application is easy, but solving the issue of NAT could be a difficult task. If you want to build your WebRTC environment without using any 3rd Party cloud solutions, I think you should take a look at an open source lib -  rfc5766-turn-server. Because it not only supports TURN, but also STUN. 

In this tutorial, you will learn how to set up a STUN & TURN server.

1.Download rfc5766-turn-server package
$ wget http://ftp.cn.debian.org/debian/pool/main/r/rfc5766-turn-server/rfc5766-turn-server_3.2.4.4-1_amd64.deb

2. Install
$ sudo apt-get update
$ sudo apt-get install gdebi-core
$ sudo gdebi rfc5766-turn-server_3.2.4.4-1_amd64.deb

Refer to docs in folder /usr/share/doc/rfc5766-turn-server

vim /opt/etc/turnserver.conf.default


3. Configuration
$ sudo vi /etc/turnserver.conf

// Setup IP address - listening-ip and external-ip are required to set up on EC2 of AWS.
listening-ip=172.31.4.37
external-ip=54.223.149.60

// If TURN server is used for WebRTC,please set long-term credential mechanism as shown below.
lt-cred-mech

// Add a user
user=weishihhsun:mypassword

// Setup realm
realm=mycompany.org

4. Start TURN Server
sudo turnserver -c /usr/local/etc/turnserver.conf --daemo

5. Setup TURN Server`s IP address
"iceServers": [{
   "url": "stun:stun.l.google.com:19302"
}, {
   "url": "turn:54.223.149.60",    // Your Server
   "username": "weishihhsun",  //  your Account
   "credential": "mypassword"   //  Your Password
}]

6. Open firewall`s ports
TCP 443
TCP 3478-3479
TCP 32355-65535
UDP 3478-3479

iptables -A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 3478:3479 -j ACCEPT
iptables -A INPUT -p tcp -m tcp --dport 32355:65535 -j ACCEPT
iptables -A INPUT -p udp -m tcp --dport 3478:3479 -j ACCEPT

Friday, July 15, 2016

How to solve a network problem ?

Have you ever had a network problem due to packet lost or some unknown issues in your routers ? How could you find out those issues may be caused by your routers or Internet Service Provider ?

The following instructions will guide you how to figure it out.

// 1. Download mtr


// 2. Execute the following command to check whether or not there is a packet lost problem in your network node.
sudo mtr -c 100 -r [target IP]


// 3. Then execute traceroute
traceroute [target IP]


You will know that the network node is shown in IP address or Domain Name.
If it is IP address, it probably could be the router; if it is the domain name, it might be your ISP`s network devices.

// 4 Download nmap
https://nmap.org/download.html


// 5. Dump router`s info and you can find out what your router is, so as to fix it.
nmap -A -T4 router IP

Ex:
EricWeis-MacBook-Air:~ EricWei$ nmap -A -T4 192.168.11.1


Starting Nmap 7.12 ( https://nmap.org ) at 2016-07-07 23:33 JST
Stats: 0:01:47 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 80.00% done; ETC: 23:35 (0:00:27 remaining)
Nmap scan report for buffalo.setup (192.168.11.1)
Host is up (0.027s latency).
Not shown: 995 closed ports
PORT      STATE SERVICE VERSION
53/tcp    open  domain  (status request not implemented)
80/tcp    open  http    Buffalo AirStation http config
| http-auth:
| HTTP/1.0 401 Unauthorized
|_  Basic realm=AirStation
|_http-title: UNAUTHORIZED
2601/tcp  open  zebra   Quagga routing software
2602/tcp  open  zebra   Quagga routing software
49152/tcp open  upnp    Intel UPnP reference SDK 1.2 (Linux 2.4.20; UPnP 1.0)
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port53-TCP:V=7.12%I=7%D=7/7%Time=577E6838%P=x86_64-apple-darwin13.4.0%r
SF:(DNSVersionBindReq,20,"\0\x1e\x02G\x81\x85\0\x01\0\0\0\0\0\0\x07version
SF:\x04bind\0\0\x10\0\x03")%r(DNSStatusRequest,E,"\0\x0c\x02H\x90\x84\0\0\
SF:0\0\0\0\0\0");
Service Info: OS: Linux; Device: WAP; CPE: cpe:/o:linux:linux_kernel:2.4.20


Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 141.69 seconds

Thursday, June 16, 2016

Tutorial (2) : How to send Push Notifications to iPhone using Java ?



Generate aps_developer.p12 for JavaPNS

Download and Upzip openssl-0.9.8k_WIN32.zip
Goto windows dos command mode

// Convert aps_developer.cer to aps_developer.pem
openssl x509 -in aps_developer.cer -inform DER -out aps_developer.pem -outform PEM 

// Generate Push_Noenc.pem from PushChatCert.p12
openssl pkcs12 -nocerts -out Push_Noenc.pem -in PushChatCert.p12

// Output aps_developer.p12 for JavaPNS
openssl pkcs12 -export -in aps_developer.pem -inkey Push_Noenc.pem -certfile PushChat.certSigningRequest -name "aps_developer" -out aps_developer.p12


Obtain Device token from iOS

Add the following code in the method of AppDelegate.didFinishLaunchingWithOptions

IOS Code:
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge)];  

To setup registerForRemoteNotificationTypes for app to receive notification message.

To extract device token by the following codes:

IOS Code: 

 - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {   
    NSString *token = [NSString stringWithFormat:@"%@", deviceToken];
    NSLog(@"My token is:%@", token);
}

- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {    
    NSString *error_str = [NSString stringWithFormat: @"%@", error];
    NSLog(@"Failed to get token, error:%@", error_str);

 
iOS device needs to implement two features: one is to register app as receiving notification type, the other is to send its token to backend JavaPNS via HTTP or TCP protocol.


Setup JavaPNS Sample code

Please add the following .jar library in your project:
1. bcprov-jdk15-146.jar
2. log4j-1.2.15.jar
3. JavaPNS_2.2.jar ( unzip JavaPNS_2.2_complete.zip )
4. Compile the source code : PushTest.java

(PS: Or simply import the testSample code by eclipse and run it)
  
JavaPNS needs certificate aps_developer.p12, and iOS token id to accomplish the function of sending Push Messages. The following codes below detail how to make it work.

public static void main(String[] args) {
                       
                        // iOS Private key as a p12 file exported by MAC
                        String keynotePath = "aps_developer.p12";
                       
                        // iOS developer certificate password exported by MAC
                        String password = "Your Pasword";
                       
                        // iOS device Token id
                        String token = "Your Device Token";
                       
                        // Test environment: Production or Sandbox(simulation)
                        String environment = "simulation";
                       
                        // Push message mode: Simple or complex or thread
    // Simple: Simple msg, complex: complex message, thread: Add multiple threads support
                        String pushMode = "complex";
                       
                        // Number of received devices
                        String deviceNum = "1";
                       
                        // Number of sender threads
                        String threadNum = "1";
                       
                        /* Initialize Log4j to print logs to console */
                        configureBasicLogging();

                        /* Push an alert */
                        try {
pushTest(keynotePath, password, token, environment, pushMode, deviceNum, threadNum);
                                   
                        } catch (CommunicationException e) {
                                    e.printStackTrace();
                        } catch (KeystoreException e) {
                                    e.printStackTrace();
                        }
            }




How to generate iOS development certificate for Push Server ?

// For Development Environment
// Convert aps_developer.cer to aps_developer.pem
openssl x509 -in aps_development.cer -inform DER -out aps_developer.pem -outform PEM

// Generate Push_Noenc.pem from PushChatCert.p12
openssl pkcs12 -nocerts -out Push_Noenc.pem -in PushChatCert.p12   // Input your password

// Output aps_developer.p12 for JavaPNS
openssl pkcs12 -export -in aps_developer.pem -inkey Push_Noenc.pem -certfile Push.certSigningRequest -name "aps_developer" -out aps_developer.p12


How to generate iOS Production certificate for Push Server?

// For Production
// Convert aps_developer.cer to aps_developer.pem
openssl x509 -in aps_production.cer -inform DER -out aps_production.pem -outform PEM

// Generate Push_Noenc.pem from PushChatCert.p12
openssl pkcs12 -nocerts -out Push_Noenc.pem -in PushChatCert.p12 

// Output aps_developer.p12 for JavaPNS
openssl pkcs12 -export -in aps_production.pem -inkey Push_Noenc.pem -certfile Push.certSigningRequest -name "aps_production" -out aps_production.p12


Next  - Tutorial(1) : How to send Push Notifications to Android using Java ?

Tuesday, June 14, 2016

Tutorial (1) : How to send Push Notifications to iPhone using Java ?

Get Started

In this tutorial, you will lean how Push Notifications work and how to send Push Notifications to iPhone using an open source library - JavaAPNS.

Apple Push Service Overview


1. An app registers to iOS to enable Push notification; iOS sends device`s UDID to APNS.
2. The app receives a “device token” from APNS. You can think of the device token as the address that push notifications will be sent to.
3. The app sends the device token to your server.
4. When something of interest to your app happens, the server sends a push notification to the Apple Push Notification Service with device token id.
5. APNS sends the push notification to the user’s device.

 Enable Provisioning Profiles and Certificates

To enable push notifications in your app, it needs to be signed with a provisioning profile that is configured for push. In addition, your server needs to sign its communications to APNS with an SSL certificate.

There are also two types of push server certificates:
- Development. If your app is running in Debug mode and is signed with the Development provisioning profile (Code Signing Identity is “iPhone Developer”), then your server must be using the Development certificate.

- Production. Apps that are distributed as Ad Hoc or on the App Store (when Code Signing Identify is “iPhone Distribution”) must talk to a server that uses the Production certificate. If there is a mismatch between these, push notifications cannot be delivered to your app.


Generating the Certificate Signing Request (CSR)

The first thing you need is your Push certificates. These identify you when communicating with APNS over SSL.

Generating the Apple Push Notification SSL certificate on Mac:






Enter your email address here. I’ve heard people recommended you use the same email address that you used to sign up for the iOS Developer Program, but it seems to accept any email address just fine.

Enter “PushChat” for Common Name. You can type anything you want here, but choose something descriptive. This allows us to easily find the private key later.

Check Saved to disk and click Continue. Save the file as “PushChat.certSigningRequest”.



Generating the private key




If you go to the Keys section of Keychain Access, you will see that a new private key has appeared in your keychain. Right click it and choose Export.

Save the private key as “PushChatCert.p12” and enter a passphrase.



4.   Making the App ID and SSL certificate
Log in to the iOS Provisioning Portal.

First, we are going to make a new App ID. Each push app needs its own unique ID because push notifications are sent to a specific application. (You cannot use a wildcard ID.)



Filled in the fields as follows:
Description: PushChat
Bundle Seed ID: Generate New (this is the default option)
Bundle Identifier: com.hollance.PushChat

It is probably best if you choose your own Bundle Identifier here – com.companyName.PushChat – instead of using mine. You will need to set this same bundle ID in your Xcode project.
This certificate is linked with your App ID. Your server can only send push notifications to that particular app, not to any other apps.
After you have made the App ID, it shows up like this in the list:



Click on the Configure link to open the Configure App ID screen.



choose Certificate Signing Request file, “PushChat.certSigningRequest” for the Development Push SSL Certificate.




Download SSL certificate.
Click Done to close the assistant and return to the Configure App ID screen.


As you can see, we have a valid certificate and push is now available for development. The development certificate is only valid for 3 months. When you are ready to release your app, repeat this process for the production certificate. The steps are the same.

Note: The production certificate remains valid for a year, but you want to renew it before the year is over to ensure there is no downtime for your app.



Until now, we have generated three files:

1. Push.certSigningRequest
2. PushChatCert.p12
3. aps_developer.cer