Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

BlackBerry Web Services

Reply
New Contributor
Posts: 3
Registered: ‎02-25-2014
My Device: z10
My Carrier: a1
Accepted Solution

raw socket connections to server inside company network

hello!

i did not find any documentation anywhere else so i hope someone can help me out.

o know for ftp/http there is a proxy that is used in work perimeter for accessing servers inside company network.

but what is the best practice for an app installed in work perimeter  to make a raw socket connection to access network resources other than http/ftp behind my company firewall? so i want something like 

 

int sock = socket(AF_INET, SOCK_STREAM,0);

connect(...) //using an host/ip inside my company and port 1234

write(...)

close(sock)

 

is this possible?

and second:will this work if i use QTCPSocket?

BlackBerry Development Advisor
Posts: 143
Registered: ‎03-08-2012
My Device: Z10
My Carrier: Bell

Re: raw socket connections to server inside company network

Hi.

 

Yes, there is a recommended approach to doing this for the current version of BES.  An HTTP proxy is used to connect to both internal corporate and external networks when in the Work perimeter.  To connect to a particular host and port, you make a HTTP CONNECT request to the proxy and then once the connection is established, you have a socket connection with the remote server.  I have written a sample app that covers the QTcpSocket / QSslSocket, BSD sockets, OpenSSL sockets, and cURL connections (this case is supposed to be transparent but there have been issues reported with some OS builds). 

 

I will be cleaning up this sample app and submitting it for review before it gets posted on GitHub.  If your need is urgent, I could share some code snippets to help you implement the solution for your specific use case.

Highlighted
New Contributor
Posts: 3
Registered: ‎02-25-2014
My Device: z10
My Carrier: a1

Re: raw socket connections to server inside company network

ok thank you. a code snippet with bsd sockets would be nice.

BlackBerry Development Advisor
Posts: 143
Registered: ‎03-08-2012
My Device: Z10
My Carrier: Bell

Re: raw socket connections to server inside company network

Very sorry for the delayed reply.  I switched teams and lost track of this thread:

 

Here is the code from my tcp BSD socket class in my sample app:

 

code assumes class contains these members:

 

    int m_socket;
    char m_readBuffer[READ_BUFFER_SIZE+1];

Some headers you will need:

 

#include <math.h>

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <netdb.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>

#include <netinet/in.h>
#include <netinet/tcp.h>

#include <openssl/err.h>

#include <openssl/ssl.h>

#include <sys/types.h>
#include <sys/socket.h>

#include <sys/proxyinfo.h>

 

functions:  (replace the logging function in the code with your own ...)

 

void TCPSocketThread::run()
{
    const char* hostName = "developer.blackberry.com"; // The host that you're connecting to
    const int port = 80;
    const char *httpRequest = "GET / HTTP/1.1\r\nHost: developer.blackberry.com\r\n\r\n";
    int bytesRead = 0, bytesWritten = 0, error, responseCount = 0;
    static fd_set write_handles;
    static fd_set read_handles;
    char message[512] = { 0 };

    // Connect the TCP socket
    safeConnectFullTcp(m_socket, hostName, port);

    // check that the safe connect returned without errors
    if (m_socket > 0) {
        while(1){

            FD_ZERO( &write_handles );
            FD_SET( m_socket, &write_handles );
            error = select(m_socket + 1, NULL, &write_handles, NULL, NULL);

            if( error < 0 ) {
            }

            if( FD_ISSET( m_socket, &write_handles ) ) {

                if (bytesWritten == 0) {
                    BESSafeTcp::consoleLog(QString(httpRequest));
                    bytesWritten = write(m_socket, httpRequest, strlen(httpRequest));
                    sprintf(message, "%d\n", bytesWritten);
                    BESSafeTcp::consoleLog(QString(message));

                } else if (bytesWritten == strlen(httpRequest)) {
                    bytesRead=read(m_socket,m_readBuffer,READ_BUFFER_SIZE);
                    sprintf(message, "%d\n", bytesRead);
                    BESSafeTcp::consoleLog(QString(message));

                    if (bytesRead > 0) {
                        m_readBuffer[bytesRead] = 0;
                        BESSafeTcp::consoleLog(QString(m_readBuffer));
                        responseCount++;
                    } else {
                        break;
                    }
                }
            }
        }

        close(m_socket);
    }
}

void TCPSocketThread::queryProxy(const char* queryHostName, const int& queryPort, const char* queryUrl, char* proxyHost, int& proxyPort)
{
    PROXYINFO *pi_handle = pi_init();
    char proxyResult[256] = { 0 };
    int index = 0;
    char *proxyPortString = NULL;
    int proxyHostLength = 0;
    char message[512] = { 0 };

    switch (pi_getproxy(pi_handle, queryHostName, queryUrl, proxyResult, 256)) {
        case PI_RESULT_PROXY:
          BESSafeTcp::consoleLog(QString("proxy result: ")  + proxyResult + "\n");;
          strcpy(proxyHost, proxyResult);
          proxyHostLength = strlen(proxyResult);
          proxyHost[proxyHostLength]  = '\0';
          for(index = 0; index < proxyHostLength; index++) {
              if (proxyHost[index] == ':') {
                  proxyHost[index] = '\0';
                  proxyPort = atoi(&proxyHost[index+1]);
                  break;
              }
          }

          sprintf(message, "sys proxy host: %s\n", proxyHost);
          BESSafeTcp::consoleLog(QString(message));
          sprintf(message, "sys proxy port: %d\n", proxyPort);
          BESSafeTcp::consoleLog(QString(message));
          break;

        case PI_RESULT_DIRECT:
          // You don't need to use a proxy. You should connect directly to this host.
          BESSafeTcp::consoleLog(QString("proxy result: ")  + proxyResult + "\n");
          proxyHost[0] = '\0';
          proxyPort = 0;
          break;

        default:
          // Something went wrong. In most cases, you'd want to connect directly in this case as well
          break;
    }

    pi_cleanup(pi_handle);
}

void TCPSocketThread::safeConnectFullTcp(int& sock, const char* hostName, const int& port)
{
    char proxyHost[256] = { 0 };
    int proxyPort;
    char *connectHost;
    int connectPort;
    char httpProxyRequest[512] = { 0 };
    char message[512] = { 0 };

    queryProxy(hostName, port, NULL, proxyHost, proxyPort);

    // Connect the TCP socket

    // if there is a proxy, you need to connect through there
    if (proxyHost[0] != '\0') {
        connectHost = proxyHost;
        connectPort = proxyPort;
        sprintf(httpProxyRequest, "CONNECT %s:%d HTTP/1.1\r\nHost: %s\r\n\r\n", hostName, port, proxyHost);
    } else {
        connectHost = (char*)hostName;
        connectPort = port;
    }


    struct hostent *hp;
    struct sockaddr_in addr;

    if(!(hp=gethostbyname(connectHost))) {
      fprintf(stderr, "Couldn't resolve host");
      exit(-1);
    }
    memset(&addr,0,sizeof(addr));
    addr.sin_addr=*(struct in_addr*)
      hp->h_addr_list[0];
    addr.sin_family=AF_INET;
    addr.sin_port=htons(connectPort);

    if((sock=socket(AF_INET,SOCK_STREAM,
      IPPROTO_TCP))<0) {
        fprintf(stderr, "Couldn't create socket");
        exit(-1);
    }
    if(::connect(sock,(struct sockaddr *)&addr,
      sizeof(addr)) <0) {
        fprintf(stderr, "Couldn't connect socket");
        exit(-1);
    }

    // if there is a proxy, send the connect request and wait for the response before proceeding further
    if (proxyHost[0] != '\0') {

        static fd_set write_handles;
        static fd_set read_handles;
        int bytesRead = 0, bytesWritten = 0, error, responseCount = 0;

        while(1){

            FD_ZERO( &write_handles );
            FD_SET( sock, &write_handles );
            error = select(sock + 1, NULL, &write_handles, NULL, NULL);

            if( error < 0 ) {
            }

            if( FD_ISSET( sock, &write_handles ) ) {

                if (bytesWritten == 0) {
                    BESSafeTcp::consoleLog(QString(httpProxyRequest));
                    bytesWritten = write(sock, httpProxyRequest, strlen(httpProxyRequest));
                    sprintf(message, "%d\n", bytesWritten);
                    BESSafeTcp::consoleLog(QString(message));
                } else if (bytesWritten == strlen(httpProxyRequest)) {
                    bytesRead=read(sock,m_readBuffer,READ_BUFFER_SIZE);
                    sprintf(message, "%d\n", bytesRead);
                    BESSafeTcp::consoleLog(QString(message));
                    if (bytesRead > 0) {
                        m_readBuffer[bytesRead] = 0;
                        BESSafeTcp::consoleLog(QString(m_readBuffer));
                        responseCount++;
                        if (responseCount == 1) {
                            if (m_readBuffer[9] != '2') {
                                sock = 0;
                            }
                            if (m_readBuffer[9] == '2') {
                                // it connected
                            }
                            break;
                        }
                    } else {
                        break;
                    }
                }
            }
        }
    }
 }