Re: ftp -w is not dying

2018-09-27 Thread sven falempin
On Thu, Sep 27, 2018 at 11:59 AM sven falempin 
wrote:

>
>
> On Thu, Sep 27, 2018 at 10:47 AM sven falempin 
> wrote:
>
>> I m not sure how this is possible but here s the data :
>>
>> i used the ENV to push -w 5 in my pkg_add process :
>> # date
>> Thu Sep 27 10:40:28 EDT 2018
>> # ps auxww | grep pkgfet
>> _pkgfetc 60348 0.0 0.1 1728 5456 ?? INp Wed05PM 0:00.09 /usr/bin/ftp -w 5
>> -S session -o - https://
>> myportal.com/tar/6.3/packages/amd64/p5-LWP-MediaTypes-6.02.tgz
>> # fstat -p  60348
>> _pkgfetc ftp 60348 5* internet stream tcp 0x806e8548
>> 172.16.1.35:5512 --> 92.222.70.241:443
>>
>> I can see the PF state on the natting device:
>>
>> tcp 206.180.254.190:52251 (172.16.1.35:5512) -> 92.222.70.241:443
>> ESTABLISHED:ESTABLISHED
>> age: 16:55:28 expires: 07:07:25 id: 5b7ce30b0094854a
>> rule: pass out quick on em5 all flags S/SA label "READY_TO_NAT" tagged
>> READY_TO_NAT
>>
>> this is stock 6.3 ftp which is still the same now (
>> https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ftp/ )
>>
>> # ktrace -p 60348
>> generate an empty 64 bit file.
>>
>> Any other test i could do to understand ?
>>
>>
>
Reading NC it seems that the 'poll' syscall is indeed required to
timeout correctly.

I m trying to find a way to recreate the problem and i am running a
modified version in a loop

My understanding of the tls_read(SSL_read then ssl_read) .. is that the
retry is for SSL protocol error
and retry which would only occur on non TCP layer. That's  irrelevant in
fetch.c
I m just guessing the  ( at the top of ssl_read )
call will write and fix an POLLIN when write is done.
This explaining trying to read again when a write is requested >.<

Nevertheless each read/write code ( and even close ) shall be precede
by a poll call.

Bellow is the patch i m testing at the moment , i do not quite like it,
it s not solving the problem, and show how the factorization of read is
making the code hard to read/modify
IMHO url_get should be just calling

url_get_https
url_get_http
url_get_ftp

and each of this function do only that. The _fin_ FILE* may be NULL
fd may be -1 randomly in the function, it s kinda messy.
And this make it difficult to nicely call poll before reading
to avoid being blocked in a read indefinitely

RCS file: /cvs/src/usr.bin/ftp/fetch.c,v
retrieving revision 1.167
diff -u -p -r1.167 fetch.c
--- fetch.c 10 Feb 2018 06:25:16 -  1.167
+++ fetch.c 27 Sep 2018 20:10:52 -
@@ -59,6 +59,7 @@
 #include 

 #ifndef NOSSL
+#include 
 #include 
 #else /* !NOSSL */
 struct tls;
@@ -73,12 +74,12 @@ voidabortfile(int);
 char   hextochar(const char *);
 char   *urldecode(const char *);
 char   *recode_credentials(const char *_userinfo);
-intftp_printf(FILE *, struct tls *, const char *, ...)
__attribute__((format(printf, 3, 4)));
+intftp_printf(FILE *, int fd, struct tls *, const char *, ...)
__attribute__((format(printf, 4, 5)));
 char   *ftp_readline(FILE *, struct tls *, size_t *);
 size_t ftp_read(FILE *, struct tls *, char *, size_t);
 #ifndef NOSSL
 intproxy_connect(int, char *, char *);
-intSSL_vprintf(struct tls *, const char *, va_list);
+intSSL_vprintf(int fd, struct tls *, const char *, va_list);
 char   *SSL_readline(struct tls *, size_t *);
 #endif /* !NOSSL */

@@ -98,6 +99,90 @@ jmp_buf  httpabort;

 static int redirect_loop;

