I am writing a simple C FTP client. I have some problems with receiving data from both FTP (21) and FTP-DATA (passive) sockets. That's my main program loop:
input_handles[0] = GetStdHandle(STD_INPUT_HANDLE);
input_handles[1] = WSACreateEvent();
input_handles[2] = INVALID_HANDLE_VALUE;
WSAEventSelect(connection->socket, input_handles[1], FD_READ);
while (1) {
wait_result = WaitForMultipleObjectsEx(num_in_handles, input_handles, FALSE, INFINITE, FALSE);
if (wait_result == WAIT_OBJECT_0) {
fgets(input_line, input_len, stdin);
ftp_cmd(connection, input_line);
if (_strnicmp(input_line, "QUIT", 4) == 0) {
WSACloseEvent(input_handles[1]);
break;
}
}
if(wait_result == WAIT_OBJECT_0 + 1 || wait_result == WAIT_OBJECT_0 + 2) {
if (WaitForSingleObject(input_handles[1], 0) == WAIT_OBJECT_0) {
ftp_recv(connection, &cmd_output);
if (cmd_output != NULL) {
printf(cmd_output);
if (strncmp(cmd_output, "227", 3) == 0) { // 227 - enter passive mode
CHECK_ERROR(ftp_passive(connection, cmd_output, &input_handles[2]));
num_in_handles = 3;
}
if(strncmp(cmd_output, "226", 3) == 0) { // 226 - exit passive mode
ftp_passive_close(connection, &input_handles[2]);
num_in_handles = 2;
}
SAFE_FREE(cmd_output);
}
}
if(num_in_handles == 3 && WaitForSingleObject(input_handles[2], 0) == WAIT_OBJECT_0) {
ftp_recv_pasv(connection, &cmd_output);
if (cmd_output != NULL)
printf(cmd_output);
SAFE_FREE(cmd_output);
// WORKS GOOD WITH THIS UNCOMMENTED
//ftp_passive_close(connection, &input_handles[2]);
//num_in_handles = 2;
}
}
}
ftp_passive() opens a socket to the address given by server and creates WSA event (input_handles[2]). ftp_passive_close() closes this socket and event.
I have no idea why it works with the commented fragment. When it's commented, my client doesn't receive any more data from any socket.
What's wrong with my code?
Related
I posted this problem a couple of hours ago, but unfortunately, the details was not clear. i've added the code and some explanation.
i have a string like this to send through socket: "000f45546874684498765" as you see the first 3 numbers are zero, when the C compiler comes to this 000 it thinks these zeros are the finishing of the string. any suggestion?
proc_socketgps(s32 TaskId)
while (1)
{
Ql_Sleep(socket_timer);
if (is_socket_success == TRUE)
{
APP_DEBUG("start socket connect\r\n");
APP_DEBUG("m_tcp_state :%d\r\n", m_tcp_state);
APP_DEBUG("STATE_SOC_SEND :%d\r\n", STATE_SOC_SEND);
APP_DEBUG("m_socketid :%d\r\n", m_socketid);
proc_handle("\x00\x11\x22", sizeof("\x00\x11\x22"));
}
static void proc_handle(unsigned char *pData, s32 len)
char *p = NULL;
s32 iret;
u8 srvport[10];
//command: Set_APN_Param=<APN>,<username>,<password>
p = Ql_strstr(pData, "Set_APN_Param=");
if (p)
{
Ql_memset(m_apn, 0, 10);
if (Analyse_Command(pData, 1, '>', m_apn))
{
APP_DEBUG("<--APN Parameter Error.-->\r\n");
return;
}
Ql_memset(m_userid, 0, 10);
if (Analyse_Command(pData, 2, '>', m_userid))
{
APP_DEBUG("<--APN Username Parameter Error.-->\r\n");
return;
}
Ql_memset(m_passwd, 0, 10);
if (Analyse_Command(pData, 3, '>', m_passwd))
{
APP_DEBUG("<--APN Password Parameter Error.-->\r\n");
return;
}
APP_DEBUG("<--Set APN Parameter Successfully<%s>,<%s>,<%s>.-->\r\n", m_apn, m_userid, m_passwd);
return;
}
//command: Set_Srv_Param=<srv ip>,<srv port>
p = Ql_strstr(pData, "Set_Srv_Param=");
if (p)
{
Ql_memset(m_SrvADDR, 0, SRVADDR_BUFFER_LEN);
if (Analyse_Command(pData, 1, '>', m_SrvADDR))
{
APP_DEBUG("<--Server Address Parameter Error.-->\r\n");
return;
}
Ql_memset(srvport, 0, 10);
if (Analyse_Command(pData, 2, '>', srvport))
{
APP_DEBUG("<--Server Port Parameter Error.-->\r\n");
return;
}
m_SrvPort = Ql_atoi(srvport);
APP_DEBUG("<--Set TCP Server Parameter Successfully<%s>,<%d>.-->\r\n", m_SrvADDR, m_SrvPort);
m_tcp_state = STATE_NW_GET_SIMSTATE;
APP_DEBUG("<--Restart the TCP connection process.-->\r\n");
return;
}
//if not command,send it to server
m_pCurrentPos = m_send_buf;
Ql_strcpy(m_pCurrentPos + m_remain_len, pData);
m_remain_len = Ql_strlen(m_pCurrentPos);
if (!Ql_strlen(m_send_buf)) //no data need to send
break;
m_tcp_state = STATE_SOC_SENDING;
do
{
ret = Ql_SOC_Send(m_socketid, m_pCurrentPos, m_remain_len);
APP_DEBUG("Message Data :%s", m_pCurrentPos);
APP_DEBUG("<--Send data,socketid=%d,number of bytes sent=%d-->\r\n", m_socketid, ret);
if (ret == m_remain_len) //send compelete
{
m_remain_len = 0;
m_pCurrentPos = NULL;
m_nSentLen += ret;
m_tcp_state = STATE_SOC_ACK;
break;
}
else if ((ret <= 0) && (ret == SOC_WOULDBLOCK))
{
//waiting CallBack_socket_write, then send data;
break;
}
else if (ret <= 0)
{
APP_DEBUG("<--Send data failure,ret=%d.-->\r\n", ret);
APP_DEBUG("<-- Close socket.-->\r\n");
Ql_SOC_Close(m_socketid); //error , Ql_SOC_Close
m_socketid = -1;
m_remain_len = 0;
m_pCurrentPos = NULL;
if (ret == SOC_BEARER_FAIL)
{
m_tcp_state = STATE_GPRS_DEACTIVATE;
}
else
{
m_tcp_state = STATE_GPRS_GET_DNSADDRESS;
}
break;
}
else if (ret < m_remain_len) //continue send, do not send all data
{
m_remain_len -= ret;
m_pCurrentPos += ret;
m_nSentLen += ret;
}
} while (1);
break;
the code has been added to the question. firs socket gets open and gets connected to the server. this function >> proc_handle("\x00\x11\x22", sizeof("\x00\x11\x22")); sends hexadecimal string, however i think c consider this part "\x00" as end of the string ! and the data won't be sent ! I already tested that if I remove "\x00" from the row above it works like a charm !
I am working on using SChannel to build a client/server program. One of the things I would like to do is have file sharing. I found some example code of a client program using Schannel to communicate and I am wondering why the max size of a message is 32kb. Here is the example function that does the receiving
int tls_handshake(tls_ctx *c, tls_session *s) {
DWORD flags_in, flags_out;
SecBuffer ib[2], ob[1];
SecBufferDesc in, out;
int len;
// send initial hello
if (!tls_hello(c, s)) {
return 0;
}
flags_in = ISC_REQ_REPLAY_DETECT |
ISC_REQ_CONFIDENTIALITY |
ISC_RET_EXTENDED_ERROR |
ISC_REQ_ALLOCATE_MEMORY |
ISC_REQ_MANUAL_CRED_VALIDATION;
c->ss = SEC_I_CONTINUE_NEEDED;
s->buflen = 0;
while (c->ss == SEC_I_CONTINUE_NEEDED ||
c->ss == SEC_E_INCOMPLETE_MESSAGE ||
c->ss == SEC_I_INCOMPLETE_CREDENTIALS)
{
if (c->ss == SEC_E_INCOMPLETE_MESSAGE)
{
// receive data from server
len = recv(s->sck, &s->buf[s->buflen], s->maxlen - s->buflen, 0);
// socket error?
if (len == SOCKET_ERROR) {
c->ss = SEC_E_INTERNAL_ERROR;
break;
// server disconnected?
} else if (len==0) {
c->ss = SEC_E_INTERNAL_ERROR;
break;
}
// increase buffer position
s->buflen += len;
}
// inspect what we've received
//tls_hex_dump(s->buf, s->buflen);
// input data
ib[0].pvBuffer = s->buf;
ib[0].cbBuffer = s->buflen;
ib[0].BufferType = SECBUFFER_TOKEN;
// empty buffer
ib[1].pvBuffer = NULL;
ib[1].cbBuffer = 0;
ib[1].BufferType = SECBUFFER_VERSION;
in.cBuffers = 2;
in.pBuffers = ib;
in.ulVersion = SECBUFFER_VERSION;
// output from schannel
ob[0].pvBuffer = NULL;
ob[0].cbBuffer = 0;
ob[0].BufferType = SECBUFFER_VERSION;
out.cBuffers = 1;
out.pBuffers = ob;
out.ulVersion = SECBUFFER_VERSION;
c->ss = c->sspi->
InitializeSecurityContextA(
&s->cc, &s->ctx, NULL, flags_in, 0,
SECURITY_NATIVE_DREP, &in, 0, NULL,
&out, &flags_out, NULL);
// what have we got so far?
if (c->ss == SEC_E_OK ||
c->ss == SEC_I_CONTINUE_NEEDED ||
(FAILED(c->ss) && (flags_out & ISC_RET_EXTENDED_ERROR)))
{
// response for server?
if (ob[0].cbBuffer != 0 && ob[0].pvBuffer) {
// send response
tls_send(s->sck, ob[0].pvBuffer, ob[0].cbBuffer);
// free response
c->sspi->FreeContextBuffer(ob[0].pvBuffer);
ob[0].pvBuffer = NULL;
}
}
// incomplete message? continue reading
if (c->ss==SEC_E_INCOMPLETE_MESSAGE) continue;
// completed handshake?
if (c->ss==SEC_E_OK) {
s->established = 1;
// If the "extra" buffer contains data, this is encrypted application
// protocol layer stuff and needs to be saved. The application layer
// will decrypt it later with DecryptMessage.
if (ib[1].BufferType == SECBUFFER_EXTRA) {
DEBUG_PRINT(" [ we have extra data after handshake.\n");
memmove(s->pExtra.pvBuffer,
&s->buf[(s->buflen - ib[1].cbBuffer)], ib[1].cbBuffer);
s->pExtra.cbBuffer = ib[1].cbBuffer;
s->pExtra.BufferType = SECBUFFER_TOKEN;
} else {
// no extra data encountered
s->pExtra.pvBuffer = NULL;
s->pExtra.cbBuffer = 0;
s->pExtra.BufferType = SECBUFFER_EMPTY;
}
break;
}
// some other error
if(FAILED(c->ss)) break;
// Copy any leftover data from the "extra" buffer, and go around again.
if(ib[1].BufferType == SECBUFFER_EXTRA) {
memmove(s->buf, &s->buf[(s->buflen - ib[1].cbBuffer)], ib[1].cbBuffer);
s->buflen = ib[1].cbBuffer;
DEBUG_PRINT(" [ we have %i bytes of extra data.\n", s->buflen);
tls_hex_dump(s->buf, s->buflen);
} else {
s->buflen = 0;
}
}
return c->ss==SEC_E_OK ? 1 : 0;
}
The code comes from a Github I found here: https://github.com/odzhan/shells/blob/master/s6/tls.c
Inside one of his header files he defines
#define TLS_MAX_BUFSIZ 32768
I have also read in other places that this is a limit with TLS. Is it possible to increase that limit? What happens if I need to receive more then that? Like a large file?
I want to make a client-server application when a client can register, login, broadcast a message to another clients, send files and so on. Everything, except sending files works pretty well.
In the client application I made a separate thread for every file that I want to send. Reading the file is successful, but sending is not that good. I should make a thread in server project for receiving the bytes sent by the client?
I want sending files to be asynchronous, so that another clients can communicate with server when server is receiving a file.
The thread for reading file and sending data to server:
DWORD WINAPI SendFile(LPVOID param)
{
FileStruct* fileStruct = (FileStruct*)param;
CM_DATA_BUFFER* dataToSend = NULL;
CM_SIZE dataToSendSize = MAXLENGTH;
CM_ERROR error;
CM_SIZE sendBytesCount = 0;
FILE* f = fopen(fileStruct->filePath, "rb");
char buffer[2];
fseek(f, 0, SEEK_SET);
if (f == NULL)
{
perror((const char*)f);
}
char messageBuffer[10];
while (fread(buffer, 1, 1, f) == 1)
{
*(int*)messageBuffer = SENDTYPE;
messageBuffer[4] = buffer[0];
messageBuffer[5] = 0;
dataToSend = NULL;
error = CreateDataBuffer(&dataToSend, dataToSendSize);
if (CM_IS_ERROR(error))
{
_tprintf_s(TEXT("Failed to create SEND data buffer with err-code=0x%X!\n"), error);
DestroyClient(fileStruct->client);
UninitCommunicationModule();
return (DWORD)-1;
}
error = CopyDataIntoBuffer(dataToSend, (const CM_BYTE*)messageBuffer, (CM_SIZE)strlen(messageBuffer));
if (CM_IS_ERROR(error))
{
_tprintf_s(TEXT("CopyDataIntoBuffer failed with err-code=0x%X!\n"), error);
DestroyDataBuffer(dataToSend);
DestroyClient(fileStruct->client);
UninitCommunicationModule();
return (DWORD)-1;
}
error = SendDataToServer(fileStruct->client, dataToSend, &sendBytesCount);
if (CM_IS_ERROR(error))
{
_tprintf_s(TEXT("SendDataToServer failed with err-code=0x%X!\n"), error);
DestroyDataBuffer(dataToSend);
DestroyClient(fileStruct->client);
UninitCommunicationModule();
return (DWORD)-1;
}
DestroyDataBuffer(dataToSend);
}
return (DWORD)0;
}
Here is a part of code from Thread Server responsible for receiving data :
while ((error = ReceiveDataFromClient(newClient, receivedData, &numberOfBytesRead)) == 0)
{
message = (char*)receivedData->DataBuffer;
if (CM_IS_ERROR(error))
{
_tprintf_s(TEXT("ReceiveDataFormServer failed with err-code=0x%X!\n"), error);
DestroyDataBuffer(sendData);
DestroyDataBuffer(receivedData);
break;
}
type = *(int*)receivedData->DataBuffer;
printf("%x\n", type);
if (type == SENDTYPE)
{
printf("%c", (char)receivedData->DataBuffer[4]);
DestroyDataBuffer(receivedData);
receivedData = NULL;
error = CreateDataBuffer(&receivedData, MAXLENGTH);
if (CM_IS_ERROR(error))
{
_tprintf_s(TEXT("Creating receivedDataBuffer failed with err-code =0x%X!\n"), error);
UninitCommunicationModule();
}
continue;
}
This is ReceiveDataFromClient function:
CM_ERROR ReceiveDataFromClient(CM_SERVER_CLIENT* Client, CM_DATA_BUFFER* DataBufferToReceive, CM_SIZE* SuccessfullyReceivedBytesCount)
{
if (Client == NULL || DataBufferToReceive == NULL || SuccessfullyReceivedBytesCount == NULL)
return CM_INVALID_PARAMETER;
CM_ERROR error = ReceiveData(
Client->ClientConnection
, DataBufferToReceive->DataBuffer
, DataBufferToReceive->DataBufferSize
, SuccessfullyReceivedBytesCount
);
if (CM_IS_ERROR(error))
return error;
DataBufferToReceive->UsedBufferSize = *SuccessfullyReceivedBytesCount;
return error;
}
And this is ReceiveData function:
CM_ERROR ReceiveData(CM_CONNECTION* Connection, CM_BYTE* OutputDataBuffer, CM_SIZE OutputDataBufferSize, CM_SIZE* SuccessfullyReceivedBytesCount)
{
if (Connection == NULL)
return CM_INVALID_CONNECTION;
if (INVALID_SOCKET == Connection->ConnectionSocket)
return CM_INVALID_PARAMETER;
int receiveResult = recv(Connection->ConnectionSocket, (char*) OutputDataBuffer, OutputDataBufferSize, 0);
if (receiveResult == SOCKET_ERROR)
{
CM_LOG_ERROR(TEXT("recv failed with err-code=0x%X!"), WSAGetLastError());
return CM_CONNECTION_RECEIVE_FAILED;
}
if (receiveResult == 0)
return CM_CONNECTION_TERMINATED;
*SuccessfullyReceivedBytesCount = (CM_SIZE)receiveResult;
return CM_SUCCESS;
}
I'm having problem getting in to the second Serial.available loop of my code located in the Package. Please, let me know, if you see anything wrong with the code.
Arduino Code
Inputs:
1. "Package" -> I get +1 back from the Serial Monitor
2. "5&12!23!34!59!70!" -> I get 0 back from the Serial Monitor. For this one, I'm supposed to see, 5 12 23 34 59 70
Please, let me know, if you see anything wrong in this code and why is the Serial.available not functional in the Package?
String incoming;
String readIncoming;
int i=0;
typedef struct {
int npins;
int addr[512];
}
measureList;
measureList list;
void setup() {
Serial.begin(9600);
Serial.println("Serial conection started");
incoming = ""; list.npins = 6;
}
void loop() {
while(Serial.available() > 0) {
incoming = Serial.readString();
if(incoming == "HI") { Serial.println("Steven"); }
if(incoming == "SampleAll") { SampleAll(); }
if(incoming == "Package") { Serial.println("+1"); Package(); }
}
}
void Package(void)
{
while(1)
{
if(Serial.available()>0 & i<= list.npins)
{
char recieved = Serial.read();
if (recieved != '&' & i == 0){incoming = incoming + recieved;}
if (recieved == '&' & i == 0){list.npins = incoming.toInt(); Serial.println(list.npins); incoming=""; i = 1;}
if (recieved != '!' & recieved != '&' & i > 0){incoming = incoming + recieved; }
if (recieved == '!' & recieved != '&' & i > 0){ list.addr[i] = incoming.toInt(); Serial.println(list.addr[i]);incoming = ""; i = i + 1;}
if (i == list.npins) {break;}
}
}
}
I was using OpenSSL version 0.9.8h in an Android project. I update it to the 0.9.8.zf version but now it doesn't work.
The two functions that highlight the problem are initialize_client_ctx and initialize_client_ctx. When I call SSL_connect I get an SSL_ERROR_SSL error value. By checking details I retrieve a "bad packet length" error (error:14092073:SSL routines:SSL3_GET_SERVER_HELLO:bad packet length).
The point in the code is indicated in a comment. The code works well with the previous version. I attach also a Wireshark capture file. Any ideas?
SSL_CTX *initialize_client_ctx(const char *keyfile, const char *certfile,
const char *password, int transport)
{
SSL_METHOD *meth = NULL;
X509 *cert = NULL;
SSL_CTX *ctx;
if (transport == IPPROTO_UDP) {
meth = DTLSv1_client_method();
} else if (transport == IPPROTO_TCP) {
meth = TLSv1_client_method();
} else {
return NULL;
}
ctx = SSL_CTX_new(meth);
if (ctx == NULL) {
//print ... Couldn't create SSL_CTX
return NULL;
}
if (password[0] != '\0') {
SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *) password);
SSL_CTX_set_default_passwd_cb(ctx, password_cb);
}
if (tls_client_local_cn_name[0] != '\0') {
cert = _tls_set_certificate(ctx, tls_client_local_cn_name);
}
if (cert==NULL && certfile[0] != '\0') {
//print several warnings....
}
if (cert!=NULL)
{
X509_free(cert);
cert = NULL;
}
/* Load the CAs we trust */
{
char *caFile = 0, *caFolder = 0;
int fd = open(eXosip_tls_ctx_params.root_ca_cert, O_RDONLY);
if (fd >= 0) {
struct stat fileStat;
if (fstat(fd, &fileStat) < 0) {
} else {
if (S_ISDIR(fileStat.st_mode)) {
caFolder = eXosip_tls_ctx_params.root_ca_cert;
} else {
caFile = eXosip_tls_ctx_params.root_ca_cert;
}
}
close(fd);
}
{
int verify_mode = SSL_VERIFY_PEER;
SSL_CTX_set_verify(ctx, verify_mode, &verify_cb);
SSL_CTX_set_verify_depth(ctx, ex_verify_depth + 1);
}
}
SSL_CTX_set_options(ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2 |
SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION |
SSL_OP_CIPHER_SERVER_PREFERENCE);
if(!SSL_CTX_set_cipher_list(ctx,"ALL")) {
//print ... set_cipher_list: cannot set anonymous DH cipher
SSL_CTX_free(ctx);
return NULL;
}
return ctx;
}
static int _tls_tl_ssl_connect_socket(struct socket_tab *sockinfo)
{
X509 *cert;
BIO *sbio;
int res;
if (sockinfo->ssl_ctx == NULL) {
sockinfo->ssl_ctx =
initialize_client_ctx(eXosip_tls_ctx_params.client.priv_key,
eXosip_tls_ctx_params.client.cert,
eXosip_tls_ctx_params.client.priv_key_pw,
IPPROTO_TCP);
sockinfo->ssl_conn = SSL_new(sockinfo->ssl_ctx);
if (sockinfo->ssl_conn == NULL) {
return -1;
}
sbio = BIO_new_socket(sockinfo->socket, BIO_NOCLOSE);
if (sbio == NULL) {
return -1;
}
SSL_set_bio(sockinfo->ssl_conn, sbio, sbio);
}
do {
struct timeval tv;
int fd;
fd_set readfds;
res = SSL_connect(sockinfo->ssl_conn);
res = SSL_get_error(sockinfo->ssl_conn, res);
if (res == SSL_ERROR_NONE) {
//printf... SSL_connect succeeded
break;
}
if (res != SSL_ERROR_WANT_READ && res != SSL_ERROR_WANT_WRITE) {
//<-- here there is a problem res == SSL_ERROR_SSL
//print ERR_reason_error_string(ERR_get_error()));
//print ERR_error_string(ERR_get_error(), NULL));
return -1;
}
tv.tv_sec = SOCKET_TIMEOUT / 1000;
tv.tv_usec = (SOCKET_TIMEOUT % 1000) * 1000;
//retry the connection
fd = SSL_get_fd(sockinfo->ssl_conn);
FD_ZERO(&readfds);
FD_SET(fd, &readfds);
res = select(fd + 1, &readfds, NULL, NULL, &tv);
if (res < 0) {
//print error
return -1;
} else if (res > 0) {
//print...connetrion done!
} else {
//socket timeout, no data to read
return 1;
}
} while (!SSL_is_init_finished(sockinfo->ssl_conn));
if (SSL_is_init_finished(sockinfo->ssl_conn)) {
//print.. SSL_is_init_finished done
} else {
//print.. failed
}
cert = SSL_get_peer_certificate(sockinfo->ssl_conn);
if (cert != 0) {
int cert_err;
tls_dump_cert_info("tls_connect: remote certificate: ", cert);
cert_err = SSL_get_verify_result(sockinfo->ssl_conn);
if (cert_err != X509_V_OK) {
//print... Failed to verify remote certificate
tls_dump_verification_failure(cert_err);
if (eXosip_tls_ctx_params.server.cert[0] != '\0') {
X509_free(cert);
return -1;
} else if (cert_err != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
&& cert_err != X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
&& cert_err != X509_V_ERR_CRL_HAS_EXPIRED
&& cert_err != X509_V_ERR_CERT_HAS_EXPIRED
&& cert_err != X509_V_ERR_CERT_REVOKED
&& cert_err != X509_V_ERR_CERT_UNTRUSTED
&& cert_err != X509_V_ERR_CERT_REJECTED) {
X509_free(cert);
return -1;
}
}
X509_free(cert);
} else {
//print .. No certificate received
/* X509_free is not necessary because no cert-object was created -> cert == NULL */
if (eXosip_tls_ctx_params.server.cert[0] == '\0') {
#ifdef ENABLE_ADH
/* how can we guess a user want ADH... specific APIs.. */
sockinfo->ssl_state = 3;
return 0;
#endif
}
return -1;
}
sockinfo->ssl_state = 3;
return 0;
}
SOLVED Thanks to Eric Tsui that helps me to figure out the problem. The 'hello' that I receive from the server in the handshake has zero length. To solve this I modified the file openssl/ssl/s3_clnt.c in the following way (toggling off the length control):
diff -ur ./s3_clnt.c ./original/s3_clnt.c
--- submodules/externals/openssl/ssl/s3_clnt.c 2015-06-29 14:59:56.723462992 +0200
+++ ../../opensslOrig/s3_clnt.c 2015-06-29 15:00:22.487464221 +0200
## -868,12 +868,14 ##
}
#endif
+#ifndef OPENSSL_NO_TLSEXT
if (p != (d + n)) {
/* wrong packet length */
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_BAD_PACKET_LENGTH);
goto f_err;
}
+#endif
return (1);
f_err: