TCP socket connection interference on send message in Kubernetes - c

I'm creating an application in C that intermediates and manages scheduled applications (NodeJs) to collect information into MongoDB.
This makes possible the application's scalability and avoids replicated values.
Problem
Local tests: OK
Container tests: Ok
K8s Minikube tests: scheduled application error in bson parse
EKS Production tests: scheduled application error in bson parse
Code of C application to send socket message:
static void
ssq_connection_server_handler()
{
...
for (i = 0; i < ssq_max_sockets; i++) {
sd = ssq_connection->clients[i];
if (FD_ISSET(sd, &master)) {
if ((ret = ssq_connection->recv(sd, buffer, SSQ_SERVER_MAX_BUFFER_SIZE)) <= 0) {
continue;
}
buffer[ret] = '\0';
token = ssq_strtok(buffer, ":");
opts = ssq_strtok(NULL, ":");
limit = ssq_atoi(opts, ssq_strlen(opts));
if (limit == SSQ_ERROR) {
limit = 10;
}
if (ssq_strcmp("next", token) == 0) {
u_char *tasks;
size_t len;
tasks = ssq_mongo_collection_find(limit, ssq_mongo->collection, &len);
ssq_connection->send(sd, tasks, len);
}
}
}
...
}
static ssize_t
ssq_connection_send_handler(int fd, u_char *buf, size_t size)
{
ssize_t n;
ssq_err_t err;
for (;;) {
n = send(fd, buf, size, 0);
ssq_log_debug("send: fd:%d %z of %uz", fd, n, size);
if (n > 0) {
return n;
}
err = ssq_socket_errno;
if (n == 0) {
ssq_log_error(SSQ_LOG_ALERT, err, "send() returned zero");
return n;
}
if (err == SSQ_EAGAIN || err == SSQ_EINTR) {
ssq_log_debug_error(err, "send() not ready");
if (err == SSQ_EAGAIN) {
return SSQ_AGAIN;
}
} else {
return SSQ_ERROR;
}
}
}
Code in NodeJs to receive message:
const net = require('net');
const { EJSON } = require('bson');
const sock = new net.Socket();
sock.connect(process.env.SSQ_PORT || 3145, process.env.SSQ_HOST || '127.0.0.1', () => {
console.log('socket connection established');
});
sock.on('data', (data) => {
try {
const tasks = EJSON.parse(data);
console.log(tasks);
process.exit(0);
} catch (err) {
console.error(err);
process.exit(1);
}
});
sock.on('error', () => {
/* void */
});
sock.on('close', () => {
console.warn('socket connection has been closed');
});
sock.write(Buffer.from('next:10'));
I think that something coming from K8s is intercepting and modifying the message.

Related

Correct closing DBus connection

Could you explain how to close DBus connection correctly/ Below is my variant:
int P_dbus_proto_init(DBusConnection **dbus_conn, const char *name, dbus_MessageHandler mh, int num_rules, const char **rules)
{
int rc = 0;
DBusError dbus_err;
dbus_error_init(&dbus_err);
*dbus_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &dbus_err);
if (dbus_error_is_set(&dbus_err))
{
FILTER_LOG_ERROR("Connection Error (%s)\n", dbus_err.message);
dbus_error_free(&dbus_err);
return -1;
}
rc = dbus_bus_request_name(*dbus_conn, name, DBUS_NAME_FLAG_REPLACE_EXISTING, &dbus_err);
if (dbus_error_is_set(&dbus_err) || (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != rc))
{
FILTER_LOG_ERROR("Connection Error (%s)\n", dbus_err.message);
dbus_error_free(&dbus_err);
return -1;
}
dbus_connection_add_filter(*dbus_conn, mh, NULL, NULL);
if (dbus_error_is_set(&dbus_err))
{
FILTER_LOG_ERROR("Add Filter Error (%s)\n", dbus_err.message);
dbus_error_free(&dbus_err);
return -1;
}
for(int i = 0; i < num_rules; i++)
{
dbus_bus_add_match(*dbus_conn, rules[i], &dbus_err);
if (dbus_error_is_set(&dbus_err))
{
FILTER_LOG_ERROR("Match Error (%s)\n", dbus_err.message);
dbus_error_free(&dbus_err);
return -1;
}
}
return 0;
}
static const char* rules[] = {
"interface='acl_management.method'",
};
And how I use it:
DBusConnection *dbus_conn;
if (P_dbus_proto_init(&dbus_conn, "com.bla-bla-bla.acl", P_dbus_proto_job, 1, rules) == 0)
{
while (dbus_connection_read_write_dispatch(dbus_conn, 5000))
{
if(p_ctx->execute.n_nl_exit_app == 0) //My app can be terminated by n_nl_exit_app flag
{
break;
}
}
dbus_connection_close(dbus_conn);// Should I do it or not?
dbus_connection_unref(dbus_conn);// Should I do it or not?
}
From dbus.freedesktop.org docs I cannot understand how to do it correctly. I can terminate my app by turn on 'n_nl_exit_app' flag - should I call dbus_connection_closein this case?

