# CRULE - Connection Rules (Reguli de Conectare)

## 📋 CE ESTE CRULE?

**CRULE** (Connection Rule) este un **sistem de reguli inteligente** care controlează **CÂND și CUM** serverul tău IRC se poate conecta la alte servere din rețea.

Este parte a sistemului **SmartRoute** - un mecanism avansat de routing pentru rețele IRC mari.

---

## 🎯 SCOPUL PRINCIPAL

CRULE permite administratorilor să definească **condiții** sub care o conexiune server-to-server:
- ✅ **Este permisă** (dacă regulile sunt îndeplinite)
- ❌ **Este blocată** (dacă regulile nu sunt îndeplinite)

### **Exemplu simplu:**
*"Nu te conecta la un server din Europa dacă există deja o conexiune către un alt server european"*

---

## 🔧 CÂND SE FOLOSEȘTE?

### **Scenarii comune:**

#### 1. **Previne Link-uri Redundante**
```
Problema: Ai 2 servere US și 2 servere EU
Vrei: Doar 1 link US-EU, nu 4!

Soluție CRULE: "connected(*eu.*)"
→ Dacă există deja un server EU conectat, nu mai face alte link-uri
```

#### 2. **Preferă Anumite Route**
```
Problema: Vrei ca Manhattan să gestioneze link-urile către Europa, nu Boston
Vrei: Boston să se conecteze doar dacă Manhattan nu e disponibil

Soluție CRULE: "!via(manhattan.*, *eu.*)"
→ Blochează Boston dacă există deja link EU prin Manhattan
```

#### 3. **Control Autoconnect vs Manual**
```
Problema: Autoconnect-ul e prea agresiv, dar vrei să lași operatorii să forțeze
Vrei: Autoconnect blocat, dar /CONNECT manual permis

Soluție CRULE: d-line (overrideable by opers)
→ Autoconnect blocat, dar operatorii pot forța cu /CONNECT
```

#### 4. **Necesită Operator Online**
```
Problema: Vrei să eviți route-uri riscante când nu e nimeni să monitorizeze
Vrei: Conectare la servere "riscante" doar când un oper e online

Soluție CRULE: "!directop()"
→ Blochează dacă NU există un operator conectat direct
```

---

## 📝 SINTAXA CRULE

### **În ircd.conf:**

```conf
CRule {
    server = "nume.server.ro";
    all = yes;              # yes = aplică la TOATE conectările
                            # no = doar la autoconnect (overrideable)
    rule = "expresie";      # Regula propriu-zisă
};
```

### **Parametri:**

| Parametru | Valori | Descriere |
|-----------|--------|-----------|
| `server` | "*.domain" | Server-ul la care se aplică regula (wildcard permis) |
| `all` | `yes` / `no` | **yes** = Blochează TOATE (inclusiv /CONNECT manual)<br>**no** = Blochează doar autoconnect |
| `rule` | "expresie" | Expresia logică care definește condiția |

---

## 🔍 FUNCȚII DISPONIBILE

### **1. connected(targetmask)**

**Ce face:** Verifică dacă există un server conectat care se potrivește cu masca

**Sintaxă:** `connected("*.eu.*")`

**Exemplu:**
```conf
CRule {
    server = "madrid.es.eu.underchat.org";
    all = no;
    rule = "connected(*.eu.*)";
};
```
**Efect:** Blochează autoconnect la Madrid dacă există DEJA un alt server EU conectat.

---

### **2. directcon(targetmask)**

**Ce face:** Verifică dacă există un server **DIRECT conectat** (nu prin intermediar) care se potrivește cu masca

**Sintaxă:** `directcon("*.us.*")`

**Exemplu:**
```conf
CRule {
    server = "boston.ma.us.underchat.org";
    all = yes;
    rule = "directcon(*.us.*)";
};
```
**Efect:** Blochează TOATE conectările la Boston dacă există deja un server US conectat **direct** la serverul curent.

---

### **3. via(viamask, targetmask)**

**Ce face:** Verifică dacă un server (targetmask) este conectat **PRIN** un alt server (viamask)

**Sintaxă:** `via("manhattan.*", "*.eu.*")`

**Exemplu:**
```conf
CRule {
    server = "*.eu.*";
    all = no;
    rule = "via(manhattan.*, *.eu.*)";
};
```
**Efect:** Blochează autoconnect la servere EU dacă există deja un server EU conectat PRIN Manhattan.

---

### **4. directop()**

**Ce face:** Verifică dacă există un **operator** conectat **direct** la serverul curent

