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 =