Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
M
mongoose
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
esp
mongoose
Commits
ed24afd1
Commit
ed24afd1
authored
Dec 08, 2015
by
Sergey Lyubka
Committed by
rojer
Dec 08, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Connect timeouts for resolving connections
PUBLISHED_FROM=068b6f75550b10913d7f13106f9a7f7dce5babec
parent
714556de
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
84 additions
and
7 deletions
+84
-7
mongoose.c
mongoose.c
+45
-6
mongoose.h
mongoose.h
+39
-1
No files found.
mongoose.c
View file @
ed24afd1
...
...
@@ -2488,11 +2488,13 @@ void mg_if_connect_cb(struct mg_connection *nc, int err) {
* either failure (and dealloc the connection)
* or success (and proceed with connect()
*/
static
void
resolve_cb
(
struct
mg_dns_message
*
msg
,
void
*
data
)
{
static
void
resolve_cb
(
struct
mg_dns_message
*
msg
,
void
*
data
,
enum
mg_resolve_err
e
)
{
struct
mg_connection
*
nc
=
(
struct
mg_connection
*
)
data
;
int
i
;
int
failure
=
-
1
;
nc
->
flags
&=
~
MG_F_RESOLVING
;
if
(
msg
!=
NULL
)
{
/*
* Take the first DNS A answer and run...
...
...
@@ -2512,6 +2514,11 @@ static void resolve_cb(struct mg_dns_message *msg, void *data) {
}
}
if
(
e
==
MG_RESOLVE_TIMEOUT
)
{
double
now
=
time
(
NULL
);
mg_call
(
nc
,
NULL
,
MG_EV_TIMER
,
&
now
);
}
/*
* If we get there was no MG_DNS_A_RECORD in the answer
*/
...
...
@@ -2557,12 +2564,18 @@ struct mg_connection *mg_connect_opt(struct mg_mgr *mgr, const char *address,
* DNS resolution is required for host.
* mg_parse_address() fills port in nc->sa, which we pass to resolve_cb()
*/
if
(
mg_resolve_async
(
nc
->
mgr
,
host
,
MG_DNS_A_RECORD
,
resolve_cb
,
nc
)
!=
0
)
{
struct
mg_connection
*
dns_conn
=
NULL
;
struct
mg_resolve_async_opts
o
;
memset
(
&
o
,
0
,
sizeof
(
o
));
o
.
dns_conn
=
&
dns_conn
;
if
(
mg_resolve_async_opt
(
nc
->
mgr
,
host
,
MG_DNS_A_RECORD
,
resolve_cb
,
nc
,
o
)
!=
0
)
{
MG_SET_PTRPTR
(
opts
.
error_string
,
"cannot schedule DNS lookup"
);
mg_destroy_conn
(
nc
);
return
NULL
;
}
nc
->
priv_2
=
dns_conn
;
nc
->
flags
|=
MG_F_RESOLVING
;
return
nc
;
#else
MG_SET_PTRPTR
(
opts
.
error_string
,
"Resolver is disabled"
);
...
...
@@ -2700,6 +2713,21 @@ void mg_forward(struct mg_connection *from, struct mg_connection *to) {
mg_send
(
to
,
from
->
recv_mbuf
.
buf
,
from
->
recv_mbuf
.
len
);
mbuf_remove
(
&
from
->
recv_mbuf
,
from
->
recv_mbuf
.
len
);
}
double
mg_set_timer
(
struct
mg_connection
*
c
,
double
timestamp
)
{
double
result
=
c
->
ev_timer_time
;
c
->
ev_timer_time
=
timestamp
;
/*
* If this connection is resolving, it's not in the list of active
* connections, so not processed yet. It has a DNS resolver connection
* linked to it. Set up a timer for the DNS connection.
*/
DBG
((
"%p %p %d"
,
c
,
c
->
priv_2
,
c
->
flags
&
MG_F_RESOLVING
));
if
((
c
->
flags
&
MG_F_RESOLVING
)
&&
c
->
priv_2
!=
NULL
)
{
((
struct
mg_connection
*
)
c
->
priv_2
)
->
ev_timer_time
=
timestamp
;
}
return
result
;
}
#ifdef NS_MODULE_LINES
#line 1 "src/net_if_socket.c"
/**/
...
...
@@ -7835,6 +7863,7 @@ struct mg_resolve_async_request {
void
*
data
;
time_t
timeout
;
int
max_retries
;
enum
mg_resolve_err
err
;
/* state */
time_t
last_time
;
...
...
@@ -7964,6 +7993,7 @@ static void mg_resolve_async_eh(struct mg_connection *nc, int ev, void *data) {
case
MG_EV_CONNECT
:
case
MG_EV_POLL
:
if
(
req
->
retries
>
req
->
max_retries
)
{
req
->
err
=
MG_RESOLVE_EXCEEDED_RETRY_COUNT
;
nc
->
flags
|=
MG_F_CLOSE_IMMEDIATELY
;
break
;
}
...
...
@@ -7977,9 +8007,11 @@ static void mg_resolve_async_eh(struct mg_connection *nc, int ev, void *data) {
msg
=
(
struct
mg_dns_message
*
)
MG_MALLOC
(
sizeof
(
*
msg
));
if
(
mg_parse_dns
(
nc
->
recv_mbuf
.
buf
,
*
(
int
*
)
data
,
msg
)
==
0
&&
msg
->
num_answers
>
0
)
{
req
->
callback
(
msg
,
req
->
data
);
req
->
callback
(
msg
,
req
->
data
,
MG_RESOLVE_OK
);
nc
->
user_data
=
NULL
;
MG_FREE
(
req
);
}
else
{
req
->
err
=
MG_RESOLVE_NO_ANSWERS
;
}
MG_FREE
(
msg
);
nc
->
flags
|=
MG_F_CLOSE_IMMEDIATELY
;
...
...
@@ -7992,10 +8024,14 @@ static void mg_resolve_async_eh(struct mg_connection *nc, int ev, void *data) {
nc
->
flags
&=
~
MG_F_CLOSE_IMMEDIATELY
;
mbuf_remove
(
&
nc
->
send_mbuf
,
nc
->
send_mbuf
.
len
);
break
;
case
MG_EV_TIMER
:
req
->
err
=
MG_RESOLVE_TIMEOUT
;
nc
->
flags
|=
MG_F_CLOSE_IMMEDIATELY
;
break
;
case
MG_EV_CLOSE
:
/* If we got here with request still not done, fire an error callback. */
if
(
req
!=
NULL
)
{
req
->
callback
(
NULL
,
req
->
data
);
req
->
callback
(
NULL
,
req
->
data
,
req
->
err
);
nc
->
user_data
=
NULL
;
MG_FREE
(
req
);
}
...
...
@@ -8017,7 +8053,7 @@ int mg_resolve_async_opt(struct mg_mgr *mgr, const char *name, int query,
struct
mg_connection
*
dns_nc
;
const
char
*
nameserver
=
opts
.
nameserver_url
;
DBG
((
"%s %d
"
,
name
,
query
));
DBG
((
"%s %d
%p"
,
name
,
query
,
opts
.
dns_conn
));
/* resolve with DNS */
req
=
(
struct
mg_resolve_async_request
*
)
MG_CALLOC
(
1
,
sizeof
(
*
req
));
...
...
@@ -8050,6 +8086,9 @@ int mg_resolve_async_opt(struct mg_mgr *mgr, const char *name, int query,
return
-
1
;
}
dns_nc
->
user_data
=
req
;
if
(
opts
.
dns_conn
!=
NULL
)
{
*
opts
.
dns_conn
=
dns_nc
;
}
return
0
;
}
...
...
mongoose.h
View file @
ed24afd1
...
...
@@ -1063,6 +1063,35 @@ enum v7_err mg_enable_javascript(struct mg_mgr *m, struct v7 *v7,
const
char
*
init_js_file_name
);
#endif
/*
* Schedule MG_EV_TIMER event to be delivered at `timestamp` time.
* `timestamp` is a UNIX time (a number of seconds since Epoch). It is
* `double` instead of `time_t` to allow for sub-second precision.
* Return the old timer value.
*
* Example: set connect timeout to 1.5 seconds:
*
* ```
* c = mg_connect(&mgr, "cesanta.com", ev_handler);
* mg_set_timer(c, time(NULL) + 1.5);
* ...
*
* void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
* switch (ev) {
* case MG_EV_CONNECT:
* mg_set_timer(c, 0); // Clear connect timer
* break;
* case MG_EV_TIMER:
* log("Connect timeout");
* c->flags |= MG_F_CLOSE_IMMEDIATELY;
* break;
```
*
* NOTE: sub-second precision is not implemented yet, current granularity
* is 1 second.
*/
double
mg_set_timer
(
struct
mg_connection
*
c
,
double
timestamp
);
#ifdef __cplusplus
}
#endif
/* __cplusplus */
...
...
@@ -2556,7 +2585,15 @@ void mg_dns_send_reply(struct mg_connection *, struct mg_dns_reply *);
extern
"C"
{
#endif
/* __cplusplus */
typedef
void
(
*
mg_resolve_callback_t
)(
struct
mg_dns_message
*
,
void
*
);
enum
mg_resolve_err
{
MG_RESOLVE_OK
=
0
,
MG_RESOLVE_NO_ANSWERS
=
1
,
MG_RESOLVE_EXCEEDED_RETRY_COUNT
=
2
,
MG_RESOLVE_TIMEOUT
=
3
};
typedef
void
(
*
mg_resolve_callback_t
)(
struct
mg_dns_message
*
dns_message
,
void
*
user_data
,
enum
mg_resolve_err
);
/* Options for `mg_resolve_async_opt`. */
struct
mg_resolve_async_opts
{
...
...
@@ -2565,6 +2602,7 @@ struct mg_resolve_async_opts {
int
timeout
;
/* in seconds; defaults to 5 if zero */
int
accept_literal
;
/* pseudo-resolve literal ipv4 and ipv6 addrs */
int
only_literal
;
/* only resolves literal addrs; sync cb invocation */
struct
mg_connection
**
dns_conn
;
/* return DNS connection */
};
/* See `mg_resolve_async_opt()` */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment