Российский Университет Дружбы Народов

Обзор протоколов работы

ICQ

Курсовая работа


Автор: Азаров Роман, НП-303
ICQ UIN: 24144078
Научный руководитель: Гостев И.М.

Москва

1999



Оглавление


Введение


ICQ - коммуникационная программа для передачи сообщений посредством сети интернет. В основе её работы положен метод сохранения всех сообщений, посылаемых пользователями, на сервере до тех пор, пока адресат не подключится к интернет. Название ICQ созвучно английскому "I seek you" - "Я тебя ищу". Эта программа была создана в 1999 году малоизвестной израильской фирмой Mirabilis. И на данный момент число ее пользователей исчисляется несколькими десятками миллионов. Популярность программе принесло удобство использования и бесплатность предоставляемых услуг.

ICQ может:


ICQ часто называют аналогом пейджера в интернете. Для обеспечения мобильности пользователей ICQ присваивает им номера, независимые от их текущего положения в сети (IP-адреса) называемые UIN (Universal Internet Number) . Но при передаче данных (сообщений, файлов и т.д.) программе приходится получать текущий IP-адрес пользователя с другой стороны, т.к. без него прямая передача по TCP/IP невозможна. Для преобразования пользовательских номеров в IP-адреса используются специальные серверы в Internet. Эти серверы специально предназначены для обслуживания пользователей ICQ и поддерживаются Mirabilis.


В момент получения доступа к Internet ICQ соединяется с одним из таких серверов и регистрируется на нем, передавая имя и пароль. Сервер запоминает текущий IP-адрес этого пользователя. Пока пользователь на линии, сервер может обрабатывать запросы других ICQ на преобразование номера пользователя в его текущий IP-адрес. Эти запросы и ответы передаются по протоколу UDP (подобно запросам и ответам DNS). Этот же сервер может служить и источником информации "доступен ли данный пользователь online".

Получив IP-адрес другой стороны, ICQ может соединиться с клиентом ICQ на другой стороне и передавать данные напрямую. Короткие сообщения ICQ может передавать по UDP. Это более быстрый и легковесный протокол чем TCP, так как не ориентирован на соединение, а посылает данные отдельными пакетами. Но UDP ненадежный, поэтому используются подтверждения доставки. ICQ делает до 6 попыток отправить сообщение по UDP. И если ни на одну из них подтверждение не пришло, ICQ выводит вам сообщение, что не пожет передать сообщение напрямую, предлагая передать через сервер Mirabilis (он, в отличие от пользователей, реже бывает недоступен). Когда получатель сообщения очередной раз подключится для регистрации, это сообщение будет ему переправлено.

Если возможно, ICQ пытается установить между переговаривающимися сторонами прямое TCP-соединение. В результате следующие сообщения могут идти по уже установленному TCP-соединению, что более надежно, чем UDP, и достаточно быстро.


Пользователь может создать “список контактов” – список других пользователей ICQ. Когда какой-либо пользователь из этого списка находясь в интернете запускает клиента ICQ и регистрируется на сервере – то уведомление об этом могут получать все в чьих “списках контактов” находится обладатель данного UIN. Каждый пользователь может указать свой “статус” свидетельствующий о желании пользователя принимать какие-либо сообщения. В последних версиях статус может принимать значение “доступен” (Available/Connect), “отлучился” (Away), “только срочные сообщения” (Do not distrub) и другие. Пользователь может свободно менять свой статус, о чем информируется каждый зарегистрированный на сервере клиент, в чьем списке контактов находится сменивший статус пользователь.


Спецификация ICQ протокола


За время существования ICQ, используемый ею протокол претерпел множество изменений и имел различные версии, каждая следующая из которых отличалась от предыдущей.


Версия 1

Эта версия устарела. На данный момент она не используется и не поддерживается.


Версия 2

Версия 2 является самой древней версией, которая до сих пор используется Mirabilis-ом.(Например, клиентом Java версии ICQ).


Рассмотрим работу протокола этой версии более подробно. Несмотря на то, что эта версия уже практически не используется, основные принципы работы и используемые структуры остались неизменны.


Соединение с другим клиентом, находящимся в данный момент в Internet (on-line) осуществляется посредством протокола TCP с установкой прямого соединения между переговаривающимися сторонами. Все другие соединения осуществляются с использованием пакетов протокола UDP посылаемых через ICQ сервер. Получение каждого UDP пакета должно быть подтверждено сервером. В случае неполучения клиентом подтверждения от сервера в течении 10 секунд, клиент повторно посылает пакет. После таких 6 неудачных посылок клиент посылает на сервер сообщение B_MESSAGE_ASK, получив которое сервер должен немедленно ответить. Процедура повторяется 2 раза. Если ни на один из посланных пакетов не было получено подтверждение, ICQ клиент предполагает, что пользователь отключился от Internet (off-line).

Перед тем как начать устанавливать какие-либо соединения, клиент должен зарегистрироваться на одном из ICQ- серверов(log-in). Во время процедуры регистрации клиент посылает серверу информацию о себе такую как IP адрес, TCP порт зарезервированный для ICQ, пароль пользователя и список других пользователей ICQ находящихся в “списке контактов” клиента. Клиент должен периодически посылать на сервер сообщение “KEEP_ALIVE” свидетельствующее о том, что клиент все еще подключен к Сети. По умолчанию клиент посылает UDP пакеты на сервер используя порт 4000.

