Российский Университет Дружбы Народов
Обзор протоколов работы
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, используемый ею протокол претерпел множество изменений и имел различные версии, каждая следующая из которых отличалась от предыдущей.
Эта версия устарела. На данный момент она не используется и не поддерживается.
Версия 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 может принимать следующие значения:
В поле 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 сама по себе почти никогда не использовалась клиентом до того момента, как она была заменена на 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 пакета шифруются по следующему алгоритму:
Где
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
Процедура расшифровки полностью аналогична (благодаря обратимости операции XOR) за исключением того, что значение CHECKCODE не высчитывается, а берется из пакета.
Следует отметить, что шифруются только данные, посылаемые клиентом серверу, или другому клиенту.
Об этой версии протокола известно не так много.
В этой версии также немного изменился формат данных в 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 в пакет ее биты “перемешиваются” по следующей таблице:
Табл. 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