13 changed files with 0 additions and 1236 deletions
@ -1,115 +0,0 @@ |
|||||||
{ |
|
||||||
"name": ".opencode", |
|
||||||
"lockfileVersion": 3, |
|
||||||
"requires": true, |
|
||||||
"packages": { |
|
||||||
"": { |
|
||||||
"dependencies": { |
|
||||||
"@opencode-ai/plugin": "1.4.3" |
|
||||||
} |
|
||||||
}, |
|
||||||
"node_modules/@opencode-ai/plugin": { |
|
||||||
"version": "1.4.3", |
|
||||||
"resolved": "https://registry.npmjs.org/@opencode-ai/plugin/-/plugin-1.4.3.tgz", |
|
||||||
"integrity": "sha512-Ob/3tVSIeuMRJBr2O23RtrnC5djRe01Lglx+TwGEmjrH9yDBJ2tftegYLnNEjRoMuzITgq9LD8168p4pzv+U/A==", |
|
||||||
"license": "MIT", |
|
||||||
"dependencies": { |
|
||||||
"@opencode-ai/sdk": "1.4.3", |
|
||||||
"zod": "4.1.8" |
|
||||||
}, |
|
||||||
"peerDependencies": { |
|
||||||
"@opentui/core": ">=0.1.97", |
|
||||||
"@opentui/solid": ">=0.1.97" |
|
||||||
}, |
|
||||||
"peerDependenciesMeta": { |
|
||||||
"@opentui/core": { |
|
||||||
"optional": true |
|
||||||
}, |
|
||||||
"@opentui/solid": { |
|
||||||
"optional": true |
|
||||||
} |
|
||||||
} |
|
||||||
}, |
|
||||||
"node_modules/@opencode-ai/sdk": { |
|
||||||
"version": "1.4.3", |
|
||||||
"resolved": "https://registry.npmjs.org/@opencode-ai/sdk/-/sdk-1.4.3.tgz", |
|
||||||
"integrity": "sha512-X0CAVbwoGAjTY2iecpWkx2B+GAa2jSaQKYpJ+xILopeF/OGKZUN15mjqci+L7cEuwLHV5wk3x2TStUOVCa5p0A==", |
|
||||||
"license": "MIT", |
|
||||||
"dependencies": { |
|
||||||
"cross-spawn": "7.0.6" |
|
||||||
} |
|
||||||
}, |
|
||||||
"node_modules/cross-spawn": { |
|
||||||
"version": "7.0.6", |
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", |
|
||||||
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", |
|
||||||
"license": "MIT", |
|
||||||
"dependencies": { |
|
||||||
"path-key": "^3.1.0", |
|
||||||
"shebang-command": "^2.0.0", |
|
||||||
"which": "^2.0.1" |
|
||||||
}, |
|
||||||
"engines": { |
|
||||||
"node": ">= 8" |
|
||||||
} |
|
||||||
}, |
|
||||||
"node_modules/isexe": { |
|
||||||
"version": "2.0.0", |
|
||||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", |
|
||||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", |
|
||||||
"license": "ISC" |
|
||||||
}, |
|
||||||
"node_modules/path-key": { |
|
||||||
"version": "3.1.1", |
|
||||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", |
|
||||||
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", |
|
||||||
"license": "MIT", |
|
||||||
"engines": { |
|
||||||
"node": ">=8" |
|
||||||
} |
|
||||||
}, |
|
||||||
"node_modules/shebang-command": { |
|
||||||
"version": "2.0.0", |
|
||||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", |
|
||||||
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", |
|
||||||
"license": "MIT", |
|
||||||
"dependencies": { |
|
||||||
"shebang-regex": "^3.0.0" |
|
||||||
}, |
|
||||||
"engines": { |
|
||||||
"node": ">=8" |
|
||||||
} |
|
||||||
}, |
|
||||||
"node_modules/shebang-regex": { |
|
||||||
"version": "3.0.0", |
|
||||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", |
|
||||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", |
|
||||||
"license": "MIT", |
|
||||||
"engines": { |
|
||||||
"node": ">=8" |
|
||||||
} |
|
||||||
}, |
|
||||||
"node_modules/which": { |
|
||||||
"version": "2.0.2", |
|
||||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", |
|
||||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", |
|
||||||
"license": "ISC", |
|
||||||
"dependencies": { |
|
||||||
"isexe": "^2.0.0" |
|
||||||
}, |
|
||||||
"bin": { |
|
||||||
"node-which": "bin/node-which" |
|
||||||
}, |
|
||||||
"engines": { |
|
||||||
"node": ">= 8" |
|
||||||
} |
|
||||||
}, |
|
||||||
"node_modules/zod": { |
|
||||||
"version": "4.1.8", |
|
||||||
"license": "MIT", |
|
||||||
"funding": { |
|
||||||
"url": "https://github.com/sponsors/colinhacks" |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
@ -1 +0,0 @@ |
|||||||
/bin/bash: строка 1: ./test_nat_detection: Нет такого файла или каталога |
|
||||||
@ -1,549 +0,0 @@ |
|||||||
// ll_queue.c - Упрощенная архитектура: разделение создания элементов и работы с очередью |
|
||||||
#include <stdlib.h> |
|
||||||
#include <string.h> |
|
||||||
#include <stdio.h> |
|
||||||
#include <assert.h> |
|
||||||
#include "ll_queue.h" |
|
||||||
#include "u_async.h" |
|
||||||
#include "debug_config.h" |
|
||||||
#include "mem.h" |
|
||||||
|
|
||||||
#ifdef _WIN32 |
|
||||||
#include <windows.h> |
|
||||||
#else |
|
||||||
#include <pthread.h> |
|
||||||
#endif |
|
||||||
|
|
||||||
// ==================== Thread safety check ==================== |
|
||||||
#ifdef QUEUE_THREAD_CHECK |
|
||||||
static inline void queue_check_thread(struct ll_queue* q) { |
|
||||||
if (!q) return; |
|
||||||
|
|
||||||
#ifdef _WIN32 |
|
||||||
DWORD current = GetCurrentThreadId(); |
|
||||||
if (q->owner_thread != current) { |
|
||||||
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "Queue '%s': thread mismatch! owner=%lu current=%lu", |
|
||||||
q->name ? q->name : "unknown", |
|
||||||
(unsigned long)q->owner_thread, |
|
||||||
(unsigned long)current); |
|
||||||
printf("ERROR: Queue '%s' accessed from wrong thread!\n", q->name ? q->name : "unknown"); |
|
||||||
abort(); |
|
||||||
} |
|
||||||
#else |
|
||||||
pthread_t current = pthread_self(); |
|
||||||
if (!pthread_equal(q->owner_thread, current)) { |
|
||||||
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "Queue '%s': thread mismatch! owner=%lu current=%lu", |
|
||||||
q->name ? q->name : "unknown", |
|
||||||
(unsigned long)q->owner_thread, |
|
||||||
(unsigned long)current); |
|
||||||
printf("ERROR: Queue '%s' accessed from wrong thread!\n", q->name ? q->name : "unknown"); |
|
||||||
abort(); |
|
||||||
} |
|
||||||
#endif |
|
||||||
} |
|
||||||
#endif |
|
||||||
|
|
||||||
// Предварительные объявления внутренних функций |
|
||||||
static void queue_resume_timeout_cb(void* arg); |
|
||||||
static void check_waiters(struct ll_queue* q); |
|
||||||
static void add_to_hash(struct ll_queue* q, struct ll_entry* entry); |
|
||||||
static void remove_from_hash(struct ll_queue* q, struct ll_entry* entry); |
|
||||||
|
|
||||||
// ==================== Управление очередью ==================== |
|
||||||
|
|
||||||
struct ll_queue* queue_new(struct UASYNC* ua, size_t hash_size, char* name) { |
|
||||||
if (!ua) return NULL; |
|
||||||
|
|
||||||
struct ll_queue* q = u_calloc(1, sizeof(struct ll_queue)); |
|
||||||
if (!q) return NULL; |
|
||||||
|
|
||||||
q->name = name; |
|
||||||
q->ua = ua; |
|
||||||
q->size_limit = -1; // Без ограничения по умолчанию |
|
||||||
q->hash_size = hash_size; |
|
||||||
|
|
||||||
#ifdef QUEUE_THREAD_CHECK |
|
||||||
#ifdef _WIN32 |
|
||||||
q->owner_thread = GetCurrentThreadId(); |
|
||||||
#else |
|
||||||
q->owner_thread = pthread_self(); |
|
||||||
#endif |
|
||||||
#endif |
|
||||||
|
|
||||||
// Создать хеш-таблицу если нужно |
|
||||||
if (hash_size > 0) { |
|
||||||
q->hash_table = u_calloc(hash_size, sizeof(struct ll_entry*)); |
|
||||||
if (!q->hash_table) { |
|
||||||
u_free(q); |
|
||||||
return NULL; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
DEBUG_DEBUG(DEBUG_CATEGORY_LL_QUEUE, "queue_new: created queue %p, hash_size=%zu", q, hash_size); |
|
||||||
|
|
||||||
return q; |
|
||||||
} |
|
||||||
|
|
||||||
struct ll_entry* ll_alloc_lldgram(uint16_t len) { |
|
||||||
struct ll_entry* entry = queue_entry_new(0); |
|
||||||
if (!entry) return NULL; |
|
||||||
|
|
||||||
entry->len=0; |
|
||||||
entry->memlen=len; |
|
||||||
entry->dgram = u_malloc(len); |
|
||||||
// entry->dgram_pool = NULL; - уже null (memset) |
|
||||||
// entry->dgram_free_fn = NULL; |
|
||||||
if (!entry->dgram) { |
|
||||||
queue_entry_free(entry); |
|
||||||
return NULL; |
|
||||||
} |
|
||||||
|
|
||||||
return entry; |
|
||||||
} |
|
||||||
|
|
||||||
void queue_free(struct ll_queue* q) { |
|
||||||
if (!q) return; |
|
||||||
|
|
||||||
DEBUG_DEBUG(DEBUG_CATEGORY_LL_QUEUE, "queue_free: freeing queue %p, head=%p, tail=%p, count=%d", |
|
||||||
q, q->head, q->tail, q->count); |
|
||||||
|
|
||||||
// ВАЖНО: Не освобождаем элементы в очереди - они должны быть извлечены отдельно |
|
||||||
// Это упрощает архитектуру и предотвращает double-u_free |
|
||||||
|
|
||||||
// Освободить хеш-таблицу |
|
||||||
if (q->hash_table) { |
|
||||||
u_free(q->hash_table); |
|
||||||
} |
|
||||||
|
|
||||||
// Отменить отложенное возобновление |
|
||||||
if (q->resume_timeout_id) { |
|
||||||
uasync_call_soon_cancel(q->ua, q->resume_timeout_id); |
|
||||||
q->resume_timeout_id = NULL; |
|
||||||
} |
|
||||||
|
|
||||||
u_free(q); |
|
||||||
} |
|
||||||
|
|
||||||
// ==================== Конфигурация очереди ==================== |
|
||||||
|
|
||||||
void queue_set_callback(struct ll_queue* q, queue_callback_fn cbk_fn, void* arg) { |
|
||||||
if (!q) return; |
|
||||||
q->callback = cbk_fn; |
|
||||||
q->callback_arg = arg; |
|
||||||
} |
|
||||||
|
|
||||||
static void queue_resume_timeout_cb(void* arg) { |
|
||||||
struct ll_queue* q = (struct ll_queue*)arg; |
|
||||||
if (!q) return; |
|
||||||
|
|
||||||
q->resume_timeout_id = NULL; |
|
||||||
|
|
||||||
// Вызвать коллбэк если есть элементы и коллбэки разрешены |
|
||||||
if (q->head && !q->callback_suspended && q->callback) { |
|
||||||
q->callback(q, q->callback_arg); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void queue_resume_callback(struct ll_queue* q) { |
|
||||||
if (!q) return; |
|
||||||
|
|
||||||
q->callback_suspended = 0; |
|
||||||
|
|
||||||
// Если есть элементы, запланировать вызов коллбэка |
|
||||||
if (q->head && q->callback && !q->resume_timeout_id) { |
|
||||||
q->resume_timeout_id = uasync_call_soon(q->ua, q, queue_resume_timeout_cb); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void queue_set_size_limit(struct ll_queue* q, int lim) { |
|
||||||
if (!q) return; |
|
||||||
q->size_limit = lim; |
|
||||||
} |
|
||||||
|
|
||||||
// ==================== Управление элементами ==================== |
|
||||||
|
|
||||||
struct ll_entry* queue_entry_new(size_t data_size) { |
|
||||||
struct ll_entry* entry = u_malloc(sizeof(struct ll_entry) + data_size); |
|
||||||
if (!entry) return NULL; |
|
||||||
|
|
||||||
memset(entry, 0, sizeof(struct ll_entry) + data_size); |
|
||||||
entry->size = data_size; |
|
||||||
entry->len = 0; |
|
||||||
entry->pool = NULL; // Выделено через u_malloc |
|
||||||
|
|
||||||
// DEBUG_DEBUG(DEBUG_CATEGORY_LL_QUEUE, "queue_entry_new: created entry %p, size=%zu", entry, data_size); |
|
||||||
|
|
||||||
return entry; |
|
||||||
} |
|
||||||
|
|
||||||
struct ll_entry* queue_entry_new_from_pool(struct memory_pool* pool) { |
|
||||||
if (!pool) return NULL; |
|
||||||
|
|
||||||
struct ll_entry* entry = memory_pool_alloc(pool); |
|
||||||
if (!entry) return NULL; |
|
||||||
|
|
||||||
memset(entry, 0, pool->object_size); |
|
||||||
entry->size = pool->object_size - sizeof(struct ll_entry); |
|
||||||
entry->len = 0; |
|
||||||
entry->pool = pool; // Выделено из пула |
|
||||||
|
|
||||||
// DEBUG_DEBUG(DEBUG_CATEGORY_LL_QUEUE, "queue_entry_new_from_pool: created entry %p from pool %p", entry, pool); |
|
||||||
|
|
||||||
return entry; |
|
||||||
} |
|
||||||
|
|
||||||
//void ll_u_free_dgram(struct ll_entry* entry) { |
|
||||||
void queue_dgram_free(struct ll_entry* entry) { |
|
||||||
if (!entry) return; |
|
||||||
|
|
||||||
if (entry->dgram) { |
|
||||||
if (entry->dgram_free_fn) { |
|
||||||
entry->dgram_free_fn(entry->dgram); // arg=NULL, если не задан |
|
||||||
} else if (entry->dgram_pool) { |
|
||||||
memory_pool_free(entry->dgram_pool, entry->dgram); |
|
||||||
} else { |
|
||||||
u_free(entry->dgram); |
|
||||||
} |
|
||||||
entry->dgram = NULL; |
|
||||||
entry->len = 0; // Опционально сброс len |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
void queue_entry_free(struct ll_entry* entry) { |
|
||||||
if (!entry) return; |
|
||||||
|
|
||||||
if (entry->pool) { |
|
||||||
memory_pool_free(entry->pool, entry); |
|
||||||
} else { |
|
||||||
u_free(entry); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// ==================== Операции с очередью ==================== |
|
||||||
|
|
||||||
// Внутренняя функция добавления в хеш-таблицу |
|
||||||
static void add_to_hash(struct ll_queue* q, struct ll_entry* entry) { |
|
||||||
if (!q || q->hash_size == 0 || !entry) return; |
|
||||||
|
|
||||||
size_t slot = entry->id % q->hash_size; |
|
||||||
entry->hash_next = q->hash_table[slot]; |
|
||||||
q->hash_table[slot] = entry; |
|
||||||
} |
|
||||||
|
|
||||||
// Внутренняя функция удаления из хеш-таблицы |
|
||||||
static void remove_from_hash(struct ll_queue* q, struct ll_entry* entry) { |
|
||||||
if (!q || q->hash_size == 0 || !entry) return; |
|
||||||
|
|
||||||
size_t slot = entry->id % q->hash_size; |
|
||||||
struct ll_entry** ptr = &q->hash_table[slot]; |
|
||||||
while (*ptr) { |
|
||||||
if (*ptr == entry) { |
|
||||||
*ptr = entry->hash_next; |
|
||||||
entry->hash_next = NULL; |
|
||||||
return; |
|
||||||
} |
|
||||||
ptr = &(*ptr)->hash_next; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
// Проверить и запустить ожидающие коллбэки |
|
||||||
static void check_waiters(struct ll_queue* q) { |
|
||||||
if (!q) return; |
|
||||||
|
|
||||||
// DEBUG_DEBUG(DEBUG_CATEGORY_LL_QUEUE, "check_waiters: checking waiters, count=%d, bytes=%zu", q->count, q->total_bytes); |
|
||||||
|
|
||||||
struct queue_waiter* waiter = &q->waiter; |
|
||||||
|
|
||||||
if (waiter->callback) { |
|
||||||
// Проверить условие: не больше max_packets и не больше max_bytes |
|
||||||
// max_bytes = 0 означает "не проверять байты" |
|
||||||
if (q->count <= waiter->max_packets && (waiter->max_bytes == 0 || q->total_bytes <= waiter->max_bytes)) { |
|
||||||
DEBUG_DEBUG(DEBUG_CATEGORY_LL_QUEUE, "check_waiters: condition met, calling callback, count=%d<=%d, bytes=%zu<=%zu (max_bytes_check=%s)", |
|
||||||
q->count, waiter->max_packets, q->total_bytes, waiter->max_bytes, |
|
||||||
waiter->max_bytes == 0 ? "disabled" : "enabled"); |
|
||||||
waiter->callback(q, waiter->callback_arg); |
|
||||||
memset(waiter, 0, sizeof(*waiter)); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
int queue_data_put(struct ll_queue* q, struct ll_entry* entry, uint32_t id) { |
|
||||||
if (!q || !entry) return -1; |
|
||||||
|
|
||||||
#ifdef QUEUE_THREAD_CHECK |
|
||||||
queue_check_thread(q); |
|
||||||
#endif |
|
||||||
|
|
||||||
#ifdef QUEUE_DEBUG |
|
||||||
// queue_check_consistency(q);// !!!! for debug - BEFORE callback |
|
||||||
#endif |
|
||||||
|
|
||||||
entry->id = id; |
|
||||||
|
|
||||||
// Проверить лимит размера |
|
||||||
if (q->size_limit >= 0 && q->count >= q->size_limit) { |
|
||||||
queue_dgram_free(entry); |
|
||||||
queue_entry_free(entry); // Освободить элемент если превышен лимит |
|
||||||
return -1; |
|
||||||
} |
|
||||||
|
|
||||||
// Добавить в конец |
|
||||||
entry->next = NULL; |
|
||||||
entry->prev = q->tail; |
|
||||||
if (q->tail) { |
|
||||||
q->tail->next = entry; |
|
||||||
} else { |
|
||||||
q->head = entry; |
|
||||||
} |
|
||||||
q->tail = entry; |
|
||||||
|
|
||||||
q->count++; |
|
||||||
entry->int_len=entry->len; |
|
||||||
q->total_bytes += entry->int_len; |
|
||||||
|
|
||||||
size_t send_q_bytes = queue_total_bytes(q); |
|
||||||
// DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "check total bytes: new_q_len=%d element_size:%d", send_q_bytes, entry->size); |
|
||||||
|
|
||||||
add_to_hash(q, entry); |
|
||||||
|
|
||||||
// DEBUG_DEBUG(DEBUG_CATEGORY_LL_QUEUE, "queue_data_put: added entry %p (id=%u), count=%d", entry, id, q->count); |
|
||||||
|
|
||||||
// ВАЖНО: проверка консистентности ДО коллбэка, так как коллбэк может модифицировать очередь |
|
||||||
#ifdef QUEUE_DEBUG |
|
||||||
queue_check_consistency(q);// !!!! for debug - BEFORE callback |
|
||||||
#endif |
|
||||||
|
|
||||||
// Если очередь была пуста и коллбэки разрешены - вызвать коллбэк |
|
||||||
if (q->count == 1 && !q->callback_suspended && q->callback) { |
|
||||||
q->callback(q, q->callback_arg); |
|
||||||
} |
|
||||||
|
|
||||||
// Проверить ожидающие коллбэки (надо только при заборе из очереди) |
|
||||||
// check_waiters(q); |
|
||||||
|
|
||||||
#ifdef QUEUE_DEBUG |
|
||||||
queue_check_consistency(q);// !!!! for debug - AFTER callback |
|
||||||
#endif |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
int queue_data_put_first(struct ll_queue* q, struct ll_entry* entry, uint32_t id) { |
|
||||||
if (!q || !entry) return -1; |
|
||||||
|
|
||||||
#ifdef QUEUE_THREAD_CHECK |
|
||||||
queue_check_thread(q); |
|
||||||
#endif |
|
||||||
|
|
||||||
entry->id = id; |
|
||||||
|
|
||||||
// Проверить лимит размера |
|
||||||
if (q->size_limit >= 0 && q->count >= q->size_limit) { |
|
||||||
queue_entry_free(entry); // Освободить элемент если превышен лимит |
|
||||||
return -1; |
|
||||||
} |
|
||||||
|
|
||||||
// Добавить в начало |
|
||||||
entry->next = q->head; |
|
||||||
entry->prev = NULL; |
|
||||||
if (q->head) { |
|
||||||
q->head->prev = entry; |
|
||||||
} else { |
|
||||||
q->tail = entry; |
|
||||||
} |
|
||||||
q->head = entry; |
|
||||||
|
|
||||||
q->count++; |
|
||||||
entry->int_len=entry->len; |
|
||||||
q->total_bytes += entry->int_len; |
|
||||||
|
|
||||||
add_to_hash(q, entry); |
|
||||||
|
|
||||||
// DEBUG_DEBUG(DEBUG_CATEGORY_LL_QUEUE, "queue_data_put_first: added entry %p (id=%u), count=%d", entry, id, q->count); |
|
||||||
|
|
||||||
// ВАЖНО: проверка консистентности ДО коллбэка |
|
||||||
#ifdef QUEUE_DEBUG |
|
||||||
queue_check_consistency(q);// !!!! for debug - BEFORE callback |
|
||||||
#endif |
|
||||||
|
|
||||||
// Если очередь была пуста и коллбэки разрешены - вызвать коллбэк |
|
||||||
if (q->count == 1 && !q->callback_suspended && q->callback) { |
|
||||||
q->callback(q, q->callback_arg); |
|
||||||
} |
|
||||||
|
|
||||||
// Проверить ожидающие коллбэки |
|
||||||
// check_waiters(q); |
|
||||||
|
|
||||||
#ifdef QUEUE_DEBUG |
|
||||||
queue_check_consistency(q);// !!!! for debug |
|
||||||
#endif |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
struct ll_entry* queue_data_get(struct ll_queue* q) { |
|
||||||
if (!q || !q->head) return NULL; |
|
||||||
|
|
||||||
#ifdef QUEUE_THREAD_CHECK |
|
||||||
queue_check_thread(q); |
|
||||||
#endif |
|
||||||
|
|
||||||
struct ll_entry* entry = q->head; |
|
||||||
|
|
||||||
q->head = entry->next; |
|
||||||
if (q->head) q->head->prev = NULL; |
|
||||||
if (!q->head) q->tail = NULL; |
|
||||||
|
|
||||||
q->count--; |
|
||||||
q->total_bytes -= entry->int_len; |
|
||||||
|
|
||||||
entry->next = NULL; |
|
||||||
entry->prev = NULL; |
|
||||||
|
|
||||||
remove_from_hash(q, entry); |
|
||||||
|
|
||||||
// DEBUG_DEBUG(DEBUG_CATEGORY_LL_QUEUE, "queue_data_get: got entry %p (id=%u), count=%d", entry, entry->id, q->count); |
|
||||||
|
|
||||||
// Приостановить коллбэки для предотвращения рекурсии |
|
||||||
q->callback_suspended = 1; |
|
||||||
|
|
||||||
// Проверить ожидающие коллбэки |
|
||||||
check_waiters(q); |
|
||||||
|
|
||||||
#ifdef QUEUE_DEBUG |
|
||||||
queue_check_consistency(q);// !!!! for debug |
|
||||||
#endif |
|
||||||
return entry; |
|
||||||
} |
|
||||||
|
|
||||||
int queue_entry_count(struct ll_queue* q) { |
|
||||||
return q ? q->count : 0; |
|
||||||
} |
|
||||||
|
|
||||||
// Функция проверки консистентности count и total_bytes |
|
||||||
// Возвращает 0 если ok, -1 если есть несоответствия |
|
||||||
int queue_check_consistency(struct ll_queue* q) { |
|
||||||
if (!q) return -1; // Недопустимая очередь |
|
||||||
|
|
||||||
// Проверка: если count > 0, то head не должен быть NULL |
|
||||||
if (q->count > 0 && !q->head) { |
|
||||||
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "Queue '%s': count=%d but head is NULL!", |
|
||||||
q->name ? q->name : "unknown", q->count); |
|
||||||
return -1; |
|
||||||
} |
|
||||||
|
|
||||||
int actual_count = 0; |
|
||||||
size_t actual_bytes = 0; |
|
||||||
struct ll_entry* current = q->head; |
|
||||||
|
|
||||||
while (current) { |
|
||||||
actual_count++; |
|
||||||
actual_bytes += current->int_len; |
|
||||||
if (current->next) { |
|
||||||
if (current->next->prev != current) { |
|
||||||
// Несоответствие в связях prev/next |
|
||||||
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "Queue '%s': prev/next error at entry %p != %p entries: %d!=%d bytes: %zu!=%zu", |
|
||||||
q->name ? q->name : "unknown", (void*)current, (void*)current->next->prev, actual_count, q->count, actual_bytes, q->total_bytes); |
|
||||||
return -1; |
|
||||||
} |
|
||||||
} |
|
||||||
current = current->next; |
|
||||||
} |
|
||||||
|
|
||||||
// Проверить хвост |
|
||||||
if (q->tail && q->tail->next != NULL) { |
|
||||||
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "Queue '%s': tail error", q->name ? q->name : "unknown"); |
|
||||||
return -1; // Хвост должен иметь next == NULL |
|
||||||
} |
|
||||||
|
|
||||||
// Сравнить с сохранёнными значениями |
|
||||||
if (actual_count != q->count || actual_bytes != q->total_bytes) { |
|
||||||
DEBUG_ERROR(DEBUG_CATEGORY_LL_QUEUE, "Queue '%s': count error entries: %d!=%d or bytes: %zu!=%zu", |
|
||||||
q->name ? q->name : "unknown", actual_count, q->count, actual_bytes, q->total_bytes); |
|
||||||
return -1; |
|
||||||
} |
|
||||||
|
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
// ==================== Асинхронное ожидание ==================== |
|
||||||
|
|
||||||
struct queue_waiter* queue_wait_threshold(struct ll_queue* q, int max_packets, size_t max_bytes, |
|
||||||
queue_threshold_callback_fn callback, void* arg) { |
|
||||||
if (!q || !callback) return NULL; |
|
||||||
|
|
||||||
struct queue_waiter* waiter = &q->waiter; |
|
||||||
|
|
||||||
// Проверить условие немедленно |
|
||||||
if (q->count <= max_packets && (max_bytes == 0 || q->total_bytes <= max_bytes)) { |
|
||||||
// Условие уже выполнено - вызвать коллбэк немедленно |
|
||||||
callback(q, arg); |
|
||||||
return NULL; |
|
||||||
} |
|
||||||
|
|
||||||
// Установить waiter для отложенного вызова |
|
||||||
waiter->max_packets = max_packets; |
|
||||||
waiter->max_bytes = max_bytes; |
|
||||||
waiter->callback = callback; |
|
||||||
waiter->callback_arg = arg; |
|
||||||
|
|
||||||
return waiter; |
|
||||||
} |
|
||||||
|
|
||||||
void queue_cancel_wait(struct ll_queue* q, struct queue_waiter* waiter) { |
|
||||||
if (!q || !waiter || waiter != &q->waiter) return; |
|
||||||
|
|
||||||
memset(waiter, 0, sizeof(*waiter)); |
|
||||||
} |
|
||||||
|
|
||||||
// ==================== Поиск и удаление по ID ==================== |
|
||||||
|
|
||||||
struct ll_entry* queue_find_data_by_id(struct ll_queue* q, uint32_t id) { |
|
||||||
if (!q || q->hash_size == 0 || !q->hash_table) return NULL; |
|
||||||
|
|
||||||
size_t slot = id % q->hash_size; |
|
||||||
struct ll_entry* entry = q->hash_table[slot]; |
|
||||||
|
|
||||||
while (entry) { |
|
||||||
if (entry->id == id) { |
|
||||||
return entry; |
|
||||||
} |
|
||||||
entry = entry->hash_next; |
|
||||||
} |
|
||||||
|
|
||||||
return NULL; |
|
||||||
} |
|
||||||
|
|
||||||
int queue_remove_data(struct ll_queue* q, struct ll_entry* entry) { |
|
||||||
if (!q || !entry) return -1; |
|
||||||
|
|
||||||
#ifdef QUEUE_THREAD_CHECK |
|
||||||
queue_check_thread(q); |
|
||||||
#endif |
|
||||||
|
|
||||||
// Удалить из двусвязного списка |
|
||||||
if (entry->prev) { |
|
||||||
entry->prev->next = entry->next; |
|
||||||
} else { |
|
||||||
q->head = entry->next; |
|
||||||
} |
|
||||||
|
|
||||||
if (entry->next) { |
|
||||||
entry->next->prev = entry->prev; |
|
||||||
} else { |
|
||||||
q->tail = entry->prev; |
|
||||||
} |
|
||||||
|
|
||||||
q->count--; |
|
||||||
q->total_bytes -= entry->int_len; |
|
||||||
|
|
||||||
entry->next = NULL; |
|
||||||
entry->prev = NULL; |
|
||||||
|
|
||||||
remove_from_hash(q, entry); |
|
||||||
|
|
||||||
// DEBUG_DEBUG(DEBUG_CATEGORY_LL_QUEUE, "queue_remove_data: removed entry %p (id=%u), count=%d", entry, entry->id, q->count); |
|
||||||
#ifdef QUEUE_DEBUG |
|
||||||
queue_check_consistency(q);// !!!! for debug |
|
||||||
#endif |
|
||||||
check_waiters(q); |
|
||||||
return 0; |
|
||||||
} |
|
||||||
@ -1,130 +0,0 @@ |
|||||||
#ifndef LL_QUEUE_H |
|
||||||
#define LL_QUEUE_H |
|
||||||
#include <stddef.h> |
|
||||||
#include <stdint.h> |
|
||||||
#include "memory_pool.h" |
|
||||||
#ifdef _WIN32 |
|
||||||
#include <winsock2.h> |
|
||||||
#include <windows.h> |
|
||||||
#else |
|
||||||
#include <pthread.h> |
|
||||||
#endif |
|
||||||
|
|
||||||
#define QUEUE_DEBUG 1 |
|
||||||
//#define QUEUE_THREAD_CHECK 1 |
|
||||||
|
|
||||||
// Forward declaration |
|
||||||
struct ll_queue; |
|
||||||
|
|
||||||
/** |
|
||||||
* @struct ll_entry |
|
||||||
* @brief Элемент очереди (переменного размера). |
|
||||||
* |
|
||||||
* Память: [struct ll_entry + data[size]]. |
|
||||||
* Индекс для поиска (произвольной длины) хранится в data[index_offset]. |
|
||||||
* Хеш (uint64_t) вычисляется по последним 8 байтам индекса. |
|
||||||
*/ |
|
||||||
struct ll_entry { |
|
||||||
char* name; |
|
||||||
struct ll_entry* next; |
|
||||||
struct ll_entry* prev; |
|
||||||
uint16_t size; ///< Размер data[] |
|
||||||
uint16_t len; |
|
||||||
uint16_t memlen; |
|
||||||
uint16_t int_len; |
|
||||||
uint8_t* dgram; |
|
||||||
void (*dgram_free_fn)(uint8_t* data); |
|
||||||
struct memory_pool* dgram_pool; |
|
||||||
struct memory_pool* pool; |
|
||||||
|
|
||||||
/* === НОВОЕ: поддержка индекса произвольной длины === */ |
|
||||||
uint16_t index_offset; ///< Смещение индекса в data[] |
|
||||||
uint16_t index_size; ///< Длина индекса (0 = без индекса) |
|
||||||
uint64_t index_hash; ///< Хеш по последним 8 байтам индекса |
|
||||||
|
|
||||||
struct ll_entry* hash_next; |
|
||||||
uint8_t data[0]; ///< Гибкий массив |
|
||||||
}; |
|
||||||
|
|
||||||
/* ... (остальные typedef'ы без изменений) ... */ |
|
||||||
|
|
||||||
struct ll_queue { |
|
||||||
char* name; |
|
||||||
struct ll_entry* head; |
|
||||||
struct ll_entry* tail; |
|
||||||
int count; |
|
||||||
size_t total_bytes; |
|
||||||
int size_limit; |
|
||||||
queue_callback_fn callback; |
|
||||||
void* callback_arg; |
|
||||||
int callback_suspended; |
|
||||||
void* resume_timeout_id; |
|
||||||
struct UASYNC* ua; |
|
||||||
struct queue_waiter waiter; |
|
||||||
struct ll_entry** hash_table; |
|
||||||
size_t hash_size; |
|
||||||
#ifdef QUEUE_THREAD_CHECK |
|
||||||
#ifdef _WIN32 |
|
||||||
DWORD owner_thread; |
|
||||||
#else |
|
||||||
pthread_t owner_thread; |
|
||||||
#endif |
|
||||||
#endif |
|
||||||
}; |
|
||||||
|
|
||||||
/* ==================== Создание / уничтожение ==================== */ |
|
||||||
struct ll_queue* queue_new(struct UASYNC* ua, size_t hash_size, char* name); |
|
||||||
void queue_free(struct ll_queue* q); |
|
||||||
|
|
||||||
/* ==================== Конфигурация ==================== */ |
|
||||||
void queue_set_size_limit(struct ll_queue* q, int lim); |
|
||||||
|
|
||||||
/* ==================== Автозабор элементов ==================== */ |
|
||||||
void queue_set_callback(struct ll_queue* q, queue_callback_fn cbk_fn, void* arg); |
|
||||||
void queue_resume_callback(struct ll_queue* q); |
|
||||||
|
|
||||||
/* ==================== Пороговое ожидание ==================== */ |
|
||||||
struct queue_waiter* queue_wait_threshold(struct ll_queue* q, int max_packets, size_t max_bytes, |
|
||||||
queue_threshold_callback_fn callback, void* arg); |
|
||||||
void queue_cancel_wait(struct ll_queue* q, struct queue_waiter* waiter); |
|
||||||
|
|
||||||
/* ==================== Работа с данными ==================== */ |
|
||||||
/* Упрощённая версия (без индекса) */ |
|
||||||
int queue_data_put(struct ll_queue* q, struct ll_entry* entry); |
|
||||||
int queue_data_put_first(struct ll_queue* q, struct ll_entry* entry); |
|
||||||
|
|
||||||
/* Версия с хешем по индексу произвольной длины */ |
|
||||||
int queue_data_put_with_index(struct ll_queue* q, struct ll_entry* entry, |
|
||||||
uint16_t index_offset, uint16_t index_size); |
|
||||||
int queue_data_put_first_with_index(struct ll_queue* q, struct ll_entry* entry, |
|
||||||
uint16_t index_offset, uint16_t index_size); |
|
||||||
|
|
||||||
struct ll_entry* queue_data_get(struct ll_queue* q); |
|
||||||
int queue_entry_count(struct ll_queue* q); |
|
||||||
|
|
||||||
/* ==================== Управление памятью ==================== */ |
|
||||||
struct ll_entry* ll_alloc_lldgram(uint16_t len); |
|
||||||
struct ll_entry* queue_entry_new(size_t data_size); |
|
||||||
struct ll_entry* queue_entry_new_from_pool(struct memory_pool* pool); |
|
||||||
void queue_entry_free(struct ll_entry* entry); |
|
||||||
void queue_dgram_free(struct ll_entry* entry); |
|
||||||
|
|
||||||
/* ==================== Поиск и удаление ==================== */ |
|
||||||
/** |
|
||||||
* @brief Поиск по индексу произвольной длины. |
|
||||||
* @note Хеш вычисляется по последним 8 байтам индекса. |
|
||||||
*/ |
|
||||||
struct ll_entry* queue_find_data_by_index(struct ll_queue* q, |
|
||||||
const void* index_key, |
|
||||||
uint16_t index_size); |
|
||||||
|
|
||||||
int queue_remove_data(struct ll_queue* q, struct ll_entry* entry); |
|
||||||
|
|
||||||
/* ==================== Утилиты ==================== */ |
|
||||||
static inline size_t queue_total_bytes(struct ll_queue* q) { |
|
||||||
return q ? q->total_bytes : 0; |
|
||||||
} |
|
||||||
|
|
||||||
int queue_check_consistency(struct ll_queue* q); |
|
||||||
|
|
||||||
#endif // LL_QUEUE_H |
|
||||||
Binary file not shown.
@ -1,6 +0,0 @@ |
|||||||
Есть 2 типа подключений - обычные (роутятся через подключения в конфиге) - по ним распространяется bgp и сигнальные пакеты |
|
||||||
|
|
||||||
А для передачи данных между узлами можно установить прямое подключение (или подключение через лучший промежуточный узел). |
|
||||||
|
|
||||||
Как работает: |
|
||||||
в nodeinfo |
|
||||||
@ -1,71 +0,0 @@ |
|||||||
подсистема роутинга |
|
||||||
utun - это сеть узлов. у каждого узла есть собственные локальные подсети. |
|
||||||
глобальная задача: создать у каждого узла полную таблицу маршрутизации. |
|
||||||
Узлы преимущественно создают связь напрямую друг с другом. Но если это не получается отправляют трафик транзитом через доступные узлы. |
|
||||||
Иногда бывает что через транзитные узлы метрики лучше чем напрямую. Используем приоритетно узлы с лучшей метриков, при нехватке bandwidth используем разные каналы (агрегируем). |
|
||||||
Динамически обновлем метрики каналов чтобы при отказе быстро переключаться на другие и не фризить обмен из-за отказов. |
|
||||||
|
|
||||||
|
|
||||||
и узлы обмениваются таблицой маршрутов между собой так чтобы у каждого была актуальная таблица подсетей всех узлов. |
|
||||||
маршрутами меняются клиенты, подключения которых которые взяты из конфига. и сервера принявшие подключения если клиент инициировал обмен маршрутами. |
|
||||||
|
|
||||||
инициируется подключение, клиент отправляет свою таблицу. когда сервер принимает таблицу - сервер помечает что по этому маршруту надо обмениваться маршрутами, далее; |
|
||||||
- добавляет узел в список рассылки обновлений маршрутов |
|
||||||
- отправляет свою таблицу |
|
||||||
- добавляет в свою таблицу отсутствующие маршруты |
|
||||||
- если что-то добавил: |
|
||||||
- рассылает измененные маршруты по списку рассылки |
|
||||||
- список рассылки - это linked-list очередей (также на базе ll_queue - каждый элемент = подписчик). один маршрут = одна отправленная кодограмма |
|
||||||
|
|
||||||
|
|
||||||
при подключении узла или изменении таблицы: узел шлёт свою таблицу |
|
||||||
формат кодограммы: [0x01 - routing module] [subcmd] [data] |
|
||||||
subcmd: |
|
||||||
1 [route] - отправка маршрута |
|
||||||
2, без данных - больше данных нет |
|
||||||
|
|
||||||
если сервер получил кодограмму маршрута - он помечает флаг в etcp что с узлом надо обмениваться маршрутами (etcp_conn->routing_exchange_active=2) и добавляет в очередь рассылки маршрутов |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
========================================= |
|
||||||
механизм инкрементальной синхронизации (реализация - потом, пока мысли) |
|
||||||
1. вычисляем хеш каждой записи в роутинг таблице. используем ip+mask+node_uid |
|
||||||
2. потом из этих хешей создаем хеш таблицу (старшие n бит номер ячейки). далее вычисляются хеши каждой ячейки. |
|
||||||
на первом этапе n=16, на втором - n=16*16 на третьем n=16*16*16. |
|
||||||
|
|
||||||
отправляем хеши удаленному узлу в формате: [n, 1 байт] ([индекс хеша 2 байта - используется n старших бит][хеш - 8 байт]) |
|
||||||
|
|
||||||
удаленный узел считает свои хеши и сравнивает. где не совпало смотрит сколько записей. |
|
||||||
если записей не много - передает эти записи. |
|
||||||
если записей много - добавляет 4 бита к хеш таблице и строит субтаблицу для |
|
||||||
========================================== |
|
||||||
|
|
||||||
Формат роутинга: |
|
||||||
|
|
||||||
Таблица узлов состоит из записей: |
|
||||||
- uid |
|
||||||
- name |
|
||||||
- links |
|
||||||
- 3 транзитных узла с метриками (RTT) |
|
||||||
- маршруты узла |
|
||||||
|
|
||||||
- текущая загрузка линка (за последние 10 сек) можно частоту адаптировать под размер сети |
|
||||||
- bandidth limit |
|
||||||
- transit bandwidth limit |
|
||||||
|
|
||||||
две группы узлов: |
|
||||||
- узлы за nat. подключаются через транзитные узлы. измеряют пинги до транзитных и выбирают N (3 default) лучшие линки. 3 лучших используем для распространения маршрутов |
|
||||||
- транзитные узлы. имеют линки с загрузкой. |
|
||||||
|
|
||||||
добавить кодограмму - отменить распространение маршрутов по линку (+ сделать важным линком) |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
карта маршрутизации: |
|
||||||
|
|
||||||
План: |
|
||||||
- сделать передачу роутинга в |
|
||||||
- сделать фоновый probe для узлов (условно 1 нода в секунду). выигравшие по качеству соатновятся основными |
|
||||||
- сделать etcp дизконнект: |
|
||||||
- отправить disconnect request + дождаться ack дальше master удаляет, slave удаляет по down. |
|
||||||
Binary file not shown.
@ -1,4 +0,0 @@ |
|||||||
Minimal fix applied to test_etcp_two_instances.c (removed duplicate init_connections calls before utun_instance_init). |
|
||||||
Test should no longer hit 'Address already in use' on second bind. |
|
||||||
Full test run requires fixing Makefile.am dependencies or rebuilding all src objects. |
|
||||||
Run 'make check' after fixing build to verify. |
|
||||||
Binary file not shown.
Binary file not shown.
@ -1,106 +0,0 @@ |
|||||||
[22:59:46-599.960] [INFO] [BGP] (route_bgp.c:390) route_bgp_init() route_bgp_init: node_id=5f75c7445af88e1f |
|
||||||
[22:59:46-600.017] [INFO] [BGP] (route_bgp.c:418) route_bgp_init() BGP module initialized (with hop_list support) |
|
||||||
[22:59:46-600.022] [INFO] [BGP] (utun_instance.c:117) instance_init_common() BGP module initialized |
|
||||||
[22:59:46-600.042] [INFO] [GENERAL] (etcp_connections.c:506) etcp_socket_add() Listen socket initialized: name=lan1 fd=8 addr=192.168.29.117:1333 |
|
||||||
[22:59:46-600.046] [INFO] [BGP] (etcp_connections.c:514) etcp_socket_add() Add Socket type=1 |
|
||||||
[22:59:46-600.061] [INFO] [GENERAL] (etcp_connections.c:506) etcp_socket_add() Listen socket initialized: name=lo0_test fd=9 addr=127.0.0.1:1330 |
|
||||||
[22:59:46-600.064] [INFO] [BGP] (etcp_connections.c:514) etcp_socket_add() Add Socket type=2 |
|
||||||
[22:59:46-600.832] [ERROR] [ETCP] (utun.c:391) main() Run mainloop |
|
||||||
[23:00:02-217.693] [TRACE] [BGP] (route_bgp.c:378) route_bgp_etcp_conn_cbk() Set ETCP ready callback for connection 8E1F->???? [] |
|
||||||
[23:00:02-217.724] [INFO] [GENERAL] (etcp_connections.c:948) etcp_connections_read_callback_socket() New connection received on socket lan1: log_name=8E1F->0C2D [] peer_id=7043239820550081581 |
|
||||||
[23:00:02-217.784] [INFO] [GENERAL] (etcp_connections.c:1079) etcp_connections_read_callback_socket() Connection established: log_name=8E1F->0C2D [] socket=lan1 link_id=1 status=UP |
|
||||||
[23:00:02-217.792] [TRACE] [BGP] (route_bgp.c:359) route_bgp_on_conn_up() Connection 8E1F->0C2D [] on up |
|
||||||
[23:00:02-217.797] [INFO] [BGP] (route_bgp.c:493) route_bgp_new_conn() New connection added to senders_list |
|
||||||
[23:00:02-217.806] [INFO] [BGP] (route_bgp.c:111) route_bgp_send_table_request() Sent table request to 8E1F->0C2D [] (version=0) |
|
||||||
[23:00:04-223.725] [TRACE] [BGP] (route_bgp.c:368) route_bgp_on_conn_down() Connection 8E1F->0C2D [] on down |
|
||||||
[23:00:04-223.747] [INFO] [BGP] (route_bgp.c:528) route_bgp_remove_conn() route_bgp_remove_conn: peer=61be9d4cd3c60c2d |
|
||||||
[23:00:04-223.763] [INFO] [BGP] (route_bgp.c:549) route_bgp_remove_conn() Connection removed, routes updated via route_remove_conn |
|
||||||
[23:00:04-223.768] [INFO] [GENERAL] (etcp_connections.c:262) keepalive_timer_cb() Link down: log_name=8E1F->0C2D [] socket=lan1 link_id=1 status=DOWN |
|
||||||
[23:44:58-804.874] [INFO] [GENERAL] (etcp_connections.c:1079) etcp_connections_read_callback_socket() Connection established: log_name=8E1F->0C2D [] socket=lan1 link_id=1 status=UP |
|
||||||
[23:44:58-804.949] [TRACE] [BGP] (route_bgp.c:359) route_bgp_on_conn_up() Connection 8E1F->0C2D [] on up |
|
||||||
[23:44:58-804.956] [INFO] [BGP] (route_bgp.c:493) route_bgp_new_conn() New connection added to senders_list |
|
||||||
[23:44:58-804.963] [INFO] [BGP] (route_bgp.c:111) route_bgp_send_table_request() Sent table request to 8E1F->0C2D [] (version=0) |
|
||||||
[23:44:58-804.973] [TRACE] [BGP] (route_bgp.c:368) route_bgp_on_conn_down() Connection 8E1F->0C2D [] on down |
|
||||||
[23:44:58-804.978] [INFO] [BGP] (route_bgp.c:528) route_bgp_remove_conn() route_bgp_remove_conn: peer=61be9d4cd3c60c2d |
|
||||||
[23:44:58-804.984] [INFO] [BGP] (route_bgp.c:549) route_bgp_remove_conn() Connection removed, routes updated via route_remove_conn |
|
||||||
[23:44:58-804.988] [INFO] [GENERAL] (etcp_connections.c:262) keepalive_timer_cb() Link down: log_name=8E1F->0C2D [] socket=lan1 link_id=1 status=DOWN |
|
||||||
[23:44:58-809.776] [TRACE] [BGP] (route_bgp.c:359) route_bgp_on_conn_up() Connection 8E1F->0C2D [] on up |
|
||||||
[23:44:58-809.832] [INFO] [BGP] (route_bgp.c:493) route_bgp_new_conn() New connection added to senders_list |
|
||||||
[23:44:58-809.846] [INFO] [BGP] (route_bgp.c:111) route_bgp_send_table_request() Sent table request to 8E1F->0C2D [] (version=0) |
|
||||||
[23:44:58-810.212] [INFO] [BGP] (route_bgp.c:256) route_bgp_receive_cbk() route_bgp_receive_cbk: from=61be9d4cd3c60c2d len=6 |
|
||||||
[23:44:58-810.260] [INFO] [BGP] (route_bgp.c:340) route_bgp_receive_cbk() Received table request from 8E1F->0C2D [] (version=0), sending full table |
|
||||||
[23:44:58-810.287] [INFO] [BGP] (route_bgp.c:78) route_bgp_send_route() Sending route 10.23.1.0/24, peer 8E1F->0C2D [] (ENTRY) |
|
||||||
[23:44:58-810.294] [INFO] [BGP] (route_bgp.c:126) route_bgp_send_full_table() Sent full routing table to 8E1F->0C2D [] (version=1) |
|
||||||
[23:44:58-814.981] [INFO] [BGP] (route_bgp.c:256) route_bgp_receive_cbk() route_bgp_receive_cbk: from=61be9d4cd3c60c2d len=18 |
|
||||||
[23:44:58-815.036] [INFO] [BGP] (route_bgp.c:302) route_bgp_receive_cbk() Received route 10.23.5.0/24 from 61be9d4cd3c60c2d (hops=1) |
|
||||||
[23:44:58-815.071] [INFO] [BGP] (route_bgp.c:144) route_bgp_broadcast_route() route_bgp_broadcast_route: network=10.23.5.0/24 exclude=0x56275e8e5d38 subcmd=1 |
|
||||||
[23:44:58-815.076] [TRACE] [BGP] (route_bgp.c:157) route_bgp_broadcast_route() route_bgp_broadcast_route: sent to 0 peers |
|
||||||
[23:44:58-815.080] [TRACE] [BGP] (route_bgp.c:318) route_bgp_receive_cbk() route_bgp_receive_cbk: INSERTED |
|
||||||
[23:44:58-815.085] [INFO] [BGP] (route_bgp.c:256) route_bgp_receive_cbk() route_bgp_receive_cbk: from=61be9d4cd3c60c2d len=18 |
|
||||||
[23:44:58-815.089] [INFO] [BGP] (route_bgp.c:302) route_bgp_receive_cbk() Received route 10.23.6.0/24 from 61be9d4cd3c60c2d (hops=1) |
|
||||||
[23:44:58-815.093] [INFO] [BGP] (route_bgp.c:144) route_bgp_broadcast_route() route_bgp_broadcast_route: network=10.23.6.0/24 exclude=0x56275e8e5d38 subcmd=1 |
|
||||||
[23:44:58-815.097] [TRACE] [BGP] (route_bgp.c:157) route_bgp_broadcast_route() route_bgp_broadcast_route: sent to 0 peers |
|
||||||
[23:44:58-815.100] [TRACE] [BGP] (route_bgp.c:318) route_bgp_receive_cbk() route_bgp_receive_cbk: INSERTED |
|
||||||
[23:44:58-815.213] [INFO] [BGP] (route_bgp.c:256) route_bgp_receive_cbk() route_bgp_receive_cbk: from=61be9d4cd3c60c2d len=18 |
|
||||||
[23:44:58-815.220] [INFO] [BGP] (route_bgp.c:302) route_bgp_receive_cbk() Received route 10.23.5.0/24 from 61be9d4cd3c60c2d (hops=1) |
|
||||||
[23:44:58-815.224] [INFO] [BGP] (route_bgp.c:144) route_bgp_broadcast_route() route_bgp_broadcast_route: network=10.23.5.0/24 exclude=0x56275e8e5d38 subcmd=2 |
|
||||||
[23:44:58-815.228] [TRACE] [BGP] (route_bgp.c:157) route_bgp_broadcast_route() route_bgp_broadcast_route: sent to 0 peers |
|
||||||
[23:44:58-815.231] [TRACE] [BGP] (route_bgp.c:318) route_bgp_receive_cbk() route_bgp_receive_cbk: INSERTED |
|
||||||
[23:44:58-815.235] [INFO] [BGP] (route_bgp.c:256) route_bgp_receive_cbk() route_bgp_receive_cbk: from=61be9d4cd3c60c2d len=18 |
|
||||||
[23:44:58-815.239] [INFO] [BGP] (route_bgp.c:302) route_bgp_receive_cbk() Received route 10.23.6.0/24 from 61be9d4cd3c60c2d (hops=1) |
|
||||||
[23:44:58-815.242] [INFO] [BGP] (route_bgp.c:144) route_bgp_broadcast_route() route_bgp_broadcast_route: network=10.23.6.0/24 exclude=0x56275e8e5d38 subcmd=2 |
|
||||||
[23:44:58-815.246] [TRACE] [BGP] (route_bgp.c:157) route_bgp_broadcast_route() route_bgp_broadcast_route: sent to 0 peers |
|
||||||
[23:44:58-815.249] [TRACE] [BGP] (route_bgp.c:318) route_bgp_receive_cbk() route_bgp_receive_cbk: INSERTED |
|
||||||
[00:40:35-599.488] [TRACE] [BGP] (route_bgp.c:368) route_bgp_on_conn_down() Connection 8E1F->0C2D [] on down |
|
||||||
[00:40:35-599.548] [INFO] [BGP] (route_bgp.c:528) route_bgp_remove_conn() route_bgp_remove_conn: peer=61be9d4cd3c60c2d |
|
||||||
[00:40:35-599.769] [INFO] [BGP] (route_bgp.c:166) route_bgp_broadcast_withdraw() route_bgp_broadcast_withdraw: node_id=61be9d4cd3c60c2d exclude=(nil) |
|
||||||
[00:40:35-599.795] [INFO] [BGP] (route_bgp.c:166) route_bgp_broadcast_withdraw() route_bgp_broadcast_withdraw: node_id=61be9d4cd3c60c2d exclude=(nil) |
|
||||||
[00:40:35-599.882] [INFO] [BGP] (route_bgp.c:549) route_bgp_remove_conn() Connection removed, routes updated via route_remove_conn |
|
||||||
[00:40:35-599.888] [INFO] [GENERAL] (etcp_connections.c:262) keepalive_timer_cb() Link down: log_name=8E1F->0C2D [] socket=lan1 link_id=1 status=DOWN |
|
||||||
[01:14:00-195.013] [TRACE] [BGP] (route_bgp.c:359) route_bgp_on_conn_up() Connection 8E1F->0C2D [] on up |
|
||||||
[01:14:00-195.072] [INFO] [BGP] (route_bgp.c:493) route_bgp_new_conn() New connection added to senders_list |
|
||||||
[01:14:00-195.084] [INFO] [BGP] (route_bgp.c:111) route_bgp_send_table_request() Sent table request to 8E1F->0C2D [] (version=0) |
|
||||||
[01:14:00-201.819] [INFO] [BGP] (route_bgp.c:256) route_bgp_receive_cbk() route_bgp_receive_cbk: from=61be9d4cd3c60c2d len=10 |
|
||||||
[01:14:00-201.866] [INFO] [BGP] (route_bgp.c:329) route_bgp_receive_cbk() Received WITHDRAW for node 5f75c7445af88e1f |
|
||||||
[01:14:00-201.888] [INFO] [BGP] (route_bgp.c:256) route_bgp_receive_cbk() route_bgp_receive_cbk: from=61be9d4cd3c60c2d len=6 |
|
||||||
[01:14:00-201.909] [INFO] [BGP] (route_bgp.c:340) route_bgp_receive_cbk() Received table request from 8E1F->0C2D [] (version=0), sending full table |
|
||||||
[01:14:00-201.920] [INFO] [BGP] (route_bgp.c:78) route_bgp_send_route() Sending route 10.23.1.0/24, peer 8E1F->0C2D [] (ENTRY) |
|
||||||
[01:14:00-201.924] [INFO] [BGP] (route_bgp.c:126) route_bgp_send_full_table() Sent full routing table to 8E1F->0C2D [] (version=1) |
|
||||||
[01:14:00-207.872] [INFO] [BGP] (route_bgp.c:256) route_bgp_receive_cbk() route_bgp_receive_cbk: from=61be9d4cd3c60c2d len=18 |
|
||||||
[01:14:00-207.908] [INFO] [BGP] (route_bgp.c:302) route_bgp_receive_cbk() Received route 10.23.5.0/24 from 61be9d4cd3c60c2d (hops=1) |
|
||||||
[01:14:00-207.916] [INFO] [BGP] (route_bgp.c:144) route_bgp_broadcast_route() route_bgp_broadcast_route: network=10.23.5.0/24 exclude=0x56275e8e5d38 subcmd=1 |
|
||||||
[01:14:00-207.920] [TRACE] [BGP] (route_bgp.c:157) route_bgp_broadcast_route() route_bgp_broadcast_route: sent to 0 peers |
|
||||||
[01:14:00-207.924] [TRACE] [BGP] (route_bgp.c:318) route_bgp_receive_cbk() route_bgp_receive_cbk: INSERTED |
|
||||||
[01:14:00-207.928] [INFO] [BGP] (route_bgp.c:256) route_bgp_receive_cbk() route_bgp_receive_cbk: from=61be9d4cd3c60c2d len=18 |
|
||||||
[01:14:00-207.932] [INFO] [BGP] (route_bgp.c:302) route_bgp_receive_cbk() Received route 10.23.6.0/24 from 61be9d4cd3c60c2d (hops=1) |
|
||||||
[01:14:00-207.936] [INFO] [BGP] (route_bgp.c:144) route_bgp_broadcast_route() route_bgp_broadcast_route: network=10.23.6.0/24 exclude=0x56275e8e5d38 subcmd=1 |
|
||||||
[01:14:00-207.939] [TRACE] [BGP] (route_bgp.c:157) route_bgp_broadcast_route() route_bgp_broadcast_route: sent to 0 peers |
|
||||||
[01:14:00-207.943] [TRACE] [BGP] (route_bgp.c:318) route_bgp_receive_cbk() route_bgp_receive_cbk: INSERTED |
|
||||||
[02:29:31-196.879] [TRACE] [BGP] (route_bgp.c:378) route_bgp_etcp_conn_cbk() Set ETCP ready callback for connection 8E1F->???? [] |
|
||||||
[02:29:31-196.922] [INFO] [GENERAL] (etcp_connections.c:948) etcp_connections_read_callback_socket() New connection received on socket lan1: log_name=8E1F->D894 [] peer_id=1206313594063214740 |
|
||||||
[02:29:31-196.953] [INFO] [GENERAL] (etcp_connections.c:1079) etcp_connections_read_callback_socket() Connection established: log_name=8E1F->D894 [] socket=lan1 link_id=1 status=UP |
|
||||||
[02:29:31-196.959] [TRACE] [BGP] (route_bgp.c:359) route_bgp_on_conn_up() Connection 8E1F->D894 [] on up |
|
||||||
[02:29:31-196.964] [INFO] [BGP] (route_bgp.c:493) route_bgp_new_conn() New connection added to senders_list |
|
||||||
[02:29:31-196.971] [INFO] [BGP] (route_bgp.c:111) route_bgp_send_table_request() Sent table request to 8E1F->D894 [] (version=0) |
|
||||||
[02:29:31-235.679] [INFO] [BGP] (route_bgp.c:256) route_bgp_receive_cbk() route_bgp_receive_cbk: from=10bdafd28ddcd894 len=18 |
|
||||||
[02:29:31-235.721] [INFO] [BGP] (route_bgp.c:302) route_bgp_receive_cbk() Received route 10.23.0.0/24 from 10bdafd28ddcd894 (hops=1) |
|
||||||
[02:29:31-235.729] [INFO] [BGP] (route_bgp.c:144) route_bgp_broadcast_route() route_bgp_broadcast_route: network=10.23.0.0/24 exclude=0x562763e892e8 subcmd=1 |
|
||||||
[02:29:31-235.738] [INFO] [BGP] (route_bgp.c:78) route_bgp_send_route() Sending route 10.23.0.0/24, peer 8E1F->0C2D [] (ENTRY) |
|
||||||
[02:29:31-235.743] [TRACE] [BGP] (route_bgp.c:157) route_bgp_broadcast_route() route_bgp_broadcast_route: sent to 1 peers |
|
||||||
[02:29:31-235.747] [TRACE] [BGP] (route_bgp.c:318) route_bgp_receive_cbk() route_bgp_receive_cbk: INSERTED |
|
||||||
[02:31:13-366.794] [TRACE] [BGP] (route_bgp.c:368) route_bgp_on_conn_down() Connection 8E1F->D894 [] on down |
|
||||||
[02:31:13-366.869] [INFO] [BGP] (route_bgp.c:528) route_bgp_remove_conn() route_bgp_remove_conn: peer=10bdafd28ddcd894 |
|
||||||
[02:31:13-366.956] [INFO] [BGP] (route_bgp.c:166) route_bgp_broadcast_withdraw() route_bgp_broadcast_withdraw: node_id=10bdafd28ddcd894 exclude=(nil) |
|
||||||
[02:31:13-366.977] [INFO] [BGP] (route_bgp.c:549) route_bgp_remove_conn() Connection removed, routes updated via route_remove_conn |
|
||||||
[02:31:13-366.982] [INFO] [GENERAL] (etcp_connections.c:262) keepalive_timer_cb() Link down: log_name=8E1F->D894 [] socket=lan1 link_id=1 status=DOWN |
|
||||||
[02:31:13-374.249] [INFO] [BGP] (route_bgp.c:256) route_bgp_receive_cbk() route_bgp_receive_cbk: from=61be9d4cd3c60c2d len=10 |
|
||||||
[02:31:13-374.306] [INFO] [BGP] (route_bgp.c:329) route_bgp_receive_cbk() Received WITHDRAW for node 0000000000000000 |
|
||||||
[02:31:17-925.784] [ERROR] [CONNECTION] (etcp_connections.c:635) etcp_link_new() Can not insert link to socket |
|
||||||
[02:31:17-925.819] [ERROR] [CONNECTION] (etcp_connections.c:1002) etcp_connections_read_callback_socket() etcp_connections_read_callback: failed to create link for connection |
|
||||||
[02:31:17-925.824] [ERROR] [ETCP] (etcp_connections.c:1221) etcp_connections_read_callback_socket() etcp_connections_read_callback: error 66 |
|
||||||
[02:31:17-968.183] [ERROR] [CONNECTION] (etcp_connections.c:635) etcp_link_new() Can not insert link to socket |
|
||||||
[02:31:17-968.247] [ERROR] [CONNECTION] (etcp_connections.c:1002) etcp_connections_read_callback_socket() etcp_connections_read_callback: failed to create link for connection |
|
||||||
[02:31:17-968.253] [ERROR] [ETCP] (etcp_connections.c:1221) etcp_connections_read_callback_socket() etcp_connections_read_callback: error 66 |
|
||||||
[02:31:18-018.408] [ERROR] [CONNECTION] (etcp_connections.c:635) etcp_link_new() Can not insert link to socket |
|
||||||
[02:31:18-018.452] [ERROR] [CONNECTION] (etcp_connections.c:1002) etcp_connections_read_callback_socket() etcp_connections_read_callback: failed to create link for connection |
|
||||||
[02:31:18-018.457] [ERROR] [ETCP] (etcp_connections.c:1221) etcp_connections_read_callback_socket() etcp_connections_read_callback: error 66 |
|
||||||
Loading…
Reference in new issue