Функции “послать сообщение пользователю неподключенному к Internet (off-line) ”, “получение информации о пользователе”, ”поиск пользователя”, “изменение информации текущего пользователя” реализуются через пакеты протокола UDP, посылаемых на сервер. В поле “DATA” UDP пакета размещается информация о UIN отправителя, код, идентифицирующий запрошенную функцию и необязательные параметры.

Когда пользователь посылает сообщение другому пользователю, который подключен (зарегистрирован на сервере), ICQ клиент пытается установить TCP соединение с этим пользователем, используя аналогичную (за небольшим исключением) структуру поля DATA TCP пакета. После посылки сообщения соединение не разрывается и может быть использовано для посылки следующих сообщений. Соединение закрывается, когда один из пользователей отсоединяется(log-off) или же теряет соединение с сервером.



Коммуникации между сервером и клиентом


Как уже было сказано ранее, для осуществления такого рода коммуникаций ICQ использует протокол UDP. Поле данных пакета UDP при посылке от клиента к серверу заполняется следующим образом:



Длина Значение Название Описание
2 байта 02 00 VERSION

Версия протокола ICQ

2 байта хх хх COMMAND Код запрашиваемой функции
2 байта хх хх SEQ_NUM Порядковый номер
4 байта хх хх хх хх UIN UIN отправителя
Переменная    

0 или больше параметров. Зависит от поля COMMAND

Здесь и далее “байт “ представляет собой последовательность из 8-и битов, старший бит ниходится слева, младший байт идет первым.


Поле данных пакета UDP при посылке от сервера клиенту заполняется следующим образом:

Длина

Значение

Название

Описание

2 байта

02 00

VERSION

Версия протокола ICQ

2 байта

хх хх

COMMAND

Код выполненной функции

2 байта

хх хх

SEQ_NUM

Порядковый номер

Переменная

хх хх

 

0 или больше параметров. Зависит от поля COMMAND



Поле VERSION присутствует во всех пакетах и является идентификатором того что это пакет ICQ .

Поле SEQ_NUM содержит порядковый номер пакета. Все пакеты должны иметь уникальный порядковый номер за исключением случая перепосылки пакета. Это поле используется для отслеживания потери или дублирования пакетов. Обыкновенно с каждым пакетом SEQ_NUM увеличивается на 1. Сервер и клиент ведут непересекающуюся нумерацию пакетов. Т.е. порядковый номер пакета от сервера никак не связан с порядковыми номерами пакетов от клиента. Сервер начинает отсчет с 00 00. Клиент же начинает отсчет с 01 00. Это поле имеет немного другую интерпретацию в случае команды ACK (см. ниже).

Поле СOMMAND при посылке сообщения от клиента серверу может принимать следующие значения:



Значение

Наименование

Описание

0A 00

ACK

Подтверждение

0E 01

SEND_MESSAGE

Послать сообщение через сервер (если, например адресат не зарегистрировался на сервере)

E8 03

LOGIN

Зарегистрироваться на сервере.

06 04

CONTACT_LIST

Передать серверу “список контактов”

1A 04

SEARCH_UIN

Искать пользователя по UIN

24 04

SEARCH_USER

Искать пользователя по имени или электронному адресу.

2E 04

KEEP_ALIVE

Посылается для подтверждения того что пользователь не отключился от Сети.

38 04

SEND_TEXT_CODE

Послать специальное сообщение на сервер в виде текста.

60 04

INFO_REQ

Запрос основной информации о пользователе.

6A 04

EXT_INFO_REQ

Запрос расширенной информации о пользователе.

9C 04

STATUS_CHANGE

Пользователь изменил свой статус.

28 05

LOGIN_2

Посылается во время регистрации на сервере.

0A 05

UPDATE_INFO

Обновить основную информацию о пользователе.

B0 04

UPDATE_EXT_INFO

Обновить расширенную информацию о пользователе.

3C 05

ADD_TO_LIST

Пользователь добавляется в “список контактов”

56 04

REQ_ADD_TO_LIST

Запрос разрешения у пользователя о добавлении его в “список контактов”

BA 04

QUERY_SERVERS

Запросить у сервера адреса других серверов.

C4 04

QUERY_ADDONS

Запросить у сервера информацию о программных расширениях.

EC 04

NEW_USER_1

Запрос разрешения на добавление пользователя в список контактов (?)

FC 03

NEW_USER_REG

Зарегистрировать нового пользователя.

A6 04

NEW_USER_INFO

Посылается основная информация о новом пользователе.

56 04

MSG_TO_NEW_USER

Послать сообщение пользователю, отсутствующему в списке контактов. Используется для отправки текста сопровождающего запрос на добавление в список контактов.



Поле СOMMAND при посылке сообщения от сервера клиенту может принимать следующие значения:



Значение

Наименование

Описание

0A 00

ACK

Подтверждение

5A 00

LOGIN_REPLY

Ответ при регистрации на сервере

6E 00

USER_ONLINE

Пользователь из списка контактов зарегистрировался на сервере или сменил свой статус на “на линии”.

78 00

USER_OFFLINE

Пользователь из списка контактов отключился от сервера или сменил свой статус на “отключен”

8C 00

USER_FOUND

Ответ на запрос о поиске. Найдена запись о пользователе отвечающем заданным параметрам.

DC 00

RECEIVE_MESSAGE

Послано сообщение через сервер.

A0 00

END_OF_SEARCH

Ответ на запрос о поиске. Больше пользователей удовлетворяющих заданным параметрам не найдено.

18 01

INFO_REPLY

Основная информация о пользователе.

22 01

EXT_INFO_REPLY

Расширенная информация о пользователе.

A4 01

STATUS_UPDATE

Пользователь из списка контактов сменил свой статус.

1C 02

REPLY_X1

Используется во время регистрации на сервере.

E0 01

UPDATE_REPLY

Подтверждение обновления основной информации.

C8 00

UPDATE_EXT_REPLY

Подтверждение обновления расширенной информации.

46 00

NEW_USER_UIN

Подтверждение о регистрации нового пользователя и новый UIN

B4 00

NEW_USER _REPLY

Подтверждение приема пакета с основной информацией о новом пользователе.

82 00

QUERY_REPLY

Ответ на запросы QUERY_SERVERS и QUERY_ADDONS



Рассмотрим подробнее некоторые команды


Сообщения от клиента серверу.

ACK (0A 00) Подтверждение.

Параметры: Нет

В отличие от остальных команд, поле SEQNUM содержит порядковый номер сообщения прием которого подтверждается. Прием этого пакета не должен быть подтвержден.


SEND_MESSAGE (0E 01) Послать сообщение через сервер.

Параметры

Длина

Значение

Имя

Описание

4 байта

xx xx xx xx

RECEIVER_UIN

UIN адресата сообщение

2 байта

(см. ниже)

MESSAGE_TYPE

Тип сообщения

2 байта

xx xx

LENGTH

Длина сообщения включая завершающий строку NULL

Переменная

 

MESSAGE

ASCIIZ строка сообщения

Сообщение может быть следующих типов:

01 00 – нормальное текстовое сообщение

04 00 – сообщение является Интернет-адресом. В таком случае оно состоит из

описания и самого URL разделенных символом 0xFE



LOGIN (E8 03) Зарегистрироваться на сервере.

Длина

Значение

Имя

Описание

4 байта

хх хх хх хх

PORT

Порт TCP который следует использовать при установлении соединения.

2 байта

хх хх

LENGTH

Длина поля PASSWORD включая завершающий NULL

Переменная

 

PASSWORD

ASCIIZ строка, содержащая пароль

4 байта

78 00 00 00

X1

Зарезервировано

4 байта

хх хх хх хх

USER_IP

IP адрес пользователя

1 байт

04

X2

Зарезервировано

4 байта

хх хх хх хх

STATUS

Статус пользователя. Обыкновенно 00 00 00 00

4 байта

02 00 00 00

X3

Зарезервировано

2 байта

хх хх

LOGIN_SEQ_NUM

Порядковый номер попытки зарегистрироваться.

4 байта

00 00 00 00

X4

Зарезервировано

4 байта

08 00 78 00

X5

Зарезервировано

В случае успешной регистрации сервер возвращает сообщение LOGIN_REPLY.


CONTACT_LIST (06 04) Информировать сервер о списке контактов пользователя.


Параметры:

Длина

Значение

Имя

Описание

2 байта

хх хх

NUM_CONTACTS

Количество записей в списке контактов

4 байта NUM_CONTACT раз

xx xx xx xx

UIN

UIN пользователя из списка контактов.

Сервер будет посылать извещение о изменении статуса каждого пользователя из списка контактов.


SEARCH_UIN (1A 04) Искать пользователя по UIN

Параметры:

Длина

Значение

Имя

Описание

2 байта

хх хх

SEARCH_SEQ_NUM

Порядковый номер запроса поиска.

4 байта

хх хх хх хх

SEARCH_UIN

UIN для поиска

SEARCH_SEQ_NUM должно быть уникальным числом для различения различных запросов поиска.

SEARCH_USER (24 04) Искать пользователя по имени или электронному

адресу

Параметры:

Длина

Значение

Имя

Описание

2 байта

хх хх

SEARCH_SEQ_NUM

Порядковый номер запроса поиска.

2 байта

хх хх

LENGTH

Длина “прозвища”. Включая завершающий NULL

Переменная

 

NICK_NAME

Прозвище. ASCIIZ строка

2 байта

хх хх

LENGTH

Длина Имени. Включая завершающий NULL

Переменная

 

FIRST_NAME

Имя. ASCIIZ строка

2 байта

хх хх

LENGTH

Длина фамилии. Включая завершающий NULL

Переменная

 

LAST_NAME

Фамилия. ASCIIZ строка

2 байта

хх хх

LENGTH

Длина электронного адреса. Включая завершающий NULL

Переменная

 

E_MAIL

Электронный адрес. ASCIIZ строка

Поля NICK_NAME, FIRST_NAME, LAST_NAME, E_MAIL могут содержать пустую строку, однако по крайней мере одно из этих полей должно быть заполнено.


KEEP_ALIVE (2E 04) Подтверждение того, что клиент все еще на линии.

Параметры: Нет

Эта команда должна посылаться клиентом серверу каждые 120 секунд.

INFO_REQ (60 04) Запрос основной информации о пользователе.

Параметры:

Длина

Значение

Имя

Описание

2 байта

хх хх

INFO_SEQ_NUM

Порядковый номер запроса

4 байта

хх хх хх хх

QUERY_UIN

UIN запрашиваемого пользователя

На этот запрос сервер отвечает сообщением INFO_REPLY (см. ниже) используя тот же самый INFO_SEQ_NUM

EXT_INFO_REQ (6A 04) Запрос расширенной информации о пользователе.