How to send properly files in a client-server application?

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;
}

Kaa Data Collection on Request, Not Loop

I'm doing Kaa project.
First, i have used Data Collection demo and then do some modification to my sensor. The data is send to platform every seconds(i can configure it).
And now, i want to create some service which if i send request(using ulfius framework), my device upload 1 data.
My problem is, i have to do more than 10 request to upload data, how can i solve it. Please Help.
Below is some of my code :
int callback_kaa(const struct _u_request * request,struct _u_response * response, void * user_data){
kaa_client_send(kaa_client, &kaa_add_log_record, (void *)kaa_client);
ulfius_set_string_body_response(response, 200, "Hello Kaa!");}
int main(/*int argc, char *argv[]*/){
printf("DHT11 Logging Demo\n");
if (wiringPiSetup() == -1) {
printf("Failed to initialize Pi wiring\n");
exit(1);}
if (ulfius_init_instance(&instance, PORT, NULL, NULL) != U_OK) {
fprintf(stderr, "Error ulfius_init_instance, abort\n");
return(1);}
ulfius_add_endpoint_by_val(&instance, "POST", "/kaaplatform", NULL, 0,&callback_kaa, NULL);
kaa_error_t error_code = kaa_client_create(&kaa_client, NULL);
KAA_RETURN_IF_ERROR(error_code, "Failed create Kaa client");
kaa_log_bucket_constraints_t bucket_sizes = {
.max_bucket_size = MAX_LOG_BUCKET_SIZE,
.max_bucket_log_count = 1,};
error_code = ext_unlimited_log_storage_create(&log_storage_context,
kaa_client_get_context(kaa_client)->logger);
KAA_RETURN_IF_ERROR(error_code, "Failed to create unlimited log storage");
error_code = ext_log_upload_strategy_create(kaa_client_get_context(kaa_client), &log_upload_strategy_context, THRESHOLD_COUNT_FLAG);
KAA_RETURN_IF_ERROR(error_code, "Failed to create log upload strategy");
error_code = ext_log_upload_strategy_set_threshold_count(log_upload_strategy_context, KAA_UPLOAD_COUNT_THRESHOLD);
KAA_RETURN_IF_ERROR(error_code, "Failed to set threshold log record count");
error_code = kaa_logging_init(kaa_client_get_context(kaa_client)>log_collector
, log_storage_context
, log_upload_strategy_context
, &bucket_sizes);
KAA_RETURN_IF_ERROR(error_code, "Failed to init Kaa log collector");
kaa_channel_manager_set_auth_failure_handler(
kaa_client_get_context(kaa_client)->channel_manager,
auth_failure_handler, kaa_client);
const uint8_t *endpoint_key_hash = NULL;
size_t endpoint_key_hash_length = 0;
ext_get_sha1_base64_public(&endpoint_key_hash, &endpoint_key_hash_length);
printf("Endpoint Key Hash: %.*s\n", (int)endpoint_key_hash_length,endpoint_key_hash);
if (ulfius_start_framework(&instance) == U_OK) {
printf("Start framework on port %d\n", instance.port);
getchar();
} else {
fprintf(stderr, "Error starting framework\n");
}
kaa_client_destroy(kaa_client);
printf("Data analytics demo stopped\n");
ulfius_stop_framework(&instance);
ulfius_clean_instance(&instance);
return error_code;
}
and also, i create some function (kaa_client_send) at file kaa_client.h :
void kaa_client_send(kaa_client_t *kaa_client,external_process_fn external_process, void *external_process_context)
{
KAA_RETURN_IF_NIL(kaa_client, KAA_ERR_BADPARAM);
kaa_error_t error_code = kaa_check_readiness(kaa_client->kaa_context);
if (error_code != KAA_ERR_NONE) {
KAA_LOG_ERROR(kaa_client->kaa_context->logger, error_code, "Cannot start Kaa client: Kaa context is not fully initialized");
return error_code;
}
kaa_client->external_process_fn = external_process;
kaa_client->external_process_context = external_process_context;
kaa_client->external_process_max_delay = 5;
kaa_client->external_process_last_call = KAA_TIME();
KAA_LOG_INFO(kaa_client->kaa_context->logger, KAA_ERR_NONE, "Starting Kaa client...");
if (kaa_client->external_process_fn) {
kaa_client->external_process_fn(kaa_client->external_process_context);
kaa_client->external_process_last_call = KAA_TIME();
}
//Check Kaa channel is ready to transmit something
if (kaa_process_failover(kaa_client->kaa_context)) {
kaa_client->boostrap_complete = false;
} else {
if (kaa_client->channel_id > 0) {
if (kaa_client->channel_state == KAA_CLIENT_CHANNEL_STATE_NOT_CONNECTED) {
error_code = kaa_client_process_channel_disconnected(kaa_client);
} else if (kaa_client->channel_state == KAA_CLIENT_CHANNEL_STATE_CONNECTED) {
error_code = kaa_client_process_channel_connected(kaa_client);
if (error_code == KAA_ERR_TIMEOUT)
kaa_client_deinit_channel(kaa_client);
}
} else {
//No initialized channels
if (kaa_client->boostrap_complete) {
KAA_LOG_INFO(kaa_client->kaa_context->logger, KAA_ERR_NONE,
"Channel [0x%08X] Boostrap complete, reinitializing to Operations ...", kaa_client->channel_id);
kaa_client->boostrap_complete = false;
kaa_client_deinit_channel(kaa_client);
error_code = kaa_client_init_channel(kaa_client, KAA_CLIENT_CHANNEL_TYPE_OPERATIONS);
if (error_code == KAA_ERR_BAD_STATE) {
kaa_client_deinit_channel(kaa_client);
kaa_client->boostrap_complete = false;
}
} else {
KAA_LOG_INFO(kaa_client->kaa_context->logger, KAA_ERR_NONE,
"Channel [0x%08X] Operations error, reinitializing to Bootstrap ...", kaa_client->channel_id);
kaa_client->boostrap_complete = true;
kaa_client_deinit_channel(kaa_client);
kaa_client_init_channel(kaa_client, KAA_CLIENT_CHANNEL_TYPE_BOOTSTRAP);
}
}
}
KAA_LOG_INFO(kaa_client->kaa_context->logger, KAA_ERR_NONE, "Kaa client stopped");
return error_code;
}

