817 lines
22 KiB
Markdown
817 lines
22 KiB
Markdown
# 📊 ANALIZĂ ARHITECTURALĂ SENIOR - Underchat IRCD (C)
|
||
|
||
**Data Analiză**: 23 Februarie 2026
|
||
**Versiune Proiect**: v1.7.5
|
||
**Analist**: Senior Software Architect (Protocoale de rețea & Sisteme distribuite)
|
||
**Limbaj**: C (confirmat - nu Python)
|
||
**Bază**: UnderNet IRCU2 - Protocol P10 (RFC 1459/2812)
|
||
|
||
---
|
||
|
||
## 🎯 EXECUTIVE SUMMARY
|
||
|
||
**Underchat IRCD** este o implementare matură în C a unui server IRC bazat pe codul UnderNet IRCU2. Arhitectura este **SINGLE-THREADED cu EVENT LOOP non-blocking**, folosind multiplexare I/O avansată (epoll/kqueue/poll/select).
|
||
|
||
### Verdict Rapid:
|
||
- ✅ **Arhitectură solidă**: Event-driven, non-blocking I/O
|
||
- ⚠️ **Performanță**: Single-threaded (limitată de CPU-ul unui singur core)
|
||
- ⚠️ **Securitate**: Câteva utilizări nesigure de strcpy/strcat/sprintf
|
||
- ✅ **RFC Compliance**: Bună conformitate cu RFC 1459/2812
|
||
- ⚠️ **Memory Management**: Potențiale leaks în gestionarea bufferelor
|
||
|
||
---
|
||
|
||
## 🏗️ ARHITECTURA SISTEMULUI
|
||
|
||
### 1. MODEL DE CONCURRENCY
|
||
|
||
**Tip**: Single-threaded, Event-driven Architecture
|
||
**Pattern**: Reactor Pattern (event loop centralizat)
|
||
|
||
```
|
||
┌─────────────────────────────────────────────┐
|
||
│ MAIN EVENT LOOP (ircd.c) │
|
||
│ │
|
||
│ while (running) { │
|
||
│ engine_loop() -> epoll_wait()/poll() │
|
||
│ ├─ Socket Events (READ/WRITE/ACCEPT) │
|
||
│ ├─ Timer Events │
|
||
│ └─ Signal Events │
|
||
│ } │
|
||
└─────────────────────────────────────────────┘
|
||
│
|
||
├─> Socket Layer (s_bsd.c)
|
||
│ ├─ LocalClientArray[MAXCONNECTIONS]
|
||
│ ├─ HighestFd tracking
|
||
│ └─ Non-blocking sockets
|
||
│
|
||
├─> Event Engine (ircd_events.c)
|
||
│ ├─ Engine abstraction layer
|
||
│ ├─ Multiple backends:
|
||
│ │ • epoll (Linux) ★ PREFERRED
|
||
│ │ • kqueue (BSD/macOS)
|
||
│ │ • /dev/poll (Solaris)
|
||
│ │ • poll() fallback
|
||
│ │ • select() fallback
|
||
│ └─ Generator/Event system
|
||
│
|
||
├─> Parser (parse.c)
|
||
│ ├─ Trie-based command lookup
|
||
│ ├─ Message dispatch table (msgtab[])
|
||
│ └─ Handler functions (m_*.c)
|
||
│
|
||
└─> Buffer Management
|
||
├─ DBuf (input buffers - dbuf.c)
|
||
├─ MsgQ (output queues - msgq.c)
|
||
└─ Packet processing (packet.c)
|
||
```
|
||
|
||
#### 1.1 Event Engine Architecture
|
||
|
||
**Fișiere cheie**:
|
||
- `ircd/ircd_events.c` - Event loop core
|
||
- `ircd/engine_epoll.c` - Linux epoll backend (PREFERRED)
|
||
- `ircd/engine_kqueue.c` - BSD kqueue backend
|
||
- `ircd/engine_poll.c` - Poll fallback
|
||
- `ircd/engine_select.c` - Select fallback
|
||
|
||
**Prioritizare Engine**:
|
||
```c
|
||
static const struct Engine *evEngines[] = {
|
||
ENGINE_KQUEUE // BSD/macOS
|
||
ENGINE_EPOLL // Linux ★
|
||
ENGINE_DEVPOLL // Solaris
|
||
ENGINE_FALLBACK // poll() sau select()
|
||
0
|
||
};
|
||
```
|
||
|
||
**Event Types** (enum EventType):
|
||
- `ET_READ` - Socket ready for reading
|
||
- `ET_WRITE` - Socket ready for writing
|
||
- `ET_ACCEPT` - New connection available
|
||
- `ET_CONNECT` - Outbound connection completed
|
||
- `ET_EOF` - Connection closed
|
||
- `ET_ERROR` - Error condition
|
||
- `ET_SIGNAL` - Signal received
|
||
- `ET_EXPIRE` - Timer expired
|
||
- `ET_DESTROY` - Resource cleanup
|
||
|
||
---
|
||
|
||
### 2. GESTIONAREA SOCKET-URILOR
|
||
|
||
#### 2.1 Structura Conexiunilor
|
||
|
||
**LocalClientArray** (`s_bsd.c:83`):
|
||
```c
|
||
struct Client* LocalClientArray[MAXCONNECTIONS];
|
||
int HighestFd = -1;
|
||
```
|
||
|
||
- **Array indexat după file descriptor**
|
||
- Dimensiune fixă: `MAXCONNECTIONS` (tipic 1024-4096)
|
||
- O(1) lookup pentru evenimente pe socket
|
||
- `HighestFd` optimizează iterarea prin conexiuni active
|
||
|
||
#### 2.2 Socket States (enum SocketState)
|
||
|
||
```c
|
||
SS_CONNECTING // Conexiune outbound în progres
|
||
SS_LISTENING // Socket ascultător
|
||
SS_CONNECTED // Socket conectat bidirectional
|
||
SS_DATAGRAM // Socket UDP (pentru UPING)
|
||
SS_CONNECTDG // UDP conectat
|
||
SS_NOTSOCK // Non-socket (pipe pentru semnale)
|
||
```
|
||
|
||
#### 2.3 Read/Write Flow
|
||
|
||
**READ PATH** (`s_bsd.c` - `read_packet()`):
|
||
```
|
||
recv() → DBuf (cli_recvQ) → packet.c → parse.c → handler (m_*.c)
|
||
```
|
||
|
||
**WRITE PATH** (`send.c` - `send_queued()`):
|
||
```
|
||
Handler → MsgQ (cli_sendQ) → deliver_it() → send()/writev()
|
||
```
|
||
|
||
**Non-blocking cu edge-triggered events** (epoll cu EPOLLET).
|
||
|
||
---
|
||
|
||
### 3. BUFFER MANAGEMENT
|
||
|
||
#### 3.1 Input Buffers (DBuf)
|
||
|
||
**Fișiere**: `ircd/dbuf.c`, `include/dbuf.h`
|
||
|
||
```c
|
||
struct DBuf {
|
||
unsigned int length; // Bytes în buffer
|
||
struct DBufBuffer *head; // Primul chunk
|
||
struct DBufBuffer *tail; // Ultimul chunk
|
||
};
|
||
```
|
||
|
||
**Caracteristici**:
|
||
- **Linked list de chunked buffers**
|
||
- Evită realocări mari
|
||
- Pool de buffere reutilizabile
|
||
- `DBufAllocCount` / `DBufUsedCount` - tracking memorie
|
||
|
||
**PROBLEMA POTENȚIALĂ**:
|
||
- ⚠️ Fără limită hard pe lungimea totală a unui DBuf
|
||
- Posibil vector de atac DoS prin flood de date incomplete
|
||
|
||
#### 3.2 Output Queues (MsgQ)
|
||
|
||
**Fișiere**: `ircd/msgq.c`, `include/msgq.h`
|
||
|
||
```c
|
||
struct MsgQ {
|
||
unsigned int length; // Bytes în queue
|
||
unsigned int count; // Număr de mesaje
|
||
struct MsgQList queue; // Queue normal
|
||
struct MsgQList prio; // Queue prioritar
|
||
};
|
||
```
|
||
|
||
**Caracteristici**:
|
||
- **Două queue-uri** (normal + prioritar)
|
||
- Mesajele server-to-server au prioritate
|
||
- `msgq_add()` - adaugă cu prioritizare
|
||
- `msgq_mapiov()` - mapare pentru writev()
|
||
|
||
**MĂSURI FLOOD PROTECTION**:
|
||
```c
|
||
// send.c:128 - Kill highest sendq când suntem fără memorie
|
||
void kill_highest_sendq(int servers_too)
|
||
```
|
||
|
||
---
|
||
|
||
### 4. PARSING & MESSAGE DISPATCH
|
||
|
||
#### 4.1 Command Lookup - Trie Data Structure
|
||
|
||
**Fișier**: `ircd/parse.c`
|
||
|
||
**Structură**:
|
||
```c
|
||
struct MessageTree {
|
||
struct Message *msg;
|
||
struct MessageTree *pointers[MAXPTRLEN]; // 32 pointers
|
||
};
|
||
|
||
static struct MessageTree msg_tree; // Comenzi text (PRIVMSG)
|
||
static struct MessageTree tok_tree; // Token-uri P10 (P)
|
||
```
|
||
|
||
**Avantaje**:
|
||
- O(k) lookup unde k = lungime comandă
|
||
- Suport dual: text + P10 tokens
|
||
- Rapid pentru comenzile frecvente
|
||
|
||
**Exemplu** (`parse.c:110`):
|
||
```c
|
||
struct Message msgtab[] = {
|
||
{ MSG_PRIVATE, TOK_PRIVATE, 0, MAXPARA, MFLG_SLOW, 0, NULL,
|
||
{ m_unregistered, m_privmsg, ms_privmsg, mo_privmsg, m_ignore },
|
||
"<target> :<message>"
|
||
},
|
||
// ... 100+ comenzi
|
||
};
|
||
```
|
||
|
||
#### 4.2 Handler Dispatch
|
||
|
||
**5 handler-uri per comandă**:
|
||
```c
|
||
{ m_unregistered, // UNREG - client neînregistrat
|
||
m_privmsg, // CLIENT - user normal
|
||
ms_privmsg, // SERVER - inter-server
|
||
mo_privmsg, // OPER - operator
|
||
m_ignore } // SERVICE - servicii (ignorat)
|
||
```
|
||
|
||
---
|
||
|
||
### 5. PROTOCOL COMPLIANCE (RFC 1459/2812)
|
||
|
||
#### 5.1 Conformitate RFC
|
||
|
||
✅ **BINE IMPLEMENTAT**:
|
||
- Message framing (512 bytes max cu CR-LF)
|
||
- Command parsing (prefix, command, params)
|
||
- Numeric replies (001-999)
|
||
- Channel modes (+o, +v, +b, +k, +l, etc.)
|
||
- User modes (+i, +w, +o, etc.)
|
||
- Server-to-server protocol (P10)
|
||
|
||
⚠️ **DEVIERI DE LA RFC**:
|
||
- Protocol P10 (UnderNet specific) - nu este RFC standard
|
||
- Numeric nicks (server NN, user NNNNN)
|
||
- Extended modes (nu sunt în RFC 1459)
|
||
|
||
#### 5.2 Message Format
|
||
|
||
**Parsing** (`packet.c:75-90`):
|
||
```c
|
||
// CORECT: Acceptă CR sau LF ca terminator
|
||
if (IsEol(*endp)) {
|
||
if (endp == client_buffer)
|
||
continue; // Skip extra LF/CR's
|
||
*endp = '\0';
|
||
|
||
if (parse_server(cptr, cli_buffer(cptr), endp) == CPTR_KILLED)
|
||
return CPTR_KILLED;
|
||
// ...
|
||
}
|
||
```
|
||
|
||
**PROBLEMA**:
|
||
- ⚠️ Acceptă CR SAU LF (nu doar CR-LF)
|
||
- Mai permisiv decât RFC, dar backward compatible
|
||
|
||
---
|
||
|
||
## 🔒 ANALIZĂ SECURITATE
|
||
|
||
### 1. INPUT VALIDATION
|
||
|
||
#### 1.1 Buffer Overflows - RISC MODERAT
|
||
|
||
**PROBLEME IDENTIFICATE**:
|
||
|
||
**strcpy/strcat/sprintf Usage** (20 instanțe):
|
||
```c
|
||
// ircd/s_user.c:744 - UNSAFE
|
||
strcpy(cli_name(new_client), nick);
|
||
|
||
// ircd/uping.c:290 - UNSAFE
|
||
sprintf(buf, " %10lu%c%6lu", ...);
|
||
|
||
// ircd/m_whois.c:148-149 - UNSAFE
|
||
strcat(markbufp, ", ");
|
||
strcat(markbufp, dp->value.cp);
|
||
```
|
||
|
||
**RECOMANDĂRI**:
|
||
```c
|
||
// Înlocuiește cu:
|
||
ircd_strncpy(cli_name(new_client), nick, NICKLEN);
|
||
ircd_snprintf(buf, sizeof(buf), " %10lu%c%6lu", ...);
|
||
```
|
||
|
||
✅ **BUN**: Proiectul folosește deja `ircd_strncpy()` și `ircd_snprintf()` în multe locuri.
|
||
|
||
#### 1.2 UTF-8 Validation
|
||
|
||
✅ **BINE IMPLEMENTAT** (`ircd_string.c:60`):
|
||
```c
|
||
int string_is_valid_utf8(const char * str)
|
||
```
|
||
- Validare completă UTF-8
|
||
- Detectează encoding invalid
|
||
- Protecție contra caractere de control
|
||
|
||
---
|
||
|
||
### 2. FLOOD PROTECTION
|
||
|
||
#### 2.1 Connection Rate Limiting
|
||
|
||
**Fișier**: `ircd/IPcheck.c`
|
||
|
||
**Mecanisme**:
|
||
```c
|
||
#define IPCHECK_CLONE_LIMIT // Max clone de pe același IP
|
||
#define IPCHECK_CLONE_PERIOD // Fereastra de timp
|
||
#define IPCHECK_CLONE_DELAY // Delay între conexiuni
|
||
|
||
struct IPRegistryEntry {
|
||
unsigned short connected; // Clienți conectați
|
||
unsigned char attempts; // Încercări recente
|
||
int last_connect; // Timestamp ultima conexiune
|
||
};
|
||
```
|
||
|
||
**Hash Table**: `IP_REGISTRY_TABLE_SIZE = 0x10000` (64K buckets)
|
||
|
||
**IPv6 Handling**:
|
||
- Doar primii 64 biți sunt considerați (rețea)
|
||
- Ultimii 64 biți (host) sunt ignorați
|
||
- Protecție contra abuzului de IPv6 /64
|
||
|
||
✅ **BUNĂ PRACTICĂ**: Canonicalizare IP pentru comparație.
|
||
|
||
#### 2.2 Message Rate Limiting
|
||
|
||
**Target Limiting** (`IPcheck.c:48`):
|
||
```c
|
||
struct IPTargetEntry {
|
||
unsigned int count; // Target-uri libere
|
||
unsigned char targets[MAXTARGETS]; // Target-uri recente
|
||
};
|
||
|
||
#define MAXTARGETS 20 // Max target-uri
|
||
#define STARTTARGETS 10 // Target-uri inițiale
|
||
```
|
||
|
||
**Token Bucket Algorithm**:
|
||
- Utilizatorii încep cu `STARTTARGETS` mesaje
|
||
- Reîncărcare progresivă: `TARGET_DELAY` secunde
|
||
- Previne spam cross-channel
|
||
|
||
#### 2.3 SendQ Limiting
|
||
|
||
**High SendQ Killing** (`send.c:115`):
|
||
```c
|
||
void kill_highest_sendq(int servers_too) {
|
||
// Găsește clientul cu cel mai mare sendQ
|
||
// Îl deconectează pentru a elibera memorie
|
||
}
|
||
```
|
||
|
||
⚠️ **PROBLEMA**:
|
||
- Trigger doar când sistemul e deja low memory
|
||
- Nu există limită preventivă per-client
|
||
- Posibil DoS prin umplerea sendQ
|
||
|
||
**RECOMANDARE**:
|
||
```c
|
||
#define MAX_SENDQ_PER_CLIENT (64 * 1024) // 64KB
|
||
|
||
if (MsgQLength(&cli_sendQ(client)) > MAX_SENDQ_PER_CLIENT) {
|
||
dead_link(client, "SendQ exceeded");
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 3. MEMORY LEAKS - RISC MODERAT
|
||
|
||
#### 3.1 DBuf/MsgQ Cleanup
|
||
|
||
✅ **BUNĂ PRACTICĂ**:
|
||
```c
|
||
// s_bsd.c - Cleanup la disconnect
|
||
DBufClear(&(cli_recvQ(to)));
|
||
MsgQClear(&(cli_sendQ(to)));
|
||
```
|
||
|
||
⚠️ **PROBLEME POTENȚIALE**:
|
||
|
||
1. **Incomplete Message Buffers**:
|
||
- Dacă un client trimite date incomplete și nu mai trimite CR-LF
|
||
- Buffer rămâne alocat indefinit
|
||
- `FLAG_NONL` este setat dar nu există timeout
|
||
|
||
2. **Event Generator Leaks**:
|
||
- `gen_ref_dec()` trebuie apelat corect
|
||
- Dacă reference count nu ajunge la 0 → leak
|
||
|
||
**RECOMANDARE**:
|
||
```c
|
||
// Adaugă timeout pentru conexiuni incomplete
|
||
#define INCOMPLETE_MESSAGE_TIMEOUT 30 // secunde
|
||
|
||
if (HasFlag(cptr, FLAG_NONL) &&
|
||
CurrentTime - cli_lasttime(cptr) > INCOMPLETE_MESSAGE_TIMEOUT) {
|
||
dead_link(cptr, "Incomplete message timeout");
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 4. RACE CONDITIONS
|
||
|
||
✅ **EVITATE** - Single-threaded architecture elimină majoritatea race conditions.
|
||
|
||
⚠️ **EXCEPȚIE**: Signal Handlers
|
||
|
||
```c
|
||
// ircd_signal.c - Signal handling
|
||
// Handlers scriu într-un pipe non-blocking
|
||
// Main loop citește din pipe → safe
|
||
```
|
||
|
||
**BUNĂ PRACTICĂ**: Self-pipe trick pentru semnale.
|
||
|
||
---
|
||
|
||
## ⚡ ANALIZĂ PERFORMANȚĂ
|
||
|
||
### 1. SCALABILITATE
|
||
|
||
#### 1.1 Connection Capacity
|
||
|
||
**LIMITE**:
|
||
```c
|
||
// MAXCONNECTIONS definit la compile-time
|
||
// Tipic: 1024-4096
|
||
|
||
LocalClientArray[MAXCONNECTIONS];
|
||
```
|
||
|
||
**C10K Problem**:
|
||
- ✅ REZOLVAT prin epoll/kqueue
|
||
- ⚠️ Single-threaded → limitat de 1 CPU core
|
||
|
||
**Benchmark Estimate** (pe hardware modern):
|
||
- ~5,000-10,000 clienți idle
|
||
- ~1,000-2,000 clienți activi
|
||
- Limitat de CPU pentru parsing/routing
|
||
|
||
#### 1.2 Message Throughput
|
||
|
||
**Bottleneck-uri**:
|
||
|
||
1. **Trie Lookup**: O(k) - foarte rapid
|
||
2. **Handler Execution**: Variabil per comandă
|
||
3. **Broadcast** (PRIVMSG la channel mare):
|
||
```c
|
||
// O(N) unde N = număr membrii
|
||
for (member in channel->members)
|
||
sendto_member(member, message);
|
||
```
|
||
|
||
**OPTIMIZARE SUGERATĂ**:
|
||
- Batch writes cu `writev()` ✅ (deja implementat)
|
||
- SendQ prioritization ✅ (deja implementat)
|
||
- ❌ LIPSĂ: Message coalescing pentru broadcasts
|
||
|
||
### 2. MEMORY FOOTPRINT
|
||
|
||
#### 2.1 Per-Client Memory
|
||
|
||
```c
|
||
struct Client {
|
||
struct Connection* cli_connect; // ~200 bytes
|
||
struct User* cli_user; // ~400 bytes (dacă user)
|
||
struct Server* cli_serv; // ~300 bytes (dacă server)
|
||
// + buffers:
|
||
struct DBuf cli_recvQ; // ~8 bytes + date
|
||
struct MsgQ cli_sendQ; // ~16 bytes + date
|
||
char cli_buffer[BUFSIZE]; // 512 bytes
|
||
};
|
||
```
|
||
|
||
**Total per client**: ~1-2 KB (fără buffers de date)
|
||
|
||
**Cu buffers**: +4-64 KB (variabil, depinde de traffic)
|
||
|
||
#### 2.2 Memory Pools
|
||
|
||
✅ **BUNĂ PRACTICĂ**:
|
||
```c
|
||
// IPcheck.c:192
|
||
static struct IPRegistryEntry* freeList;
|
||
|
||
// Refolosire structuri în loc de free/malloc repetat
|
||
```
|
||
|
||
---
|
||
|
||
### 3. LATENCY
|
||
|
||
**Message Latency Path**:
|
||
```
|
||
Client A → recv() → parse → handler → sendto → Client B's sendQ → send()
|
||
↑_____ ~0.1-1ms (local) _____↑
|
||
```
|
||
|
||
**Factori latență**:
|
||
1. **Syscall overhead**: recv/send
|
||
2. **Event loop iteration**: ~1-10ms între iterații
|
||
3. **SendQ flushing**: Doar când socket e writable
|
||
|
||
✅ **OPTIMIZARE**: Write imediat dacă sendQ e gol
|
||
```c
|
||
// send.c - try immediate write before queueing
|
||
```
|
||
|
||
---
|
||
|
||
## 🐛 VULNERABILITĂȚI IDENTIFICATE
|
||
|
||
### CRITICAL (🔴)
|
||
|
||
*Niciuna identificată în analiza curentă*
|
||
|
||
### HIGH (🟠)
|
||
|
||
1. **SendQ Exhaustion DoS**
|
||
- **Locație**: `send.c`
|
||
- **Risc**: Client poate umple sendQ până la OOM
|
||
- **Fix**: Limită hard per-client + disconnect proactiv
|
||
|
||
2. **Incomplete Message Buffer Leak**
|
||
- **Locație**: `packet.c`, `s_bsd.c`
|
||
- **Risc**: Mesaje fără CR-LF rămân în memorie
|
||
- **Fix**: Timeout pentru FLAG_NONL
|
||
|
||
### MEDIUM (🟡)
|
||
|
||
3. **Unsafe String Operations**
|
||
- **Locație**: Multiple (20 instanțe strcpy/strcat/sprintf)
|
||
- **Risc**: Buffer overflow dacă input nevalidat
|
||
- **Fix**: Replace with ircd_strncpy/ircd_snprintf
|
||
|
||
4. **IPv6 Clone Detection Limited**
|
||
- **Locație**: `IPcheck.c`
|
||
- **Risc**: Doar /64 verificat, nu full /128
|
||
- **Fix**: Opțiune configurabilă pentru prefix length
|
||
|
||
### LOW (🟢)
|
||
|
||
5. **Message Parser Permissiveness**
|
||
- **Locație**: `packet.c`
|
||
- **Risc**: Acceptă CR sau LF (nu doar CR-LF)
|
||
- **Fix**: Strict RFC mode optional
|
||
|
||
---
|
||
|
||
## 📊 METRICI DE CALITATE COD
|
||
|
||
### Complexitate
|
||
|
||
| Metric | Valoare | Assessment |
|
||
|--------|---------|------------|
|
||
| **Files** | ~150 .c files | Mare |
|
||
| **Lines of Code** | ~50,000+ | Mare |
|
||
| **Functions** | ~1,000+ | Modular |
|
||
| **Max Function Size** | ~500 lines | 🟡 Unele funcții mari |
|
||
| **Cyclomatic Complexity** | Variabilă | 🟡 Averaging medium |
|
||
|
||
### Maintainability
|
||
|
||
✅ **PRO**:
|
||
- Modularizare clară (per-funcționalitate)
|
||
- Headers separate cu API-uri clare
|
||
- Comentarii rezonabile
|
||
- Coding style consistent
|
||
|
||
⚠️ **CONTRA**:
|
||
- Global state extensiv (GlobalClientList, etc.)
|
||
- Macro-uri complexe (client accessors)
|
||
- Unele funcții foarte lungi
|
||
- Documentație inline limitată
|
||
|
||
---
|
||
|
||
## 🎯 RECOMANDĂRI PRIORITIZATE
|
||
|
||
### URGENT (Implementare în 1-2 săptămâni)
|
||
|
||
1. **🔒 Fix Unsafe String Operations**
|
||
```c
|
||
// Replace toate instanțele:
|
||
strcpy() → ircd_strncpy()
|
||
strcat() → ircd_strlcat() sau snprintf()
|
||
sprintf() → ircd_snprintf()
|
||
```
|
||
|
||
2. **🛡️ SendQ Hard Limits**
|
||
```c
|
||
#define MAX_SENDQ_USER 65536 // 64KB
|
||
#define MAX_SENDQ_SERVER 524288 // 512KB
|
||
|
||
// În send.c, verifică înainte de msgq_add()
|
||
```
|
||
|
||
3. **⏱️ Incomplete Message Timeout**
|
||
```c
|
||
// În s_bsd.c read_packet():
|
||
if (HasFlag(cptr, FLAG_NONL) && timeout_exceeded(cptr)) {
|
||
dead_link(cptr, "Incomplete message timeout");
|
||
}
|
||
```
|
||
|
||
### SHORT-TERM (1-3 luni)
|
||
|
||
4. **📊 Monitoring & Metrics**
|
||
```c
|
||
// Adaugă contoare pentru:
|
||
- Mesaje procesate/sec
|
||
- Conexiuni acceptate/respinse
|
||
- SendQ usage histogram
|
||
- CPU usage per handler
|
||
```
|
||
|
||
5. **🧪 Unit Testing**
|
||
- Parser tests (trie lookup)
|
||
- Buffer management tests (DBuf, MsgQ)
|
||
- IPcheck tests (rate limiting)
|
||
- Mock socket tests
|
||
|
||
6. **📝 Memory Leak Detection**
|
||
```bash
|
||
# Run sub Valgrind
|
||
valgrind --leak-check=full --track-origins=yes ./ircd
|
||
```
|
||
|
||
### MID-TERM (3-6 luni)
|
||
|
||
7. **⚡ Performance Optimizations**
|
||
- Message coalescing pentru broadcast
|
||
- Zero-copy buffer passing (splice/sendfile)
|
||
- JIT compilation pentru hot commands (optional)
|
||
|
||
8. **🔐 Security Hardening**
|
||
- ASLR verification
|
||
- Stack canaries
|
||
- Seccomp filters (Linux)
|
||
- Pledge/unveil (OpenBSD)
|
||
|
||
9. **📚 Documentation**
|
||
- Architecture diagrams (flow charts)
|
||
- API documentation (Doxygen)
|
||
- Security audit report
|
||
- Performance tuning guide
|
||
|
||
### LONG-TERM (6-12 luni)
|
||
|
||
10. **🧵 Multi-threading (Optional)**
|
||
- Thread pool pentru parsing
|
||
- Lock-free queues pentru cross-thread messaging
|
||
- MASSIVE REFACTOR - evaluat risc/beneficiu
|
||
|
||
11. **🌐 IPv6 Full Support**
|
||
- Full /128 tracking în IPcheck
|
||
- IPv6-only mode
|
||
- Dual-stack optimization
|
||
|
||
12. **🔄 Protocol Extensions**
|
||
- IRCv3 capabilities
|
||
- WebSocket support
|
||
- Message tags
|
||
|
||
---
|
||
|
||
## 📈 COMPARAȚIE CU ALTERNATIVE
|
||
|
||
| Caracteristică | Underchat IRCD | Inspircd | UnrealIRCd | Charybdis |
|
||
|----------------|----------------|----------|------------|-----------|
|
||
| **Limbaj** | C | C++ | C | C |
|
||
| **Threading** | Single | Multi-thread | Multi-thread | Single |
|
||
| **Event Loop** | epoll/kqueue | epoll/kqueue | epoll/kqueue | epoll/kqueue |
|
||
| **Protocol** | P10 (UnderNet) | Modular | Modular | TS6 |
|
||
| **RFC Compliance** | 🟡 Medium | ✅ High | ✅ High | ✅ High |
|
||
| **Extensibility** | 🟡 Medium | ✅ High (modules) | ✅ High (modules) | ✅ High (modules) |
|
||
| **Memory Safety** | 🟡 C (manual) | 🟡 C++ (manual) | 🟡 C (manual) | 🟡 C (manual) |
|
||
| **Performance** | 🟢 Good | ✅ Excellent | ✅ Excellent | 🟢 Good |
|
||
| **Maturitate** | ✅ Mature | ✅ Mature | ✅ Mature | ✅ Mature |
|
||
|
||
**Verdict**:
|
||
- **Underchat IRCD** este competitiv pentru rețele mici-medii (< 5000 useri)
|
||
- Pentru scale mai mare: consideră InspIRCd (multi-thread) sau Charybdis (TS6)
|
||
|
||
---
|
||
|
||
## 🎓 CONCLUZIE
|
||
|
||
### Strengths (💪)
|
||
|
||
1. **Arhitectură solidă**: Event-driven, non-blocking I/O
|
||
2. **Cod matur**: Bazat pe UnderNet IRCU2 (20+ ani de dezvoltare)
|
||
3. **Performanță bună**: Pentru cazuri de utilizare single-core
|
||
4. **Modularitate**: Comenzi separate în m_*.c files
|
||
5. **Portabilitate**: Suport multi-platform (Linux, BSD, macOS)
|
||
|
||
### Weaknesses (⚠️)
|
||
|
||
1. **Single-threaded**: Nu scalează pe multi-core
|
||
2. **Unsafe C**: 20+ instanțe de strcpy/strcat/sprintf
|
||
3. **Memory management**: Potențiale leaks în edge cases
|
||
4. **Limited flood protection**: SendQ fără limită hard
|
||
5. **Protocol lock-in**: P10 specific (nu compatibil cu alte rețele)
|
||
|
||
### Risk Assessment
|
||
|
||
| Categorie | Nivel Risc | Justificare |
|
||
|-----------|------------|-------------|
|
||
| **Security** | 🟡 MEDIUM | Unsafe string ops, dar mitigat de validări |
|
||
| **Availability** | 🟢 LOW | Flood protection rezonabilă |
|
||
| **Performance** | 🟡 MEDIUM | Single-core limited, dar suficient pentru < 5K users |
|
||
| **Maintainability** | 🟢 LOW | Cod matur, modular, bine structurat |
|
||
| **Scalability** | 🟠 HIGH | Hard limit la 1 CPU core, MAXCONNECTIONS fix |
|
||
|
||
### Final Recommendation
|
||
|
||
**DEPLOY** cu următoarele condiții:
|
||
|
||
1. ✅ **Implementează fix-urile URGENT** (unsafe strings, sendQ limits)
|
||
2. ✅ **Monitorizare activă** (CPU, memory, connections)
|
||
3. ✅ **Testing extins** (load testing, fuzz testing)
|
||
4. ⚠️ **Plan de scale**: Pentru >5000 users, consideră alternative multi-thread
|
||
|
||
**PENTRU PRODUCȚIE**:
|
||
- Perfect pentru comunități mici-medii (< 2000 users)
|
||
- Necesită hardening de securitate înainte de expunere publică
|
||
- Recomand firewall rules + rate limiting la nivel de rețea
|
||
- Monitoring 24/7 obligatoriu
|
||
|
||
---
|
||
|
||
## 📞 NEXT STEPS
|
||
|
||
1. **Discuție tehnică**: Prioritizare fix-uri vs. features
|
||
2. **Security audit**: Penetration testing extern
|
||
3. **Load testing**: Simulare 1000+ clienți concurenți
|
||
4. **Code review**: Peer review pentru commits critice
|
||
5. **Documentation sprint**: README tehnic + architecture guide
|
||
|
||
---
|
||
|
||
**Semnat**:
|
||
Senior Software Architect
|
||
Specialized in Network Protocols & Distributed Systems
|
||
Data: 23 Februarie 2026
|
||
|
||
---
|
||
|
||
## 📚 ANEXE
|
||
|
||
### A. GLOSAR TEHNIC
|
||
|
||
- **P10**: Protocol server-to-server folosit de UnderNet
|
||
- **Numeric nick**: Format NNNNN pentru identificare unică
|
||
- **Trie**: Prefix tree pentru lookup rapid comenzi
|
||
- **Event loop**: Main loop care multiplexează I/O
|
||
- **epoll**: Linux kernel API pentru event notification
|
||
- **SendQ**: Queue de mesaje în așteptare pentru trimitere
|
||
- **DBuf**: Dynamic buffer pentru date primite
|
||
|
||
### B. FIȘIERE CHEIE ANALIZATE
|
||
|
||
```
|
||
ircd/ircd.c # Entry point, main loop
|
||
ircd/s_bsd.c # Socket handling, I/O
|
||
ircd/ircd_events.c # Event engine core
|
||
ircd/engine_epoll.c # Epoll backend
|
||
ircd/parse.c # Command parsing (trie)
|
||
ircd/packet.c # Packet processing
|
||
ircd/send.c # Message sending
|
||
ircd/IPcheck.c # Rate limiting
|
||
ircd/dbuf.c # Input buffers
|
||
ircd/msgq.c # Output queues
|
||
include/client.h # Client structure
|
||
include/struct.h # User/Server structures
|
||
```
|
||
|
||
### C. REFERINȚE
|
||
|
||
- RFC 1459: Internet Relay Chat Protocol
|
||
- RFC 2812: Internet Relay Chat: Client Protocol
|
||
- UnderNet IRCU2: https://github.com/UndernetIRC/ircu2
|
||
- Epoll man page: man 7 epoll
|
||
- Kqueue man page: man 2 kqueue
|
||
|
||
---
|
||
|
||
*Acest document este confidențial și destinat echipei tehnice Underchat.*
|
||
|