static int create_client_socket(const char *hostname)
{
    int sock;
    int err;
    
    
    printf("Create client socket\n");
    sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if(sock<0) {
        perror("client socket");
        return sock;
    }

    
#if 1
    err=TLSSocket_Attach(sock);
    if(err<0) {
        perror("TLSSocket_Attach (server)");
        exit(err);
    }
#endif 
    

    struct hostent *host;
    struct sockaddr_in server_addr;  
    
    //host = gethostbyname("kruk.apple.com");
    //host = gethostbyname("localhost");
    host= gethostbyname(hostname);
    if(!host) {
        herror("host");
        return -1;
    }
    server_addr.sin_family = AF_INET;     
    server_addr.sin_port = htons(23232);   
    server_addr.sin_addr = *((struct in_addr *)host->h_addr);
    bzero(&(server_addr.sin_zero),8); 
    
    err = connect(sock, (struct sockaddr *)&server_addr,
                  sizeof(struct sockaddr));
    if(err)
    {
        perror("connect");
        return err;
    }

    return sock;
}
int dtls_client(const char *hostname, int bypass)
{
    int fd;
    int tlsfd;
    struct sockaddr_in sa;
    
    printf("Running dtls_client test with hostname=%s, bypass=%d\n", hostname, bypass);

    if ((fd=socket(AF_INET, SOCK_DGRAM, 0))==-1) {
        perror("socket");
        exit(-1);
    }
    
    memset((char *) &sa, 0, sizeof(sa));
    sa.sin_family = AF_INET;
    sa.sin_port = htons(PORT);
    if (inet_aton(hostname, &sa.sin_addr)==0) {
        fprintf(stderr, "inet_aton() failed\n");
        exit(1);
    }
    
    if(connect(fd, (struct sockaddr *)&sa, sizeof(sa))==-1)
    {
        perror("connect");
        return errno;
    }
    
    /* Change to non blocking io */
    fcntl(fd, F_SETFL, O_NONBLOCK);
    
    SSLRecordContextRef c=(intptr_t)fd;
    
    
    OSStatus            ortn;
    SSLContextRef       ctx = NULL;
    
    SSLClientCertificateState certState;
    SSLCipherSuite negCipher;
    SSLProtocol negVersion;
    
	/*
	 * Set up a SecureTransport session.
	 */
    
    ctx = SSLCreateContextWithRecordFuncs(kCFAllocatorDefault, kSSLClientSide, kSSLDatagramType, &TLSSocket_Funcs);
    if(!ctx) {
        printSslErrStr("SSLCreateContextWithRecordFuncs", -1);
        return -1;
    }

    printf("Attaching filter\n");
    ortn = TLSSocket_Attach(fd);
    if(ortn) {
		printSslErrStr("TLSSocket_Attach", ortn);
		return ortn;        
    }
    
    if(bypass) {
        tlsfd = open("/dev/tlsnke", O_RDWR);
        if(tlsfd<0) {
            perror("opening tlsnke dev");
            exit(-1);
        }
    }

    ortn = SSLSetRecordContext(ctx, c);
	if(ortn) {
		printSslErrStr("SSLSetRecordContext", ortn);
		return ortn;
	}
    
    ortn = SSLSetMaxDatagramRecordSize(ctx, 600);
    if(ortn) {
		printSslErrStr("SSLSetMaxDatagramRecordSize", ortn);
        return ortn;
	}
    
    /* Lets not verify the cert, which is a random test cert */
    ortn = SSLSetEnableCertVerify(ctx, false);
    if(ortn) {
        printSslErrStr("SSLSetEnableCertVerify", ortn);
        return ortn;
    }
    
    ortn = SSLSetCertificate(ctx, server_chain());
    if(ortn) {
        printSslErrStr("SSLSetCertificate", ortn);
        return ortn;
    }
    
    printf("Handshake...\n");

    do {
		ortn = SSLHandshake(ctx);
	    if(ortn == errSSLWouldBlock) {
            /* keep UI responsive */
            sslOutputDot();
	    }
    } while (ortn == errSSLWouldBlock);
    
    
    SSLGetClientCertificateState(ctx, &certState);
	SSLGetNegotiatedCipher(ctx, &negCipher);
	SSLGetNegotiatedProtocolVersion(ctx, &negVersion);
    
    int count;
    size_t len;
    ssize_t sreadLen, swriteLen;
    size_t readLen, writeLen;

    char buffer[BUFLEN];
    
    count = 0;
    while(count<COUNT) {
        int timeout = 10000;
        
        snprintf(buffer, BUFLEN, "Message %d", count);
        len = strlen(buffer);
        
        if(bypass) {
            /* Send data through the side channel, kind of like utun would */
            swriteLen=write(tlsfd, buffer, len);
            if(swriteLen<0) {
                perror("write to tlsfd");
                break;
            }
            writeLen=swriteLen;
        } else {
            ortn=SSLWrite(ctx, buffer, len, &writeLen);
            if(ortn) {
                printSslErrStr("SSLWrite", ortn);
                break;
            }
        }

        printf("Wrote %lu bytes\n", writeLen);
        
        count++;
        
        if(bypass) {
            do {
                sreadLen=read(tlsfd, buffer, BUFLEN);
            } while((sreadLen==-1) && (errno==EAGAIN) && (timeout--));
            if((sreadLen==-1) && (errno==EAGAIN)) {
                printf("Read timeout...\n");
                continue;
            }
            if(sreadLen<0) {
                perror("read from tlsfd");
                break;
            }
            readLen=sreadLen;
        }
        else {
            do {
                ortn=SSLRead(ctx, buffer, BUFLEN, &readLen);
            } while((ortn==errSSLWouldBlock) && (timeout--));
            if(ortn==errSSLWouldBlock) {
                printf("SSLRead timeout...\n");
                continue;
            }
            if(ortn) {
                printSslErrStr("SSLRead", ortn);
                break;
            }
        }

        buffer[readLen]=0;
        printf("Received %lu bytes: %s\n", readLen, buffer);
        
    }
    
    SSLClose(ctx);
    
    SSLDisposeContext(ctx);
    
    return ortn;
}