Параметры:

Длина

Значение

Имя

Описание

2 байта

хх хх

INFO_SEQ_NUM

Порядковый номер запроса

4 байта

хх хх хх хх

QUERY_UIN

UIN запрашиваемого пользователя

На этот запрос сервер отвечает сообщением EXT_INFO_REPLY (см. ниже) используя тот же самый INFO_SEQ_NUM

CHANGE_PASSWORD (9C 04) Сменить пароль пользователя.

Параметры:

Длина

Значение

Имя

Описание

2 байта

хх хх

PASSWORD_SEQ_NUM

Порядковый номер запроса на смену пароля

2 байта

хх хх

LENGTH

Длина нового пароля, включая завершающий NULL

Переменная

 

NEW_PASSWORD

Новый пароль. ASCIIZ строка


STATUS_CHANGE (D8 04) Пользователь сменил свой статус

Параметры:

Длина

Значение

Имя

Описание

4 байта

хх хх 00 00

(см. ниже)

STATUS

Новый статус пользователя

Возможные значения поля STATUS:

00 00 00 00

На линии (on_line/connected)

01 00 00 00

Ушел (Away)

11 00 00 00

Не беспокоить (Do Not Disturb -DND)

00 01 00 00

Невидим (Invisible)




Сообщения от сервера клиенту.


ACK (0A 00) Подтверждение.

Параметры: Нет


В отличие от остальных команд, поле SEQNUM содержит порядковый номер сообщения прием которого подтверждается. Прием этого пакета не должен быть подтвержден.



LOGIN_REPLY (5A 00) Ответ при регистрации на ICQ - сервере.


Параметры:

Длина

Значение

Имя

Описание

4 байта

хх хх хх хх

USER_UIN

UIN пользователя

4 байта

хх хх хх хх

USER_IP

IP пользователя

2 байта

хх хх

LOGIN_SEQ_NUM

Порядковый номер запроса на регистрацию.

4 байта

01 00 01 00

X1

неизвестно

4 байта

xx 00 16 00

X2

Неизвестно

4 байта

8C 00 00 00

X3

Неизвестно

4 байта

78 00 05 00

X4

Неизвестно

6 байт

0A 00 05 00 01 00

X5

неизвестно

Поле LOGIN_SEQ_NUM содержит значение одноименного поля соответствующего пакета с запросом на регистрацию (LOGIN).


USER_FOUND (8C 00) Найден пользователь удовлетворяющий заданным

критериям поиска.


Параметры:

Длина

Значение

Имя

Описание

2 байта

хх хх

SEARCH_SEQ_NUM

Порядковый номер запроса поиска.

4 байта

хх хх хх хх

FOUND_UIN

UIN найденного пользователя

2 байта

хх хх

LENGTH

Длина “прозвища”. Включая завершающий NULL

Переменная

 

NICK_NAME

Прозвище. ASCIIZ строка

2 байта

хх хх

LENGTH

Длина имени. Включая завершающий NULL

Переменная

 

FIRST_NAME

Имя. ASCIIZ строка

2 байта

хх хх

LENGTH

Длина фамилии. Включая завершающий NULL

Переменная

 

LAST_NAME

Фамилия. ASCIIZ строка

2 байта

хх хх

LENGTH

Длина электронного адреса. Включая завершающий NULL

Переменная

 

E_MAIL

Электронный адрес. ASCIIZ строка

1 байт

хх

AUTHORIZE

Необходимость авторизации.

Для каждого пользователя подходящего заданным критериям поиска будет создан такой пакет. Но не более 40 штук. По окончании создания пакетов содержащих сообщения USER_FOUND сервер посылает сообщение END_OF_SEARCH .

Поле AUTHORIZE содержит байт со значением 00 или 01, что означает необходимость разрешения данного пользователя, для добавление его в чей-либо в список контактов, или отсутствие такой необходимости соответственно.



RECEIVE_MESSAGE (DC 00) Сообщение пользователю, посланное через

сервер.


Параметры:

Длина

Значение

Имя

Описание

4 байта

хх хх хх хх

REMOTE_UIN

UIN отправителя

2 байта

хх хх

YEAR

Год посылки сообщения

1 байт

хх

MONTH

Месяц посылки сообщения

1 байт

хх

DAY

День посылки сообщения

1 байт

хх

HOUR

Час посылки сообщения

1 байт

хх

MINUTE

Минута посылки сообщения

2 байта

хх хх

TYPE

Тип сообщения (см. ниже)

2 байта

хх хх

LENGTH

Длина текста сообщения. Включая завершающий NULL

переменная

 

MESSAGE

Текст сообщения. ASCIIZ строка.


Поле TYPE может принимать следующие значения:

01 00 - нормальное сообщение

04 00 - сообщение является Интернет-адресом.(URL) В таком случае оно

состоит из описания и самого URL разделенных символом 0xFE

0C 00 - сообщение о том, что пользователь был добавлен в список

контактов. При этом поле MESSAGE имеет следующую

структуру:


<nick name> - Прозвище добавившего.

FE - Разделитель – символ с кодом 0хFE

<first name> - Имя добавившего.

FE - Разделитель.

<last name> - Фамилия добавившего.

FE - Разделитель.

<e-mail> - Электронный адрес добавившего.

FE - Разделитель

<authorize> - Символ “1” или “0” в зависимости от необходимости

автоизации для добавления пользователя в список

