Hi Patrick, It looks like that you don't have ipv6 support, maybe kernel module don't loaded. Try to test like this $ ls /proc/net/if_inet6
Here is more info how to test ipv6 support in linux http://www.tldp.org/HOWTO/Linux+IPv6-HOWTO/systemcheck-kernel.html I clone you repository, apply you patch, and the server is started. netstat shows: $ netstat -anp | fgrep https tcp6 0 0 :::8421 :::* LISTEN 15079/https-server What about IPv6 and IPv4 at the same time There is socket option: IPV6_V6ONLY (ipv6 (7)), default value is 1. But you can't set this option right using libevent, but you can set default value for this option using using proc: $ echo 0 | sudo tee -a /proc/sys/net/ipv6/bindv6only But after this you program have segfault On Sat, Jan 26, 2013 at 6:29 AM, Patrick Pelletier <ppellet...@oblong.com> wrote: > I've put my sample code up on github, so we have something concrete to talk > about: > > https://github.com/ppelleti/https-example > > However, I think I've figured out why I'm getting the ECONNREFUSED: it's for > the obvious reason, that my server is only running on IPv4, and not on IPv6. > I was led astray by the comment saying that ECONNREFUSED was expected when > connecting to localhost, but I don't think that comment is relevant to my > situation. I'm getting a perfectly legitimate ECONNREFUSED, because my > server is only running on 127.0.0.1, and isn't running on ::1. > > I was also led astray by the fact that curl seems to connect to IPv4 first > (or maybe it tries both?), while evhttp tries IPv6 first, and gives up if it > doesn't work. So curl was working fine for me, but it was using IPv4 even > when I gave it the name "localhost". However, if I give curl the "-6" > option, then it doesn't work either. That's when I realized my server > wasn't running on ::1. > > So, I tried running my server on IPv6 instead of IPv4, by making this > change: > > --- a/https-server.c > +++ b/https-server.c > @@ -230,7 +230,7 @@ static int serve_some_http (void) > evhttp_set_gencb (http, send_document_cb, NULL); > > /* Now we tell the evhttp what port to listen on */ > - handle = evhttp_bind_socket_with_handle (http, "0.0.0.0", port); > + handle = evhttp_bind_socket_with_handle (http, "::0", port); > if (! handle) > { fprintf (stderr, "couldn't bind to port %d. Exiting.\n", (int) port); > return 1; > > but then the server fails to run, like this: > > ppelletier@chives:~/src/https-example$ ./https-server > Using OpenSSL version "OpenSSL 1.0.1c 10 May 2012" > and libevent version "2.1.2-alpha-dev" > Loading certificate chain from 'server-certificate-chain.pem' > and private key from 'server-private-key.pem' > [warn] getaddrinfo: address family for nodename not supported > couldn't bind to port 8421. Exiting. > > So, I'm not sure what's going on there. And anyway, I don't really want to > run the server on just IPv6; I want it to answer on both IPv4 and IPv6. But > I don't know if there's a way to do that other than running two http > servers. > > --Patrick > > > > On 01/23/2013 10:18 PM, Azat Khuzhin wrote: >> >> What about your ECONNREFUSED, does you have something like this, if >> you run "curl -v --data CORRECT_POST_DATA_HERE HOST" ? >> (it seems that you try POST request: client_do_post) >> Does you server ("localhost") have the valid HTTP answer? >> >> Why it couldn't get response after first request. >> Could you post you code somewhere? If you don't want to show all of >> it, you could write 20-40 lines, that can reproduce this problem. >> >> About retries: could you send backtrace when this messages are printed? >> >> >> Thanks. >> >> On Thu, Jan 24, 2013 at 7:36 AM, Patrick Pelletier >> <ppellet...@oblong.com> wrote: >>> >>> On 01/22/2013 02:54 PM, Azat Khuzhin wrote: >>> >>>> Could you try to test my patch >>>> >>>> >>>> https://github.com/azat/libevent/commit/71e709c7829275a594f767b27468b1b52e8b5bb9.patch >>>> >>>> and write if it works for you? >>> >>> >>> >>> Thanks, I think that's a step in the right direction. >>> >>> However, I'm still having trouble. My callback is getting called with >>> evhttp_request_get_response_code (req) == 0. (i. e. something went >>> wrong, >>> but we don't know what. That gets back to the original topic of this >>> thread, that evhttp is very vague about what errors happened.) >>> >>> Here's the backtrace when my callback gets called: >>> >>> #0 request_finished (req=0x758df0, arg=0x7fffffffe070) at >>> client-http.c:46 >>> #1 0x00007ffff7628b58 in evhttp_connection_cb_cleanup (evcon=0x758280) >>> at http.c:1319 >>> #2 0x00007ffff7629050 in evhttp_connection_cb (bufev=0x7579b0, what=33, >>> arg=0x758280) at http.c:1462 >>> #3 0x00007ffff75f93d0 in bufferevent_run_deferred_callbacks_locked ( >>> cb=0x757b50, arg=0x7579b0) at bufferevent.c:161 >>> #4 0x00007ffff7604389 in event_process_active_single_queue >>> (base=0x756790, >>> activeq=0x754080, max_to_process=2147483647, endtime=0x0) at >>> event.c:1476 >>> #5 0x00007ffff760464e in event_process_active (base=0x756790) at >>> event.c:1538 >>> #6 0x00007ffff7604db2 in event_base_loop (base=0x756790, flags=0) >>> at event.c:1761 >>> #7 0x000000000040dd49 in client_do_post (host=0x4e9aa8 "localhost", >>> port=8421, passcode=0x4e9ab2 "R23") at client-http.c:246 >>> #8 0x000000000040ddba in main (argc=1, argv=0x7fffffffe288) >>> at client-main.c:30 >>> >>> (all the line numbers correspond to your "fix-http-for-ipv6" branch, >>> commit >>> 71e709c7829275a594f767b27468b1b52e8b5bb9) >>> >>> It appears that what's happening is the "if (errno == ECONNREFUSED) goto >>> cleanup;" in http.c:1409 is being triggered. The comment right above it >>> says: >>> >>> /* some operating systems return ECONNREFUSED immediately >>> * when connecting to a local address. the cleanup is going >>> * to reschedule this function call. >>> */ >>> >>> Obviously my operating system (Ubuntu 10.04 LTS) must be one of these >>> operating systems. But then I was curious why the cleanup wasn't >>> rescheduling the function call, the way the comment said it would. >>> >>> It turns out that at the top of evhttp_connection_cb_cleanup is: >>> >>> if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) >>> >>> and that was the problem. retry_max defaults to 0, which means that it >>> actually won't retry the way the comment said it would. This seems like >>> a >>> poor default, given that the code is relying on a retry being possible, >>> for >>> the ECONNREFUSED case. >>> >>> So, I tried fixing this in my client code by calling: >>> >>> evhttp_connection_set_retries (conn, 3); >>> >>> However, now what happens is I get: >>> >>> [warn] Epoll ADD(1) on fd 7 failed. Old events were 0; read change was 1 >>> (add); write change was 0 (none): Bad file descriptor >>> [warn] Epoll ADD(4) on fd 7 failed. Old events were 0; read change was 0 >>> (none); write change was 1 (add): Bad file descriptor >>> >>> and my http request still fails. But that's as far as I've gotten in >>> debugging it, though. >>> >>> But thanks for your patch! I think that will be part of the solution; >>> I'm >>> just running into other evhttp issues now (the ECONNREFUSED and retry >>> thing). >>> >>> --Patrick >>> >> >> >> > -- Azat Khuzhin *********************************************************************** To unsubscribe, send an e-mail to majord...@freehaven.net with unsubscribe libevent-users in the body.