diff --git a/dist/antd-1.0.6b.tar.gz b/dist/antd-1.0.6b.tar.gz index 3a5db8b..9f6a0be 100644 Binary files a/dist/antd-1.0.6b.tar.gz and b/dist/antd-1.0.6b.tar.gz differ diff --git a/lib/ws.c b/lib/ws.c index 6a221c3..40cec80 100644 --- a/lib/ws.c +++ b/lib/ws.c @@ -3,7 +3,7 @@ #include #include #include -#include //hostent +#include //hostent #ifdef USE_OPENSSL #include #include @@ -16,41 +16,44 @@ #include "handle.h" #include "ws.h" -static void ws_gen_mask_key(ws_msg_header_t * header) +static void ws_gen_mask_key(ws_msg_header_t *header) { int r = rand(); - header->mask_key[0] = (r >> 24) & 0xFF; - header->mask_key[1] = (r >> 16) & 0xFF; - header->mask_key[2] = (r >> 8) & 0xFF; - header->mask_key[3] = r & 0xFF; + header->mask_key[0] = (r >> 24) & 0xFF; + header->mask_key[1] = (r >> 16) & 0xFF; + header->mask_key[2] = (r >> 8) & 0xFF; + header->mask_key[3] = r & 0xFF; } /** * Read a frame header * based on this header, we'll decide * the appropriate handle for frame data */ -ws_msg_header_t * ws_read_header(void* client) +ws_msg_header_t *ws_read_header(void *client) { - + uint8_t byte = 0; uint8_t bytes[8]; - ws_msg_header_t* header = (ws_msg_header_t*) malloc(sizeof(*header)); - + ws_msg_header_t *header = (ws_msg_header_t *)malloc(sizeof(*header)); + // get first byte - if(antd_recv(client, &byte, sizeof(byte)) <0) goto fail; - if(BITV(byte,6) || BITV(byte,5) || BITV(byte,4)) goto fail;// all RSV bit must be 0 - + if (antd_recv(client, &byte, sizeof(byte)) < 0) + goto fail; + if (BITV(byte, 6) || BITV(byte, 5) || BITV(byte, 4)) + goto fail; // all RSV bit must be 0 + //printf("FIN: %d, RSV1: %d, RSV2: %d, RSV3:%d, opcode:%d\n", BITV(byte,7), BITV(byte,6), BITV(byte,5), BITV(byte,4),(byte & 0x0F) ); // find and opcode - header->fin = BITV(byte,7); + header->fin = BITV(byte, 7); header->opcode = (byte & 0x0F); - + // get next byte - if(antd_recv(client, &byte, sizeof(byte)) <0) goto fail; - + if (antd_recv(client, &byte, sizeof(byte)) < 0) + goto fail; + //printf("MASK: %d paylen:%d\n", BITV(byte,7), (byte & 0x7F)); // check mask bit, should be 1 - header->mask = BITV(byte,7); + header->mask = BITV(byte, 7); /*if(!BITV(byte,7)) { // close the connection with protocol error @@ -59,137 +62,160 @@ ws_msg_header_t * ws_read_header(void* client) }*/ // get the data length of the frame int len = (byte & 0x7F); - if(len <= 125) + if (len <= 125) { header->plen = len; - } else if(len == 126) + } + else if (len == 126) { - if(antd_recv(client,bytes, 2*sizeof(uint8_t)) <0) goto fail; - header->plen = (bytes[0]<<8) + bytes[1]; - - } else + if (antd_recv(client, bytes, 2 * sizeof(uint8_t)) < 0) + goto fail; + header->plen = (bytes[0] << 8) + bytes[1]; + } + else { //read only last 4 byte - if(antd_recv(client,bytes, 8*sizeof(uint8_t)) <0) goto fail; - header->plen = (bytes[4]<<24) + (bytes[5]<<16) + (bytes[6] << 8) + bytes[7] ; + if (antd_recv(client, bytes, 8 * sizeof(uint8_t)) < 0) + goto fail; + header->plen = (bytes[4] << 24) + (bytes[5] << 16) + (bytes[6] << 8) + bytes[7]; } //printf("len: %d\n", header->plen); // last step is to get the maskey - if(header->mask) - if(antd_recv(client,header->mask_key, 4*sizeof(uint8_t)) <0) goto fail; + if (header->mask) + if (antd_recv(client, header->mask_key, 4 * sizeof(uint8_t)) < 0) + goto fail; //printf("key 0: %d key 1: %d key2:%d, key3: %d\n",header->mask_key[0],header->mask_key[1],header->mask_key[2], header->mask_key[3] ); - + // check wheather it is a ping or a close message // process it and return NULL //otherwise return the header //return the header - switch(header->opcode){ - case WS_CLOSE: // client requests to close the connection + switch (header->opcode) + { + case WS_CLOSE: // client requests to close the connection // send back a close message - ws_send_close(client,1000,header->mask?0:1); + UNUSED(ws_send_close(client, 1000, header->mask ? 0 : 1)); //goto fail; break; - - case WS_PING: // client send a ping + + case WS_PING: // client send a ping // send back a pong message - ws_pong(client,header, header->mask?0:1 ); + UNUSED(ws_pong(client, header, header->mask ? 0 : 1)); + break; + + default: break; - - default: break; } return header; - - fail: + +fail: free(header); return NULL; - } /** * Read data from client * and unmask data using the key */ -int ws_read_data(void* client, ws_msg_header_t* header, int len, uint8_t* data) +int ws_read_data(void *client, ws_msg_header_t *header, int len, uint8_t *data) { // if len == -1 ==> read all remaining data to 'data'; - if(header->plen == 0) return 0; - int dlen = (len==-1 || len > (int)header->plen)?(int)header->plen:len; - if((dlen = antd_recv(client,data, dlen)) <0) return -1; + if (header->plen == 0) + return 0; + int dlen = (len == -1 || len > (int)header->plen) ? (int)header->plen : len; + if ((dlen = antd_recv(client, data, dlen)) < 0) + return -1; header->plen = header->plen - dlen; // unmask received data - if(header->mask) - for(int i = 0; i < dlen; ++i) - data[i] = data[i]^ header->mask_key[i%4]; + if (header->mask) + for (int i = 0; i < dlen; ++i) + data[i] = data[i] ^ header->mask_key[i % 4]; data[dlen] = '\0'; return dlen; } -void _send_header(void* client, ws_msg_header_t header) +int _send_header(void *client, ws_msg_header_t header) { uint8_t byte = 0; uint8_t bytes[8]; - for(int i=0; i< 8; i++) bytes[i] = 0; + for (int i = 0; i < 8; i++) + bytes[i] = 0; //first byte |FIN|000|opcode| byte = (header.fin << 7) + header.opcode; //printf("BYTE: %d\n", byte); - antd_send(client, &byte, 1); + if (antd_send(client, &byte, 1) != 1) + return -1; // second byte, payload length // mask may be 0 or 1 //if(header.mask == 1) // printf("Data is masked\n"); - if(header.plen <= 125) + if (header.plen <= 125) { - byte = (header.mask << 7) + header.plen; - antd_send(client, &byte, 1); + byte = (header.mask << 7) + header.plen; + if (antd_send(client, &byte, 1) != 1) + return -1; } - else if(header.plen < 65536) // 16 bits + else if (header.plen < 65536) // 16 bits { byte = (header.mask << 7) + 126; bytes[0] = (header.plen) >> 8; bytes[1] = (header.plen) & 0x00FF; - antd_send(client, &byte, 1); - antd_send(client, &bytes, 2); + if (antd_send(client, &byte, 1) != 1) + return -1; + if (antd_send(client, bytes, 2) != 2) + return -1; } else // > 16 bits { - byte = (header.mask << 7) + 127; + byte = (header.mask << 7) + 127; bytes[4] = (header.plen) >> 24; - bytes[5] = ((header.plen)>>16) & 0x00FF; - bytes[6] = ((header.plen)>>8) & 0x00FF; + bytes[5] = ((header.plen) >> 16) & 0x00FF; + bytes[6] = ((header.plen) >> 8) & 0x00FF; bytes[7] = (header.plen) & 0x00FF; - antd_send(client, &byte, 1); - antd_send(client, &bytes, 8); + if (antd_send(client, &byte, 1) != 1) + return -1; + if (antd_send(client, bytes, 8) != 8) + return -1; } // send mask key - if(header.mask) + if (header.mask) { - antd_send(client, header.mask_key,4); + if (antd_send(client, header.mask_key, 4) != 4) + return -1; } + return 0; } /** * Send a frame to client */ -void ws_send_frame(void* client, uint8_t* data, ws_msg_header_t header) +int ws_send_frame(void *client, uint8_t *data, ws_msg_header_t header) { - uint8_t * masked; + uint8_t *masked; masked = data; - if(header.mask) + int ret; + if (header.mask) { ws_gen_mask_key(&header); - masked = (uint8_t*) malloc(header.plen); - for(int i = 0; i < (int)header.plen; ++i) - masked[i] = data[i]^ header.mask_key[i%4]; + masked = (uint8_t *)malloc(header.plen); + for (int i = 0; i < (int)header.plen; ++i) + masked[i] = data[i] ^ header.mask_key[i % 4]; } - _send_header(client, header); - if(header.opcode == WS_TEXT) - antd_send(client,(char*)masked,header.plen); + if (_send_header(client, header) != 0) + return -1; + if (header.opcode == WS_TEXT) + ret = antd_send(client, (char *)masked, header.plen); else - antd_send(client,(uint8_t*)masked,header.plen); - if(masked && header.mask) + ret = antd_send(client, (uint8_t *)masked, header.plen); + if (masked && header.mask) free(masked); + if (ret != (int)header.plen) + { + return -1; + } + return 0; } /** * send a text data frame to client */ -void ws_send_text(void* client, const char* data,int mask) +int ws_send_text(void *client, const char *data, int mask) { ws_msg_header_t header; header.fin = 1; @@ -198,51 +224,51 @@ void ws_send_text(void* client, const char* data,int mask) header.plen = strlen(data); //_send_header(client,header); //send(client, data, header.plen,0); - ws_send_frame(client,(uint8_t*)data,header); + return ws_send_frame(client, (uint8_t *)data, header); } /** * send a single binary data fram to client * not tested yet, but should work */ -void ws_send_binary(void* client, uint8_t* data, int l, int mask) +int ws_send_binary(void *client, uint8_t *data, int l, int mask) { ws_msg_header_t header; header.fin = 1; header.opcode = WS_BIN; header.plen = l; header.mask = mask; - ws_send_frame(client,data, header); + return ws_send_frame(client, data, header); //_send_header(client,header); //send(client, data, header.plen,0); } /* * send a file as binary data */ -void ws_send_file(void* client, const char* file, int mask) +int ws_send_file(void *client, const char *file, int mask) { uint8_t buff[1024]; FILE *ptr; - ptr = fopen(file,"rb"); - if(!ptr) + ptr = fopen(file, "rb"); + if (!ptr) { - ws_send_close(client,1011,mask); - return; + return ws_send_close(client, 1011, mask); } ws_msg_header_t header; size_t size; int first_frame = 1; + int ret = 0; //ws_send_frame(client,buff,header); header.mask = mask; - while(!feof(ptr)) + while (!feof(ptr)) { - size = fread(buff,1,1024,ptr); - if(feof(ptr)) + size = fread(buff, 1, 1024, ptr); + if (feof(ptr)) header.fin = 1; else header.fin = 0; // clear opcode - if(first_frame) + if (first_frame) { header.opcode = WS_BIN; first_frame = 0; @@ -251,55 +277,63 @@ void ws_send_file(void* client, const char* file, int mask) header.opcode = 0; header.plen = size; //printf("FIN: %d OC:%d\n", header.fin, header.opcode); - ws_send_frame(client,buff,header); + ret += ws_send_frame(client, buff, header); } fclose(ptr); + if (ret != 0) + { + return -1; + } + return 0; } /** * Not tested yet * but should work */ -void ws_pong(void* client, ws_msg_header_t* oheader, int mask) +int ws_pong(void *client, ws_msg_header_t *oheader, int mask) { ws_msg_header_t pheader; + int ret; pheader.fin = 1; pheader.opcode = WS_PONG; pheader.plen = oheader->plen; pheader.mask = mask; - uint8_t *data = (uint8_t*)malloc(oheader->plen); - if(!data) return; - - if(ws_read_data(client, oheader, pheader.plen,data) == -1) + uint8_t *data = (uint8_t *)malloc(oheader->plen); + if (!data) + return -1; + + if (ws_read_data(client, oheader, pheader.plen, data) == -1) { ERROR("Cannot read ping data %d", pheader.plen); free(data); - return; + return -1; } - ws_send_frame(client,data,pheader); + ret = ws_send_frame(client, data, pheader); free(data); //_send_header(client, pheader); //send(client, data, len, 0); + return ret; } -void ws_ping(void* client, const char* echo, int mask) +int ws_ping(void *client, const char *echo, int mask) { ws_msg_header_t pheader; pheader.fin = 1; pheader.opcode = WS_PING; pheader.plen = strlen(echo); pheader.mask = mask; - ws_send_frame(client,(uint8_t*)echo,pheader); + return ws_send_frame(client, (uint8_t *)echo, pheader); } /* * Not tested yet, but should work */ -void ws_send_close(void* client, unsigned int status, int mask) +int ws_send_close(void *client, unsigned int status, int mask) { //printf("CLOSED\n"); ws_msg_header_t header; header.fin = 1; header.opcode = WS_CLOSE; header.plen = 2; - header.mask=mask; + header.mask = mask; uint8_t bytes[2]; bytes[0] = status >> 8; bytes[1] = status & 0xFF; @@ -310,82 +344,82 @@ void ws_send_close(void* client, unsigned int status, int mask) header.mask_key[1] = bytes[1]; bytes[0] = bytes[1] ^ bytes[1]; }*/ - ws_send_frame(client,bytes,header); + return ws_send_frame(client, bytes, header); //_send_header(client, header); //send(client,bytes,2,0); } -int ip_from_hostname(const char * hostname , char* ip) +int ip_from_hostname(const char *hostname, char *ip) { - struct hostent *he; - struct in_addr **addr_list; - int i; - if ( (he = gethostbyname( hostname ) ) == NULL) - { - // get the host info - ERROR("gethostbyname:%s",strerror(errno)); - return -1; - } - addr_list = (struct in_addr **) he->h_addr_list; - - for(i = 0; addr_list[i] != NULL; i++) - { - //Return the first one; - strcpy(ip , inet_ntoa(*addr_list[i]) ); - return 0; - } - return -1; + struct hostent *he; + struct in_addr **addr_list; + int i; + if ((he = gethostbyname(hostname)) == NULL) + { + // get the host info + ERROR("gethostbyname:%s", strerror(errno)); + return -1; + } + addr_list = (struct in_addr **)he->h_addr_list; + + for (i = 0; addr_list[i] != NULL; i++) + { + //Return the first one; + strcpy(ip, inet_ntoa(*addr_list[i])); + return 0; + } + return -1; } /* send a request */ -int request_socket(const char* ip, int port) +int request_socket(const char *ip, int port) { int sockfd; struct sockaddr_in dest; - + // time out setting struct timeval timeout; timeout.tv_sec = CONN_TIME_OUT_S; - timeout.tv_usec = 0;//3 s - if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) + timeout.tv_usec = 0; //3 s + if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { ERROR("Socket: %s", strerror(errno)); return -1; } - if (setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,sizeof(timeout)) < 0) - ERROR("setsockopt failed:%s", strerror(errno)); + if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0) + ERROR("setsockopt failed:%s", strerror(errno)); - if (setsockopt (sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout,sizeof(timeout)) < 0) - ERROR("setsockopt failed:%s",strerror(errno)); + if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0) + ERROR("setsockopt failed:%s", strerror(errno)); /*struct linger lingerStruct; lingerStruct.l_onoff = 0; // turn lingering off for sockets setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &lingerStruct, sizeof(lingerStruct));*/ - - bzero(&dest, sizeof(dest)); - dest.sin_family = AF_INET; - dest.sin_port = htons(port); - if ( inet_aton(ip, &dest.sin_addr) == 0 ) - { + + bzero(&dest, sizeof(dest)); + dest.sin_family = AF_INET; + dest.sin_port = htons(port); + if (inet_aton(ip, &dest.sin_addr) == 0) + { perror(ip); close(sockfd); return -1; - } - if ( connect(sockfd, (struct sockaddr*)&dest, sizeof(dest)) != 0 ) + } + if (connect(sockfd, (struct sockaddr *)&dest, sizeof(dest)) != 0) { close(sockfd); - ERROR("Connect:%s",strerror(errno)); + ERROR("Connect:%s", strerror(errno)); return -1; } return sockfd; } -void ws_client_close(ws_client_t* wsclient) +void ws_client_close(ws_client_t *wsclient) { antd_close(wsclient->antdsock); #ifdef USE_OPENSSL - if(wsclient->ssl_ctx) + if (wsclient->ssl_ctx) { SSL_CTX_free(wsclient->ssl_ctx); FIPS_mode_set(0); @@ -401,14 +435,14 @@ void ws_client_close(ws_client_t* wsclient) } //this is for the client side, not use for now -int ws_client_connect(ws_client_t* wsclient, port_config_t pcnf) +int ws_client_connect(ws_client_t *wsclient, port_config_t pcnf) { - char ip[100]; - int stat = ip_from_hostname(wsclient->host,ip); - if(stat == -1) + char ip[100]; + int stat = ip_from_hostname(wsclient->host, ip); + if (stat == -1) return -1; int sock = request_socket(ip, pcnf.port); - if(sock <= 0) + if (sock <= 0) { ERROR("Cannot request socket"); return -1; @@ -419,36 +453,37 @@ int ws_client_connect(ws_client_t* wsclient, port_config_t pcnf) wsclient->antdsock->last_io = time(NULL); wsclient->antdsock->zstream = NULL; #ifdef USE_OPENSSL - if(pcnf.usessl) + if (pcnf.usessl) { SSL_library_init(); SSL_load_error_strings(); ERR_load_crypto_strings(); - OpenSSL_add_ssl_algorithms(); + OpenSSL_add_ssl_algorithms(); const SSL_METHOD *method; unsigned long ssl_err = 0; method = SSLv23_client_method(); ssl_err = ERR_get_error(); - if(!method) + if (!method) { ERROR("SSLv23_method: %s", ERR_error_string(ssl_err, NULL)); return -1; } wsclient->ssl_ctx = SSL_CTX_new(method); ssl_err = ERR_get_error(); - if (!wsclient->ssl_ctx) { + if (!wsclient->ssl_ctx) + { ERROR("SSL_CTX_new: %s", ERR_error_string(ssl_err, NULL)); return -1; } // configure the context #if defined(SSL_CTX_set_ecdh_auto) - SSL_CTX_set_ecdh_auto(wsclient->ssl_ctx, 1); + SSL_CTX_set_ecdh_auto(wsclient->ssl_ctx, 1); #else - SSL_CTX_set_tmp_ecdh(wsclient->ssl_ctx, EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); + SSL_CTX_set_tmp_ecdh(wsclient->ssl_ctx, EC_KEY_new_by_curve_name(NID_X9_62_prime256v1)); #endif - SSL_CTX_set_options(wsclient->ssl_ctx, SSL_OP_NO_TLSv1|SSL_OP_NO_TLSv1_1|SSL_OP_NO_SSLv2|SSL_OP_NO_TICKET); + SSL_CTX_set_options(wsclient->ssl_ctx, SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_SSLv2 | SSL_OP_NO_TICKET); // set the cipher suit - const char* suit = wsclient->ciphersuit?wsclient->ciphersuit:PREFERRED_WS_CIPHERS; + const char *suit = wsclient->ciphersuit ? wsclient->ciphersuit : PREFERRED_WS_CIPHERS; //const char* suit = "AES128-SHA"; if (SSL_CTX_set_cipher_list(wsclient->ssl_ctx, suit) != 1) { @@ -458,21 +493,24 @@ int ws_client_connect(ws_client_t* wsclient, port_config_t pcnf) return -1; } - if(wsclient->sslcert && wsclient->sslkey) + if (wsclient->sslcert && wsclient->sslkey) { - if (SSL_CTX_use_certificate_file(wsclient->ssl_ctx,wsclient->sslcert, SSL_FILETYPE_PEM) <= 0) { + if (SSL_CTX_use_certificate_file(wsclient->ssl_ctx, wsclient->sslcert, SSL_FILETYPE_PEM) <= 0) + { ssl_err = ERR_get_error(); ERROR("SSL_CTX_use_certificate_file: %s", ERR_error_string(ssl_err, NULL)); return -1; } - if(wsclient->sslpasswd) - SSL_CTX_set_default_passwd_cb_userdata(wsclient->ssl_ctx,(void*)wsclient->sslpasswd); - if (SSL_CTX_use_PrivateKey_file(wsclient->ssl_ctx,wsclient->sslkey, SSL_FILETYPE_PEM) <= 0) { + if (wsclient->sslpasswd) + SSL_CTX_set_default_passwd_cb_userdata(wsclient->ssl_ctx, (void *)wsclient->sslpasswd); + if (SSL_CTX_use_PrivateKey_file(wsclient->ssl_ctx, wsclient->sslkey, SSL_FILETYPE_PEM) <= 0) + { ssl_err = ERR_get_error(); ERROR("SSL_CTX_use_PrivateKey_file: %s", ERR_error_string(ssl_err, NULL)); return -1; } - if (SSL_CTX_check_private_key(wsclient->ssl_ctx) == 0) { + if (SSL_CTX_check_private_key(wsclient->ssl_ctx) == 0) + { ssl_err = ERR_get_error(); ERROR("SSL_CTX_check_private_key: %s", ERR_error_string(ssl_err, NULL)); return -1; @@ -480,12 +518,12 @@ int ws_client_connect(ws_client_t* wsclient, port_config_t pcnf) } // - // validate - if(wsclient->verify_location) + // validate + if (wsclient->verify_location) { SSL_CTX_set_verify(wsclient->ssl_ctx, SSL_VERIFY_PEER, NULL); - SSL_CTX_set_verify_depth(wsclient->ssl_ctx, 5); - if(!SSL_CTX_load_verify_locations(wsclient->ssl_ctx, wsclient->verify_location, NULL)) + SSL_CTX_set_verify_depth(wsclient->ssl_ctx, 5); + if (!SSL_CTX_load_verify_locations(wsclient->ssl_ctx, wsclient->verify_location, NULL)) { ssl_err = ERR_get_error(); // TODO Close the context @@ -495,32 +533,32 @@ int ws_client_connect(ws_client_t* wsclient, port_config_t pcnf) } else { - SSL_CTX_set_verify(wsclient->ssl_ctx, SSL_VERIFY_NONE, NULL); + SSL_CTX_set_verify(wsclient->ssl_ctx, SSL_VERIFY_NONE, NULL); } - wsclient->antdsock->ssl = (void*)SSL_new(wsclient->ssl_ctx); - if(!wsclient->antdsock->ssl) + wsclient->antdsock->ssl = (void *)SSL_new(wsclient->ssl_ctx); + if (!wsclient->antdsock->ssl) { ssl_err = ERR_get_error(); ERROR("SSL_new: %s", ERR_error_string(ssl_err, NULL)); return -1; } - SSL_set_fd((SSL*)wsclient->antdsock->ssl, wsclient->antdsock->sock); + SSL_set_fd((SSL *)wsclient->antdsock->ssl, wsclient->antdsock->sock); int stat, ret; ERR_clear_error(); - while( (ret = SSL_connect(wsclient->antdsock->ssl)) <= 0) + while ((ret = SSL_connect(wsclient->antdsock->ssl)) <= 0) { stat = SSL_get_error(wsclient->antdsock->ssl, ret); switch (stat) { - case SSL_ERROR_WANT_READ: - case SSL_ERROR_WANT_WRITE: - case SSL_ERROR_NONE: - continue; - default: - ERR_print_errors_fp(stderr); - ERROR("Error performing SSL handshake %d", stat); - return -1; + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + case SSL_ERROR_NONE: + continue; + default: + ERR_print_errors_fp(stderr); + ERROR("Error performing SSL handshake %d", stat); + return -1; } } } @@ -528,69 +566,67 @@ int ws_client_connect(ws_client_t* wsclient, port_config_t pcnf) return 0; } - - - -int ws_open_handshake(ws_client_t* client) +int ws_open_handshake(ws_client_t *client) { char buf[MAX_BUFF]; - // now send ws request handshake - sprintf(buf, CLIENT_RQ,client->resource,client->host); + // now send ws request handshake + sprintf(buf, CLIENT_RQ, client->resource, client->host); //printf("Send %s\n", buf); - int size = antd_send(client->antdsock, buf, strlen(buf)); - if(size != (int)strlen(buf)) - { - ERROR("Cannot send request \n"); - return -1; - } - // now verify if server accept the socket - size = read_buf(client->antdsock,buf,MAX_BUFF); - char* token; - int done = 0; - while (size > 0 && strcmp("\r\n",buf)) + int size = antd_send(client->antdsock, buf, strlen(buf)); + if (size != (int)strlen(buf)) { - char* line = buf; - token = strsep(&line,":"); - trim(token,' '); - if(token != NULL &&strcasecmp(token,"Sec-WebSocket-Accept") == 0) - { - token = strsep(&line,":"); - trim(token,' '); - trim(token,'\n'); - trim(token,'\r'); - if(strcasecmp(token, SERVER_WS_KEY) == 0) - { - //LOG("Handshake sucessfull\n"); - done = 1; - } else - { - ERROR("WS handshake, Wrong key %s vs %s",token,SERVER_WS_KEY); - return -1; - } - } - //if(line) free(line); - size = read_buf(client->antdsock,buf,MAX_BUFF); + ERROR("Cannot send request \n"); + return -1; } - if(done) - return 0; - return -1; -} -char* get_ip_address() -{ - struct ifaddrs* addrs; - getifaddrs(&addrs); - struct ifaddrs* tmp = addrs; - char* ip; - while (tmp) + // now verify if server accept the socket + size = read_buf(client->antdsock, buf, MAX_BUFF); + char *token; + int done = 0; + while (size > 0 && strcmp("\r\n", buf)) { - if (tmp->ifa_addr && tmp->ifa_addr->sa_family == AF_INET) - { + char *line = buf; + token = strsep(&line, ":"); + trim(token, ' '); + if (token != NULL && strcasecmp(token, "Sec-WebSocket-Accept") == 0) + { + token = strsep(&line, ":"); + trim(token, ' '); + trim(token, '\n'); + trim(token, '\r'); + if (strcasecmp(token, SERVER_WS_KEY) == 0) + { + //LOG("Handshake sucessfull\n"); + done = 1; + } + else + { + ERROR("WS handshake, Wrong key %s vs %s", token, SERVER_WS_KEY); + return -1; + } + } + //if(line) free(line); + size = read_buf(client->antdsock, buf, MAX_BUFF); + } + if (done) + return 0; + return -1; +} +char *get_ip_address() +{ + struct ifaddrs *addrs; + getifaddrs(&addrs); + struct ifaddrs *tmp = addrs; + char *ip; + while (tmp) + { + if (tmp->ifa_addr && tmp->ifa_addr->sa_family == AF_INET) + { struct sockaddr_in *pAddr = (struct sockaddr_in *)tmp->ifa_addr; - ip = inet_ntoa(pAddr->sin_addr); - if(strcmp(ip,"127.0.0.1") != 0) + ip = inet_ntoa(pAddr->sin_addr); + if (strcmp(ip, "127.0.0.1") != 0) return ip; - } - tmp = tmp->ifa_next; + } + tmp = tmp->ifa_next; } freeifaddrs(addrs); return "127.0.0.1"; diff --git a/lib/ws.h b/lib/ws.h index 490c084..2e814e4 100644 --- a/lib/ws.h +++ b/lib/ws.h @@ -6,23 +6,24 @@ #include "handle.h" #define CONN_TIME_OUT_S 3 -#define BITV(v,i) ((v & (1 << i)) >> i) -#define WS_TEXT 0x1 -#define WS_BIN 0x2 +#define BITV(v, i) ((v & (1 << i)) >> i) +#define WS_TEXT 0x1 +#define WS_BIN 0x2 #define WS_CLOSE 0x8 -#define WS_PING 0x9 +#define WS_PING 0x9 #define WS_PONG 0xA -#define ws_t(c ,d) (ws_send_text(c,d,0)) -#define ws_b(c , d,z) (ws_send_binary(c,d,z,0)) -#define ws_f(c,f) (ws_send_file(c,f,0)) -#define ws_close(c,r) (ws_send_close(c,r,0)) +#define ws_t(c, d) (ws_send_text(c, d, 0)) +#define ws_b(c, d, z) (ws_send_binary(c, d, z, 0)) +#define ws_f(c, f) (ws_send_file(c, f, 0)) +#define ws_close(c, r) (ws_send_close(c, r, 0)) #define MAX_BUFF 1024 #define PREFERRED_WS_CIPHERS "HIGH:!aNULL:!kRSA:!SRP:!PSK:!CAMELLIA:!RC4:!MD5:!DSS" #define CLIENT_RQ "GET /%s HTTP/1.1\r\nHost: %s\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nSec-WebSocket-Version: 13\r\n\r\n" #define SERVER_WS_KEY "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=" -typedef struct{ +typedef struct +{ uint8_t fin; uint8_t opcode; unsigned int plen; @@ -30,40 +31,40 @@ typedef struct{ uint8_t mask_key[4]; } ws_msg_header_t; -typedef struct{ - const char* host; - const char* resource; - antd_client_t* antdsock; +typedef struct +{ + const char *host; + const char *resource; + antd_client_t *antdsock; // ssl - const char* sslcert; - const char* sslkey; - const char* sslpasswd; - const char* ciphersuit; - const char* verify_location; - void * ssl_ctx; + const char *sslcert; + const char *sslkey; + const char *sslpasswd; + const char *ciphersuit; + const char *verify_location; + void *ssl_ctx; } ws_client_t; +ws_msg_header_t *ws_read_header(void *); +int ws_send_frame(void *, uint8_t *, ws_msg_header_t); +int ws_pong(void *client, ws_msg_header_t *, int mask); -ws_msg_header_t * ws_read_header(void*); -void ws_send_frame(void* , uint8_t* , ws_msg_header_t ); -void ws_pong(void* client, ws_msg_header_t*, int mask); +int ws_ping(void *client, const char *echo, int mask); -void ws_ping(void* client, const char* echo, int mask); +int ws_send_text(void *client, const char *data, int mask); +int ws_send_close(void *client, unsigned int status, int mask); +int ws_send_file(void *client, const char *file, int mask); +int ws_send_binary(void *client, uint8_t *data, int l, int mask); -void ws_send_text(void* client, const char* data,int mask); -void ws_send_close(void* client, unsigned int status, int mask); -void ws_send_file(void* client, const char* file, int mask); -void ws_send_binary(void* client, uint8_t* data, int l, int mask); - -int ws_read_data(void* , ws_msg_header_t*, int, uint8_t*); -int request_socket(const char* ip, int port); -int ip_from_hostname(const char * hostname , char* ip); +int ws_read_data(void *, ws_msg_header_t *, int, uint8_t *); +int request_socket(const char *ip, int port); +int ip_from_hostname(const char *hostname, char *ip); //int ws_open_hand_shake(const char* host, int port, const char* resource); -char* get_ip_address(); +char *get_ip_address(); // client -void ws_client_close(ws_client_t* wsclient); -int ws_client_connect(ws_client_t* wsclient, port_config_t pcnf); -int ws_open_handshake(ws_client_t* client); +void ws_client_close(ws_client_t *wsclient); +int ws_client_connect(ws_client_t *wsclient, port_config_t pcnf); +int ws_open_handshake(ws_client_t *client); #endif \ No newline at end of file