контактов. “1” – если такая авторизация не требуется.




END_OF_SEARCH (A0 00) - Окончание создание пакетов с сообщением

USER_FOUND

Параметры:

Длина

Значение

Имя

Описание

2 байта

хх хх

SEARCH_SEQ_NUM

Порядковый номер запроса на поиск

1 байт

хх

MORE_FOUND

Найдено ли большее количество пользователей?

Если критериям поиска удовлетворяет более 40 пользователей, то будет сгенерированы пакеты USER_FOUND только для первых 40. И поле MORE_FOUND завершающего сообщения END_OF_SEARCH будет содержать значение 01. В противном случае это поле будет содержать 00.


INFO_REPLY (18 01) Основная информация о пользователе


Параметры:

Длина

Значение

Имя

Описание

2 байта

хх хх

INFO_SEQ_NUM

Порядковый номер запроса.

4 байта

хх хх хх хх

REMOTE_UIN

UIN пользователя

2 байта

хх хх

LENGTH

Длина “прозвища”. Включая завершающий NULL

Переменная

 

NICK_NAME

Прозвище. ASCIIZ строка

2 байта

хх хх

LENGTH

Длина имени. Включая завершающий NULL

Переменная

 

FIRST_NAME

Имя. ASCIIZ строка

2 байта

хх хх

LENGTH

Длина фамилии. Включая завершающий NULL

Переменная

 

LAST_NAME

Фамилия. ASCIIZ строка

2 байта

хх хх

LENGTH

Длина электронного адреса. Включая завершающий NULL

Переменная

 

E_MAIL

Электронный адрес. ASCIIZ строка

1 байт

хх

AUTHORIZE

Необходимость авторизации.

Значения параметров полностью совпадают с одноименными параметрами сообщения USER_FOUND.



EXT_INFO_REPLY (22 01) Расширенная информация о пользователе.


Параметры:

Длина

Значение

Имя

Описание

2 байта

хх хх

INFO_SEQ_NUM

Порядковый номер запроса

4 байта

хх хх хх хх

REMOTE_UIN

UIN пользователя

2 байта

хх хх

LENGTH

Длина названия города. Включая завершающий NULL

Переменная

 

CITY

Название города. ASCIIZ строка

2 байта

хх хх

COUNTRY_CODE

Код страны

1 байт

хх

COUNTRY_STATUS

Был ли введен код страны

2 байта

хх хх

LENGTH

Длина названия штата. Включая завершающий NULL

Переменная

 

STATE

Название штата (актуально только для CША)

2 байта

хх хх

AGE

Возраст

1 байт

хх

SEX

Пол

2 байта

хх хх

LENGTH

Длина телефона. Включая завершающий NULL

Переменная

 

PHONE

Телефон. ASCIIZ строка.

2 байта

хх хх

LENGTH

Длина адреса домашней странички. Включая завершающий NULL

перемення

 

HOME_PAGE

Домашняя страничка. ASCIIZ строка.

2 байта

хх хх

LENGTH

Длина “текста о себе” пользователя.

Переменная

 

ABOUT

“Текст о себе” ASCIIZ строка.

Параметр COUNTRY_CODE представляет из себя международный телефонный префикс. Для США это значение 01 00 (т.е. 1) для России 07 00. Если пользователь указывал код своей страны, то поле COUNTRY_STATUS содержит значение 0хFE в противном случае поле COUNTRY_CODE содержит значение FF FF и COUNTRY_STATUS содержит байт 0х9С.


Поле SEX может принимать следующие значения:

  1. - пол не указан

  2. - женский

  3. - мужской


В поле ABOUT пользователь может написать любой текст. Обыкновенно, это информация о себе.


STATUS_UPDATE (A4 01) Пользователь из списка контактов сменил

свой статус.


Параметры:

Длина

Значение

Имя

Описание

4 байта

хх хх хх хх

REMOTE_UIN

UIN пользователя чей статус изменился

4 байта

хх хх хх хх

STATUS

Новый статус пользователя.

Поле STATUS может принимать такие же значения, как и в команде STATUS_CHANGE (D8 04).


Коммуникации между двумя клиентами



Когда пользователь пытается послать сообщение другому пользователю, клиентская программа сначала проверяет, установлено ли TCP соединение с удаленным пользователем. В случае наличия такого соединения, оно будет использовано для передачи сообщения. В противном случае с сервера запрашивается IP адрес и порт второго пользователя и предпринимается попытка установить TCP соединение. Обыкновенно порт берется в диапазоне 1200-1300 (десятичное). После установления соединения посылается сообщение CHANNEL_INIT. После этого каждый раз для посылки текстового сообщения создается пакет с сообщением CHANNEL_MESSAGE. Получение каждого пакета должно быть подтверждено сообщением CHANNEL_ACK.

Взаимодействие с использованием протокола TCP также как и с использованием протокола UDP базируется на посылке независимых пакетов.



CHANNEL_INIT Инициировать TCP соединение между двумя

пользователями

Параметры:

Длина

Значение

Имя

Описание

2 байта

1А 00

LENGTH

Суммарная длина следующих полей

1 байт

FF

INIT_IDENT

Идентификатор того, что это пакет CHANNEL_INIT

2 байта

02 00

VERSION

Идентификатор версии протокола

6 байт

00 00 00 00

X1

Зарезервировано

4 байта

хх хх хх хх

MY_UIN

UIN отправителя пакета.

4 байта

