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