- tv.tv_sec = TFTP_TIMEOUT;
- tv.tv_usec = 0;
-
- FD_ZERO(&rfds);
- FD_SET(socketfd, &rfds);
-
- switch (select(socketfd + 1, &rfds, NULL, NULL, &tv)) {
- struct sockaddr *from;
- socklen_t fromlen;
-
- case 1:
- fromlen = peer_lsa->len;
- from = alloca(fromlen);
- memset(from, 0, fromlen);
-
- len = recvfrom(socketfd, rbuf, tftp_bufsize, 0,
- from, &fromlen);
- if (len < 0) {
- bb_perror_msg("recvfrom");
- break;
- }
-#if ENABLE_FEATURE_IPV6
- if (from->sa_family == AF_INET6)
- if (((struct sockaddr_in6*)from)->sin6_port != port)
- goto recv_again;
-#endif
- if (from->sa_family == AF_INET)
- if (((struct sockaddr_in*)from)->sin_port != port)
- goto recv_again;
- timeout = 0;
- break;
- case 0:
+ /* Receive packet */
+ /*pfd[0].fd = socketfd;*/
+ pfd[0].events = POLLIN;
+ switch (safe_poll(pfd, 1, waittime_ms)) {
+ unsigned from_port;
+ case 1:
+ from->len = peer_lsa->len;
+ memset(&from->sa, 0, peer_lsa->len);
+ len = recvfrom(socketfd, rbuf, tftp_bufsize, 0,
+ &from->sa, &from->len);
+ if (len < 0) {
+ bb_perror_msg("recvfrom");
+ goto ret;
+ }
+ from_port = get_nport(&from->sa);
+ if (port == org_port) {
+ /* Our first query went to port 69
+ * but reply will come from different one.
+ * Remember and use this new port */
+ port = from_port;
+ set_nport(peer_lsa, from_port);
+ }
+ if (port != from_port)
+ goto recv_again;
+ goto process_pkt;
+ case 0:
+ retries--;
+ if (retries == 0) {