Рано чи пізно всі там будемо, тому треба думати про ipv6. Нажаль я не маю мережі і тому я не впроважував цю фічу бо я завжди намагаюсь все перевіряти. Я можу робити фічи віддаленно, але ця фіча доволі серьйозна, а всі з ким я контактував (ну такий уж я) не переконали мене робити на їх мережах.
В цій темі я хочу знайти правильний напрямок розвитку, таку реалізацію, щоб було як можна більше плюсів і як можна меньше мінусів. Поки я почну з міркувань) Я хочу зробити дуже нескладну реалізацію. Принаймні на початку. Можна сказати зараз це моя головна ціль - зробити саме нескладно. Тому що я бачу, що ipv6 це як раз спрощення. Дивно, але це так. Чому я це стверджую? ip v4 мають обмежану кількість адрес, тому нам постійно треба щось робити щоб обходити це обмеження. Один з варіантів - це пул ip адрес. В цьому і основна проблема - дедлокі та постійні затупи коли нам треба вибрати вільну адресу. В ip v6 по ідеї не повино цього бути.
Що таке видача ip адреси? Це функція, яка отримує на вхід id абонента, а на виході видає його ip. Коли в ip v6 адрес настільки багато, то ми можемо вираховувати ip по формулі без всяких пулів. Давайте приклад в ip версії 4 (чотири) я покажу як це могло бути:
user id = 10 ip = 10.0.0.10
user id = 25 ip = 10.0.0.25
user id = 54 ip = 10.0.0.54
user id = 119 ip = 10.0.1.19
Звичайно в ipv4 це не може працювати, бо якщо ми видалемо user-а з id = 25, то вільна адреса 10.0.0.25 нікому ніколи не буде видана. Тому придумали всякі прив'язки ip, пули і т.д. В ipv6 адрес настільки багато, що ці дирки можна ігнорувати.
Більше! Я знаю, що є мережі, які не можуть ігнорувати ці дирки, тому що в них є дуже великі підмережі для великих клієнтів. Але навіть в цьому випадку у мене є простий алгоритм без дирок! Я це назвав "стратегією". Зараз приведу реалізацію, де використовується стратегія 0 (супер примитивна, супер швидка, но з "дирками") і стратегія 1 (трохи повільніша, але без дирок).
Створив таблицю:
select * from ipv6_nets;
+----+-------------+------+----------+
| id | net | mask | strategy |
+----+-------------+------+----------+
| 1 | FFFF:BBBB:: | 56 | 0 |
| 2 | FFFF:CCCC:: | 48 | 1 |
+----+-------------+------+----------+
якщо у клієнта в допданих буде прописано "видавати ip /56", то ми будемо видавати ip з мережи FFFF:BBBB::. При цьому використовувати стратегію 0.
Наприклад, у нас 4 абона,
id=2 ipv6_mask=56
id=3 ipv6_mask=56
id=4 ipv6_mask=48
id=5 ipv6_mask=48
забігаючи вперед покажу результат видачі ip:
MySQL [nodeny]> select ipv6_by_uid(2);
+------------------------+
| ipv6_by_uid(2) |
+------------------------+
| ffff:bbbb:0:0:200::/56 |
+------------------------+
MySQL [nodeny]> select ipv6_by_uid(3);
+------------------------+
| ipv6_by_uid(3) |
+------------------------+
| ffff:bbbb:0:0:300::/56 |
+------------------------+
MySQL [nodeny]> select ipv6_by_uid(4);
+----------------------+
| ipv6_by_uid(4) |
+----------------------+
| ffff:cccc:0:0:1::/48 |
+----------------------+
MySQL [nodeny]> select ipv6_by_uid(5);
+----------------------+
| ipv6_by_uid(5) |
+----------------------+
| ffff:cccc:0:0:2::/48 |
+----------------------+
Тобто видно, що перші 2 адреси отримані по стратегії 0 - тобто id юзера просто вписується в ipv6 мережу. Я знаю деякі так і роблять. Id у юзера постійний, він буде постійно отримувати одну й ту саму адресу і ніколи ні з ким не перетинеться.
Інші 2 адреси отримані по стратегії 1 - грубо кажучи, в момент розрахунку ip, вони нумеруються по-порядку з одиниці і цей номер йде в формулу. Наважливо наскільки великий id - він по ітогу буде маленьким (в залежності від загальної кількості абонетів в цієй стратегії).
В одній мережі можна використовувати і одну стратегію і обидві. Тепер сама функція видачі ip:
DROP FUNCTION IF EXISTS `ipv6_by_uid`;
DELIMITER $$
CREATE FUNCTION ipv6_by_uid(user_id INT) RETURNS VARCHAR(32)
DETERMINISTIC
BEGIN
DECLARE ipv6_net VARCHAR(32);
DECLARE ipv6_mask INT;
DECLARE ipv6_strategy TINYINT;
DECLARE ipv6_num INT;
SELECT net, mask, strategy
INTO ipv6_net, ipv6_mask, ipv6_strategy
FROM ipv6_nets
WHERE mask = (SELECT _ipv6_mask FROM data0 WHERE uid=user_id);
SELECT user_id INTO ipv6_num;
IF( ipv6_strategy = 1 ) THEN
SELECT row_num INTO ipv6_num
FROM (
SELECT uid, ROW_NUMBER() OVER(ORDER BY id) AS row_num
FROM data0 WHERE _ipv6_mask=48
) a
WHERE uid=user_id;
END IF;
RETURN CONCAT(INET6_NTOA(
INET6_ATON(ipv6_net) |
(
INET6_ATON(CONCAT('::', HEX(MOD(ipv6_num, 65536)))) |
(INET6_ATON(CONCAT('::', HEX(ROUND(ipv6_num / 65536)))) << 16)
) << ipv6_mask
), '/', ipv6_mask);
END$$
DELIMITER ;
Вона реально дуже проста. Її можна ускладнити коли буде декілько мереж з однією маскою, но то вже інша задача.
Чому все, що я написав, здається мені дуже простим? Тому що в білінгу не використовується ніяких пулів, ніяких прив'язок і т.д. Все що додається:
1) інтерфейс редагування ipv6 мереж
2) вивід ip адреси у абона
3) відредагувати ваши радіуси, ви же знаєте які там атрібути видавать залізякам
Тобто можна запустити ipv6 для частини мережі, білінг і не помітить цього, ну тобто всі ipv4 процеси будть йти як і йшли до цього.