хх хх хх хх

MY_IP

IP отправителя пакета

4 байта

хх хх хх хх

MY_IP_REAL

Актуальный IP отправителя пакета

1 байт

04

X2

Зарезервировано

4 байта

хх хх хх хх

MY_PORT

TCP порт для ответных сообщений.

MY_REAL_IP отличается от MY_IP тем что первое является “локальным” IP адресом, а второй “реальным” Эти два значения будут различаться только в том случае если клиент находится за файрволом.



CHANNEL_MESSAGE послать текстовое сообщение непосредственно

пользователю

Параметры:

Длина

Значение

Имя

Описание

2 байта

xx xx

LENGTH

Суммарная длина следующих полей

4 байта

xx xx xx xx

UIN

UIN отправителя

2 байта

02 00

VERSION

Идентификатор версии протокола

2 байта

ЕЕ 07

MSG_COMMAND

Идентификатор того что этот пакет CHANNEL_MESSAGE

2 байта

00 00

X1

Зарезервировано

4 байта

xx xx xx xx

UIN_2

Дублирует поле UIN

2 байта

xx xx

TYPE

Тип сообщения

2 байта

xx xx

LENGTH

Длина текста сообщения. Включая завершающий NULL

Переменная

 

MESSAGE

Текст сообщения. ASCIIZ строка.

4 байта

xx xx xx xx

MY_IP_REAL

Актуальный IP отправителя пакета

4 байта

xx xx xx xx

MY_IP

IP отправителя пакета

4 байта

xx xx xx xx

PORT

TCP порт для ответных сообщений.

3 байта

04 00 00

X2

Зарезервировано.

2 байта

xx xx

CMD_TYPE

Идентификатор того является ли этот текст просто сообщением или ответом.

4 байта

xx FF FF FF

X3

Зарезервировано.

Поле TYPE принимает такие же значения как и в команде RECEIVE_MESSAGE

Возможные значения поля CMD_TYPE:

10 00 - это просто сообщение.

00 00 - это сообщение является автоматически созданным ответом.

“Автоматические ответы” создаются по получению каждого простого сообщения. Обыкновенно они содержат пустые сообщения. Их функция аналогична сообщениям ACK, используемым при взаимодействии с сервером.



Версии 3 и 4

Версия 3 сама по себе почти никогда не использовалась клиентом до того момента, как она была заменена на V4. Тем не менее, сервер все еще отвечает V3-пакетами V4-клиентам.


Рассмотрим некоторые изменения в версии 4.

В этой версии немного изменился формат данных в UDP пакете:


Длина

Значение

Название

Описание

2 байта

04 00

VERSION

Версия протокола ICQ

4 байта

хх хх 00 00

RANDOM_ NUMBER

Случайная величина.

2 байта

хх хх

COMMAND

Код запрашиваемой функции

2 байта

хх хх

SEQ_NUM1

Порядковый номер

2 байта

хх хх

SEQ_NUM2

Порядковый номер

4 байта

хх хх хх хх

UIN

UIN отправителя

4 байта

хх хх хх хх

CHECKCODE

Контрольная сумма.

Переменная

   

0 или больше параметров. Зависит от поля COMMAND



Появились новые варианты статуса состояния пользователя, которые можно использовать в командах LOGIN, STATUS_CHANGE, STATUS_UPDATE:


Значение

Название

Описание

00 00 00 00

STATUS_ONLINE

Пользователь на линии

01 00 00 00

STATUS_AWAY

Пользователь отлучился

13 00 00 00

STATUS_DND

Не беспокоить

00 01 00 00

STATUS_INVISIBLE

Пользователь в режиме “невидимости”

10 00 00 00

STATUS_OCCUPIED

Занят

04 00 00 00

STATUS_NA

Не доступен

20 00 00 00

STATUS_CHAT

Не против чата



Кроме того, все данные UDP пакета шифруются по следующему алгоритму:

  1. Вычисляется контрольная сумма по следующему алгоритму:

  1. Формируется число N1= 0x B8 B4 B2 B6


Где

B8 – 8-oй байт данных (младший байт поля SEQ_NUM1)

B6 – 6-oй байт данных (младший байт кода запрашиваемой функции)

B4 – 4-oй байт данных (младший байт второго слова

RANDOM_NUMBER)

B2 – 2-oй байт данных (младший байт первого слова поля

RANDOM_NUMBER)

b) PL = длина данных пакета.

R1 = Случайное число между 00 и PL – 4. Но не попадающее в диапазон [16,19] (смещения байтов контрольной суммы в пакете)

R2 = Случайное число от 00 до 255 (0xFF).


с) Формируется число N2

X4=R1

X3 = NOT (байт по смещению X4)

X2 = R2

X1 = NOT (байт по смещению X2 в таблице 1)

N2 = 0x X4 X3 X2 X1


В качестве таблицы используемой в формировании числа N2 разработчики взяли текст из документации к программе:


POS   DATA                                               ASCII

--- -----------------------------------------------   ----------------
00 - 0A 5B 31 5D 20 59 6F 75 20 63 61 6E 20 6D 6F 64   .[1] You can mod
10 - 69 66 79 20 74 68 65 20 73 6F 75 6E 64 73 20 49   ify the sounds I
20 - 43 51 20 6D 61 6B 65 73 2E 20 4A 75 73 74 20 73   CQ makes. Just s
30 - 65 6C 65 63 74 20 22 53 6F 75 6E 64 73 22 20 66   elect "Sounds" f
40 - 72 6F 6D 20 74 68 65 20 22 70 72 65 66 65 72 65   rom the "prefere
50 - 6E 63 65 73 2F 6D 69 73 63 22 20 69 6E 20 49 43   nces/misc" in IC
60 - 51 20 6F 72 20 66 72 6F 6D 20 74 68 65 20 22 53   Q or from the "S
70 - 6F 75 6E 64 73 22 20 69 6E 20 74 68 65 20 63 6F   ounds" in the co
80 - 6E 74 72 6F 6C 20 70 61 6E 65 6C 2E 20 43 72 65   ntrol panel. Cre
90 - 64 69 74 3A 20 45 72 61 6E 0A 5B 32 5D 20 43 61   dit: Eran.[2] Ca
A0 - 6E 27 74 20 72 65 6D 65 6D 62 65 72 20 77 68 61   n't remember wha
B0 - 74 20 77 61 73 20 73 61 69 64 3F 20 20 44 6F 75   t was said? Dou
C0 - 62 6C 65 2D 63 6C 69 63 6B 20 6F 6E 20 61 20 75   ble-click on a u
D0 - 73 65 72 20 74 6F 20 67 65 74 20 61 20 64 69 61   ser to get a dia
E0 - 6C 6F 67 20 6F 66 20 61 6C 6C 20 6D 65 73 73 61   log of all messa
F0 - 67 65 73 20 73 65 6E 74 20 69 6E 63 6F 6D 69 6E   ges sent incomin
-- -----------------------------------------------   ----------------

Табл. 1


Из N1 и N2 CHECKCODE вычисляется как N1 XOR N2.




2) Затем вычисляются значения:

PL = длина данных пакета.

CODE1 = (DWORD) (PL * 0x66756B65)

CODE2 = (DWORD) (CODE1 + CHECKCODE)

N = (PL + 3) DIV 4

POS = 0


После этого в цикле:


while POS < N do

begin

T = POS MOD 0x0100

CODE3 = CODE2 + TABLE[T] (Байт T из таблицы Табл. 1)

DATA = DWORD по смещению POS в данных пакета

DATA = DATA XOR CODE3

DWORD по смещению POS в данных пакета = DATA

POS = POS + 4

end


3) первые 2 байта полученных данных заменяются на 04 00


Процедура расшифровки полностью аналогична (благодаря обратимости операции XOR) за исключением того, что значение CHECKCODE не высчитывается, а берется из пакета.

Следует отметить, что шифруются только данные, посылаемые клиентом серверу, или другому клиенту.


Версия 5

В начале 1998 года появилась следующая версия протокола. На данный момент она является последней модификацией протокола ICQ.

Об этой версии протокола известно не так много.


В этой версии также немного изменился формат данных в UDP пакете:


Длина

Значение

Название

Описание

2 байта

05 00

VERSION

Версия протокола ICQ

4 байта

00 00 00 00

ZERO

Зарезервировано

4 байта

хх хх хх хх

UIN

UIN отправителя

4 байта

хх хх хх хх

SESSION_ID

Случайная величина

2 байта

хх хх хх хх

COMMAND

Код запрашиваемой функции

2 байта

хх хх

SEQ_NUM1

Порядковый номер

2 байта

хх хх

SEQ_NUM2

Порядковый номер

4 байта

хх хх хх хх

CHECKCODE

Контрольная сумма.

Переменная

   

0 или больше параметров. Зависит от поля COMMAND




Так же известно, что подверглись изменению алгоритмы генерации CHECKCODE и шифрования данных.


Для генерирования CHECKCODE аналогично 4-ой версии протокола формируются 2 числа: N1 и N2 и затем производится операция XOR.

Как и в 4-ой версии протокола, число N1 cоставляется из 8-ого, 4-ого, 2-ого и 6-ого байта данных пакета.


PL = длина данных пакета.

R1 = Случайное число между 00 и (PL - 18) - 1

R2 = Случайное число от 00 до 255 (0xFF).


X4 = R1

X3 = NOT (BYTE по смещению X4 в данных пакета)

X2 = R2

X1 = NOT (BYTE по смещению X2 в таблице Табл. 2)

Число N2 составляется из полученных таким образом байт.

N2 = 0x X4 X3 X2 X1


Следующая таблица, похоже, тоже является преобразованной частью какого-то текста. Однако выяснить это пока не удалось.


POS   DATA                                           ASCII

