-
Notifications
You must be signed in to change notification settings - Fork 375
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dtlsconnection.c‘s connection_find() function crash. #692
Comments
Do you have an example how to reproduce this? |
#define OBJ_COUNT 3
int main_lwm2m_open(int argc, char *argv[])
{
client_data_t data;
int result;
lwm2m_context_t * lwm2mH = NULL;
const char * localPort = "56830";
const char * server = "www.leshan_server.com";
const char * serverPort = "5684";
char * name = "testlwm2mclient";
int lifetime = 300;
int batterylevelchanging = 0;
time_t reboot_time = 0;
int opt;
bool bootstrapRequested = false;
bool serverPortChanged = false;
#ifdef LWM2M_BOOTSTRAP
lwm2m_client_state_t previousState = STATE_INITIAL;
#endif
char * pskId = NULL;
#ifdef WITH_TINYDTLS
char * psk = "A0203040";
#endif
uint16_t pskLen = -1;
char * pskBuffer = NULL;
memset(&data, 0, sizeof(client_data_t));
data.addressFamily = AF_INET;
if (!server)
{
server = (AF_INET == data.addressFamily ? DEFAULT_SERVER_IPV4 : DEFAULT_SERVER_IPV6);
}
/*
*This call an internal function that create an IPV6 socket on the port 5683.
*/
fprintf(stderr, "Trying to bind LWM2M Client to port %s\r\n", localPort);
data.sock = create_socket(localPort, data.addressFamily);
if (data.sock < 0)
{
fprintf(stderr, "Failed to open socket: %d %s\r\n", errno, strerror(errno));
return -1;
}
/*
* Now the main function fill an array with each object, this list will be later passed to liblwm2m.
* Those functions are located in their respective object file.
*/
#ifdef WITH_TINYDTLS
if (psk != NULL)
{
pskLen = strlen(psk) / 2;
pskBuffer = malloc(pskLen);
if (NULL == pskBuffer)
{
fprintf(stderr, "Failed to create PSK binary buffer\r\n");
return -1;
}
// Hex string to binary
char *h = psk;
char *b = pskBuffer;
char xlate[] = "0123456789ABCDEF";
for ( ; *h; h += 2, ++b)
{
char *l = strchr(xlate, toupper(*h));
char *r = strchr(xlate, toupper(*(h+1)));
if (!r || !l)
{
fprintf(stderr, "Failed to parse Pre-Shared-Key HEXSTRING\r\n");
return -1;
}
*b = ((l - xlate) << 4) + (r - xlate);
}
}
#endif
char serverUri[50];
int serverId = 123;
#ifdef WITH_TINYDTLS
sprintf (serverUri, "coaps://%s:%s", server, serverPort);
#else
sprintf (serverUri, "coap://%s:%s", server, serverPort);
#endif
#ifdef LWM2M_BOOTSTRAP
objArray[0] = get_security_object(serverId, serverUri, pskId, pskBuffer, pskLen, bootstrapRequested);
#else
objArray[0] = get_security_object(serverId, serverUri, pskId, pskBuffer, pskLen, false);
#endif
if (NULL == objArray[0])
{
fprintf(stderr, "Failed to create security object\r\n");
return -1;
}
data.securityObjP = objArray[0];
objArray[1] = get_server_object(serverId, "U", lifetime, false);
if (NULL == objArray[1])
{
fprintf(stderr, "Failed to create server object\r\n");
return -1;
}
objArray[2] = get_object_device();
if (NULL == objArray[2])
{
fprintf(stderr, "Failed to create Device object\r\n");
return -1;
}
/*
* The liblwm2m library is now initialized with the functions that will be in
* charge of communication
*/
lwm2mH = lwm2m_init(&data);
if (NULL == lwm2mH)
{
fprintf(stderr, "lwm2m_init() failed\r\n");
return -1;
}
#ifdef WITH_TINYDTLS
data.lwm2mH = lwm2mH;
#endif
/*
* We configure the liblwm2m library with the name of the client - which shall be unique for each client -
* the number of objects we will be passing through and the objects array
*/
result = lwm2m_configure(lwm2mH, name, NULL, NULL, OBJ_COUNT, objArray);
if (result != 0)
{
fprintf(stderr, "lwm2m_configure() failed: 0x%X\r\n", result);
return -1;
}
signal(SIGINT, handle_sigint);
/**
* Initialize value changed callback.
*/
init_value_change(lwm2mH);
fprintf(stdout, "LWM2M Client \"%s\" started on port %s\r\n", name, localPort);
fprintf(stdout, "> "); fflush(stdout);
/*
* We now enter in a while loop that will handle the communications from the server
*/
while (0 == g_quit)
{
struct timeval tv;
fd_set readfds;
if (g_reboot)
{
time_t tv_sec;
tv_sec = lwm2m_gettime();
if (0 == reboot_time)
{
reboot_time = tv_sec + 5;
}
if (reboot_time < tv_sec)
{
/*
* Message should normally be lost with reboot ...
*/
fprintf(stderr, "reboot time expired, rebooting ...");
system_reboot();
}
else
{
tv.tv_sec = reboot_time - tv_sec;
}
}
else if (batterylevelchanging)
{
update_battery_level(lwm2mH);
tv.tv_sec = 5;
}
else
{
tv.tv_sec = 60;
}
tv.tv_usec = 0;
FD_ZERO(&readfds);
FD_SET(data.sock, &readfds);
FD_SET(STDIN_FILENO, &readfds);
/*
* This function does two things:
* - first it does the work needed by liblwm2m (eg. (re)sending some packets).
* - Secondly it adjusts the timeout value (default 60s) depending on the state of the transaction
* (eg. retransmission) and the time between the next operation
*/
result = lwm2m_step(lwm2mH, &(tv.tv_sec));
fprintf(stdout, " -> State: ");
switch (lwm2mH->state)
{
case STATE_INITIAL:
fprintf(stdout, "STATE_INITIAL\r\n");
break;
case STATE_BOOTSTRAP_REQUIRED:
fprintf(stdout, "STATE_BOOTSTRAP_REQUIRED\r\n");
break;
case STATE_BOOTSTRAPPING:
fprintf(stdout, "STATE_BOOTSTRAPPING\r\n");
break;
case STATE_REGISTER_REQUIRED:
fprintf(stdout, "STATE_REGISTER_REQUIRED\r\n");
break;
case STATE_REGISTERING:
fprintf(stdout, "STATE_REGISTERING\r\n");
break;
case STATE_READY:
fprintf(stdout, "STATE_READY\r\n");
break;
default:
fprintf(stdout, "Unknown...\r\n");
break;
}
/*add by dsl 20230403 start*****************/
if(STATE_READY == lwm2mH->state)
{
fprintf(stdout, "LWM2M Client connected succeed!");
g_quit = 1;
break;
}
/*add by dsl 20230403 end***************************/
if (result != 0)
{
fprintf(stderr, "lwm2m_step() failed: 0x%X\r\n", result);
#ifdef LWM2M_BOOTSTRAP
if(previousState == STATE_BOOTSTRAPPING)
{
#ifdef LWM2M_WITH_LOGS
fprintf(stdout, "[BOOTSTRAP] restore security and server objects\r\n");
#endif
prv_restore_objects(lwm2mH);
lwm2mH->state = STATE_INITIAL;
} else
#endif
return -1;
}
#ifdef LWM2M_BOOTSTRAP
update_bootstrap_info(&previousState, lwm2mH);
#endif
/*
* This part will set up an interruption until an event happen on SDTIN or the socket until "tv" timed out (set
* with the precedent function)
*/
result = select(FD_SETSIZE, &readfds, NULL, NULL, &tv);
if (result < 0)
{
if (errno != EINTR)
{
fprintf(stderr, "Error in select(): %d %s\r\n", errno, strerror(errno));
}
}
else if (result > 0)
{
uint8_t buffer[MAX_PACKET_SIZE];
ssize_t numBytes;
/*
* If an event happens on the socket
*/
if (FD_ISSET(data.sock, &readfds))
{
struct sockaddr_storage addr;
socklen_t addrLen;
addrLen = sizeof(addr);
/*
* We retrieve the data received
*/
numBytes = recvfrom(data.sock, buffer, MAX_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrLen);
if (0 > numBytes)
{
fprintf(stderr, "Error in recvfrom(): %d %s\r\n", errno, strerror(errno));
}
else if (numBytes >= MAX_PACKET_SIZE)
{
fprintf(stderr, "Received packet >= MAX_PACKET_SIZE\r\n");
}
else if (0 < numBytes)
{
char s[INET6_ADDRSTRLEN];
in_port_t port;
#ifdef WITH_TINYDTLS
dtls_connection_t * connP;
#else
connection_t * connP;
#endif
if (AF_INET == addr.ss_family)
{
struct sockaddr_in *saddr = (struct sockaddr_in *)&addr;
inet_ntop(saddr->sin_family, &saddr->sin_addr, s, INET6_ADDRSTRLEN);
port = saddr->sin_port;
}
else if (AF_INET6 == addr.ss_family)
{
struct sockaddr_in6 *saddr = (struct sockaddr_in6 *)&addr;
inet_ntop(saddr->sin6_family, &saddr->sin6_addr, s, INET6_ADDRSTRLEN);
port = saddr->sin6_port;
}
fprintf(stderr, "%zd bytes received from [%s]:%hu\r\n", numBytes, s, ntohs(port));
/*
* Display it in the STDERR
*/
output_buffer(stderr, buffer, (size_t)numBytes, 0);
connP = connection_find(data.connList, &addr, addrLen);
if (connP != NULL)
{
/*
* Let liblwm2m respond to the query depending on the context
*/
#ifdef WITH_TINYDTLS
int result = connection_handle_packet(connP, buffer, numBytes);
if (0 != result)
{
printf("error handling message %d\n",result);
}
#else
lwm2m_handle_packet(lwm2mH, buffer, (size_t)numBytes, connP);
#endif
conn_s_updateRxStatistic(objArray[7], numBytes, false);
}
else
{
fprintf(stderr, "received bytes ignored!\r\n");
}
}
}
/*
* If the event happened on the SDTIN
*/
else if (FD_ISSET(STDIN_FILENO, &readfds))
{
numBytes = read(STDIN_FILENO, buffer, MAX_PACKET_SIZE - 1);
if (numBytes > 1)
{
buffer[numBytes] = 0;
/*
* We call the corresponding callback of the typed command passing it the buffer for further arguments
*/
handle_command(lwm2mH, commands, (char*)buffer);
}
if (g_quit == 0)
{
fprintf(stdout, "\r\n> ");
fflush(stdout);
}
else
{
fprintf(stdout, "\r\n");
}
}
}
}
/*
* Finally when the loop is left smoothly - asked by user in the command line interface - we unregister our client from it
*/
if (g_quit == 1)
{
#ifdef WITH_TINYDTLS
free(pskBuffer);
#endif
#ifdef LWM2M_BOOTSTRAP
close_backup_object();
#endif
lwm2m_close(lwm2mH);
}
close(data.sock);
connection_free(data.connList);
clean_security_object(objArray[0]);
lwm2m_free(objArray[0]);
clean_server_object(objArray[1]);
lwm2m_free(objArray[1]);
free_object_device(objArray[2]);
#ifdef MEMORY_TRACE
if (g_quit == 1)
{
trace_print(0, 1);
}
#endif
return 0;
}
int main()
{
int num = 0;
while(1)
{
main_lwm2m_open();
sleep(10);
fprintf(stdout, "\r\n> loop_num=%d", );
}
return 0;
} |
@FishPickBeans Do you have any new on that issue? I cannot reproduce it as you described it. Do you have a branch with your example that reliably reproduces your problem? |
Issue: lwm2mclient.c with dtls connect open and close for Loop, dtlsconnection.c‘s connection_find() function crash. when second loop.
Reason:
The text was updated successfully, but these errors were encountered: