33
Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

Embed Size (px)

Citation preview

Page 1: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

Implementierung eines IRC Servers in Java

von

M. Serhat Cinar AI 11030409

WPF Compiler & Interpreter SS04

bei Prof. Dr. Ehses

Page 2: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

2

IRC

IRC := Internet Relay Chat (Relay = Relais, Übertragung)

Der Benutzer meldet sich bei einem Server (z.B. A) an.Dieser Server wiederum ist mit anderen Servern desselben Netzes

verbunden (z.B. mit Server C über Server B).Jeder Benutzer, der mit einem Server verbunden ist erhält vom Server

eine Liste aller Channels, die in dem jeweiligen Netz verfügbar sind und kann sich in jedem beliebigen Channel anmelden (JOIN).

Das IRC-Geflecht von Servern ist in Netze aufgeteilt. Beispiele für verschiedene große Netze sind das DALnet, Efnet oder IRCnet.

Benutzer im selben Channel können sich unterhalten (chatten). Schickt Benutzer A über Server A eine Nachricht an Benutzer C an

Server C, so wird die Nachricht wie ein PING über das IRC-Netz geschickt. Die verschiedenen Stationen bei einer solchen Weiterleitung nennt man Relais.

Das Prinzip ist dem DNS, Mail-Relay oder dem PING Protokoll ähnlich.

Page 3: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

3

IRC als Netzwerk

Page 4: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

4

IRC - Standard

Die Standards für das IRC-Protokoll werden in den Request for Comments (RFC‘s) verwaltet.

RFC 1459 - IRC ProtocolRFC 2810 - IRC ArchitectureRFC 2811 - IRC Channel ManagementRFC 2812 - IRC Client ProtocolRFC 2813 - IRC Server Protocol

Page 5: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

5

RFC 2812 Internet Relay Chat: Client Protocol 1/2

message = [ ":" prefix SPACE ] command [ params ] crlf

prefix = servername / ( nickname [ [ "!" user ] "@" host ] )

command = 1*letter / 3digit

params = *14( SPACE middle ) [ SPACE ":" trailing ]

=/ 14( SPACE middle ) [ SPACE [ ":" ] trailing ]

nospcrlfcl = %x01-09 / %x0B-0C / %x0E-1F / %x21-39 / %x3B-FF

; any octet except NUL, CR, LF, " " and ":"

middle = nospcrlfcl *( ":" / nospcrlfcl )

trailing = *( ":" / " " / nospcrlfcl )

SPACE = %x20 ; space character

crlf = %x0D %x0A ; "carriage return" "linefeed"

letter = %x41-5A / %x61-7A ; A-Z / a-z

digit = %x30-39 ; 0-9

hexdigit = digit / "A" / "B" / "C" / "D" / "E" / "F"

special = %x5B-60 / %x7B-7D

; "[", "]", "\", "`", "_", "^", "{", "|", "}„

user = 1*( %x01-09 / %x0B-0C / %x0E-1F / %x21-3F / %x41-FF )

; any octet except NUL, CR, LF, " " and "@"

Page 6: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

6

RFC 2812 Internet Relay Chat: Client Protocol 2/2

key = 1*23( %x01-05 / %x07-08 / %x0C / %x0E-1F / %x21-7F )

; any 7-bit US_ASCII character,

; except NUL, CR, LF, FF, h/v TABs, and " "

servername = hostname

host = hostname / hostaddr

hostname = shortname *( "." shortname )

shortname = ( letter / digit ) *( letter / digit / "-" )

*( letter / digit )

; as specified in RFC 1123 [HNAME]

hostaddr = ip4addr / ip6addr

ip4addr = 1*3digit "." 1*3digit "." 1*3digit "." 1*3digit

ip6addr = 1*hexdigit 7( ":" 1*hexdigit )

ip6addr =/ "0:0:0:0:0:" ( "0" / "FFFF" ) ":" ip4addr

nickname = ( letter / special ) *8( letter / digit / special / "-" )

Page 7: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

7

Message Grundstruktur

Message

:Prefix Command Paramlist

:TrailingSPACE Param *Server / User

Page 8: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

8

Verschiedene Implementierungen: CRLF vs. LF

RFC 2812:message = [ ":" prefix SPACE ] command [ params ]

crlfcrlf = %x0D %x0A

mIRC:4E 49 43 4B 20 74 65 73 74 0A NICK

test.

BitchX:4E 49 43 4B 20 74 65 73 74 0D 0A NICK

test..

Page 9: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

9

jIrcSX.flex 1/2

CR = \x0D

LF = \x0A

CRLF = {CR} {LF}

SPACE = \x20

DIGIT = \x30|\x31|\x32|\x33|\x34|\x35|\x36|\x37|\x38|\x39

LETTER_HEX = "A" | "B" | "C" | "D" | "E" | "F"

LETTER = [A-Za-z]

COLON = ":"

AT = "@"

EXCLAMATION_MARK = "!"

DOT = "."

VALUE = "#"

COMMA = ","

PLUS = "+"

MINUS = "-"

AND = "&"

Page 10: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

10

jIrcSX.flex 2/2

UNDERSCORE = "_"ACCENT_CIRCONFLEX = "^"SQUARED_BRACKET_LEFT = "["SQUARED_BRACKET_RIGHT = "]"BRACE_LEFT = "{"BRACE_RIGHT = "}"BACKSLASH = "\\"APOSTROPHE = "`"OR = "|"TAB = \x09NULL = \x00BELL = \x07FF = \x0CSYMBOL_OTHER = .

HEXDIGIT = {DIGIT} | {LETTER_HEX}IP6ADDR = ( {HEXDIGIT}+ (":" {HEXDIGIT}+){7} ) | ( "0:0:0:0:0:" ("0"|"FFFF") ":" {IP4ADDR} )IP4ADDR = {DIGIT} {1,3} "." {DIGIT} {1,3} "." {DIGIT} {1,3} "." {DIGIT} {1,3}

HOSTNAME = {SHORTNAME} ( "." {SHORTNAME})+SHORTNAME = ( {LETTER} | {DIGIT} ) ( {LETTER} | {DIGIT} | "-" )*

( {LETTER} | {DIGIT} )*

Page 11: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

11

Recursive Descending Parser

private int lookahead(), private void match(int symbol), private void match()public INode parse(String pIrcMessage)private INode message()private INode prefix()private String nickname()private String letterOrSpecial()private String letterOrSpecialOrDigitOrMinusOrEmpty()private String user()private String userLetterOrEmpty()private INode host()private INode hostaddr()private INode command()private INode params()private String middle()private String middleRepeatOrEmpty()private String trailing()

Page 12: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

12

MessageNode

public class MessageNode implements INode {public INode mPrefix, mCommand, mParams;public void accept(IVisitor v)[...] public String getCommand(){

return ((CommandNode) mCommand).mCommand;}public boolean hasColonedTrailing(){

if (mParams==null) return false;return ((ParamsNode) mParams).mColonedTrailing;

}public int getParamsSize(){

if (mParams==null) return 0;return ((ParamsNode) mParams).mMiddles.size();

}public String getParam(int i){

if (mParams==null) return null;ParamsNode lPN = (ParamsNode) mParams;if (lPN.mMiddles == null || lPN.mMiddles.size()<=i) return

null;return ((String)lPN.mMiddles.get(i));

}}

Page 13: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

13

Weitere Nodes 1/2

public class PrefixHostNameNode implements INode {

public String mServerName;

[...]

}

public class CommandNode implements INode {

public String mCommand;

[...]

}

public class PrefixNickUserHostNode implements INode {

public String mNickName, mUser;

public INode mHost;

[...]

}

Page 14: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

14

Weitere Nodes 2/2

public class IPv4AdressNode implements INode {

public String mAdress;

[...]

}

public class ParamsNode implements INode {

public Vector mMiddles;

public boolean mColonedTrailing = false;

}

Page 15: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

15

Verbindungsaufbau Client->Server 1/2

The commands described here are used to register a connection with an IRC server as

a user as well as to correctly disconnect.

A "PASS" command is not required for a client connection to be registered, but it MUST

precede the latter of the NICK/USER combination (for a user connection) or the SERVICE command (for a service connection). The RECOMMENDED order for a client to register is as follows:

1. Pass message 2. Nick message 2. Service message 3. User message

Upon success, the client will receive an RPL_WELCOME (for users) or RPL_YOURESERVICE (for services) message indicating that the connection is

now registered and known the to the entire IRC network.The reply message MUST contain the full client identifier upon which it was

registered.

Page 16: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

16

Verbindungsaufbau Client->Server 2/2

NICK test

USER test "" "irc.gamesnet.net" :x

:genesis.GamesNET.net NOTICE AUTH :Looking up the hostname for 81.173.149.151...

:genesis.GamesNET.net NOTICE AUTH :Please wait while your system is scanned for insecure proxy servers...

:genesis.GamesNET.net NOTICE AUTH :Successfully resolved your IP to xdsl-81-173-149-151.netcologne.de.

PING :4048004E

PING :4048004E

PONG :4048004E

PONG :4048004E

:genesis.GamesNET.net 001 test :Welcome to the Internet Relay Chat network, [email protected]

= Client = Server

Page 17: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

17

NICK Message

Command: NICK Parameters: <nickname>

NICK command is used to give user a nickname or change the existing one.

Numeric Replies: ERR_NONICKNAMEGIVEN ERR_ERRONEUSNICKNAME ERR_NICKNAMEINUSE ERR_NICKCOLLISION ERR_UNAVAILRESOURCE ERR_RESTRICTED

Examples: NICK Wiz ; Introducing new nick "Wiz" if session is still

unregistered, or user changing his nickname to "Wiz"

:[email protected] NICK Kilroy ;Server telling that WiZ changed his nickname to Kilroy.

Page 18: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

18

Weitere Befehle 1/3

3.1 Connection Registration3.1.1 Password message3.1.2 Nick message3.1.3 User message3.1.4 Oper message3.1.5 User mode message3.1.6 Service message3.1.7 Quit3.1.8 Squit

3.2 Channel operations3.2.1 Join message3.2.2 Part message3.2.3 Channel mode message3.2.4 Topic message3.2.5 Names message3.2.6 List message3.2.7 Invite message3.2.8 Kick command

Page 19: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

19

Weitere Befehle 2/3

3.3 Sending messages3.3.1 Private messages3.3.2 Notice

3.4 Server queries and commands3.4.1 Motd message3.4.2 Lusers message3.4.3 Version message3.4.4 Stats message3.4.5 Links message3.4.6 Time message3.4.7 Connect message3.4.8 Trace message3.4.9 Admin command3.4.10 Info command

3.5 Service Query and Commands 3.5.1 Servlist message 3.5.2 Squery

Page 20: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

20

Weitere Befehle 3/3

3.6 User based queries 3.6.1 Who query 3.6.2 Whois query 3.6.3 Whowas3.7 Miscellaneous messages 3.7.1 Kill message 3.7.2 Ping message 3.7.3 Pong message 3.7.4 Error4. Optional features 4.1 Away 4.2 Rehash message 4.3 Die message 4.4 Restart message 4.5 Summon message 4.6 Users 4.7 Operwall message 4.8 Userhost message 4.9 Ison message

Page 21: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

21

Software Architektur

.

Server ClientHandler

1 *

RDParser

11

RegistrationProcessor

CommandProcessor

1 11 44

.

.

User1 1

UserList

11

1

*

Page 22: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

22

User

Die Klasse User verwaltet userbezogene Informationen.

public class User {

public String mNick;

public ClientHandler mClientHandler;

public String mPass;

public String mUsername;

public String mHostname;

public String mRealname;

public String mMode;

public MessageNode mLastMessage;

public String mInternetAdress;

}

Page 23: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

23

Server

Der Server erzeugt einen ServerSocket auf dem IRC Port 6667. Für jede ankommende Verbindung wird ein eigener ClientHandler erzeugt.

while (mRunning){new ClientHandler(lServerSocket.accept(), this);

}

Weiterhin stellt der Server Zentrale Informationen zur Verfügung, wie die Liste der aktuell verbundenen Clients.

public String getName()public String getServerAdress()public String getServerAdressString()public int getServerPort()public UserList getUserList()

Page 24: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

24

ClientHandler 1/3

Jeder Client erhält einen eigenen ClientHandler, der als nebenläufiger Prozess alle Eingabezeichen des Clients aus dem InputStream des Sockets liest, bis das Ende einer Message erreicht wird und anschließend parst.

public synchronized MessageNode getNextMessageNode() throws SyntaxException, IOException{StringBuffer lInputBuffer = new StringBuffer();int lReadByte;while ( (lReadByte = mInputReader.read()) != -1){

lInputBuffer.append((char)lReadByte);if (lInputBuffer.indexOf(LexicalSymbols.STRING_LF)>-1)

break;}if (lReadByte==-1) mUser.mLastMessage = null;else mUser.mLastMessage = (MessageNode) mServer.parse(lInputBuffer.toString());return mUser.mLastMessage;

}

Page 25: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

25

ClientHandler 2/3

Weitere Methoden ermöglichen das Senden von Nachrichten über den OutputSteam:

public synchronized void sendMessage(String pMessage){

Log.getInstance().writeln(toString()+" sending: "+pMessage);

mPrintWriter.print(pMessage+LexicalSymbols.STRING_CRLF);

mPrintWriter.flush();

}

