LCF-AT

WinSock problem

36 posts in this topic

Hi guys,

today I have some questions about a problem I have using WinSock APIs and maybe you could help to find & fix the problem reason.

So before a while I coded a tool to check many diffrent internet links from same server only with sending a HEAD requests and checking the status value of response.All was working so far without problems.Now I changed my internet provider to get a better internet connection / speed etc and I also have a new device / router I do use for this and with that I get always this problem.On the first view all is working as before too but with the diffrent that after I did send some requests (30 - 50) it stops for some seconds and then it works go on for next 5 - 10 requests and stops again and so go on.At the end if I have bad luck I get a error message from connect API (10060  Connection timed out).Now the question is why I get this error after sending some requests?This didnt happend before and why does it always make some breaks between some requests so this also didnt happend before too.What could be the reason for this problem?Now I also tried to add any timeout value for connect API and used setsockopt API with SO_RCVTIMEO and timeout of 1 - 3 seconds but it dosent work for connect API and it hangs so long in this API till it comes back with success or error.Is there a way to set timeout for connect API to prevent hanging inisde this API a too long time?

- New device I use (Has also IPv6 and any moddern stuff etc)

- New Internet Provider

- Old Lan Cable?

Could the Lan cable I do use be the problem maybe?So as I said I still use my old cable which is 10 years old and I also dont get 100 % speed (mbps) so I get 30 % less speed with using my old cable.If I use the short cable which was send to me on laptop then I also get 100 % speed but could this also be the problem reason for the send request issue I told above?I am not sure.Maybe anyone of you has any ideas what the problem could be and how to fix it.

Thank you

Share this post


Link to post
Share on other sites

Hi again,

so I still cant set any timeout for connect API.

Example: If I call google.com with any port value like google.com:20 then my code hangs into connect API for more than 10 - 20 seconds before I get the error message 10060.If I enter same address & port into browser FF then I get straight a message about pot blocked etc so its maybe done by FF itself so I think.If I use port 39 then FF does also use a long time before I get error info etc.So what I want is to find any API / code / Example just to set a timeout for the connect API to prevent that it keep a long time into this API before it comes back.Lets say I wanna just set a timeout of 3 seconds so is it doable or not and if yes what I have to do?

Thank you

Share this post


Link to post
Share on other sites

If i understand you correctly

Your get this error 10060 ( ) after 10-20 sec if not connect to this site?

And you wish close this socked in 3 sec?

 

What use you WinInet or WinSock?

 

Quote

int select(
  _In_    int                  nfds,
  _Inout_ fd_set               *readfds,
  _Inout_ fd_set               *writefds,
  _Inout_ fd_set               *exceptfds,
  _In_    const struct timeval *timeout //  The maximum time for select to wait, provided in the form of a TIMEVAL structure. Set the timeout parameter to null for blocking operations. 
);

https://msdn.microsoft.com/en-us/library/windows/desktop/ms740141(v=vs.85).aspx

Share this post


Link to post
Share on other sites

Hi raggy,

I use Winsock in that case.Yes,if I call any site in a loop then I get this problem that it hangs inside of connect API for more or less time and this I wanna prevent with any timeout for connect API so that it will only check max 3 seconds only or less so it should not keep inside so long (10+ sec) etc.So thats the problem I got with my new ISP or new device I use so before with my old ISP / device everything was working ok.

So the whole time I checked already the internet to find any infos and code examples to set any timeout for connect API and the only stuff I find is to use ioctlsocket API to enable nonblocking mode and then you get the error WSAEWOULDBLOCK after connect API and then you need to call select API with FDSET struct & timeout and if you get as reutun no SOCKET_ERROR and not 0 = succes .....but then I get unblock error from recv API.Something dosent work in that case or maybe I did anything wrong.

I made a short video where you can see how I get this error with my test app using my normal winsock connect code.Maybe you have any idea what I could do to fix this error & breaking problems.If you need test app / code then tell me.

WinSock 10060 Problem.rar

Thanks

Share this post


Link to post
Share on other sites