--- -----------------------------------------------   ----------------
00 - 59 60 37 6B 65 62 46 48 53 61 4C 59 60 57 5B 3D   Y`7kebFHSaLY`W[=
10 - 5E 34 6D 36 50 3F 6F 67 53 61 4C 59 40 47 63 39   ^4m6P?ogSaLY@Gc9
20 - 50 5F 5F 3F 6F 47 43 69 48 33 31 64 35 5A 4A 42   P__?oGCiH31d5ZJB
30 - 56 40 67 53 41 07 6C 49 58 3B 4D 46 68 43 69 48   V@gSA.lIX;MFhCiH
40 - 33 31 44 65 62 46 48 53 41 07 6C 69 48 33 51 54   31DebFHSA.liH3QT
50 - 5D 4E 6C 49 38 4B 55 4A 62 46 48 33 51 34 6D 36   ]NlI8KUJbFH3Q4m6
60 - 50 5F 5F 5F 3F 6F 47 63 59 40 67 33 31 64 35 5A   P___?oGcY@g31d5Z
70 - 6A 52 6E 3C 51 34 6D 36 50 5F 5F 3F 4F 37 4B 35   jRn<Q4m6P__?O7K5
80 - 5A 4A 62 66 58 3B 4D 66 58 5B 5D 4E 6C 49 58 3B   ZJbfX;MfX[]NlIX;
90 - 4D 66 58 3B 4D 46 48 53 61 4C 59 40 67 33 31 64   MfX;MFHSaLY@g31d
A0 - 55 6A 32 3E 44 45 52 6E 3C 31 64 55 6A 52 4E 6C   Uj2>DERn<1dUjRNl
B0 - 69 48 53 61 4C 39 30 6F 47 63 59 60 57 5B 3D 3E   iHSaL90oGcY`W[=>
C0 - 64 35 3A 3A 5A 6A 52 4E 6C 69 48 53 61 6C 49 58   d5::ZjRNliHSalIX
D0 - 3B 4D 46 68 63 39 50 5F 5F 3F 6F 67 53 41 25 41   ;MFhc9P__?ogSA%A
E0 - 3C 51 54 3D 5E 54 5D 4E 4C 39 50 5F 5F 5F 3F 6F   <QT=^T]NL9P___?o
F0 - 47 43 69 48 33 51 54 5D 6E 3C 31 64 35 5A 00 00   GCiH3QT]n<1d5Z..
--- -----------------------------------------------   ----------------

Табл. 2.


Перед помещением величины CHECKCODE в пакет ее биты “перемешиваются” по следующей таблице:

bit 31 -> bit 21
bit 30 -> bit 20
bit 29 -> bit 19
bit 28 -> bit 18
bit 27 -> bit 17
bit 26 -> bit 11
bit 25 -> bit 26
bit 24 -> bit 25
bit 23 -> bit 24
bit 22 -> bit 23
bit 21 -> bit 22
bit 20 -> bit 05
bit 19 -> bit 04
bit 18 -> bit 03
bit 17 -> bit 02
bit 16 -> bit 01
bit 15 -> bit 31
bit 14 -> bit 30
bit 13 -> bit 29
bit 12 -> bit 28
bit 11 -> bit 27
bit 10 -> bit 00
bit 09 -> bit 10
bit 08 -> bit 09
bit 07 -> bit 08
bit 06 -> bit 07
bit 05 -> bit 06
bit 04 -> bit 16
bit 03 -> bit 15
bit 02 -> bit 14
bit 01 -> bit 13
bit 00 -> bit 12


Табл. 3.


При декодировании данных значение CHECKCODE должно быть восстановлено по этой же таблице в обратнюу сторону.

Т.е. bit 31 <- bit 21; bit 30 <- bit 20 и т.д.


2) Дале по алгоритму, аналогичному используемому в 4-ой версии протокола для шифрования и расшифровывания данных используется следующий алгоритм:


PL = Длина данных

CODE1 = (DWORD) (PL * 0x68656C6C) (flush the overflow)

CODE2 = (DWORD) (CODE1 + CHECKCODE) (flush the overflow)

N = (PL + 0x03)

POS = 0x0A


3) цикле делаем следующие преобразования:

while POS < N do

begin

T = POS MOD 0x0100

CODE3 = CODE2 + TABLE[T] (Байт в таблице по смещению T)

DATA = DWORD по смещению POS в данных пакета

DATA = DATA XOR CODE3

DWORD по смещению POS в данных пакета = DATA

POS = POS + 4

End




Заключение

Несомненно, ICQ является заслуживающей внимание услугой предоставляемой Сетью. На данный момент организуются службы, позволяющие посылать сообщения пользователям ICQ с помощью обыкновенного телефона – используя ресурсы пейджинговых компаний. Это, как и бесплатность самой ICQ, делают последнюю еще более превлекательным для пользователей сети Интернет. Существует так же возможность создавать собственные локальные ICQ-сервера, которые позволяют общаться пользователям Интранет не завися от серверов Mirabilis.








Список сокращений




TCP - Transmission Control Protocol.

UDP - User Datagram Protocol

IP - Internet Protoco

UIN - Universal Internet Number

DNS - Domain Name System


Литература и ресурсы


  1. "Освой самостоятельно TCP/IP" Тимоти Паркер 1997, Москва
  2. http://info.internet.isi.edu/in-notes/rfc/files/rfc793.txt
    "User Datagram Protocol"
  3. http://info.internet.isi.edu/in-notes/rfc/files/rfc793.txt
    "Transmission Controt Protocol"
  4. http://www.lgg.ru/~sophocles/
    “The ICQ Protocol Site”
  5. http://www.mirabilis.com/, http://www.icq.com/
    Официальный сайт Mirabilis, и официальный сайт поддержки ICQ
  6. http://www.lgg.ru/~sophocles/spec/v2/icq091.txt
    “THE ICQ PROTOCOL v2”
  7. http://www.globalserve.net/~jphowe/icq
    Описание ICQ протокола версии 3
  8. http://www.lgg.ru/~sophocles/spec/v5/v5-encryption.txt
    “ENCRYPTION and CHECKCODE of the ICQ Protocol V5”
  9. http://www.algonet.se/~henisak/icq/icqv5.html
    Version 5 of the ICQ Protocol
  10. http://www.algonet.se/~henisak/icq/tcp02.txt
    ICQ TCP Protocol as used by STRICQ