source: code/trunk/upstream.go@ 16

Last change on this file since 16 was 16, checked in by contact, 5 years ago

Handle upstream RPL_MYINFO messages

File size: 2.5 KB
RevLine 
[13]1package jounce
2
3import (
4 "crypto/tls"
5 "fmt"
6 "io"
7 "net"
8
9 "gopkg.in/irc.v3"
10)
11
[14]12const (
[16]13 rpl_localusers = "265"
[14]14 rpl_globalusers = "266"
15)
16
[13]17type upstreamConn struct {
[16]18 upstream *Upstream
19 net net.Conn
20 irc *irc.Conn
21 srv *Server
[14]22 registered bool
[16]23
24 serverName string
25 availableUserModes string
26 availableChannelModes string
27 channelModesWithParam string
[13]28}
29
30func (c *upstreamConn) handleMessage(msg *irc.Message) error {
31 switch msg.Command {
32 case "PING":
33 // TODO: handle params
34 return c.irc.WriteMessage(&irc.Message{
35 Command: "PONG",
36 Params: []string{c.srv.Hostname},
37 })
[14]38 case irc.RPL_WELCOME:
39 c.registered = true
[16]40 c.srv.Logger.Printf("Connection to %q registered", c.upstream.Addr)
41 case irc.RPL_MYINFO:
42 if len(msg.Params) < 5 {
43 return newNeedMoreParamsError(msg.Command)
44 }
45 c.serverName = msg.Params[1]
46 c.availableUserModes = msg.Params[3]
47 c.availableChannelModes = msg.Params[4]
48 if len(msg.Params) > 5 {
49 c.channelModesWithParam = msg.Params[5]
50 }
51 case irc.RPL_YOURHOST, irc.RPL_CREATED:
[14]52 // Ignore
53 case irc.RPL_LUSERCLIENT, irc.RPL_LUSEROP, irc.RPL_LUSERUNKNOWN, irc.RPL_LUSERCHANNELS, irc.RPL_LUSERME:
54 // Ignore
55 case irc.RPL_MOTDSTART, irc.RPL_MOTD, irc.RPL_ENDOFMOTD:
56 // Ignore
57 case rpl_localusers, rpl_globalusers:
58 // Ignore
59 case irc.RPL_STATSVLINE, irc.RPL_STATSPING, irc.RPL_STATSBLINE, irc.RPL_STATSDLINE:
60 // Ignore
[13]61 default:
62 c.srv.Logger.Printf("Unhandled upstream message: %v", msg)
63 }
[14]64 return nil
[13]65}
66
67func connect(s *Server, upstream *Upstream) error {
68 s.Logger.Printf("Connecting to %v", upstream.Addr)
69
70 netConn, err := tls.Dial("tcp", upstream.Addr, nil)
71 if err != nil {
72 return fmt.Errorf("failed to dial %q: %v", upstream.Addr, err)
73 }
74
[16]75 c := upstreamConn{
76 upstream: upstream,
77 net: netConn,
78 irc: irc.NewConn(netConn),
79 srv: s,
80 }
[13]81 defer netConn.Close()
82
83 err = c.irc.WriteMessage(&irc.Message{
84 Command: "NICK",
85 Params: []string{upstream.Nick},
86 })
87 if err != nil {
88 return err
89 }
90
91 err = c.irc.WriteMessage(&irc.Message{
92 Command: "USER",
93 Params: []string{upstream.Username, "0", "*", upstream.Realname},
94 })
95 if err != nil {
96 return err
97 }
98
99 for {
100 msg, err := c.irc.ReadMessage()
101 if err == io.EOF {
102 break
103 } else if err != nil {
104 return fmt.Errorf("failed to read IRC command: %v", err)
105 }
106
107 if err := c.handleMessage(msg); err != nil {
[16]108 c.srv.Logger.Printf("Failed to handle message %q from %q: %v", msg, upstream.Addr, err)
[13]109 }
110 }
111
112 return netConn.Close()
113}
Note: See TracBrowser for help on using the repository browser.