Commit 5d97f4fb7b4c58df7d4170a56d89cf2b4a649c7d

Authored by perry.werneck@gmail.com
1 parent 08be26b2

Incluindo timeout de 2 minutos ao tentar conectar com o host para prevenir travamentos

Showing 1 changed file with 70 additions and 0 deletions   Show diff stats
src/lib3270/telnet.c
... ... @@ -374,12 +374,82 @@ struct connect_parm
374 374  
375 375 static int do_connect_sock(H3270 *h, struct connect_parm *p)
376 376 {
  377 +#ifdef WIN32
377 378  
378 379 if(connect(p->sockfd, p->addr, p->addrlen) == -1)
379 380 p->err = socket_errno();
380 381 else
381 382 p->err = 0;
382 383  
  384 +#else
  385 +
  386 + // Linux, use 120 seconds timeout
  387 + fcntl(p->sockfd, F_SETFL,fcntl(p->sockfd,F_GETFL,0)|O_NONBLOCK);
  388 +
  389 + errno = 0;
  390 + if(connect(p->sockfd, p->addr, p->addrlen))
  391 + {
  392 + if( errno != EINPROGRESS )
  393 + {
  394 + p->err = errno;
  395 + lib3270_write_log(h,"lib3270","Error %s on connect",strerror(errno));
  396 + }
  397 + else
  398 + {
  399 + // Connection in progress, wait
  400 + fd_set wr;
  401 + struct timeval tm;
  402 + int err;
  403 + socklen_t len = sizeof(err);
  404 +
  405 + FD_ZERO(&wr);
  406 + FD_SET(p->sockfd, &wr);
  407 + memset(&tm,0,sizeof(tm));
  408 +
  409 + tm.tv_sec = 120; // 2 minutes timeout
  410 +
  411 + switch(select(p->sockfd+1, NULL, &wr, NULL, &tm))
  412 + {
  413 + case 0:
  414 + lib3270_write_log(h,"lib3270","Connect timeout");
  415 + p->err = ETIMEDOUT;
  416 + break;
  417 +
  418 + case -1:
  419 + lib3270_write_log(h,"lib3270","Select error \"%s while connecting",strerror(errno));
  420 + p->err = errno;
  421 + break;
  422 +
  423 + default:
  424 +
  425 + // Se o socket nao esta disponivel para gravacao o connect falhou
  426 + if(!FD_ISSET(p->sockfd,&wr))
  427 + {
  428 + lib3270_write_log(h,"lib3270","Unexpected connection failure, the socket wasn't ready to write");
  429 + p->err = ENOTCONN;
  430 + }
  431 + else if(getsockopt(p->sockfd, SOL_SOCKET, SO_ERROR, &err, &len) < 0)
  432 + {
  433 + lib3270_write_log(h,"lib3270","Connect error. Error \"%s\" when getting socket state",strerror(errno));
  434 + p->err = ENOTCONN;
  435 + }
  436 + else if(err)
  437 + {
  438 + lib3270_write_log(h,"lib3270","Connection error \"%s\"",strerror(err));
  439 + p->err = err;
  440 + }
  441 + else
  442 + {
  443 + lib3270_write_log(h,"lib3270","Connected to host");
  444 + p->err = 0;
  445 + }
  446 + }
  447 + }
  448 + }
  449 +
  450 + fcntl(p->sockfd, F_SETFL,fcntl(p->sockfd,F_GETFL,0)&(~O_NONBLOCK));
  451 +#endif // WIN32
  452 +
383 453 return 0;
384 454 }
385 455  
... ...