"bad packet length" error after updating to OpenSSL 0.9.8.zf

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:

Restarting a UDP socket to accept DTLS connection not working

I am starting a UDP Server and then accepting a DTLS connection to read incoming data. The code is working fine. But once I reuse the connection from the client by restarting the client socket Server is unable to read anything. Using Cyassl library for SSL instance creation.
In Client:
Socket Binding and DTLS initialisation is fine as it is re-using the DTLS context used earlier.
In Server:
Also the socket closing and starting everything is fine but still I am unable to receive in the accepted FD.
But if I put a sleep of exactly 5 seconds between closing and starting the UDP server everything is fine. But I don't want to use blocking I/O like the sleep.
Please do help.
Server:
Accepting data received in m_udp_fd:
if(FD_ISSET(m_udp_fd, &rfds))
{
if(m_accepted_flag==0)
{
udp_read_connect(m_udp_fd);
open_dtls_server();
if(m_ssl_accept(m_udp_fd)>0)
{
media_accepted_flag = 1;
}
}
else
{
// Read data
if(process_dtls_packet(m_udp_fd)<=0)
{
//Clear FD here
}
}
}
Place where the connection is broken depending whether TCP connection is broken or not.
This is getting hit perfectly:
if (FD_ISSET(m_fd, &rfds))
{
if(process_msg(m_fd)<=0)
{
closesocket(m_fd);
FD_CLR(m_fd,recv_fds);
if(recv_fdmax == m_fd)
{
recv_fdmax = max(x_fd,y_fd);
recv_fdmax = max(recv_fdmax,z_fd);
recv_fdmax = max(recv_fdmax,p_fd);
recv_fdmax = max(recv_fdmax,q_fd);
}
}
if(m_accepted_flag!=0)
{
m_accepted_flag = 0;
x_accepted_flag = 0;
//This sleep when kept works perfectly
Sleep(5000);
close_m_and_x_connection(&recv_fdmax,recv_fds,&m_udp_fd,&x_udp_fd);
}
}
UDP Read Connect Function:
int udp_read_connect(SOCKET sockfd)
{
struct sockaddr cliaddr;
char b[1500];
int n;
int len = sizeof(cliaddr);
n = (int)recvfrom(sockfd, (char*)b, sizeof(b), MSG_PEEK,
(struct sockaddr*)&cliaddr, &len);
if (n > 0)
{
if (connect(sockfd, (const struct sockaddr*)&cliaddr,sizeof(cliaddr)) != 0)
printf("udp connect failed");
}
else
printf("recvfrom failed");
return sockfd;
}
Open DTLS Server Method: Here dtls_ctx and dtls_meth are global variables.
int open_dtls_server()
{
int verify_flag = OFF;
int error;
if(dtls_ctx!= NULL)
return;
dtls_ctx = ssl_create_context(DTLS_V1, &dtls_meth);
dtls_meth = CyaDTLSv1_server_method();
if(dtls_meth==NULL)
{
return -1;
}
dtls_ctx = CyaSSL_CTX_new(dtls_meth);
if(NULL == dtls_ctx)
{
ERR_print_errors_fp(stderr);
return -1;
}
if((status = LoadSSLCertificate(dtls_ctx,sslInfo,&error,0)) == 1)
{
return 0;
}
else
return 1;
if(CyaSSL_CTX_use_PrivateKey_file(dtls_ctx, SSL_SERVER_RSA_KEY, SSL_FILETYPE_PEM) <= 0)
{
ERR_print_errors_fp(stderr);
return -1;
}
if(CyaSSL_CTX_check_private_key(dtls_ctx) != 1)
{
return -1;
}
if(verify_flag)
{
if(!CyaSSL_CTX_load_verify_locations(dtls_ctx, SSL_SERVER_RSA_CA_CERT, NULL))
{
ERR_print_errors_fp(stderr);
return -1;
}
CyaSSL_CTX_set_verify(dtls_ctx, SSL_VERIFY_PEER, NULL);
}
CyaSSL_CTX_set_options(dtls_ctx, SSL_OP_ALL);
return 1;
}
m_ssl_accept Function: ssl_m is also a global variable.
int m_ssl_accept(int confd)
{
int ret;
if(ssl_m==NULL)
{
ssl_m = CyaSSL_new(dtls_ctx);
if (ssl_m == NULL)
printf("SSL_new failed");
CyaSSL_set_fd(ssl_m, confd);
}
do
{
if((ret = CyaSSL_accept(ssl_m))!= 1)
{
printf("Handshake Error on M Channel %d with FD: [%d]\n",
return -1;
}
}while(ret != 1);
return 1;
}

Resources