Hi and thanks for a answer.I tried setsockopt already before and you only can set a timeout ( SO_RCVTIMEO ) for recv calls. :( I found also some infos about connect API and that its used a default timeout set by Windows (normaly you cant change it by API) and that you can edit this anyhow in registry but I dont wanna use or try this method.Would be better to find any code solution for this problem.

greetz

Share this post


Link to post
Share on other sites

Hi again,

this I found too before and tried it but also without succes so I got after this error on recv API about blocking.

Question about this small code example.

&iMode = Pointer address to ASCII string 1 right?Like addr chr$("1")

What about this...

    fd_set Write, Err;
    FD_ZERO(&Write);
    FD_ZERO(&Err);
    FD_SET(sock, &Write);
    FD_SET(sock, &Err);
 
    // check if the socket is ready
    select(0,NULL,&Write,&Err,&Timeout);			
    if(FD_ISSET(sock, &Write)) 

FD_ZERO?Only have FD_SET struct.What about FD_ISSET?Maybe you can explain this part what to use & fill correctly for ASM.

fd_set STRUCT
  fd_count  DWORD      ?
  fd_array  SOCKET FD_SETSIZE dup(?)
fd_set ENDS

So in fd_count I have to copy the socket value right?Dont know what to enter into array.Do you have maybe a example file of this small code or maybe you can compile this small code part to exe file which I could debug in Olly to see how to use it right. :)

One info: On Net I found a tool called etoolz what has a HTTP Header option to check links too etc and there you can also set a timeout in the settings and it works there but it used WinInet functions like explorer (have read this in description) and not WInsock. :(

greetz

Share this post


Link to post
Share on other sites

fd_set Write, Err;

makes 2 structs, called Write and Err

the & is a pointer to them

FD_ZERO etc i suspect are macros that populate the structs

https://msdn.microsoft.com/en-us/library/windows/desktop/ms740142(v=vs.85).aspx

yep, macros

#define FD_SETSIZE 64

#define FD_CLR(fd, set)      __WS_FD_CLR((fd),(set), fd_set)
#define FD_SET(fd, set)      __WS_FD_SET((fd),(set), fd_set)
#define FD_ZERO(set)         (((fd_set*)(set))->fd_count=0)
#define FD_ISSET(fd, set)    __WSAFDIsSet((SOCKET)(fd), (fd_set*)(set))

so asm wise.

so FD_SET would add a socket to the array in fd_set struct

FD_ZERO sets the fd_count part of the array to zero

.fd_set Write, Err;
    FD_ZERO(&Write);
    FD_ZERO(&Err);
    FD_SET(sock, &Write);
    FD_SET(sock, &Err);
 

would then be
Write fd_set<>

Err fd_set<>

FD_ZERO(&Write) becomes mov [Write.fd_set.fd_count], 0

FD_ZERO(&Err) becomes mov [Err.fd_set.fd_count], 0

FD_SET(sock, &write)

would be similar to mov [Write.fd_set.fd_array[0]], sock

and incrementing the fd_count part presumably

hope that helps :) basically its just manipulating a struct
 

 

1 person likes this

Share this post


Link to post
Share on other sites

Hi and thanks again but still have some problems and dont get it work.

local   Write:fd_set
local   Err:fd_set
local   tv:timeval


......
invoke ioctlsocket,s,FIONBIO, chr$("1")

invoke  connect, s, addr peer, sizeof peer

invoke ioctlsocket,s,FIONBIO, chr$("0")

mov [Write.fd_set.fd_count], 0
mov [Err.fd_set.fd_count], 0
mov eax, s
mov [Write.fd_set.fd_array[0]], eax
mov tv.tv_sec,3
mov tv.tv_usec,0

invoke select,0,NULL,addr Write,addr Err,addr tv

I get now Error: 10057 from send API but the strange thing is if I debug the file in Olly and set soft bp at connect API and after this API then send & recv works!?Why this?If I remove bps and start again then I get error again.Whats this again for a BS?Uhhhmmmm!If I set a sleep time of 200ms before send API then it works for a while before I get again this error and checking does stop but I dont wanna use any sleep API.So what now?

greetz

Share this post


Link to post
Share on other sites

local   Write:fd_set
local   Err:fd_set
local   tv:timeval

local value1text:BYTE

local value0text:BYTE

mov [value1text], '1' ; im assuming its 1 textual and not 01h...

mov [value0text], '0' ; again...

 

lea eax, value1text
......
invoke ioctlsocket,s,FIONBIO, eax

invoke  connect, s, addr peer, sizeof peer

lea eax, value0text

invoke ioctlsocket,s,FIONBIO, eax

mov [Write.fd_set.fd_count], 0
mov [Err.fd_set.fd_count], 0
mov eax, s
mov [Write.fd_set.fd_array[0]], eax
mov tv.tv_sec,3
mov tv.tv_usec,0

you forgot to update write count

mov [Write.fd_set.fd_count], 1 ;

invoke select,0,NULL,addr Write,addr Err,addr tv

the '1' and '0' part might need to be null terminated strings, its been a while since i worked with winsock

also, you might want to make sure your structs and other local stuff are clean... otherwise , because they're on stack they'll contain random(ish) crap

Edited by evlncrn8
1 person likes this

Share this post


Link to post
Share on other sites

Hi again and thanks so far.So yesterday I tried it and found out that its normal to get this error message from Send API WSAENOTCONN if the connect API could not make a connection in time X and does aboard then. :)

Also it seems I have to use no strings for ioctlsocket for cmd parameter so here I use just 1h & 0h pointer addresses so with strings pointers it does fail.I got it so now...

.data
sockopt1 dword 1 
sockopt0 dword 0


invoke ioctlsocket,s,FIONBIO, addr sockopt1
invoke  connect, s, addr peer, sizeof peer
invoke ioctlsocket,s,FIONBIO, addr sockopt0

mov [Write.fd_set.fd_count], 1
mov [Err.fd_set.fd_count], 0
mov eax, s
mov [Write.fd_set.fd_array[0]], eax
mov tv.tv_sec,3
mov tv.tv_usec,0 

invoke select,0,NULL,addr Write,addr Err,addr tv

........
invoke  send, s, esi, ebx, 0
.if eax == SOCKET_ERROR
    invoke WSAGetLastError
    .if eax == WSAENOTCONN
        jmp CHECK_NEXT

Timeout does work now and just used the set time limit I did set and does aboard then = WSAEWOULDBLOCK after connect API.Just need to check the error now on connect or send API etc but all in all it works now as I wanted to use any working timeout for connect API and to prevent long waiting in that API.:)

Thanks again for your helpfully help evlncrn8. :)

1 person likes this

Share this post


Link to post
Share on other sites

Hi guys its me again,

so I have a problem calling some sites via Winsock APIs who using SSL so with normal requests I only get the info site was moved to location xy which is same just only it used SSL / https.Normaly in that case I call the site with WinInet functions and SSL paramter (simple to use) and it works but I dont wanna always switch from WInSock to WInInet if a site is using SSL so I wanna also handle it via WinSock APIs.Now after searching on internet again I found something in MSDN using also Winsock APIs but with WSA at the beginning.....

https://msdn.microsoft.com/en-us/library/windows/desktop/bb394814(v=vs.85).aspx

....and now I tried to change my already used APIs to WSA...xy.First problem I got is the API called WSASetSocketSecurity so I dont have this API & lib for fwpuclnt for masm. :( Also I am not sure if I had the lib whether it will also work then get success after calling any SSL site with my code....

WSAStartup
inet_addr / gethostbyname / gethostbyaddr
socket / WSASocket
connect / WSAConnect
send / WSASend
recv / WSARecv
closesocket
WSACleanup

...just wanna handle this SSL stuff with any simple method without much effort.Also I cant find any examples in MASM for this or using any SSLlib (OpenSSL or any other things).Maybe you can help to create a simple example for me if possible to get this problem finally solved.

Thank you

Share this post


Link to post
Share on other sites

Hi guys,

so could anyone show me a simple MASM friendly example how to create a SSL connection with WinSock?I still dont get it and dont wanna always switch to WinInet just to prevent the 301 Moved Permanently response if I call any site.

Thank you

Share this post


Link to post
Share on other sites

It's far from "simple" even when using C/C++. That's why there soecial libraries (like openssl) just for this purpose.. 

I know it's not the answer you want to hear, but that's just how it is. :)

Share this post


Link to post
Share on other sites

Good ok,so if I really need to use something like OpenSSL could you then create a simple example (or exe file) using the dll functions etc?Just anything what calls any site with GET command.Maybe then I could debug it to see how I have to do it to write something in WinASM what will work then with that WinSock SSL stuff etc.

greetz

EDIT: So I have no plan about WinHttp (looks like WinInet) Ted.So I would still like to use WinSock so there I know a little or more how to use it and have just that trouble that I need anything between to handle SSL stuff etc.

Edited by LCF-AT

Share this post


Link to post
Share on other sites
5 hours ago, LCF-AT said:

so could anyone show me a simple MASM friendly example how to create a SSL connection with WinSock?I still dont get it and dont wanna always switch to WinInet just to prevent the 301 Moved Permanently response if I call any site.

Hi @LCF-AT :

1. A WinSock Networking Tutorial for MASM here :

Quote

Includes Code examples also in MASM ! You can either just  follow that link above OR read the tut from the BEGINNING .

 

2. You can use the WinSock Debug Tool for ASM from this page or get the tool DIRECTLY from THIS LINK .

3. A Winsock Usage in MASM example can be found here (SOURCE CODE from GitHub) .

4. A SIMPLE Client-Server example using WinSock in MASM is ATTACHED to this post. Original page here . The ZIP file thats attached to this post is quite self-sufficient  and understandable without any  need to refer to the site.

5.The page actually dealing with the coding of the example WinSock prog in ASM, from my link in (1) above , to connect to another computer/server using the Winsocks lib can be directly accessed HERE .

The SOURCE CODE EXAMPLE used in the tut can be directly downloaded HERE .

Good Luck ! :)

 

socket.zip

Edited by Techlord
1 person likes this

Share this post


Link to post
Share on other sites

@LCF-AT Also wanted to add :

Specifically for implementing SSL through ASM, you may find THIS link quite useful.

SOURCE CODE example of a tiny program ATTACHED to this post which shows the principles involved.

Basic principle and differences :

Quote

Your main concern is to sort through the OpenSSL API, and their manual on openssl.org is not very straightforward (it is just scattered manpages). Basically, you establish a normal socket connection using winsock, and then "layer" SSL on top of it using SSL_connect(socket, ...). Then, once SSL_connect does its handshaking, you will use SSL_send and SSL_recv, as opposed to send/recv. They act just the same, except SSL_send and SSL_recv will handle the encryption for you.

ftpbnc contains code to handle both types of connection (non-SSL and SSL), so you can clearly see the difference in programming both types of connections.

Linking openssl libraries (libeay32 and ssleay32) should be the least of your worries.

 

Method (Here they used FASM (Flat Assembler instead of MASM but its almost the same) - This is excerpted from the same link given above:

  •  
Quote

 

  • Install this package: http://www.slproweb.com/products/Win32OpenSSL.html
  • Port the code from MASM to FASM.
  • Compile to FASM as a MS COFF object
  • Use MS link.exe or POlink.exe or whatever other shit is able to link MS COFF .obj into .exe
  • Test with stunnel.exe or similar tool. You can use Link-Net IRC servers to test SSL

Alternatively,

  • Use dll2inc.exe from my website (check the footer of this message) to make include files for DLLs ssleay32.dll libeay32.dll
  • Port the code from MASM to FASM.
  • Compile to FASM as a PE 4.0 file
  • Test with stunnel.exe or similar tool. You can use Link-Net IRC servers to test SSL

Instead of my dll2inc, you can use 2397197 other DLL2INC implementations...

 

Greetz :)

ftpbnc-0.4.zip

1 person likes this

Share this post


Link to post
Share on other sites

Hi Techlord,

