curl / Mailing Lists / curl-library / Single Mail
Buy commercial curl support from WolfSSL. We help you work out your issues, debug your libcurl applications, use the API, port to new platforms, add new features and more. With a team lead by the curl founder himself.

Re: Retrieving the local address between connect() and HTTP

From: Ray Satiro via curl-library <curl-library_at_cool.haxx.se>
Date: Sun, 26 Apr 2020 19:05:51 -0400

On 4/26/2020 4:44 PM, Jean-Francois Dockes wrote:
> Ray Satiro via curl-library writes:
> > On 4/26/2020 10:40 AM, Jean-Francois Dockes via curl-library wrote:
> > > My apologies if this is a frequent question, I could not find an answer.
> > >
> > > It would be convenient for me to retrieve the local address of the
> > > connected socket used for an HTTP GET before the HTTP transaction
> > > begins.
> > >
> > > The pseudo HTTP protocol which my code implements (UPnP) needs to set a
> > > HTTP header which contains a callback URL for the remote host to send
> > > events to. In case the local machine has multiple interfaces, the easiest
> > > way to build an URL which the remote is guaranteed to be able to connect to
> > > seems to be just using the connected socket local address.
> > >
> > > Unfortunately, it seems that the two callbacks in this area,
> > > CURLOPT_SOCKOPTFUNCTION and CURLOPT_OPENSOCKETFUNCTION, occur before the
> > > socket is connected.
> > >
> > > I could connect the socket myself (losing the nice CURL code which does it
> > > for me), or find another way to derive the right interface from the
> > > remote address I am connecting to, but a getsockname() on the connected
> > > socket would be much simpler. So I was hoping that there was a way.
> > >
> > > This is assuming that I can call CURLOPT_HTTPHEADER from this point, which
> > > may also not be the case. So, questions...
> >
> > I don't think that is possible without doing the connect yourself. There
> > is CURLINFO_ACTIVESOCKET [1] but it doesn't set the socket until the
> > transfer is done. It is really meant to be used with
> > CURLOPT_CONNECT_ONLY [2].
> >
> > Try doing the connection yourself, set CURLOPT_HTTPHEADER and then in
> > CURLOPT_SOCKOPTFUNCTION [3] return CURL_SOCKOPT_ALREADY_CONNECTED.
>
> Thanks for the CURLOPT_CONNECT_ONLY pointer.
>
> Is there something to prevent me from using the resulting socket fd with
> CURLOPT_OPENSOCKETFUNCTION / CURLOPT_SOCKOPTFUNCTION ? I see that this is a
> bit convoluted, but it gains me the use of the libcurl URL parsing and
> connect code instead of DIY. Does it make sense ? Performance is no big
> issue in my use case.

I'm not sure I understand. If you are using libcurl to CONNECT_ONLY [1]
then it doesn't do data transfer (ie no HTTP). Is that what you want? If
it is then yes you can use ACTIVESOCKET.

OTOH if you want libcurl to do a HTTP transfer and you want the socket
right after the connection is made then you should make the connection.
Note libcurl may make multiple connections in the case of happy eyeballs
or DOH (DNS-over-HTTPS) or FTP, so unless you don't use all of that you
can't really be sure which socket is the transfer socket. In other
words, the socket callbacks may be called multiple times for one
transfer. (Also multiple times if the connection failed).

I hesitate to mention this but if you are so against manually connecting
you might be able to get away with it. You could save the socket from
CURLOPT_SOCKOPTFUNCTION and then in the progress function check to see
if socket != CURL_SOCKET_BAD && socket != prev and if so change the
headers. You'd be relying on the progress function to be called after
the connection is made but before the HTTP request is generated (ie
before the user-specified headers are added) which is not guaranteed.

[1]: https://curl.haxx.se/libcurl/c/CURLOPT_CONNECT_ONLY.html

-------------------------------------------------------------------
Unsubscribe: https://cool.haxx.se/list/listinfo/curl-library
Etiquette: https://curl.haxx.se/mail/etiquette.html
Received on 2020-04-27