-
Notifications
You must be signed in to change notification settings - Fork 49
ames: libnatpmp for real this time #646
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
14be6de
c496367
d02c620
cca7582
879e86d
00f659e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| cc_library( | ||
| name = "natpmp", | ||
| srcs = ["natpmp.c", "getgateway.c"], | ||
| hdrs = ["natpmp.h", "getgateway.h", "natpmp_declspec.h"], | ||
| copts = ["-O3"], | ||
| linkstatic = True, | ||
| visibility = ["//visibility:public"], | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ | |
| #include "ur.h" | ||
|
|
||
| #include "zlib.h" | ||
| #include "natpmp.h" | ||
|
|
||
| #include <ent.h> | ||
|
|
||
|
|
@@ -71,6 +72,11 @@ typedef enum u3_stun_state { | |
| u3_lane sef_u; // our lane, if we know it | ||
| c3_o wok_o; // STUN worked, set on first success | ||
| } sun_u; // | ||
| struct { | ||
| natpmp_t req_u; // libnatpmp struct for mapping request | ||
| uv_poll_t pol_u; // handle waits on libnatpmp socket | ||
| uv_timer_t tim_u; // every two hours if mapping succeeds | ||
| } nat_u; // libnatpmp stuff for port forwarding | ||
| c3_o nal_o; // lane cache backcompat flag | ||
| struct { // config: | ||
| c3_o net_o; // can send | ||
|
|
@@ -2765,6 +2771,69 @@ _ames_recv_cb(uv_udp_t* wax_u, | |
| } | ||
| } | ||
|
|
||
| static void natpmp_init(uv_timer_t* handle); | ||
|
|
||
| static void | ||
| natpmp_cb(uv_poll_t* handle, | ||
| c3_i status, | ||
| c3_i events) | ||
| { | ||
|
|
||
| if (status != 0) { | ||
| return; | ||
| } | ||
|
|
||
| u3_ames* sam_u = handle->data; | ||
|
|
||
| natpmpresp_t response; | ||
| c3_i err_i = readnatpmpresponseorretry(&sam_u->nat_u.req_u, &response); | ||
| if ( NATPMP_TRYAGAIN == err_i ) { | ||
| return; | ||
| } | ||
|
|
||
| uv_poll_stop(handle); | ||
|
|
||
| if ( 0 != err_i ) { | ||
| u3l_log("ames: natpmp error %i", err_i); | ||
| uv_poll_stop(&sam_u->nat_u.pol_u); | ||
| closenatpmp(&sam_u->nat_u.req_u); | ||
| return; | ||
| } | ||
|
|
||
| u3l_log("ames: mapped public port %hu to localport %hu lifetime %u", | ||
| response.pnu.newportmapping.mappedpublicport, | ||
| response.pnu.newportmapping.privateport, | ||
| response.pnu.newportmapping.lifetime); | ||
|
|
||
| closenatpmp(&sam_u->nat_u.req_u); | ||
| sam_u->nat_u.tim_u.data = sam_u; | ||
| uv_timer_start(&sam_u->nat_u.tim_u, natpmp_init, 7200000, 0); | ||
| } | ||
|
|
||
| static void | ||
| natpmp_init(uv_timer_t *handle) | ||
| { | ||
| u3_ames* sam_u = handle->data; | ||
| c3_s por_s = sam_u->pir_u->por_s; | ||
|
|
||
| c3_i err_i = initnatpmp(&sam_u->nat_u.req_u, 0, 0); | ||
|
|
||
| if (err_i != 0) { | ||
| return; | ||
| } | ||
|
|
||
| err_i = uv_poll_init(u3L, &sam_u->nat_u.pol_u, sam_u->nat_u.req_u.s); | ||
|
|
||
| if (err_i != 0) { | ||
| return; | ||
| } | ||
|
|
||
| sendnewportmappingrequest(&sam_u->nat_u.req_u, NATPMP_PROTOCOL_UDP, por_s, por_s, 7200); | ||
|
|
||
| sam_u->nat_u.pol_u.data = sam_u; | ||
| uv_poll_start(&sam_u->nat_u.pol_u, UV_READABLE, natpmp_cb); | ||
| } | ||
|
|
||
| static void | ||
| _mdns_dear_bail(u3_ovum* egg_u, u3_noun lud) | ||
| { | ||
|
|
@@ -2885,6 +2954,11 @@ _ames_io_start(u3_ames* sam_u) | |
| u3z(our); | ||
|
|
||
| mdns_init(por_s, !sam_u->pir_u->fak_o, our_s, _ames_put_dear, (void *)sam_u); | ||
|
|
||
| if ( c3n == sam_u->pir_u->fak_o ) { | ||
| uv_timer_start(&sam_u->nat_u.tim_u, natpmp_init, 0, 0); | ||
| } | ||
|
|
||
| c3_free(our_s); | ||
| } | ||
|
|
||
|
|
@@ -3126,6 +3200,12 @@ _ames_io_exit(u3_auto* car_u) | |
| uv_close(&sam_u->had_u, _ames_exit_cb); | ||
| uv_close((uv_handle_t*)&sam_u->sun_u.dns_u, 0); | ||
| uv_close((uv_handle_t*)&sam_u->sun_u.tim_u, 0); | ||
| uv_close((uv_handle_t*)&sam_u->nat_u.tim_u, 0); | ||
|
|
||
| uv_handle_type handle = uv_handle_get_type((uv_handle_t *)&sam_u->nat_u.pol_u); | ||
| if ( UV_UNKNOWN_HANDLE != handle) { | ||
| uv_close((uv_handle_t*)&sam_u->nat_u.pol_u, 0); | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure if this is quite right -- the definition of "active" for different handle types is fairly involved. What we actually want is just "has this handle every been initialized?". We can obviously track that ourselves, but I think this will also work:
|
||
| } | ||
|
|
||
| /* _ames_io_info(): produce status info. | ||
|
|
@@ -3228,6 +3308,10 @@ u3_ames_io_init(u3_pier* pir_u) | |
| sam_u->sun_u.tim_u.data = sam_u; | ||
| sam_u->sun_u.dns_u.data = sam_u; | ||
|
|
||
| // initialize libnatpmp | ||
| sam_u->nat_u.tim_u.data = sam_u; | ||
| uv_timer_init(u3L, &sam_u->nat_u.tim_u); | ||
|
|
||
| // enable forwarding on galaxies only | ||
| u3_noun who = u3i_chubs(2, sam_u->pir_u->who_d); | ||
| u3_noun rac = u3do("clan:title", who); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're not checking
statusfor errors here. And I'm not sure ifreadnatpmpresponseorretry()can/will handle all cases for us.