OPT_CONNECT_TIMEOUT not working as expected?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

OPT_CONNECT_TIMEOUT not working as expected?

Jump to solution
2,541 Views
CarlFST60L
Senior Contributor II

Hi,

I have played with this for a little while and been unable to resolve my issue.

Firstly, I am running MQX3.7 on the 52259evb.

My software is all fine and works as well as it can with the exception of OPT_CONNECT_TIMEOUT.

All I want to happen is connect() to return after 1 second if it fails to connect, but its always a couple of minutes which is way to long for our application.

I simply have the MQX RTCS connecting to my linux box or cygwin terminal. It Accepts connections using netcat listen on port 23 (nc -l 23) which works exactly as expected every time.

I have another UDP socket which is connected using similar methods and 100% works. this UDP issues commands such as RC:192.168.1.10:23 (Remote Connect to IP on port). This all works 100%. If my linux box is not listening, or, I try to connect to an unknown network like RC:199.199.199.199:10000 it just stays in 'connect()' for a couple of minutes regardless of what value I put in OPT_CONNECT_TIMEOUT.

Is my understanding of this wrong? Is this timer related to TCP packet time-outs? or some other timeout??

Here is a code snippet: (note there is some other code and messy debug info as I am just testing, the values of RC are global so they are not shown in the decleration)

//------------------------------------------------------

//This thread is called after another thread already has a UDP session attached and connected to my server which is where the RC: command comes from

void ETHRC_Task(uint_32)

{

  sockaddr_in remote_sin;

  uint_16     remote_len = sizeof(remote_sin);

  uint_32     count;

  uint_32 error;

  uint_32 i = 0;

  sockaddr_in local_sin; //Local address

  uint_32 sock = 0;

  int option = 0;

  local_sin.sin_family      = AF_INET;

  local_sin.sin_port        = ETHRC_HOST_PORT; //Get the port

  local_sin.sin_addr.s_addr = INADDR_ANY;

  // Create a datagram socket:

  sock = socket(PF_INET, SOCK_STREAM, 0);

  if (sock == RTCS_SOCKET_ERROR)

  {

  Write_Log((uchar*)STR_ERROR_CODE, ETH_SOCKET_CREATION_FAILED, 3, 0);

  (uint_32)shutdown(sock, SOCKET_SHUT_PARAM);

  _task_abort(MQX_NULL_TASK_ID);

  }

  printf("\nSocket configured\n");

  i = sizeof(int);

  option = TRUE; //Dont wait for data to come, just poll it

  error = setsockopt(sock, SOL_TCP, OPT_RECEIVE_NOWAIT, &option, sizeof(option));

  if(error != RTCS_OK) printf("Cannot set OPT_RECEIVE_NOWAIT %x\n", error);

  error = getsockopt(sock, SOL_TCP, OPT_RECEIVE_NOWAIT, &option, (uint_32_ptr *)&i);

  if(error != RTCS_OK) printf("getsockopt(OPT_RECEIEVE_NOWAIT) failed with error %x\n", error);

  else printf("getsockopt OPT_RECEIEVE_NOWAIT = %X\n", option);

   option = 1000; //5 second timeout on connections

  error = setsockopt(sock, SOL_TCP, OPT_CONNECT_TIMEOUT, &option, sizeof(option));

  if(error != RTCS_OK) printf("Cannot set OPT_CONNECT_TIMEOUT %x\n", error);

  error = getsockopt(sock, SOL_TCP, OPT_CONNECT_TIMEOUT, &option, (uint_32_ptr *)&i);

  if(error != RTCS_OK) printf("getsockopt(OPT_CONNECT_TIMEOUT) failed with error %x\n", error);

  else printf("getsockopt OPT_CONNECT_TIMEOUT = %X\n", option);

  // Bind the datagram socket to the UDP port:

  error = bind(sock, &local_sin, sizeof(local_sin));

  if (error != RTCS_OK) {

  // ***FIX, log and restart task or manage proerly

  //if(LiveLogDisplayLevel >= 4) printf("Bind fail\n");

  Write_Log((uchar*)STR_ERROR_CODE, ETH_BIND_FAILED, 3, 0);

  (uint_32)shutdown(sock, SOCKET_SHUT_PARAM);

  _task_abort(MQX_NULL_TASK_ID);

  }

  printf("Socket Bind complete\n");

  memset((char *) &remote_sin, 0, sizeof(sockaddr_in));

  remote_sin.sin_family = AF_INET;

  remote_sin.sin_port = ETHRC_HOST_PORT; //Port (same as local outgoing port)

  remote_sin.sin_addr.s_addr = ETHRC_HOST_IP; //Server address

  error = connect(sock, &remote_sin, sizeof(sockaddr_in));

  if (error != RTCS_OK)

  {

  Write_Log((uchar*)STR_ERROR_CODE, ETH_REBIND_FAIL1, 3, 0);

  (uint_32)shutdown(sock, SOCKET_SHUT_PARAM);

  _task_abort(MQX_NULL_TASK_ID);

  }

  printf("Socket connected\n");

//------------------------------------------------------

1 Solution
1,261 Views
DavidS
NXP Employee
NXP Employee

Hi Carl,

Did you resolve this?

If not just tossing out random thoughts.

- Do you have KEEPALIVE active?

- I see other timeouts in the tcp.c file (part of TCP_Process_open() ) and wonder if they might be causing trouble at the tcb level?.

/* User timeout (R1) */

if ( coptions->utimeout >= 0 ) {

tcb->

sndto_1 = coptions->utimeout;

}

else {

tcb->

sndto_1 = 0;

}

/* Endif */

/* Connection timeout (R2) */

if ( coptions->timeout > 0 ) {

tcb->

sndto_2 = coptions->timeout;

}

else {

tcb->

sndto_2 = 2 * tcb->sndrtomax;

}

/* Endif */

.

.

.

/* Keepalive timeout */

if ( coptions->keepalive

> 0 ) {

tcb->

keepaliveto = coptions->keepalive

* 60000L;

}

else

{

tcb->

keepaliveto

= 0;

}

/* Endif */

The tcp.h has:

int_32 utimeout;

/* User timeout (msec) - TCP R1 period */

int_32 timeout; /* Connection timeout (msec) - TCP R2 period (use 0 to default) */

Comments in tcp.c:

/* Soft timeout (R1) must occur *before* hard timeout (R2) (see RFC1122

** section 4.2.3.5 for more details on these timeouts) */

The code here adjust the R1 to meet the above requirement.

Regards,

David

View solution in original post

0 Kudos
Reply
8 Replies
1,261 Views
everkimage
Contributor IV

The code here adjust the R1 to meet the above requirement.

how can i modify the value of R1???

0 Kudos
Reply
1,261 Views
Martin_
NXP Employee
NXP Employee

R1 corresponds with stream socket option OPT_SEND_TIMEOUT. You can use setsockopt() to modify this.

0 Kudos
Reply
1,261 Views
everkimage
Contributor IV

it's still not work.and this is my code :

i = 1;

i = setsockopt( sock, SOL_TCP, OPT_KEEPALIVE, &i, sizeof( i ) );

   

i = TCP_CONNECT_TIMEOUT / 2;

i = setsockopt( sock, SOL_TCP, OPT_SEND_TIMEOUT, &i, sizeof( i ) );

   

i = TCP_CONNECT_TIMEOUT;

i = setsockopt( sock, SOL_TCP, OPT_CONNECT_TIMEOUT, &i, sizeof( i ) );

0 Kudos
Reply
1,261 Views
everkimage
Contributor IV

I try to change the value of DEFAULT_CONNECT_TIMEOUT,and rebuild the all projects,but it still does not work!

when i shutdown the server program,connect() returns in several seconds.

but when i disconnect the cable,it always wait for a long time.

God,help me!:smileycry:

0 Kudos
Reply
1,261 Views
everkimage
Contributor IV

TCP_SENDTIMEOUT_MIN ok.

0 Kudos
Reply
1,261 Views
CarlFST60L
Senior Contributor II

For some reason this forum wont let you edit the first post? weird...

Anyway, here is the consol output:

RC:192.168.2.20:10000 (this is nothing on my network or subnet)

Socket configured

getsockopt OPT_RECEIEVE_NOWAIT = 1

getsockopt OPT_CONNECT_TIMEOUT = 3E8

Socket Bind complete

ERROR CODE > 147 (2 minutes or so later, this is the error code on connect())

We have also notice this commend:

"Values ≥ 180,000 (RTCS maintains the connection for this number of milliseconds)."

So how do I stop RTCS maintaining the connection? I assume this is the problem...

0 Kudos
Reply
1,261 Views
ARQuattr
Contributor IV

Hi Carl, were you able to resolve this so that it times-out if it doesn't connect in 1s?  How was it done?

Thanks

0 Kudos
Reply
1,262 Views
DavidS
NXP Employee
NXP Employee

Hi Carl,

Did you resolve this?

If not just tossing out random thoughts.

- Do you have KEEPALIVE active?

- I see other timeouts in the tcp.c file (part of TCP_Process_open() ) and wonder if they might be causing trouble at the tcb level?.

/* User timeout (R1) */

if ( coptions->utimeout >= 0 ) {

tcb->

sndto_1 = coptions->utimeout;

}

else {

tcb->

sndto_1 = 0;

}

/* Endif */

/* Connection timeout (R2) */

if ( coptions->timeout > 0 ) {

tcb->

sndto_2 = coptions->timeout;

}

else {

tcb->

sndto_2 = 2 * tcb->sndrtomax;

}

/* Endif */

.

.

.

/* Keepalive timeout */

if ( coptions->keepalive

> 0 ) {

tcb->

keepaliveto = coptions->keepalive

* 60000L;

}

else

{

tcb->

keepaliveto

= 0;

}

/* Endif */

The tcp.h has:

int_32 utimeout;

/* User timeout (msec) - TCP R1 period */

int_32 timeout; /* Connection timeout (msec) - TCP R2 period (use 0 to default) */

Comments in tcp.c:

/* Soft timeout (R1) must occur *before* hard timeout (R2) (see RFC1122

** section 4.2.3.5 for more details on these timeouts) */

The code here adjust the R1 to meet the above requirement.

Regards,

David

0 Kudos
Reply