mirror of
https://github.com/lxsang/ant-http
synced 2024-12-26 00:38:21 +01:00
improve websocket lib
This commit is contained in:
parent
708e492c49
commit
4b6de31e66
BIN
dist/antd-1.0.6b.tar.gz
vendored
BIN
dist/antd-1.0.6b.tar.gz
vendored
Binary file not shown.
494
lib/ws.c
494
lib/ws.c
@ -3,7 +3,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include<netdb.h> //hostent
|
#include <netdb.h> //hostent
|
||||||
#ifdef USE_OPENSSL
|
#ifdef USE_OPENSSL
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
#include <openssl/err.h>
|
#include <openssl/err.h>
|
||||||
@ -16,41 +16,44 @@
|
|||||||
#include "handle.h"
|
#include "handle.h"
|
||||||
|
|
||||||
#include "ws.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();
|
int r = rand();
|
||||||
header->mask_key[0] = (r >> 24) & 0xFF;
|
header->mask_key[0] = (r >> 24) & 0xFF;
|
||||||
header->mask_key[1] = (r >> 16) & 0xFF;
|
header->mask_key[1] = (r >> 16) & 0xFF;
|
||||||
header->mask_key[2] = (r >> 8) & 0xFF;
|
header->mask_key[2] = (r >> 8) & 0xFF;
|
||||||
header->mask_key[3] = r & 0xFF;
|
header->mask_key[3] = r & 0xFF;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Read a frame header
|
* Read a frame header
|
||||||
* based on this header, we'll decide
|
* based on this header, we'll decide
|
||||||
* the appropriate handle for frame data
|
* 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 byte = 0;
|
||||||
uint8_t bytes[8];
|
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
|
// get first byte
|
||||||
if(antd_recv(client, &byte, sizeof(byte)) <0) goto fail;
|
if (antd_recv(client, &byte, sizeof(byte)) < 0)
|
||||||
if(BITV(byte,6) || BITV(byte,5) || BITV(byte,4)) goto fail;// all RSV bit must be 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) );
|
//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
|
// find and opcode
|
||||||
header->fin = BITV(byte,7);
|
header->fin = BITV(byte, 7);
|
||||||
header->opcode = (byte & 0x0F);
|
header->opcode = (byte & 0x0F);
|
||||||
|
|
||||||
// get next byte
|
// 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));
|
//printf("MASK: %d paylen:%d\n", BITV(byte,7), (byte & 0x7F));
|
||||||
// check mask bit, should be 1
|
// check mask bit, should be 1
|
||||||
header->mask = BITV(byte,7);
|
header->mask = BITV(byte, 7);
|
||||||
/*if(!BITV(byte,7))
|
/*if(!BITV(byte,7))
|
||||||
{
|
{
|
||||||
// close the connection with protocol error
|
// 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
|
// get the data length of the frame
|
||||||
int len = (byte & 0x7F);
|
int len = (byte & 0x7F);
|
||||||
if(len <= 125)
|
if (len <= 125)
|
||||||
{
|
{
|
||||||
header->plen = len;
|
header->plen = len;
|
||||||
} else if(len == 126)
|
}
|
||||||
|
else if (len == 126)
|
||||||
{
|
{
|
||||||
if(antd_recv(client,bytes, 2*sizeof(uint8_t)) <0) goto fail;
|
if (antd_recv(client, bytes, 2 * sizeof(uint8_t)) < 0)
|
||||||
header->plen = (bytes[0]<<8) + bytes[1];
|
goto fail;
|
||||||
|
header->plen = (bytes[0] << 8) + bytes[1];
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
//read only last 4 byte
|
//read only last 4 byte
|
||||||
if(antd_recv(client,bytes, 8*sizeof(uint8_t)) <0) goto fail;
|
if (antd_recv(client, bytes, 8 * sizeof(uint8_t)) < 0)
|
||||||
header->plen = (bytes[4]<<24) + (bytes[5]<<16) + (bytes[6] << 8) + bytes[7] ;
|
goto fail;
|
||||||
|
header->plen = (bytes[4] << 24) + (bytes[5] << 16) + (bytes[6] << 8) + bytes[7];
|
||||||
}
|
}
|
||||||
//printf("len: %d\n", header->plen);
|
//printf("len: %d\n", header->plen);
|
||||||
// last step is to get the maskey
|
// last step is to get the maskey
|
||||||
if(header->mask)
|
if (header->mask)
|
||||||
if(antd_recv(client,header->mask_key, 4*sizeof(uint8_t)) <0) goto fail;
|
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] );
|
//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
|
// check wheather it is a ping or a close message
|
||||||
// process it and return NULL
|
// process it and return NULL
|
||||||
//otherwise return the header
|
//otherwise return the header
|
||||||
//return the header
|
//return the header
|
||||||
switch(header->opcode){
|
switch (header->opcode)
|
||||||
case WS_CLOSE: // client requests to close the connection
|
{
|
||||||
|
case WS_CLOSE: // client requests to close the connection
|
||||||
// send back a close message
|
// 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;
|
//goto fail;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WS_PING: // client send a ping
|
case WS_PING: // client send a ping
|
||||||
// send back a pong message
|
// 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;
|
break;
|
||||||
|
|
||||||
default: break;
|
|
||||||
}
|
}
|
||||||
return header;
|
return header;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
free(header);
|
free(header);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Read data from client
|
* Read data from client
|
||||||
* and unmask data using the key
|
* 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 len == -1 ==> read all remaining data to 'data';
|
||||||
if(header->plen == 0) return 0;
|
if (header->plen == 0)
|
||||||
int dlen = (len==-1 || len > (int)header->plen)?(int)header->plen:len;
|
return 0;
|
||||||
if((dlen = antd_recv(client,data, dlen)) <0) return -1;
|
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;
|
header->plen = header->plen - dlen;
|
||||||
// unmask received data
|
// unmask received data
|
||||||
if(header->mask)
|
if (header->mask)
|
||||||
for(int i = 0; i < dlen; ++i)
|
for (int i = 0; i < dlen; ++i)
|
||||||
data[i] = data[i]^ header->mask_key[i%4];
|
data[i] = data[i] ^ header->mask_key[i % 4];
|
||||||
data[dlen] = '\0';
|
data[dlen] = '\0';
|
||||||
return dlen;
|
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 byte = 0;
|
||||||
uint8_t bytes[8];
|
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|
|
//first byte |FIN|000|opcode|
|
||||||
byte = (header.fin << 7) + header.opcode;
|
byte = (header.fin << 7) + header.opcode;
|
||||||
//printf("BYTE: %d\n", byte);
|
//printf("BYTE: %d\n", byte);
|
||||||
antd_send(client, &byte, 1);
|
if (antd_send(client, &byte, 1) != 1)
|
||||||
|
return -1;
|
||||||
// second byte, payload length
|
// second byte, payload length
|
||||||
// mask may be 0 or 1
|
// mask may be 0 or 1
|
||||||
//if(header.mask == 1)
|
//if(header.mask == 1)
|
||||||
// printf("Data is masked\n");
|
// printf("Data is masked\n");
|
||||||
if(header.plen <= 125)
|
if (header.plen <= 125)
|
||||||
{
|
{
|
||||||
byte = (header.mask << 7) + header.plen;
|
byte = (header.mask << 7) + header.plen;
|
||||||
antd_send(client, &byte, 1);
|
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;
|
byte = (header.mask << 7) + 126;
|
||||||
bytes[0] = (header.plen) >> 8;
|
bytes[0] = (header.plen) >> 8;
|
||||||
bytes[1] = (header.plen) & 0x00FF;
|
bytes[1] = (header.plen) & 0x00FF;
|
||||||
antd_send(client, &byte, 1);
|
if (antd_send(client, &byte, 1) != 1)
|
||||||
antd_send(client, &bytes, 2);
|
return -1;
|
||||||
|
if (antd_send(client, bytes, 2) != 2)
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
else // > 16 bits
|
else // > 16 bits
|
||||||
{
|
{
|
||||||
byte = (header.mask << 7) + 127;
|
byte = (header.mask << 7) + 127;
|
||||||
bytes[4] = (header.plen) >> 24;
|
bytes[4] = (header.plen) >> 24;
|
||||||
bytes[5] = ((header.plen)>>16) & 0x00FF;
|
bytes[5] = ((header.plen) >> 16) & 0x00FF;
|
||||||
bytes[6] = ((header.plen)>>8) & 0x00FF;
|
bytes[6] = ((header.plen) >> 8) & 0x00FF;
|
||||||
bytes[7] = (header.plen) & 0x00FF;
|
bytes[7] = (header.plen) & 0x00FF;
|
||||||
antd_send(client, &byte, 1);
|
if (antd_send(client, &byte, 1) != 1)
|
||||||
antd_send(client, &bytes, 8);
|
return -1;
|
||||||
|
if (antd_send(client, bytes, 8) != 8)
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
// send mask key
|
// 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
|
* 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;
|
masked = data;
|
||||||
if(header.mask)
|
int ret;
|
||||||
|
if (header.mask)
|
||||||
{
|
{
|
||||||
ws_gen_mask_key(&header);
|
ws_gen_mask_key(&header);
|
||||||
masked = (uint8_t*) malloc(header.plen);
|
masked = (uint8_t *)malloc(header.plen);
|
||||||
for(int i = 0; i < (int)header.plen; ++i)
|
for (int i = 0; i < (int)header.plen; ++i)
|
||||||
masked[i] = data[i]^ header.mask_key[i%4];
|
masked[i] = data[i] ^ header.mask_key[i % 4];
|
||||||
}
|
}
|
||||||
_send_header(client, header);
|
if (_send_header(client, header) != 0)
|
||||||
if(header.opcode == WS_TEXT)
|
return -1;
|
||||||
antd_send(client,(char*)masked,header.plen);
|
if (header.opcode == WS_TEXT)
|
||||||
|
ret = antd_send(client, (char *)masked, header.plen);
|
||||||
else
|
else
|
||||||
antd_send(client,(uint8_t*)masked,header.plen);
|
ret = antd_send(client, (uint8_t *)masked, header.plen);
|
||||||
if(masked && header.mask)
|
if (masked && header.mask)
|
||||||
free(masked);
|
free(masked);
|
||||||
|
if (ret != (int)header.plen)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* send a text data frame to client
|
* 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;
|
ws_msg_header_t header;
|
||||||
header.fin = 1;
|
header.fin = 1;
|
||||||
@ -198,51 +224,51 @@ void ws_send_text(void* client, const char* data,int mask)
|
|||||||
header.plen = strlen(data);
|
header.plen = strlen(data);
|
||||||
//_send_header(client,header);
|
//_send_header(client,header);
|
||||||
//send(client, data, header.plen,0);
|
//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
|
* send a single binary data fram to client
|
||||||
* not tested yet, but should work
|
* 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;
|
ws_msg_header_t header;
|
||||||
header.fin = 1;
|
header.fin = 1;
|
||||||
header.opcode = WS_BIN;
|
header.opcode = WS_BIN;
|
||||||
header.plen = l;
|
header.plen = l;
|
||||||
header.mask = mask;
|
header.mask = mask;
|
||||||
ws_send_frame(client,data, header);
|
return ws_send_frame(client, data, header);
|
||||||
//_send_header(client,header);
|
//_send_header(client,header);
|
||||||
//send(client, data, header.plen,0);
|
//send(client, data, header.plen,0);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* send a file as binary data
|
* 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];
|
uint8_t buff[1024];
|
||||||
FILE *ptr;
|
FILE *ptr;
|
||||||
ptr = fopen(file,"rb");
|
ptr = fopen(file, "rb");
|
||||||
if(!ptr)
|
if (!ptr)
|
||||||
{
|
{
|
||||||
ws_send_close(client,1011,mask);
|
return ws_send_close(client, 1011, mask);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ws_msg_header_t header;
|
ws_msg_header_t header;
|
||||||
size_t size;
|
size_t size;
|
||||||
int first_frame = 1;
|
int first_frame = 1;
|
||||||
|
int ret = 0;
|
||||||
//ws_send_frame(client,buff,header);
|
//ws_send_frame(client,buff,header);
|
||||||
header.mask = mask;
|
header.mask = mask;
|
||||||
while(!feof(ptr))
|
while (!feof(ptr))
|
||||||
{
|
{
|
||||||
size = fread(buff,1,1024,ptr);
|
size = fread(buff, 1, 1024, ptr);
|
||||||
if(feof(ptr))
|
if (feof(ptr))
|
||||||
header.fin = 1;
|
header.fin = 1;
|
||||||
else
|
else
|
||||||
header.fin = 0;
|
header.fin = 0;
|
||||||
// clear opcode
|
// clear opcode
|
||||||
if(first_frame)
|
if (first_frame)
|
||||||
{
|
{
|
||||||
header.opcode = WS_BIN;
|
header.opcode = WS_BIN;
|
||||||
first_frame = 0;
|
first_frame = 0;
|
||||||
@ -251,55 +277,63 @@ void ws_send_file(void* client, const char* file, int mask)
|
|||||||
header.opcode = 0;
|
header.opcode = 0;
|
||||||
header.plen = size;
|
header.plen = size;
|
||||||
//printf("FIN: %d OC:%d\n", header.fin, header.opcode);
|
//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);
|
fclose(ptr);
|
||||||
|
if (ret != 0)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Not tested yet
|
* Not tested yet
|
||||||
* but should work
|
* 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;
|
ws_msg_header_t pheader;
|
||||||
|
int ret;
|
||||||
pheader.fin = 1;
|
pheader.fin = 1;
|
||||||
pheader.opcode = WS_PONG;
|
pheader.opcode = WS_PONG;
|
||||||
pheader.plen = oheader->plen;
|
pheader.plen = oheader->plen;
|
||||||
pheader.mask = mask;
|
pheader.mask = mask;
|
||||||
uint8_t *data = (uint8_t*)malloc(oheader->plen);
|
uint8_t *data = (uint8_t *)malloc(oheader->plen);
|
||||||
if(!data) return;
|
if (!data)
|
||||||
|
return -1;
|
||||||
if(ws_read_data(client, oheader, pheader.plen,data) == -1)
|
|
||||||
|
if (ws_read_data(client, oheader, pheader.plen, data) == -1)
|
||||||
{
|
{
|
||||||
ERROR("Cannot read ping data %d", pheader.plen);
|
ERROR("Cannot read ping data %d", pheader.plen);
|
||||||
free(data);
|
free(data);
|
||||||
return;
|
return -1;
|
||||||
}
|
}
|
||||||
ws_send_frame(client,data,pheader);
|
ret = ws_send_frame(client, data, pheader);
|
||||||
free(data);
|
free(data);
|
||||||
//_send_header(client, pheader);
|
//_send_header(client, pheader);
|
||||||
//send(client, data, len, 0);
|
//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;
|
ws_msg_header_t pheader;
|
||||||
pheader.fin = 1;
|
pheader.fin = 1;
|
||||||
pheader.opcode = WS_PING;
|
pheader.opcode = WS_PING;
|
||||||
pheader.plen = strlen(echo);
|
pheader.plen = strlen(echo);
|
||||||
pheader.mask = mask;
|
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
|
* 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");
|
//printf("CLOSED\n");
|
||||||
ws_msg_header_t header;
|
ws_msg_header_t header;
|
||||||
header.fin = 1;
|
header.fin = 1;
|
||||||
header.opcode = WS_CLOSE;
|
header.opcode = WS_CLOSE;
|
||||||
header.plen = 2;
|
header.plen = 2;
|
||||||
header.mask=mask;
|
header.mask = mask;
|
||||||
uint8_t bytes[2];
|
uint8_t bytes[2];
|
||||||
bytes[0] = status >> 8;
|
bytes[0] = status >> 8;
|
||||||
bytes[1] = status & 0xFF;
|
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];
|
header.mask_key[1] = bytes[1];
|
||||||
bytes[0] = bytes[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_header(client, header);
|
||||||
//send(client,bytes,2,0);
|
//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 hostent *he;
|
||||||
struct in_addr **addr_list;
|
struct in_addr **addr_list;
|
||||||
int i;
|
int i;
|
||||||
if ( (he = gethostbyname( hostname ) ) == NULL)
|
if ((he = gethostbyname(hostname)) == NULL)
|
||||||
{
|
{
|
||||||
// get the host info
|
// get the host info
|
||||||
ERROR("gethostbyname:%s",strerror(errno));
|
ERROR("gethostbyname:%s", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
addr_list = (struct in_addr **) he->h_addr_list;
|
addr_list = (struct in_addr **)he->h_addr_list;
|
||||||
|
|
||||||
for(i = 0; addr_list[i] != NULL; i++)
|
for (i = 0; addr_list[i] != NULL; i++)
|
||||||
{
|
{
|
||||||
//Return the first one;
|
//Return the first one;
|
||||||
strcpy(ip , inet_ntoa(*addr_list[i]) );
|
strcpy(ip, inet_ntoa(*addr_list[i]));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
send a request
|
send a request
|
||||||
*/
|
*/
|
||||||
int request_socket(const char* ip, int port)
|
int request_socket(const char *ip, int port)
|
||||||
{
|
{
|
||||||
int sockfd;
|
int sockfd;
|
||||||
struct sockaddr_in dest;
|
struct sockaddr_in dest;
|
||||||
|
|
||||||
// time out setting
|
// time out setting
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
timeout.tv_sec = CONN_TIME_OUT_S;
|
timeout.tv_sec = CONN_TIME_OUT_S;
|
||||||
timeout.tv_usec = 0;//3 s
|
timeout.tv_usec = 0; //3 s
|
||||||
if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
|
if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
||||||
{
|
{
|
||||||
ERROR("Socket: %s", strerror(errno));
|
ERROR("Socket: %s", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (setsockopt (sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,sizeof(timeout)) < 0)
|
if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0)
|
||||||
ERROR("setsockopt failed:%s", strerror(errno));
|
ERROR("setsockopt failed:%s", strerror(errno));
|
||||||
|
|
||||||
if (setsockopt (sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout,sizeof(timeout)) < 0)
|
if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0)
|
||||||
ERROR("setsockopt failed:%s",strerror(errno));
|
ERROR("setsockopt failed:%s", strerror(errno));
|
||||||
/*struct linger lingerStruct;
|
/*struct linger lingerStruct;
|
||||||
lingerStruct.l_onoff = 0; // turn lingering off for sockets
|
lingerStruct.l_onoff = 0; // turn lingering off for sockets
|
||||||
setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &lingerStruct, sizeof(lingerStruct));*/
|
setsockopt(sockfd, SOL_SOCKET, SO_LINGER, &lingerStruct, sizeof(lingerStruct));*/
|
||||||
|
|
||||||
bzero(&dest, sizeof(dest));
|
bzero(&dest, sizeof(dest));
|
||||||
dest.sin_family = AF_INET;
|
dest.sin_family = AF_INET;
|
||||||
dest.sin_port = htons(port);
|
dest.sin_port = htons(port);
|
||||||
if ( inet_aton(ip, &dest.sin_addr) == 0 )
|
if (inet_aton(ip, &dest.sin_addr) == 0)
|
||||||
{
|
{
|
||||||
perror(ip);
|
perror(ip);
|
||||||
close(sockfd);
|
close(sockfd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if ( connect(sockfd, (struct sockaddr*)&dest, sizeof(dest)) != 0 )
|
if (connect(sockfd, (struct sockaddr *)&dest, sizeof(dest)) != 0)
|
||||||
{
|
{
|
||||||
close(sockfd);
|
close(sockfd);
|
||||||
ERROR("Connect:%s",strerror(errno));
|
ERROR("Connect:%s", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return sockfd;
|
return sockfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ws_client_close(ws_client_t* wsclient)
|
void ws_client_close(ws_client_t *wsclient)
|
||||||
{
|
{
|
||||||
antd_close(wsclient->antdsock);
|
antd_close(wsclient->antdsock);
|
||||||
|
|
||||||
#ifdef USE_OPENSSL
|
#ifdef USE_OPENSSL
|
||||||
if(wsclient->ssl_ctx)
|
if (wsclient->ssl_ctx)
|
||||||
{
|
{
|
||||||
SSL_CTX_free(wsclient->ssl_ctx);
|
SSL_CTX_free(wsclient->ssl_ctx);
|
||||||
FIPS_mode_set(0);
|
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
|
//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];
|
char ip[100];
|
||||||
int stat = ip_from_hostname(wsclient->host,ip);
|
int stat = ip_from_hostname(wsclient->host, ip);
|
||||||
if(stat == -1)
|
if (stat == -1)
|
||||||
return -1;
|
return -1;
|
||||||
int sock = request_socket(ip, pcnf.port);
|
int sock = request_socket(ip, pcnf.port);
|
||||||
if(sock <= 0)
|
if (sock <= 0)
|
||||||
{
|
{
|
||||||
ERROR("Cannot request socket");
|
ERROR("Cannot request socket");
|
||||||
return -1;
|
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->last_io = time(NULL);
|
||||||
wsclient->antdsock->zstream = NULL;
|
wsclient->antdsock->zstream = NULL;
|
||||||
#ifdef USE_OPENSSL
|
#ifdef USE_OPENSSL
|
||||||
if(pcnf.usessl)
|
if (pcnf.usessl)
|
||||||
{
|
{
|
||||||
SSL_library_init();
|
SSL_library_init();
|
||||||
SSL_load_error_strings();
|
SSL_load_error_strings();
|
||||||
ERR_load_crypto_strings();
|
ERR_load_crypto_strings();
|
||||||
OpenSSL_add_ssl_algorithms();
|
OpenSSL_add_ssl_algorithms();
|
||||||
const SSL_METHOD *method;
|
const SSL_METHOD *method;
|
||||||
unsigned long ssl_err = 0;
|
unsigned long ssl_err = 0;
|
||||||
method = SSLv23_client_method();
|
method = SSLv23_client_method();
|
||||||
ssl_err = ERR_get_error();
|
ssl_err = ERR_get_error();
|
||||||
if(!method)
|
if (!method)
|
||||||
{
|
{
|
||||||
ERROR("SSLv23_method: %s", ERR_error_string(ssl_err, NULL));
|
ERROR("SSLv23_method: %s", ERR_error_string(ssl_err, NULL));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
wsclient->ssl_ctx = SSL_CTX_new(method);
|
wsclient->ssl_ctx = SSL_CTX_new(method);
|
||||||
ssl_err = ERR_get_error();
|
ssl_err = ERR_get_error();
|
||||||
if (!wsclient->ssl_ctx) {
|
if (!wsclient->ssl_ctx)
|
||||||
|
{
|
||||||
ERROR("SSL_CTX_new: %s", ERR_error_string(ssl_err, NULL));
|
ERROR("SSL_CTX_new: %s", ERR_error_string(ssl_err, NULL));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
// configure the context
|
// configure the context
|
||||||
#if defined(SSL_CTX_set_ecdh_auto)
|
#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
|
#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
|
#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
|
// 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";
|
//const char* suit = "AES128-SHA";
|
||||||
if (SSL_CTX_set_cipher_list(wsclient->ssl_ctx, suit) != 1)
|
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;
|
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();
|
ssl_err = ERR_get_error();
|
||||||
ERROR("SSL_CTX_use_certificate_file: %s", ERR_error_string(ssl_err, NULL));
|
ERROR("SSL_CTX_use_certificate_file: %s", ERR_error_string(ssl_err, NULL));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(wsclient->sslpasswd)
|
if (wsclient->sslpasswd)
|
||||||
SSL_CTX_set_default_passwd_cb_userdata(wsclient->ssl_ctx,(void*)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 (SSL_CTX_use_PrivateKey_file(wsclient->ssl_ctx, wsclient->sslkey, SSL_FILETYPE_PEM) <= 0)
|
||||||
|
{
|
||||||
ssl_err = ERR_get_error();
|
ssl_err = ERR_get_error();
|
||||||
ERROR("SSL_CTX_use_PrivateKey_file: %s", ERR_error_string(ssl_err, NULL));
|
ERROR("SSL_CTX_use_PrivateKey_file: %s", ERR_error_string(ssl_err, NULL));
|
||||||
return -1;
|
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();
|
ssl_err = ERR_get_error();
|
||||||
ERROR("SSL_CTX_check_private_key: %s", ERR_error_string(ssl_err, NULL));
|
ERROR("SSL_CTX_check_private_key: %s", ERR_error_string(ssl_err, NULL));
|
||||||
return -1;
|
return -1;
|
||||||
@ -480,12 +518,12 @@ int ws_client_connect(ws_client_t* wsclient, port_config_t pcnf)
|
|||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
|
||||||
// validate
|
// validate
|
||||||
if(wsclient->verify_location)
|
if (wsclient->verify_location)
|
||||||
{
|
{
|
||||||
SSL_CTX_set_verify(wsclient->ssl_ctx, SSL_VERIFY_PEER, NULL);
|
SSL_CTX_set_verify(wsclient->ssl_ctx, SSL_VERIFY_PEER, NULL);
|
||||||
SSL_CTX_set_verify_depth(wsclient->ssl_ctx, 5);
|
SSL_CTX_set_verify_depth(wsclient->ssl_ctx, 5);
|
||||||
if(!SSL_CTX_load_verify_locations(wsclient->ssl_ctx, wsclient->verify_location, NULL))
|
if (!SSL_CTX_load_verify_locations(wsclient->ssl_ctx, wsclient->verify_location, NULL))
|
||||||
{
|
{
|
||||||
ssl_err = ERR_get_error();
|
ssl_err = ERR_get_error();
|
||||||
// TODO Close the context
|
// TODO Close the context
|
||||||
@ -495,32 +533,32 @@ int ws_client_connect(ws_client_t* wsclient, port_config_t pcnf)
|
|||||||
}
|
}
|
||||||
else
|
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);
|
wsclient->antdsock->ssl = (void *)SSL_new(wsclient->ssl_ctx);
|
||||||
if(!wsclient->antdsock->ssl)
|
if (!wsclient->antdsock->ssl)
|
||||||
{
|
{
|
||||||
ssl_err = ERR_get_error();
|
ssl_err = ERR_get_error();
|
||||||
ERROR("SSL_new: %s", ERR_error_string(ssl_err, NULL));
|
ERROR("SSL_new: %s", ERR_error_string(ssl_err, NULL));
|
||||||
return -1;
|
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;
|
int stat, ret;
|
||||||
ERR_clear_error();
|
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);
|
stat = SSL_get_error(wsclient->antdsock->ssl, ret);
|
||||||
switch (stat)
|
switch (stat)
|
||||||
{
|
{
|
||||||
case SSL_ERROR_WANT_READ:
|
case SSL_ERROR_WANT_READ:
|
||||||
case SSL_ERROR_WANT_WRITE:
|
case SSL_ERROR_WANT_WRITE:
|
||||||
case SSL_ERROR_NONE:
|
case SSL_ERROR_NONE:
|
||||||
continue;
|
continue;
|
||||||
default:
|
default:
|
||||||
ERR_print_errors_fp(stderr);
|
ERR_print_errors_fp(stderr);
|
||||||
ERROR("Error performing SSL handshake %d", stat);
|
ERROR("Error performing SSL handshake %d", stat);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -528,69 +566,67 @@ int ws_client_connect(ws_client_t* wsclient, port_config_t pcnf)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ws_open_handshake(ws_client_t *client)
|
||||||
|
|
||||||
|
|
||||||
int ws_open_handshake(ws_client_t* client)
|
|
||||||
{
|
{
|
||||||
char buf[MAX_BUFF];
|
char buf[MAX_BUFF];
|
||||||
// now send ws request handshake
|
// now send ws request handshake
|
||||||
sprintf(buf, CLIENT_RQ,client->resource,client->host);
|
sprintf(buf, CLIENT_RQ, client->resource, client->host);
|
||||||
//printf("Send %s\n", buf);
|
//printf("Send %s\n", buf);
|
||||||
int size = antd_send(client->antdsock, buf, strlen(buf));
|
int size = antd_send(client->antdsock, buf, strlen(buf));
|
||||||
if(size != (int)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))
|
|
||||||
{
|
{
|
||||||
char* line = buf;
|
ERROR("Cannot send request \n");
|
||||||
token = strsep(&line,":");
|
return -1;
|
||||||
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)
|
// now verify if server accept the socket
|
||||||
return 0;
|
size = read_buf(client->antdsock, buf, MAX_BUFF);
|
||||||
return -1;
|
char *token;
|
||||||
}
|
int done = 0;
|
||||||
char* get_ip_address()
|
while (size > 0 && strcmp("\r\n", buf))
|
||||||
{
|
|
||||||
struct ifaddrs* addrs;
|
|
||||||
getifaddrs(&addrs);
|
|
||||||
struct ifaddrs* tmp = addrs;
|
|
||||||
char* ip;
|
|
||||||
while (tmp)
|
|
||||||
{
|
{
|
||||||
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;
|
struct sockaddr_in *pAddr = (struct sockaddr_in *)tmp->ifa_addr;
|
||||||
ip = inet_ntoa(pAddr->sin_addr);
|
ip = inet_ntoa(pAddr->sin_addr);
|
||||||
if(strcmp(ip,"127.0.0.1") != 0)
|
if (strcmp(ip, "127.0.0.1") != 0)
|
||||||
return ip;
|
return ip;
|
||||||
}
|
}
|
||||||
tmp = tmp->ifa_next;
|
tmp = tmp->ifa_next;
|
||||||
}
|
}
|
||||||
freeifaddrs(addrs);
|
freeifaddrs(addrs);
|
||||||
return "127.0.0.1";
|
return "127.0.0.1";
|
||||||
|
71
lib/ws.h
71
lib/ws.h
@ -6,23 +6,24 @@
|
|||||||
#include "handle.h"
|
#include "handle.h"
|
||||||
|
|
||||||
#define CONN_TIME_OUT_S 3
|
#define CONN_TIME_OUT_S 3
|
||||||
#define BITV(v,i) ((v & (1 << i)) >> i)
|
#define BITV(v, i) ((v & (1 << i)) >> i)
|
||||||
#define WS_TEXT 0x1
|
#define WS_TEXT 0x1
|
||||||
#define WS_BIN 0x2
|
#define WS_BIN 0x2
|
||||||
#define WS_CLOSE 0x8
|
#define WS_CLOSE 0x8
|
||||||
#define WS_PING 0x9
|
#define WS_PING 0x9
|
||||||
#define WS_PONG 0xA
|
#define WS_PONG 0xA
|
||||||
#define ws_t(c ,d) (ws_send_text(c,d,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_b(c, d, z) (ws_send_binary(c, d, z, 0))
|
||||||
#define ws_f(c,f) (ws_send_file(c,f,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_close(c, r) (ws_send_close(c, r, 0))
|
||||||
#define MAX_BUFF 1024
|
#define MAX_BUFF 1024
|
||||||
|
|
||||||
#define PREFERRED_WS_CIPHERS "HIGH:!aNULL:!kRSA:!SRP:!PSK:!CAMELLIA:!RC4:!MD5:!DSS"
|
#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 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="
|
#define SERVER_WS_KEY "s3pPLMBiTxaQ9kYGzzhZRbK+xOo="
|
||||||
|
|
||||||
typedef struct{
|
typedef struct
|
||||||
|
{
|
||||||
uint8_t fin;
|
uint8_t fin;
|
||||||
uint8_t opcode;
|
uint8_t opcode;
|
||||||
unsigned int plen;
|
unsigned int plen;
|
||||||
@ -30,40 +31,40 @@ typedef struct{
|
|||||||
uint8_t mask_key[4];
|
uint8_t mask_key[4];
|
||||||
} ws_msg_header_t;
|
} ws_msg_header_t;
|
||||||
|
|
||||||
typedef struct{
|
typedef struct
|
||||||
const char* host;
|
{
|
||||||
const char* resource;
|
const char *host;
|
||||||
antd_client_t* antdsock;
|
const char *resource;
|
||||||
|
antd_client_t *antdsock;
|
||||||
// ssl
|
// ssl
|
||||||
const char* sslcert;
|
const char *sslcert;
|
||||||
const char* sslkey;
|
const char *sslkey;
|
||||||
const char* sslpasswd;
|
const char *sslpasswd;
|
||||||
const char* ciphersuit;
|
const char *ciphersuit;
|
||||||
const char* verify_location;
|
const char *verify_location;
|
||||||
void * ssl_ctx;
|
void *ssl_ctx;
|
||||||
} ws_client_t;
|
} 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*);
|
int ws_ping(void *client, const char *echo, int mask);
|
||||||
void ws_send_frame(void* , uint8_t* , ws_msg_header_t );
|
|
||||||
void ws_pong(void* client, ws_msg_header_t*, 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);
|
int ws_read_data(void *, ws_msg_header_t *, int, uint8_t *);
|
||||||
void ws_send_close(void* client, unsigned int status, int mask);
|
int request_socket(const char *ip, int port);
|
||||||
void ws_send_file(void* client, const char* file, int mask);
|
int ip_from_hostname(const char *hostname, char *ip);
|
||||||
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_open_hand_shake(const char* host, int port, const char* resource);
|
//int ws_open_hand_shake(const char* host, int port, const char* resource);
|
||||||
char* get_ip_address();
|
char *get_ip_address();
|
||||||
|
|
||||||
// client
|
// client
|
||||||
|
|
||||||
void ws_client_close(ws_client_t* wsclient);
|
void ws_client_close(ws_client_t *wsclient);
|
||||||
int ws_client_connect(ws_client_t* wsclient, port_config_t pcnf);
|
int ws_client_connect(ws_client_t *wsclient, port_config_t pcnf);
|
||||||
int ws_open_handshake(ws_client_t* client);
|
int ws_open_handshake(ws_client_t *client);
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue
Block a user