thanks for the infos but this about SSL I found too yesterday but I dont get it also not with that C language thing. :slap:Looks all like much work with this entire certificate stuff and the other key things.I just looking for any simple way to use APIs xy etc.Hmmm,so I dont get it and it seems I can only use WinInet APIs with SSL if nobody does show me any uderstandable example. :( 

greetz

Share this post


Link to post
Share on other sites

Hi @LCF-AT,

4 hours ago, LCF-AT said:

thanks for the infos but this about SSL I found too yesterday but I dont get it also not with that C language thing

 

You can actually compile the C directly to "readable" ASM with this directives/command :

gcc  -S -c foo.c

So you can take the above code in C and then compile it directly into ASM and see the code in ASM.

 

If you want to see the C code together with the assembly it was converted to, use a command line like this:

gcc -c -g -Wa,-a,-ad [other GCC options] foo.c > foo.lst

which will output the combined C/assembly listing to the file foo.lst

That way you can study what the C code translates to !

 

Alternatively, you can just COMBINE the code in C for the SSL part, with your remaining code in MASM, to finally build an exe, using a comand something like this :

Quote

nasm -f <object fileformat> -o myasmprog.o myasmprog.asm
gcc -c SSL_Part.c
gcc SSL_Part.o myasmprog.o

 

 

 

5 hours ago, LCF-AT said:

Looks all like much work with this entire certificate stuff and the other key things.I just looking for any simple way to use APIs xy etc

One of the MAIN features of SSL is encryption and authentication based on certificates and as Kao and oters have already mentioned above, it can get very complicated :)

 

May I suggest you do the following first please ( I did so and I found it very helpful, thats why) :

Download and install this tiny package from here : http://www.slproweb.com/products/Win32OpenSSL.html

It contains all the necessary DLLs and .obj files along with a ton of examples. Please go through them. If necessary, convert the examples given in C to MASM, with the technique I mentioned above

2. Use dll2inc.exe to convert the  DLLs from the folder after install , to INC files so that you can use it in your own ASM project ...

Sorry , but the file that I attached above is an excellent example of how to use SSL to connect .

 

If you need me to convert the example to ASM code, please let me know. Because I do not want to spend another hour working on it , only to have you end up finally saying in a single sentence that it was not what you needed, thereby making all effort a huge waste :D

The bottomline would be, that codeing for SSL connections in ASM would be very inflexible and the code would come out to be LONG and confusing (unlike with simple http). That is why, coders generally prefer using C or C++ (higher languages I mean) so that we can have greater flexibility.

 

What I am trying to provide is a solution that meets your needs (thats what I do for al my clients in Real Life too).

 

So if you want a piece of code of code in ASM that connects using SSL, I think that you should sincerely check out the steps I outlined above, starting with the install of the tiny package...

Good luck :)

 

 

 

1 person likes this

Share this post


Link to post
Share on other sites

Hi again,

so I did installed MinGW and OpenSSL package to have header files too.Now I tried to find any client SSL example in C or C++ and found some code here..

http://languageshelp.blogspot.de/2008/01/ssl-openssl-with-visual-c.html

....but got problems with that paths to compile something.So is this source example I found ok or not?If I check the code then all is same like normal WinSock client till connect API...

ssl = SSL_new (ctx);                         CHK_NULL(ssl);    
SSL_set_fd (ssl, sd);
err = SSL_connect (ssl);                     CHK_SSL(err);
scert = SSL_get_peer_certificate (ssl);       CHK_NULL(scert);
txt = X509_NAME_oneline (X509_get_subject_name (scert),0,0);
OPENSSL_free (txt);
txt = X509_NAME_oneline (X509_get_issuer_name  (scert),0,0);
OPENSSL_free (txt);
X509_free (scert);
err = SSL_write (ssl, "Me escucha alguien?", strlen("Me escucha alguien?"));  CHK_SSL(err);
  
err = SSL_read (ssl, buff, sizeof(buff) - 1);                     CHK_SSL(err);
buff[err] = '\0';
printf ("Leidos %d caracteres:'%s'\n", err, buff);
SSL_shutdown (ssl);  /* enviamos la notificacion de cierre de SSL/TLS */
  