+#ifndef NOSSL
+/*from netcat.c correct way to timeout a tls_call*/
+int
+timeout_tls(int s, struct tls *tls_ctx, int (*func)(struct tls *))
+{
+   int timeout = connect_timeout; // glu
+   struct pollfd pfd;
+   int ret;
+
+   while ((ret = (*func)(tls_ctx)) != 0) {
+   if (ret == TLS_WANT_POLLIN)
+   pfd.events = POLLIN;
+   else if (ret == TLS_WANT_POLLOUT)
+   pfd.events = POLLOUT;
+   else
+   break;
+   pfd.fd = s;
+   if ((ret = poll(, 1, timeout)) == 1)
+   continue;
+   else if (ret == 0) {
+   errno = ETIMEDOUT;
+   ret = -1;
+   break;
+   } else
+   err(1, "poll failed");
+   }
+
+   return ret;
+}
+
+/*must realloc / offset*/
+int
+timeout_tls_write(int s, struct tls *tls_ctx,
+   const void *buf, size_t buflen)
+{
+   int timeout = connect_timeout; // glu
+   struct pollfd pfd;
+   int ret;
+
+   // should check ready first => do poll write then write
+   while ((ret = tls_write(tls_ctx,buf,buflen)) != 0) {
+   if (ret == TLS_WANT_POLLIN)
+   pfd.events = POLLIN;
+   else if (ret == TLS_WANT_POLLOUT)
+   pfd.events = POLLOUT;
+   else
+   break;
+   pfd.fd = s;
+   if ((ret = 

Re: ftp -w is not dying

2018-09-27 Thread sven falempin
On Thu, Sep 27, 2018 at 10:47 AM sven falempin 
wrote:

> I m not sure how this is possible but here s the data :
>
> i used the ENV to push -w 5 in my pkg_add process :
> # date
> Thu Sep 27 10:40:28 EDT 2018
> # ps auxww | grep pkgfet
> _pkgfetc 60348 0.0 0.1 1728 5456 ?? INp Wed05PM 0:00.09 /usr/bin/ftp -w 5
> -S session -o - https://
> myportal.com/tar/6.3/packages/amd64/p5-LWP-MediaTypes-6.02.tgz
> # fstat -p  60348
> _pkgfetc ftp 60348 5* internet stream tcp 0x806e8548
> 172.16.1.35:5512 --> 92.222.70.241:443
>
> I can see the PF state on the natting device:
>
> tcp 206.180.254.190:52251 (172.16.1.35:5512) -> 92.222.70.241:443
> ESTABLISHED:ESTABLISHED
> age: 16:55:28 expires: 07:07:25 id: 5b7ce30b0094854a
> rule: pass out quick on em5 all flags S/SA label "READY_TO_NAT" tagged
> READY_TO_NAT
>
> this is stock 6.3 ftp which is still the same now (
> https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ftp/ )
>
> # ktrace -p 60348
> generate an empty 64 bit file.
>
> Any other test i could do to understand ?
>
>

My understanding of the code is that the -w cannot work .
I have been using a lot of socket and c code, and
always ended using non blocking fd because : life

the code is not using non blocking fd , and rely on the POLLIN of tls in a
strange way

The syscall in fetch.c are ( geee the get_url is crazy long and full o
ifdef :s )

error = getaddrinfo(host, port, , );
fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);

(void)signal(SIGALRM, tooslow);
alarmtimer(connect_timeout);

connect ( and tls_init and stuff

and then

directly tls_read like that :

do {
  tret = tls_read(tls, buf, len);
} while (tret == TLS_WANT_POLLIN || tret == TLS_WANT_POLLOUT);

i did not code much with tls_read
but calling tls_read on TLS_WANT_POLLOUT

seems
far FETCH

Cheers.

-- 
--
-
Knowing is not enough; we must apply. Willing is not enough; we must do


ftp -w is not dying

2018-09-27 Thread sven falempin
I m not sure how this is possible but here s the data :

i used the ENV to push -w 5 in my pkg_add process :
# date
Thu Sep 27 10:40:28 EDT 2018
# ps auxww | grep pkgfet
_pkgfetc 60348 0.0 0.1 1728 5456 ?? INp Wed05PM 0:00.09 /usr/bin/ftp -w 5
-S session -o - https://
myportal.com/tar/6.3/packages/amd64/p5-LWP-MediaTypes-6.02.tgz
# fstat -p  60348
_pkgfetc ftp 60348 5* internet stream tcp 0x806e8548
172.16.1.35:5512 --> 92.222.70.241:443

I can see the PF state on the natting device:

tcp 206.180.254.190:52251 (172.16.1.35:5512) -> 92.222.70.241:443
ESTABLISHED:ESTABLISHED
age: 16:55:28 expires: 07:07:25 id: 5b7ce30b0094854a
rule: pass out quick on em5 all flags S/SA label "READY_TO_NAT" tagged
READY_TO_NAT

this is stock 6.3 ftp which is still the same now (
https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ftp/ )

# ktrace -p 60348
generate an empty 64 bit file.

Any other test i could do to understand ?

--
-
Knowing is not enough; we must apply. Willing is not enough; we must do