**Sintaxă:** `directop()`

**Exemplu:**
```conf
CRule {
    server = "risky.server.net";
    all = no;
    rule = "!directop()";
};
```
**Efect:** Blochează autoconnect la `risky.server.net` dacă **NU** există un operator online (pentru monitorizare).

---

## 🧮 OPERATORI LOGICI

### **1. NOT (negare) - `!`**

```conf
rule = "!connected(*.eu.*)";
```
**Înseamn:** "dacă **NU** există un server EU conectat"

### **2. AND (și) - `&&`**

```conf
rule = "connected(*.eu.*) && !directcon(*.eu.*)";
```
**Înseamnă:** "dacă există un server EU conectat **ȘI** nu e conectat direct"

### **3. OR (sau) - `||`**

```conf
rule = "connected(*.eu.*) || connected(*.asia.*)";
```
**Înseamnă:** "dacă există un server EU conectat **SAU** un server Asia conectat"

### **4. Paranteze pentru grupare - `()`**

```conf
rule = "connected(*.eu.*) && (!directcon(*.eu.*) || via(manhattan.*, *.eu.*))";
```
**Înseamnă:** "dacă există EU conectat **ȘI** (**nu** e direct **SAU** e prin Manhattan)"

---

## 💡 EXEMPLE PRACTICE

### **Exemplu 1: Previne Link-uri Multiple către Europa**

```conf
# Pe server US: Boston
CRule {
    server = "*.eu.underchat.org";
    all = no;
    rule = "connected(*.eu.underchat.org)";
};
```
**Efect:**
- ✅ Prima conexiune la un server EU → **PERMISĂ**
- ❌ A doua conexiune la alt server EU → **BLOCATĂ** (autoconnect)
- ✅ Operator poate forța cu `/CONNECT madrid.es.eu.underchat.org`

---

### **Exemplu 2: Preferă Manhattan pentru Link-uri EU**

```conf
# Pe server US: Boston
CRule {
    server = "*.eu.underchat.org";
    all = no;
    rule = "connected(*.eu.underchat.org) && (!directcon(*.eu.underchat.org) || via(manhattan.*, *.eu.underchat.org))";
};
```
**Efect:**
- Dacă există deja un server EU conectat:
  - ❌ Boston nu se mai conectează (lasă Manhattan să gestioneze)
  - Excepție: Dacă Boston DEJA are link EU direct, îl păstrează

---

### **Exemplu 3: Necesită Operator pentru Route-uri Riscante**

```conf
# Link către server nesigur
CRule {
    server = "experimental.test.org";
    all = no;
    rule = "!directop()";
};
```
**Efect:**
- ❌ Autoconnect blocat dacă **NU** există oper online
- ✅ Dacă un oper e online, autoconnect **PERMIS**
- ✅ Oper poate forța manual oricând cu `/CONNECT`

---

### **Exemplu 4: Permite doar 1 Link per Continent**

```conf
# Reguli pentru un HUB global
CRule {
    server = "*.eu.*";
    all = no;
    rule = "connected(*.eu.*)";
};

CRule {
    server = "*.asia.*";
    all = no;
    rule = "connected(*.asia.*)";
};

CRule {
    server = "*.us.*";
    all = no;
    rule = "connected(*.us.*)";
};
```
**Efect:**
- Maxim 1 link către fiecare continent
- Previne "mesh" complet (prea multe conexiuni)

---

## ⚙️ DIFERENȚA ÎNTRE `all = yes` și `all = no`

### **`all = yes` (D-line în conf vechi)**

```conf
CRule {
    server = "*.eu.*";
    all = yes;
    rule = "connected(*.eu.*)";
};
```
**Blochează:**
- ❌ Autoconnect
- ❌ `/CONNECT` de la operatori
- ❌ Conexiuni incoming de la alte servere

**Folosit pentru:** Reguli **ABSOLUTE** care nu trebuie niciodată încălcate

---

### **`all = no` (d-line în conf vechi)**

```conf
CRule {
    server = "*.eu.*";
    all = no;
    rule = "connected(*.eu.*)";
};
```
**Blochează:**
- ❌ Autoconnect

**PERMITE:**
- ✅ `/CONNECT` manual de la operatori
- ✅ Conexiuni incoming de la alte servere

**Folosit pentru:** Reguli de **OPTIMIZARE** care pot fi override-uite manual

---

## 🔧 CONFIGURARE ÎN ircd.conf

### **Exemplu Complet:**

```conf
# ============================================================================
# SECȚIUNE: CRULE - Reguli de Conectare Inteligente
# ============================================================================

# Regula 1: Previne link-uri redundante către Europa
CRule {
    server = "*.eu.underchat.org";
    all = no;
    rule = "connected(*.eu.underchat.org)";
};

# Regula 2: Preferă Manhattan pentru link-uri EU (Boston backup)
CRule {
    server = "madrid.es.eu.underchat.org";
    all = no;
    rule = "via(manhattan.*, *.eu.underchat.org)";
};

# Regula 3: Link-uri experimentale doar cu oper online
CRule {
    server = "experimental.*.underchat.org";
    all = no;
    rule = "!directop()";
};

# Regula 4: Nu permite NICIODATĂ link către servere blacklist
CRule {
    server = "*.blacklisted.net";
    all = yes;
    rule = "connected(*)";  # Întotdeauna blocat
};
```

---

## 📊 VERIFICARE ȘI DEBUGGING

### **Comenzi IRC pentru testare:**

```irc
# Vezi toate regulile configurate
/STATS d

# Vezi doar regulile absolute (all = yes)
/STATS D

# Testează o conexiune (ca operator)
/CONNECT madrid.es.eu.underchat.org
```

### **Output `/STATS d` exemplu:**

```
:server 242 nick D madrid.es.eu.underchat.org::connected(*.eu.*)
:server 242 nick d experimental.*.underchat.org::!directop()
```

- **D** (majusculă) = `all = yes` (absolute)
- **d** (minusculă) = `all = no` (overrideable)

---

## 🎯 AVANTAJE CRULE

### ✅ **1. Control Granular**
Definești exact CÂND și CUM se fac conexiunile, nu doar "poate sau nu poate".

### ✅ **2. Optimizare Topologie**
Previne "mesh" complet (toate serverele conectate între ele) care poate cauza lag și probleme de routing.

### ✅ **3. Reducere Costuri**
Link-urile internationale costă trafic → CRULE limitează link-urile redundante.

### ✅ **4. Siguranță**
Poate preveni conexiuni nedorite sau periculoase automat.

### ✅ **5. Flexibilitate**
Operatorii pot override-ui regulile `all = no` când e necesar.

---

## 🚨 CÂND NU TREBUIE FOLOSIT

### ❌ **Rețele mici (< 5 servere)**
Overhead-ul de configurare nu merită pentru rețele mici.

### ❌ **Topologie simplă**
Dacă ai doar 2-3 servere într-o linie, CRULE e overkill.

### ❌ **Fără operatori experimentați**
Regulile complexe pot bloca conexiuni necesare dacă sunt configurate greșit.

---

## 🎓 TUTORIAL: Primul Tău CRULE

### **Scenariul:**
- Ai 2 servere US: `boston.us` și `newyork.us`
- Ai 2 servere EU: `madrid.eu` și `paris.eu`
- Vrei: Doar 1 link US-EU (nu 4!)

### **Soluția:**

**Pe fiecare server US, adaugă:**
```conf
CRule {
    server = "*.eu.underchat.org";
    all = no;
    rule = "connected(*.eu.underchat.org)";
};
```

**Pe fiecare server EU, adaugă:**
```conf
CRule {
    server = "*.us.underchat.org";
    all = no;
    rule = "connected(*.us.underchat.org)";
};
```

**Rezultat:**
- ✅ Prima conexiune US-EU → Permisă (ex: boston-madrid)
- ❌ A doua conexiune US-EU → Blocată automat (ex: newyork-paris)
- ✅ Dacă prima conexiune cade, a doua devine activă automat

---

## 📚 RESURSE SUPLIMENTARE

- **Documentație completă:** `doc/readme.crules`
- **Cod sursă:** `ircd/crule.c`
- **Exemple config:** `ircd/test/ircd-t1.conf`
- **RFC IRC:** Nu există standard oficial, e specific Undernet/Nefarious

---

## 🎯 CONCLUZIE

**CRULE = SmartRoute pentru IRC**

În loc să definești doar:
- ❌ "Poate să se conecteze la X?"

Poți defini:
- ✅ "Poate să se conecteze la X **DACĂ** Y și Z sunt îndeplinite?"

Este un sistem **puternic** dar **complex** - folosește-l doar dacă ai nevoie de control granular asupra topologiei rețelei!

---

**Data:** 14 Februarie 2026  
**Versiune:** 1.0  
**Pentru:** UnderChat IRCd v1.3.1+