public synchronized void sendNumericReply(String [] pNumber){

sendMessage(NumericReplies.getNumericReplyMessage(pNumber, mUser));

}

Page 26: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

26

ClientHandler 3/3

try {RegistrationProcessor lRegistration = new RegistrationProcessor();lRegistration.process(mUser, null);while (mRunning){

// read next message from clienttry {

lMessage = getNextMessageNode(); if (lMessage==null)mRunning = false; if

(mCommandProcessors.containsKey(lMessage.getCommand().toUpperCase())){

lCommandProcessor = (ICommandProcessor) mCommandProcessors.get(lMessage.getCommand().toUpperCase());

lCommandProcessor.process(mUser, lMessage);}

}catch (SyntaxException e) {

Log.getInstance().writeln("ParseException: "+e.toString());sendNumericReply(NumericReplies.ERR_NEEDMOREPARAMS);

}

Page 27: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

27

ICommandProcessor

public interface ICommandProcessor {public void process(User pUser, MessageNode pMessageNode)

throws IOException;

public String getCommandString();}

Page 28: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

28

NickProcessor

public void process(User pUser, MessageNode pMessageNode)throws IOException {

String lNewNick = pMessageNode.getParam(0); if (lNewNick != null){

UserList lList = pUser.mClientHandler.getServer().getUserList();

lList.renameUser(pUser, lNewNick);// TODO broadcast new nick of user

}else pUser.mClientHandler.

sendNumericReply(NumericReplies.ERR_NONICKNAMEGIVEN);

}

public String getCommandString() {return CommandStrings.NICK;

}

Page 29: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

29

PingProcessor

public void process(User pUser, MessageNode pMessageNode)

throws IOException {

// PING :4048004E

// PONG :4048004E

String lPingCode = pMessageNode.getParam(0);

if (lPingCode != null)

pUser.mClientHandler.sendMessage("PONG :"+lPingCode);

else pUser.mClientHandler.sendMessage("PONG");

}

public String getCommandString() {

return CommandStrings.PING;

}

Page 30: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

30

Auszug einer Login-Prozedur 1/2

Client connected: 127.0.0.1

ClientHandler 127.0.0.1 received: "NICK test"

COMMAND: NICK

MIDDLE: test

ClientHandler test received: "USER test "" "127.0.0.1" :x"

COMMAND: USER

MIDDLE: test

MIDDLE: ""

MIDDLE: "127.0.0.1"

ClientHandler test sending: :127.0.0.1 001 test :Welcome to the Internet Relay Network [email protected]

ClientHandler test sending: :127.0.0.1 002 test :Your host is 127.0.0.1 [127.0.0.1:6667], running version jIRC Server X Version 25.06.2004

ClientHandler test sending: :127.0.0.1 003 test :This server was created <date>

Page 31: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

31

Auszug einer Login-Prozedur 2/2

ClientHandler test sending: :127.0.0.1 004 test :127.0.0.1 [127.0.0.1:6667] <version> <available user modes> <available channel modes>

ClientHandler test sending: :127.0.0.1 005 test :Try server 127.0.0.1, port <port number>

ClientHandler test sending: :127.0.0.1 251 test :There are <integer> users and <integer> services on <integer> servers

ClientHandler test sending: :127.0.0.1 252 test <integer> :operator(s) online

ClientHandler test sending: :127.0.0.1 253 test <integer> :unknown connection(s)

ClientHandler test sending: :127.0.0.1 254 test <integer> :channels formed

ClientHandler test sending: :127.0.0.1 255 test :I have <integer> clients and <integer> servers

ClientHandler test sending: :127.0.0.1 375 test :- <server> Message of the day -

ClientHandler test sending: :127.0.0.1 372 test :- <text>ClientHandler test sending: :127.0.0.1 376 test :End of MOTD

command

Page 32: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

32

TODO

• Weitere IRC Befehle über die Schnittstelle ICommandProcessor implementieren

• Channel Verwaltung• Server to Server Kommunikation

Page 33: Implementierung eines IRC Servers in Java von M. Serhat Cinar AI 11030409 WPF Compiler & Interpreter SS04 bei Prof. Dr. Ehses

33

Referenzen

jIrcSX – www.graviton.de/ai/c-und-iDer in diesem Projekt entstehende IRC-Server

BitchX – www.bitchx.orgDOS IRC Client für Unix/Linux/MacOS/Windows

mIRC - www.mirc.comIRC Client mit GUI für Windows

RFC Archiv - www.faqs.org/rfcs

jFlex – jflex.deJava Scanner Generator