cURL / Mailing Lists / curl-library / Single Mail

curl-library

multi_perform blocks and never returns when built with schannel WinIDN

From: Pär Björklund <per.bjorklund_at_gmail.com>
Date: Sun, 31 May 2015 13:10:44 +0200

We're seeing an issue in Kodi after updating libcurl to 7.40.0 built with
schannel + WinIDN and USE_SYNC_DNS set.
I've also tested this with libcurl 7.42.1.

Set set up the socket as follows
easy_setopt(h, CURLOPT_WRITEDATA, state);
easy_setopt(h, CURLOPT_WRITEFUNCTION, write_callback);
easy_setopt(h, CURLOPT_READDATA, state);
easy_setopt(h, CURLOPT_READFUNCTION, read_callback);
easy_setopt(h, CURLOPT_WRITEHEADER, state);
easy_setopt(h, CURLOPT_HEADERFUNCTION, header_callback);
easy_setopt(h, CURLOPT_HEADER, FALSE);
easy_setopt(h, CURLOPT_FOLLOWLOCATION, TRUE);
easy_setopt(h, CURLOPT_MAXREDIRS, 5);
easy_setopt(h, CURLOPT_NOSIGNAL, TRUE);
easy_setopt(h, CURLOPT_FAILONERROR, 1);
easy_setopt(h, CURLOPT_SSL_VERIFYPEER, 0);
easy_setopt(h, CURLOPT_SSL_VERIFYHOST, 0);
easy_setopt(h, CURLOPT_TRANSFERTEXT, FALSE);
easy_setopt(h, CURLOPT_CONNECTTIMEOUT, 10);
easy_setopt(h, CURLOPT_LOW_SPEED_LIMIT, 1);
easy_setopt(h, CURLOPT_LOW_SPEED_TIME, 20);

I've used this url for testing but it happens with many or most in my
testing.
Sorry about the giant url.

https://r1---sn-uxaxovg-5gol.googlevideo.com/videoplayback?id=o-AEZ5jv
TJ5SZq56g8wjQjxZ_0xUZ2RQv949wY8OkBYopa&fexp=9406983%2C9408142
%2C9408420%2C9408710%2C9413503%2C9415304%2C952612%2C952641
&signature=891DA4619664947F7615F137ED72A99FC7E09BF7.8B830E99AD9
A3BF894B3A81701462B5F5CFA3B55&pcm2cms=yes&ms=au&mt=14330682
32&upn=_9M69B_4Fa4&mv=m&dur=568.238&pl=20&expire=1433089894&
mm=31&ip=85.230.189.157&ratebypass=yes&sver=3&requiressl=yes&sour
ce=youtube&initcwndbps=2540000&ipbits=0&itag=22&key=yt5&mime=vid
eo%2Fmp4&sparams=dur%2Cid%2Cinitcwndbps%2Cip%2Cipbits%2Citag%2
Cmime%2Cmm%2Cms%2Cmv%2Cpcm2cms%2Cpl%2Cratebypass%2Crequir
essl%2Csource%2Cupn%2Cexpire

When we call multi_perform on this it starts reading and it calls our
write_callback
As it should but it never actually returns control back to us. It doesn't
even call
The progress callback if it's set because it's stuck in an inner loop.

Callstack is as follows
Kodi.exe!write_callback(char * buffer, unsigned int size, unsigned int
nitems, void * userp) Line 108 C++
libcurl.dll!Curl_client_chop_write(connectdata * conn, int type, char * ptr,
unsigned int len) Line 434 C
libcurl.dll!readwrite_data(SessionHandle * data, connectdata * conn,
SingleRequest * k, int * didwhat, bool * done) Line 742 C
libcurl.dll!Curl_readwrite(connectdata * conn, bool * done) Line 1064 C
libcurl.dll!multi_runsingle(Curl_multi * multi, timeval now, SessionHandle *
data) Line 1512 C
libcurl.dll!curl_multi_perform(void * multi_handle, int * running_handles)
Line 1791 C
Kodi.exe!XCURL::DllLibCurl::multi_perform(void * p1, int * p2) Line 75 C++

I've narrowed it down to the loop in in readwrite_data, data_pending is
always returning
true because there is more data pending but it means that we can't abort the
transfer say
with CURLE_ABORTED_BY_CALLBACK as the callback is never called.

I've also tried to break the loop by return bogus values from the
write_callback to try and pause
the transfer but it didn't make any difference for some reason(I did test
several times but maybe
I did something wrong there).

Rebuilding libcurl with openssl 1.0.2a instead of schannel makes it behave
as normal, not blocking in
multi_perform.

Testing is done on Windows 8.1 and Windows Server 2012R2 with latest patches
installed.

Let me know if there's any details I've left out that may be of help

Regards
Pär Björklund

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2015-05-31