/* Liberamos los recursos utilizados */
 
closesocket (sd);
SSL_free (ssl);
SSL_CTX_free (ctx);

....so somehow it should be translateable to MASM + just using the dll & functions itself without to have a lib or not?So what do you think?Is there anything doable or not?I am not sure and need any help of course.

greetz

Share this post


Link to post
Share on other sites

Hi again,

another question.So I have test again a little the diffrent between WinSock & WinInet and found some issues.In the past I created 2 request ways using one time normal WinSock way and one time WinInet way with SSL to prevent the moved permanently 301 problem I get for some sites using WinSock way.Today I checked any site with WinSock I got again this 301 message = no chance to bypass it and used the WinInet way I got error on HttpSendRequest 12029 (cant create connection to server) and the problem in this case was using port 443 for SSL.Now I did added another WinInet way using normal http request without SSL and there its working and I get status 200 back + site content and thats a thing I dont understand.So why is then WinSock not working to get status 200 (just only 301) and for WinInet without SSL its working?!?

SSL
InternetConnect INTERNET_DEFAULT_HTTPS_PORT 
HttpOpenRequest INTERNET_FLAG_SECURE or INTERNET_FLAG_RELOAD

Normal
InternetConnect INTERNET_DEFAULT_HTTP_PORT
HttpOpenRequest INTERNET_FLAG_RELOAD

The normal way should be same as WinSock way


--------------Normal----------------------------
GET https://forum.tuts4you.com/ HTTP/1.1
Host: forum.tuts4you.com
Connection: close
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)

HTTP/1.1 200 OK
------------------------------------------------


--------------WinSock---------------------------
GET https://forum.tuts4you.com/ HTTP/1.1
Host: forum.tuts4you.com
Connection: close
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)

HTTP/1.1 301 Moved Permanently
Location: https://forum.tuts4you.comhttps/forum.tuts4you.com/

or

GET https://forum.tuts4you.com/ HTTP/1.1
Host: 198.57.187.53
Connection: close
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)

HTTP/1.1 200 OK

But: Pagecontent isnt same as for WinInet

<html><head><META HTTP-EQUIV="refresh" CONTENT="0;URL=/cgi-sys/defaultwebpage.cgi"></head><body></body></html>

Thats strange for me.So why is this T4Y site in that case working with WinInet normal way without SSL and normal WinSock not?So I thought I need to use extra SSL stuff for WinInet & WinSock to bypass this 301 moved permanently issues.So whats the diffrent here now?

That really bad.So lets say I build a tool to request sites then I need to add 3 methods.First my fav using WInSock and if this failed because of 301 problem I need to switch to WinInet SSL and if this failed because of connection problem with port 443 then I have to use WinInet without SSL.Uhhhhhh what a puke. :(

greetz

Share this post


Link to post
Share on other sites

You're violating all the standards for HTTP(S) requests (see RFC2616) in so many ways that I'm surprised it sometimes actually works..

 

#1 - if you put an IP address in the "host" field, you'll get webservers default page back. One physical server can host multiple webs, so it really needs a correct host field to know which web you want to access.

#2 - you should not put protocol and server name (aka "absolute URI") in the GET line. That syntax is reserved for proxies only ("To allow for transition to absoluteURIs in all requests in future versions of HTTP, all HTTP/1.1 servers MUST accept the absoluteURI form in requests, even though HTTP/1.1 clients will only generate them in requests to proxies.")

As for your 3 examples, the are missing impotant data, like to which port your client connected and whether in reality it was HTTP or HTTPS connection. My guess:

1) https to port 443. Works as intended, even though it violates RFCs I mentioned;

2) http request to port 80, incorrectly specifies HTTPS and absolute URI in the GET. Server redirects to HTTPS, location field is broken because you used absolute URI. "Garbage in, garbage out"

3) http request to port 80, incorrect host field. Server gives you the default web page. "Garbage in, garbage out".. :)

 

1 person likes this

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now