[IRC-DEV] Propuesta definitiva de API TCP/IP 0 de Olimpo ( revisión 2)

Jesus Cea Avion jcea at argo.es
Wed Sep 11 13:50:09 CEST 2002


Este documento define la propuesta definitiva (11/Sep/02) para el nivel
CERO del API TCP/IP de Olimpo.

El objetivo de este API es crear un estándar para que los bots y Olimpo
puedan comunicarse a través de TCP/IP. Ello posibilita, por ejemplo, que
los bots puedan residir en cualquier lugar de internet, y que
IRC-Hispano no tenga por qué tener acceso a su código fuente.

Existe interés, también, en que este API sea utilizado en otras redes,
de forma que los bots se puedan utilizar tanto en IRC-Hispano como en la
"competencia".


ESPECIFICACIONES

El API consiste en el intercambio de comandos y respuestas, de forma
asíncrona.

El servidor envía los comandos y las respuestas como texto terminado con
un "\r\n" (retorno de carro y salto de línea, ASCII 13 y 10,
respectivamente). El servidor acepta texto terminado con "\r\n" y "\n".
Es decir, el "\r" es opcional, pero se recomienda.

Los comandos y respuestas ignoran mayúsculas y minúsculas en su nombre.

El servidor desconectará cualquier bot que utilice un comando no
documentado o utilice una sintaxis ilegal.

La longitud máxima de una línea permitida por el servidor es de 256
bytes. Si un bot intenta enviar líneas más largas, será desconectado.

El servidor puede enviar líneas arbitrariamente largas, y los bots deben
soportarlo.

Solo se admiten comunicaciones con usuario con modo "+r".

COMANDOS y RESPUESTAS

CHALLENGE
Sintaxis: "challenge" mecanismos ":"reto

Este comando es enviado por el servidor para verificar la identidad de
un bot que intenta conectarse. El servidor plantea un reto, que el bot
debe responder correctamente antes de que se le permita conectar y de
que pueda enviar ningún comando al sistema o recibir notificaciones
desde el mismo.

En este momento se definen los mecanismos "HMAC-MD5" y "HMAC-SHA1". Ver
http://rfc.net/rfc2104.html, http://rfc.net/rfc1321.html y
http://rfc.net/rfc2201.html, para más información.

"reto" es un parámetro proporcionado por el servidor.

CHALLENGE-RESULT
Sintaxis: "challenge-result" mecanismo level nick ":"resultado

Ésta es la respuesta enviada por el bot al comando "challenge-result".
El resultado se envía codificado en hexadecimal.

El cliente debe elegir un mecanismo de entre los propuestos por el
servidor.

"level" indica el nivel de acceso que estamos solicitando. Este
documento define el nivel "0".

Olimpo no admite que el cliente envíe *NINGÚN* comando *ANTES* de haber
completado la autentificación. Hacerlo será causa de desconexión.

VERSION
Sintaxis: "version" (cliente -> servidor)
          "version" ":"version (servidor->cliente)

Proporciona la versión de protocolo. La versión actual es "1".

BYE
Sintaxis: "bye" ":"razón

Este comando indica la causa de la desconexión inminente. Cuando el
receptor lee este comando, debe cerrar la conexión.

Este comando puede ser enviado tanto por el cliente como por Olimpo. Se
puede cerrar una conexión sin enviar este comando, pero no se
recomienda, ya que complica la depuración o la información almacenada en
logs.

PING
Sintaxis: "ping" ":"token

Envía un "ping" al otro extremo.

PONG
Sintaxis: "pong" ":"token

Responde al "ping". El token *DEBE* ser el mismo del "ping".

COMMANDLIST
Sintaxis: "commandlist" comandos...

Este mensaje comunica al servidor la lista de comandos que acepta el
bot. El servidor sólo enviará al bot los privados de usuarios
conteniendo dichos mensajes. Si un usuario envía un comando inexistente,
el servidor lo ignorará y nunca llegará al bot.

Se ignora mayúsculas y minúsculas.

Cada comando "COMMANDLIST" que se envíe al servidor, añade comandos a la
lista de comandos permitidos. Es decir, son acumulativos.

PRIVMSG
Sintaxis: "privmsg" csesion ":"texto

"csesion" identifica la sesión de conexión que corresponde a ese
usuario.

Cuando lo envía el servidor, indica un privado de un usuario. Si el bot
no tiene constancia de la sesión especificada, se está abriendo una
nueva sesión de conexión de forma implícita.

Cuando lo envía el bot, indica un privado *AL* usuario. Si la sesión de
conexión ya no existe, el servidor responderá con su cierre.

NOTICE
Sintaxis: "notice" csesion ":"texto

"csesion" identifica la sesión de conexión que corresponde a ese
usuario.

Cuando lo envía el servidor, indica un privado de un usuario. Si el bot
no tiene constancia de la sesión especificada, se está abriendo una
nueva sesión de conexión de forma implícita.

Cuando lo envía el bot, indica un privado *AL* usuario. Si la sesión de
conexión ya no existe, el servidor responderá con su cierre.

CSESSION
Sintaxis: "csession" comando csesion..

Realiza operaciones sobre una sesión o un grupo de sesiones de conexión.

Los comandos son:

"test": Comprueba si una sesión existe. Cliente -> Servidor
"open": Abre una sesión nueva. Este comando lo envía el servidor, y
puede ser implícito.
"closed": Avisa de que una sesión ya no existe o ya no nos interesa.
Bidireccional.
"exists": Avisa de que una sesión sigue existiendo, como respuesta a
"test". Servidor -> cliente


SINTAXIS pseudoBNF

envio:= (comando | respuesta) ("\n" | "\r\n")
comando:= challenge | bye | ping | privmsg | notice | csession
respuesta:= challenge-result | pong |
challenge:= "challenge" metodos-challenge ":"reto
metodos-challenge:= metodo-challenge [metodo-challenge..]
metodo-challenge:= ("HMAC-MD5" | "HMAC-SHA1")
reto:= imprimible..
alfanumerico:= ("a"|..|"z"|"A"|..|"Z"|"0"|.."9")
challenge-result:= "challenge-result" metodo-challenge level nick
":"respuesta
level:= alfanumerico..
nick:= alfanumextras..
alfanumextras=(alfanumerico | "-" | "_")
respuesta=hexadecimal..
hexadecimal=("A"|..|"F"|"a"|..|"f"|"0".."9")
imprimiblesinespacio:=('\0001'|..|'\0010') | '\0013' | '\0014' |
                      ('\0016'|..|'\0377')
imprimible:= (imprimiblesinespacio | " " | "\t")
bye:= "bye" ":"razón
razón:= imprimible..
ping:= "ping" ":"razón
pong:= "pong" ":"razón
commandlist:= "commandlist" listacomando..
listacomando:= imprimiblesinespacio..
privmsg:= "privmsg" csesion ":"texto
notice:="notice" csesion ":"texto
csesion:= alfanumerico..
texto:= imprimible..
csession:= "csession" comando-csesion csesion..
comando-csesion:= "test" | "open" | "closed" | "exists"


SESIONES DE CONEXION

Una sesión de conexion identifica unívocamente a un usuario en una
conexión determinada. Su validez termina cuando:

a) El usuario se desconecta, aunque vuelva a reconectarse.
b) Cuando hay un split en la red.
c) Si el usuario cambia de nick.


RACIONAL

Ha pasado mucho tiempo desde la última versión de este borrador, que fue
enviada en Febrero. No hay cambios reseñables desde aquel borrador (el
segundo), pero se ha analizado detalladamente la conveniencia de que el
API se basase en el estándar IRC "clásico", en vez de definir un
protocolo 100% nuevo.

Los puntos a favor son:

a) Protocolo conocido ya por los desarrolladores de IRC.

b) Existen ya librerías cliente que soportan el protocolo IRC clásico.

c) Compatibilidad con infinidad de bots, scripts, etc. ya existentes.

d) Se puede desarrollar un servicio sobre IRC clásico y migrarlo a
Olimpo sin tocar ni una línea de código.

Los puntos en contra son:

a) La mayoría de los comandos y modos IRC no tienen sentido en el API,
por lo que no estarían soportados y podrían complicar la migración de
servicios IRC clásicos.

b) Habría que ampliar el protocolo IRC con algunos comandos necesarios
para el API (como el control de sesiones), con lo que ya no sería
protocolo IRC tradicional.

Tras dar muchas vueltas a ambas alternativas, he optado por la opción de
definir un protocolo nuevo tras darme cuenta de que con dicho protocolo
resulta relativamente simple crear un PROXY que, por un entremo hable
protocolo Olimpo y por el otro extremo use protocolo IRC clásico. Es
decir, resulta sencillo programar un "adaptador de protocolo" que
permita conectar un servicio IRC clásico a Olimpo.

Realizar la adaptación al revés resulta imposible, así que la decisión,
ahora, está clara.




More information about the IRC-Dev mailing list