|
|
|
|
@ -73,12 +73,12 @@ static int router_send_one_flags(struct ETCP_ROUTER_CONN* rconn, const uint8_t*
|
|
|
|
|
|
|
|
|
|
struct ETCP_CONN* conn = route_bgp_find_conn_for_node(inst->bgp, rconn->remote_node_id); |
|
|
|
|
if (!conn) { |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_ETCP, "router_send_one: no route to %016llx svc_id=%u", |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_ETCPROUTE, "router_send_one: no route to %016llx svc_id=%u", |
|
|
|
|
(unsigned long long)rconn->remote_node_id, rconn->svc_id); |
|
|
|
|
queue_entry_free(entry); queue_dgram_free(entry); if (!seq_flags) rconn->tx_seq--; return -1; |
|
|
|
|
} |
|
|
|
|
rconn->last_dgram_ts = get_current_timestamp(); |
|
|
|
|
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "router_send: seq=%u → %016llx svc_id=%u len=%zu inflight=%u", |
|
|
|
|
DEBUG_TRACE(DEBUG_CATEGORY_ETCPROUTE, "router_send: seq=%u → %016llx svc_id=%u len=%zu inflight=%u", |
|
|
|
|
seq, (unsigned long long)rconn->remote_node_id, rconn->svc_id, pl_len, |
|
|
|
|
rconn->tx_seq - rconn->rx_acked); |
|
|
|
|
return etcp_send(conn, entry); |
|
|
|
|
@ -99,7 +99,7 @@ static void router_send_to(struct UTUN_INSTANCE* inst, uint64_t dst, uint8_t svc
|
|
|
|
|
if (!entry) { u_free(hdr); return; } |
|
|
|
|
entry->dgram = (uint8_t*)hdr; |
|
|
|
|
entry->len = SVC_ROUTE_HDR_SIZE; |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "router_send_to: seq_flags=0x%08x → %016llx svc_id=%u", |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_ETCPROUTE, "router_send_to: seq_flags=0x%08x → %016llx svc_id=%u", |
|
|
|
|
seq_flags, (unsigned long long)dst, svc_id); |
|
|
|
|
etcp_send(conn, entry); |
|
|
|
|
} |
|
|
|
|
@ -114,7 +114,7 @@ static void router_send_close_to_service(struct ETCP_ROUTER_CONN* rconn) {
|
|
|
|
|
if (!e->dgram) { queue_entry_free(e); return; } |
|
|
|
|
e->dgram[0] = rconn->svc_id; |
|
|
|
|
e->len = 1; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "router_close_svc: svc_id=%u remote=%016llx", |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_ETCPROUTE, "router_close_svc: svc_id=%u remote=%016llx", |
|
|
|
|
rconn->svc_id, (unsigned long long)rconn->remote_node_id); |
|
|
|
|
cb(NULL, e); |
|
|
|
|
} |
|
|
|
|
@ -143,7 +143,7 @@ static void router_close_and_notify(struct ETCP_ROUTER_CONN* rconn) {
|
|
|
|
|
} |
|
|
|
|
if (inst->router_conns) |
|
|
|
|
queue_remove_data(inst->router_conns, &rconn->ll); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "router_conn: closed remote=%016llx svc_id=%u", |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_ETCPROUTE, "router_conn: closed remote=%016llx svc_id=%u", |
|
|
|
|
(unsigned long long)rconn->remote_node_id, rconn->svc_id); |
|
|
|
|
queue_entry_free(&rconn->ll); |
|
|
|
|
} |
|
|
|
|
@ -173,18 +173,18 @@ static void router_send_resume_cb(void* arg) {
|
|
|
|
|
|
|
|
|
|
static void router_enqueue_send(struct ETCP_ROUTER_CONN* rconn, const uint8_t* payload, size_t pl_len) { |
|
|
|
|
struct ll_entry* qe = queue_entry_new(0); |
|
|
|
|
if (!qe) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "router_enqueue_send: queue_entry_new failed"); return; } |
|
|
|
|
if (!qe) { DEBUG_ERROR(DEBUG_CATEGORY_ETCPROUTE, "router_enqueue_send: queue_entry_new failed"); return; } |
|
|
|
|
qe->dgram = u_malloc(pl_len); |
|
|
|
|
if (!qe->dgram) { queue_entry_free(qe); return; } |
|
|
|
|
qe->len = pl_len; |
|
|
|
|
if (pl_len > 0) memcpy(qe->dgram, payload, pl_len); |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_ETCPROUTE, "router_send_q: queued svc_id=%u inflight=%u send_q=%d", |
|
|
|
|
rconn->svc_id, rconn->tx_seq - rconn->rx_acked, queue_entry_count(rconn->send_q)); |
|
|
|
|
queue_data_put(rconn->send_q, qe); |
|
|
|
|
rconn->send_blocked = 1; |
|
|
|
|
if (!rconn->send_resume_timer) |
|
|
|
|
rconn->send_resume_timer = uasync_set_timeout(rconn->inst->ua, |
|
|
|
|
ROUTER_SEND_RESUME_TB, rconn, router_send_resume_cb, "router_send_resume"); |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "router_send_q: queued svc_id=%u inflight=%u send_q=%d", |
|
|
|
|
rconn->svc_id, rconn->tx_seq - rconn->rx_acked, queue_entry_count(rconn->send_q)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ====================================================================
|
|
|
|
|
@ -205,12 +205,12 @@ static void router_send_ack(struct ETCP_ROUTER_CONN* rconn) {
|
|
|
|
|
struct UTUN_INSTANCE* inst = rconn->inst; |
|
|
|
|
struct ETCP_CONN* conn = route_bgp_find_conn_for_node(inst->bgp, rconn->remote_node_id); |
|
|
|
|
if (!conn) { |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_ETCP, "router_ack: no route to %016llx svc_id=%u", |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_ETCPROUTE, "router_ack: no route to %016llx svc_id=%u", |
|
|
|
|
(unsigned long long)rconn->remote_node_id, rconn->svc_id); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
struct SVC_ROUTE_HDR* hdr = (struct SVC_ROUTE_HDR*)u_malloc(SVC_ROUTE_HDR_SIZE); |
|
|
|
|
if (!hdr) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "router_ack: u_malloc failed"); return; } |
|
|
|
|
if (!hdr) { DEBUG_ERROR(DEBUG_CATEGORY_ETCPROUTE, "router_ack: u_malloc failed"); return; } |
|
|
|
|
hdr->cmd = ETCP_ID_SVC_ROUTE; |
|
|
|
|
hdr->dst_node_id = rconn->remote_node_id; |
|
|
|
|
hdr->src_node_id = inst->node_id; |
|
|
|
|
@ -222,7 +222,7 @@ static void router_send_ack(struct ETCP_ROUTER_CONN* rconn) {
|
|
|
|
|
entry->dgram = (uint8_t*)hdr; |
|
|
|
|
entry->len = SVC_ROUTE_HDR_SIZE; |
|
|
|
|
|
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "router_ack: → %016llx svc_id=%u rx_seq=%u", |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_ETCPROUTE, "router_ack: → %016llx svc_id=%u rx_seq=%u", |
|
|
|
|
(unsigned long long)rconn->remote_node_id, rconn->svc_id, rconn->rx_seq); |
|
|
|
|
etcp_send(conn, entry); |
|
|
|
|
} |
|
|
|
|
@ -260,19 +260,19 @@ static void router_deliver(struct ETCP_ROUTER_CONN* rconn, struct ETCP_CONN* con
|
|
|
|
|
struct UTUN_INSTANCE* inst = rconn->inst; |
|
|
|
|
etcp_recv_fn cb = inst->router_bindings.callbacks[rconn->svc_id]; |
|
|
|
|
if (!cb) { |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_ETCP, "router_deliver: no handler for svc_id=%u", rconn->svc_id); |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_ETCPROUTE, "router_deliver: no handler for svc_id=%u", rconn->svc_id); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
size_t entry_len = 1 + payload_len; |
|
|
|
|
struct ll_entry* svc_entry = queue_entry_new(0); |
|
|
|
|
if (!svc_entry) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "router_deliver: queue_entry_new failed"); return; } |
|
|
|
|
if (!svc_entry) { DEBUG_ERROR(DEBUG_CATEGORY_ETCPROUTE, "router_deliver: queue_entry_new failed"); return; } |
|
|
|
|
svc_entry->len = entry_len; |
|
|
|
|
svc_entry->dgram = u_malloc(entry_len); |
|
|
|
|
if (!svc_entry->dgram) { queue_entry_free(svc_entry); return; } |
|
|
|
|
svc_entry->dgram[0] = rconn->svc_id; |
|
|
|
|
if (payload_len > 0) memcpy(svc_entry->dgram + 1, payload, payload_len); |
|
|
|
|
|
|
|
|
|
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "router_deliver: svc_id=%u len=%zu from remote=%016llx", |
|
|
|
|
DEBUG_TRACE(DEBUG_CATEGORY_ETCPROUTE, "router_deliver: svc_id=%u len=%zu from remote=%016llx", |
|
|
|
|
rconn->svc_id, payload_len, (unsigned long long)rconn->remote_node_id); |
|
|
|
|
cb(conn, svc_entry); |
|
|
|
|
} |
|
|
|
|
@ -299,7 +299,7 @@ static void etcp_router_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry)
|
|
|
|
|
if (!entry) return; |
|
|
|
|
struct UTUN_INSTANCE* inst = conn ? conn->instance : NULL; |
|
|
|
|
if (!inst || entry->len < SVC_ROUTE_HDR_SIZE) { |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_ETCP, "etcp_router: invalid packet inst=%p len=%zu min=%u", |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_ETCPROUTE, "etcp_router: invalid packet inst=%p len=%zu min=%u", |
|
|
|
|
(void*)inst, entry->len, (unsigned)SVC_ROUTE_HDR_SIZE); |
|
|
|
|
if (entry) { queue_dgram_free(entry); queue_entry_free(entry); } |
|
|
|
|
return; |
|
|
|
|
@ -344,7 +344,7 @@ static void etcp_router_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry)
|
|
|
|
|
{ |
|
|
|
|
int32_t d = (int32_t)(seq - rconn->rx_seq); |
|
|
|
|
if (d > ROUTER_MAX_INFLIGHT || d < -ROUTER_MAX_INFLIGHT) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "router: seq=%u out of bounds, rx_seq=%u (d=%d), dropping", |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_ETCPROUTE, "router: seq=%u out of bounds, rx_seq=%u (d=%d), dropping", |
|
|
|
|
seq, rconn->rx_seq, d); |
|
|
|
|
queue_dgram_free(entry); queue_entry_free(entry); |
|
|
|
|
return; |
|
|
|
|
@ -354,7 +354,7 @@ static void etcp_router_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry)
|
|
|
|
|
// Дубликат (seq уже доставлен или в recv_q)
|
|
|
|
|
if (((int32_t)(rconn->rx_seq - seq) > 0) || |
|
|
|
|
queue_find_data_by_index(rconn->recv_q, &seq)) { |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "router: dup seq=%u rx_seq=%u, dropping", seq, rconn->rx_seq); |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_ETCPROUTE, "router: dup seq=%u rx_seq=%u, dropping", seq, rconn->rx_seq); |
|
|
|
|
queue_dgram_free(entry); queue_entry_free(entry); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
@ -368,10 +368,10 @@ static void etcp_router_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry)
|
|
|
|
|
qe->len = pl_len; |
|
|
|
|
memcpy(qe->dgram, pl, pl_len); |
|
|
|
|
|
|
|
|
|
queue_data_put_with_index(rconn->recv_q, qe); |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "router: queued seq=%u rx_seq=%u recv_q=%d from %016llx svc_id=%u", |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_ETCPROUTE, "router: queued seq=%u rx_seq=%u recv_q=%d from %016llx svc_id=%u", |
|
|
|
|
seq, rconn->rx_seq, queue_entry_count(rconn->recv_q), |
|
|
|
|
(unsigned long long)hdr->src_node_id, rconn->svc_id); |
|
|
|
|
queue_data_put_with_index(rconn->recv_q, qe); |
|
|
|
|
|
|
|
|
|
if (seq == rconn->rx_seq) |
|
|
|
|
router_try_assembly(rconn, conn); |
|
|
|
|
@ -382,12 +382,12 @@ static void etcp_router_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry)
|
|
|
|
|
// ========== Транзит ==========
|
|
|
|
|
struct ETCP_CONN* next = route_bgp_find_conn_for_node(inst->bgp, hdr->dst_node_id); |
|
|
|
|
if (!next) { |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_ETCP, "etcp_router: no route to %016llx svc_id=%u, dropping", |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_ETCPROUTE, "etcp_router: no route to %016llx svc_id=%u, dropping", |
|
|
|
|
(unsigned long long)hdr->dst_node_id, hdr->svc_id); |
|
|
|
|
queue_dgram_free(entry); queue_entry_free(entry); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "etcp_router: forwarding svc_id=%u → %016llx via %s", |
|
|
|
|
DEBUG_TRACE(DEBUG_CATEGORY_ETCPROUTE, "etcp_router: forwarding svc_id=%u → %016llx via %s", |
|
|
|
|
hdr->svc_id, (unsigned long long)hdr->dst_node_id, next->log_name); |
|
|
|
|
etcp_send(next, entry); |
|
|
|
|
} |
|
|
|
|
@ -398,21 +398,21 @@ static void etcp_router_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry)
|
|
|
|
|
// ====================================================================
|
|
|
|
|
|
|
|
|
|
int etcp_router_init(struct UTUN_INSTANCE* inst) { |
|
|
|
|
if (!inst) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "etcp_router_init: NULL instance"); return -1; } |
|
|
|
|
if (!inst) { DEBUG_ERROR(DEBUG_CATEGORY_ETCPROUTE, "etcp_router_init: NULL instance"); return -1; } |
|
|
|
|
memset(&inst->router_bindings, 0, sizeof(inst->router_bindings)); |
|
|
|
|
inst->router_conns = queue_new(inst->ua, |
|
|
|
|
ROUTER_CONN_HASH_SIZE, 0, 9, "router_conns"); |
|
|
|
|
if (!inst->router_conns) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "etcp_router_init: queue_new(router_conns) failed"); |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_ETCPROUTE, "etcp_router_init: queue_new(router_conns) failed"); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
int ret = etcp_bind(inst, ETCP_ID_SVC_ROUTE, etcp_router_recv_cb); |
|
|
|
|
if (ret != 0) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "etcp_router_init: etcp_bind failed, ret=%d", ret); |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_ETCPROUTE, "etcp_router_init: etcp_bind failed, ret=%d", ret); |
|
|
|
|
queue_free(inst->router_conns); inst->router_conns = NULL; |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "etcp_router initialized for node %016llx", (unsigned long long)inst->node_id); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_ETCPROUTE, "etcp_router initialized for node %016llx", (unsigned long long)inst->node_id); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -443,43 +443,43 @@ void etcp_router_destroy(struct UTUN_INSTANCE* inst) {
|
|
|
|
|
inst->router_conns = NULL; |
|
|
|
|
} |
|
|
|
|
memset(&inst->router_bindings, 0, sizeof(inst->router_bindings)); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "etcp_router destroyed"); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_ETCPROUTE, "etcp_router destroyed"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int etcp_router_bind(struct UTUN_INSTANCE* inst, uint8_t svc_id, etcp_recv_fn callback) { |
|
|
|
|
if (!inst) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "etcp_router_bind: NULL instance"); return -1; } |
|
|
|
|
if (!callback) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "etcp_router_bind: NULL callback for svc_id=%u", svc_id); return -1; } |
|
|
|
|
if (!inst) { DEBUG_ERROR(DEBUG_CATEGORY_ETCPROUTE, "etcp_router_bind: NULL instance"); return -1; } |
|
|
|
|
if (!callback) { DEBUG_ERROR(DEBUG_CATEGORY_ETCPROUTE, "etcp_router_bind: NULL callback for svc_id=%u", svc_id); return -1; } |
|
|
|
|
if (inst->router_bindings.callbacks[svc_id]) |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_ETCP, "etcp_router_bind: overwriting svc_id=%u", svc_id); |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_ETCPROUTE, "etcp_router_bind: overwriting svc_id=%u", svc_id); |
|
|
|
|
inst->router_bindings.callbacks[svc_id] = callback; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "etcp_router_bind: svc_id=%u → cb=%p", svc_id, (void*)callback); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_ETCPROUTE, "etcp_router_bind: svc_id=%u → cb=%p", svc_id, (void*)callback); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int etcp_router_unbind(struct UTUN_INSTANCE* inst, uint8_t svc_id) { |
|
|
|
|
if (!inst) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "etcp_router_unbind: NULL instance"); return -1; } |
|
|
|
|
if (!inst) { DEBUG_ERROR(DEBUG_CATEGORY_ETCPROUTE, "etcp_router_unbind: NULL instance"); return -1; } |
|
|
|
|
if (!inst->router_bindings.callbacks[svc_id]) { |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_ETCP, "etcp_router_unbind: svc_id=%u not bound", svc_id); |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_ETCPROUTE, "etcp_router_unbind: svc_id=%u not bound", svc_id); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
inst->router_bindings.callbacks[svc_id] = NULL; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "etcp_router_unbind: svc_id=%u", svc_id); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_ETCPROUTE, "etcp_router_unbind: svc_id=%u", svc_id); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int etcp_route_send(struct UTUN_INSTANCE* inst, uint64_t dst_node_id, struct ll_entry* entry) { |
|
|
|
|
if (!inst || !entry) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "etcp_route_send: NULL inst=%p entry=%p", (void*)inst, (void*)entry); |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_ETCPROUTE, "etcp_route_send: NULL inst=%p entry=%p", (void*)inst, (void*)entry); |
|
|
|
|
if (entry) { queue_dgram_free(entry); queue_entry_free(entry); } return -1; |
|
|
|
|
} |
|
|
|
|
if (!entry->dgram || entry->len < 1) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "etcp_route_send: empty entry"); queue_dgram_free(entry); queue_entry_free(entry); return -1; |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_ETCPROUTE, "etcp_route_send: empty entry"); queue_dgram_free(entry); queue_entry_free(entry); return -1; |
|
|
|
|
} |
|
|
|
|
uint8_t svc_id = entry->dgram[0]; |
|
|
|
|
size_t payload_len = entry->len - 1; |
|
|
|
|
|
|
|
|
|
if (dst_node_id == inst->node_id) { |
|
|
|
|
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "etcp_route_send: loopback svc_id=%u len=%zu", svc_id, payload_len); |
|
|
|
|
DEBUG_TRACE(DEBUG_CATEGORY_ETCPROUTE, "etcp_route_send: loopback svc_id=%u len=%zu", svc_id, payload_len); |
|
|
|
|
if (inst->router_bindings.callbacks[svc_id]) |
|
|
|
|
inst->router_bindings.callbacks[svc_id](NULL, entry); |
|
|
|
|
else { queue_dgram_free(entry); queue_entry_free(entry); } |
|
|
|
|
@ -488,7 +488,7 @@ int etcp_route_send(struct UTUN_INSTANCE* inst, uint64_t dst_node_id, struct ll_
|
|
|
|
|
|
|
|
|
|
struct ETCP_CONN* etcp_conn = route_bgp_find_conn_for_node(inst->bgp, dst_node_id); |
|
|
|
|
if (!etcp_conn) { |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_ETCP, "etcp_route_send: no BGP route to %016llx svc_id=%u, dropping", |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_ETCPROUTE, "etcp_route_send: no BGP route to %016llx svc_id=%u, dropping", |
|
|
|
|
(unsigned long long)dst_node_id, svc_id); |
|
|
|
|
queue_dgram_free(entry); queue_entry_free(entry); |
|
|
|
|
return -1; |
|
|
|
|
@ -544,7 +544,7 @@ struct ETCP_ROUTER_CONN* etcp_router_conn_get(struct UTUN_INSTANCE* inst,
|
|
|
|
|
|
|
|
|
|
size_t data_size = sizeof(struct ETCP_ROUTER_CONN) - sizeof(struct ll_entry); |
|
|
|
|
rconn = (struct ETCP_ROUTER_CONN*)queue_entry_new(data_size); |
|
|
|
|
if (!rconn) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "router_conn_get: queue_entry_new failed"); return NULL; } |
|
|
|
|
if (!rconn) { DEBUG_ERROR(DEBUG_CATEGORY_ETCPROUTE, "router_conn_get: queue_entry_new failed"); return NULL; } |
|
|
|
|
rconn->remote_node_id = remote_node_id; |
|
|
|
|
rconn->svc_id = svc_id; |
|
|
|
|
rconn->last_dgram_ts = get_current_timestamp(); |
|
|
|
|
@ -557,19 +557,19 @@ struct ETCP_ROUTER_CONN* etcp_router_conn_get(struct UTUN_INSTANCE* inst,
|
|
|
|
|
rconn->send_blocked = 0; |
|
|
|
|
rconn->send_resume_timer = NULL; |
|
|
|
|
rconn->recv_q = queue_new(inst->ua, ROUTER_RECVQ_HASH_SIZE, 0, 4, "router_recv_q"); |
|
|
|
|
if (!rconn->recv_q) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "router_conn_get: queue_new(recv_q) failed"); queue_entry_free(&rconn->ll); return NULL; } |
|
|
|
|
if (!rconn->recv_q) { DEBUG_ERROR(DEBUG_CATEGORY_ETCPROUTE, "router_conn_get: queue_new(recv_q) failed"); queue_entry_free(&rconn->ll); return NULL; } |
|
|
|
|
rconn->send_q = queue_new(inst->ua, 0, 0, 0, "router_send_q"); |
|
|
|
|
if (!rconn->send_q) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "router_conn_get: queue_new(send_q) failed"); queue_free(rconn->recv_q); queue_entry_free(&rconn->ll); return NULL; } |
|
|
|
|
queue_data_put_with_index(inst->router_conns, &rconn->ll); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "router_conn: new conn remote=%016llx svc_id=%u", |
|
|
|
|
if (!rconn->send_q) { DEBUG_ERROR(DEBUG_CATEGORY_ETCPROUTE, "router_conn_get: queue_new(send_q) failed"); queue_free(rconn->recv_q); queue_entry_free(&rconn->ll); return NULL; } |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_ETCPROUTE, "router_conn: new conn remote=%016llx svc_id=%u", |
|
|
|
|
(unsigned long long)remote_node_id, svc_id); |
|
|
|
|
queue_data_put_with_index(inst->router_conns, &rconn->ll); |
|
|
|
|
return rconn; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int etcp_router_conn_send(struct ETCP_ROUTER_CONN* rconn, |
|
|
|
|
const uint8_t* data, size_t len) { |
|
|
|
|
if (!rconn || !data || len == 0) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "router_conn_send: invalid args rconn=%p data=%p len=%zu", |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_ETCPROUTE, "router_conn_send: invalid args rconn=%p data=%p len=%zu", |
|
|
|
|
(void*)rconn, (const void*)data, len); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
@ -604,7 +604,7 @@ void etcp_router_conn_close_all_for_node(struct UTUN_INSTANCE* inst, uint64_t re
|
|
|
|
|
while ((f = queue_data_get(rconn->send_q)) != NULL) { queue_dgram_free(f); queue_entry_free(f); } |
|
|
|
|
queue_free(rconn->send_q); |
|
|
|
|
} |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "router_conn: closed by node remote=%016llx svc_id=%u", |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_ETCPROUTE, "router_conn: closed by node remote=%016llx svc_id=%u", |
|
|
|
|
(unsigned long long)rconn->remote_node_id, rconn->svc_id); |
|
|
|
|
queue_entry_free(&rconn->ll); |
|
|
|
|
} else { |
|
|
|
|
|