/* Server side. Accept a new socket connection off our listen socket. This code is not specific to SSL. */ SOCKET socketAccept(SOCKET listenfd, int *err) { struct sockaddr_in addr; SOCKET fd; int len; /* Wait(blocking)/poll(non-blocking) for an incoming connection */ len = sizeof(addr); if ((fd = accept(listenfd, (struct sockaddr *)&addr, &len)) == INVALID_SOCKET) { *err = getSocketError(); if (*err != WOULD_BLOCK) { fprintf(stderr, "Error %d accepting new socket\n", *err); } return INVALID_SOCKET; } /* fd is the newly accepted socket. Disable Nagle on this socket. Set blocking mode as default */ /* fprintf(stdout, "Connection received from %d.%d.%d.%d\n", addr.sin_addr.S_un.S_un_b.s_b1, addr.sin_addr.S_un.S_un_b.s_b2, addr.sin_addr.S_un.S_un_b.s_b3, addr.sin_addr.S_un.S_un_b.s_b4); */ nvram_set("ssl_client_ip",inet_ntoa(addr.sin_addr)); setSocketNodelay(fd); setSocketBlock(fd); return fd; }
SOCKET socketConnect(char *ip, short port, int *err) { struct sockaddr_in addr; SOCKET fd; int rc; struct hostent *hp; if(!(hp = gethostbyname(ip))) { fprintf(stderr, "Host not found %s\n",ip); return INVALID_SOCKET; } 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(port); if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { fprintf(stderr, "Error creating socket\n"); *err = getSocketError(); return INVALID_SOCKET; } fcntl(fd, F_SETFD, FD_CLOEXEC); rc = 1; setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&rc, sizeof(rc)); setSocketNodelay(fd); setSocketBlock(fd); rc = connect(fd, (struct sockaddr *)&addr, sizeof(addr)); #if WIN if (rc != 0) #else if (rc < 0) #endif { *err = getSocketError(); perror("connect"); return INVALID_SOCKET; } return fd; }
SOCKET socketAccept(SOCKET listenfd, int *err) { struct sockaddr_in addr; SOCKET fd; int len; len = sizeof(addr); if ((fd = accept(listenfd, (struct sockaddr *)&addr, &len)) == INVALID_SOCKET) { *err = getSocketError(); if (*err != WOULD_BLOCK) { fprintf(stderr, "Error %d accepting new socket\n", *err); } return INVALID_SOCKET; } setSocketNodelay(fd); setSocketBlock(fd); return fd; }
/* Client side. Open a socket connection to a remote ip and port. This code is not specific to SSL. */ SOCKET socketConnect(char *ip, short port, int *err) { struct sockaddr_in addr; SOCKET fd; int rc; struct hostent *hent; char ipbuf[20]; if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { fprintf(stderr, "Error creating socket\n"); *err = getSocketError(); return INVALID_SOCKET; } /* Make sure the socket is not inherited by exec'd processes Set the REUSEADDR flag to minimize the number of sockets in TIME_WAIT */ fcntl(fd, F_SETFD, FD_CLOEXEC); rc = 1; // setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&rc, sizeof(rc)); setSocketNodelay(fd); /* Turn on blocking mode for the connecting socket */ setSocketBlock(fd); /* //Marked by Gemtek hent = gethostbyname(ip); if (!hent) { fprintf(stderr, "Error resolving host\n"); } */ memset((char *) &addr, 0x0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); //Gemtek added sprintf( ipbuf ,"%s", "127.0.0.1" ); fprintf( stderr , "ip:port ==> %s:%d\n" , ipbuf , port ); //Gemtek added if( NULL != ip && strlen( ipbuf ) >= 7 && 0!=strcmp( ipbuf , "localhost") ) { //bcopy(hent->h_addr, &addr.sin_addr, hent->h_length); addr.sin_addr.s_addr = inet_addr( ipbuf ) ; } rc = connect(fd, (struct sockaddr *)&addr, sizeof(addr)); #if WIN if (rc != 0) { #else if (rc < 0) { #endif *err = getSocketError(); return INVALID_SOCKET; } return fd; } /******************************************************************************/ /* Server side. Accept an incomming SSL connection request. 'conn' will be filled in with information about the accepted ssl connection return -1 on error, 0 on success, or WOULD_BLOCK for non-blocking sockets */ int sslAccept(sslConn_t **cpp, SOCKET fd, sslKeys_t *keys, int (*certValidator)(sslCertInfo_t *t, void *arg), int flags) { sslConn_t *conn; unsigned char buf[1024]; int status, rc; /* Associate a new ssl session with this socket. The session represents the state of the ssl protocol over this socket. Session caching is handled automatically by this api. */ conn = calloc(sizeof(sslConn_t), 1); conn->fd = fd; if (matrixSslNewSession(&conn->ssl, keys, NULL, SSL_FLAGS_SERVER | flags) < 0) { sslFreeConnection(&conn); return -1; } /* MatrixSSL doesn't provide buffers for data internally. Define them here to support buffered reading and writing for non-blocking sockets. Although it causes quite a bit more work, we support dynamically growing the buffers as needed. Alternately, we could define 16K buffers here and not worry about growing them. */ memset(&conn->inbuf, 0x0, sizeof(sslBuf_t)); conn->insock.size = 10240; conn->insock.start = conn->insock.end = conn->insock.buf = (unsigned char *)malloc(conn->insock.size); conn->outsock.size = 10240; conn->outsock.start = conn->outsock.end = conn->outsock.buf = (unsigned char *)malloc(conn->outsock.size); conn->inbuf.size = 0; conn->inbuf.start = conn->inbuf.end = conn->inbuf.buf = NULL; *cpp = conn; readMore: rc = sslRead(conn, buf, sizeof(buf), &status); /* Reading handshake records should always return 0 bytes, we aren't expecting any data yet. */ if (rc == 0) { if (status == SSLSOCKET_EOF || status == SSLSOCKET_CLOSE_NOTIFY) { sslFreeConnection(&conn); return -1; } if (matrixSslHandshakeIsComplete(conn->ssl) == 0) { goto readMore; } } else if (rc > 0) { socketAssert(0); return -1; } else { fprintf(stderr, "sslRead error in sslAccept\n"); sslFreeConnection(&conn); return -1; } *cpp = conn; return 0; }