Changeset 55 in code
- Timestamp:
- Feb 17, 2020, 11:36:42 AM (5 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/downstream.go
r54 r55 57 57 func newDownstreamConn(srv *Server, netConn net.Conn) *downstreamConn { 58 58 msgs := make(chan *irc.Message, 64) 59 conn:= &downstreamConn{59 dc := &downstreamConn{ 60 60 net: netConn, 61 61 irc: irc.NewConn(netConn), … … 67 67 go func() { 68 68 for msg := range msgs { 69 if err := conn.irc.WriteMessage(msg); err != nil {70 conn.logger.Printf("failed to write message: %v", err)71 } 72 } 73 if err := conn.net.Close(); err != nil {74 conn.logger.Printf("failed to close connection: %v", err)69 if err := dc.irc.WriteMessage(msg); err != nil { 70 dc.logger.Printf("failed to write message: %v", err) 71 } 72 } 73 if err := dc.net.Close(); err != nil { 74 dc.logger.Printf("failed to close connection: %v", err) 75 75 } else { 76 conn.logger.Printf("connection closed")76 dc.logger.Printf("connection closed") 77 77 } 78 78 }() 79 79 80 return conn81 } 82 83 func ( c *downstreamConn) prefix() *irc.Prefix {80 return dc 81 } 82 83 func (dc *downstreamConn) prefix() *irc.Prefix { 84 84 return &irc.Prefix{ 85 Name: c.nick,86 User: c.username,85 Name: dc.nick, 86 User: dc.username, 87 87 // TODO: fill the host? 88 88 } 89 89 } 90 90 91 func ( c *downstreamConn) readMessages() error {92 c.logger.Printf("new connection")91 func (dc *downstreamConn) readMessages() error { 92 dc.logger.Printf("new connection") 93 93 94 94 for { 95 msg, err := c.irc.ReadMessage()95 msg, err := dc.irc.ReadMessage() 96 96 if err == io.EOF { 97 97 break … … 100 100 } 101 101 102 err = c.handleMessage(msg)102 err = dc.handleMessage(msg) 103 103 if ircErr, ok := err.(ircError); ok { 104 ircErr.Message.Prefix = c.srv.prefix()105 c.SendMessage(ircErr.Message)104 ircErr.Message.Prefix = dc.srv.prefix() 105 dc.SendMessage(ircErr.Message) 106 106 } else if err != nil { 107 107 return fmt.Errorf("failed to handle IRC command %q: %v", msg.Command, err) 108 108 } 109 109 110 if c.closed {110 if dc.closed { 111 111 return nil 112 112 } … … 116 116 } 117 117 118 func ( c *downstreamConn) Close() error {119 if c.closed {118 func (dc *downstreamConn) Close() error { 119 if dc.closed { 120 120 return fmt.Errorf("downstream connection already closed") 121 121 } 122 122 123 if u := c.user; u != nil {123 if u := dc.user; u != nil { 124 124 u.lock.Lock() 125 125 for i := range u.downstreamConns { 126 if u.downstreamConns[i] == c {126 if u.downstreamConns[i] == dc { 127 127 u.downstreamConns = append(u.downstreamConns[:i], u.downstreamConns[i+1:]...) 128 128 } … … 137 137 } 138 138 139 close( c.messages)140 c.closed = true141 142 return nil 143 } 144 145 func ( c *downstreamConn) SendMessage(msg *irc.Message) {146 c.messages <- msg147 } 148 149 func ( c *downstreamConn) handleMessage(msg *irc.Message) error {139 close(dc.messages) 140 dc.closed = true 141 142 return nil 143 } 144 145 func (dc *downstreamConn) SendMessage(msg *irc.Message) { 146 dc.messages <- msg 147 } 148 149 func (dc *downstreamConn) handleMessage(msg *irc.Message) error { 150 150 switch msg.Command { 151 151 case "QUIT": 152 return c.Close()152 return dc.Close() 153 153 case "PING": 154 154 // TODO: handle params 155 c.SendMessage(&irc.Message{156 Prefix: c.srv.prefix(),155 dc.SendMessage(&irc.Message{ 156 Prefix: dc.srv.prefix(), 157 157 Command: "PONG", 158 Params: []string{ c.srv.Hostname},158 Params: []string{dc.srv.Hostname}, 159 159 }) 160 160 return nil 161 161 default: 162 if c.registered {163 return c.handleMessageRegistered(msg)162 if dc.registered { 163 return dc.handleMessageRegistered(msg) 164 164 } else { 165 return c.handleMessageUnregistered(msg)166 } 167 } 168 } 169 170 func ( c *downstreamConn) handleMessageUnregistered(msg *irc.Message) error {165 return dc.handleMessageUnregistered(msg) 166 } 167 } 168 } 169 170 func (dc *downstreamConn) handleMessageUnregistered(msg *irc.Message) error { 171 171 switch msg.Command { 172 172 case "NICK": 173 if err := parseMessageParams(msg, & c.nick); err != nil {173 if err := parseMessageParams(msg, &dc.nick); err != nil { 174 174 return err 175 175 } 176 176 case "USER": 177 177 var username string 178 if err := parseMessageParams(msg, &username, nil, nil, & c.realname); err != nil {179 return err 180 } 181 c.username = "~" + username178 if err := parseMessageParams(msg, &username, nil, nil, &dc.realname); err != nil { 179 return err 180 } 181 dc.username = "~" + username 182 182 default: 183 c.logger.Printf("unhandled message: %v", msg)183 dc.logger.Printf("unhandled message: %v", msg) 184 184 return newUnknownCommandError(msg.Command) 185 185 } 186 if c.username != "" &&c.nick != "" {187 return c.register()188 } 189 return nil 190 } 191 192 func ( c *downstreamConn) register() error {193 u := c.srv.getUser(strings.TrimPrefix(c.username, "~"))186 if dc.username != "" && dc.nick != "" { 187 return dc.register() 188 } 189 return nil 190 } 191 192 func (dc *downstreamConn) register() error { 193 u := dc.srv.getUser(strings.TrimPrefix(dc.username, "~")) 194 194 if u == nil { 195 c.logger.Printf("failed authentication: unknown username %q",c.username)196 c.SendMessage(&irc.Message{197 Prefix: c.srv.prefix(),195 dc.logger.Printf("failed authentication: unknown username %q", dc.username) 196 dc.SendMessage(&irc.Message{ 197 Prefix: dc.srv.prefix(), 198 198 Command: irc.ERR_PASSWDMISMATCH, 199 199 Params: []string{"*", "Invalid username or password"}, … … 202 202 } 203 203 204 c.registered = true205 c.user = u204 dc.registered = true 205 dc.user = u 206 206 207 207 u.lock.Lock() 208 u.downstreamConns = append(u.downstreamConns, c)208 u.downstreamConns = append(u.downstreamConns, dc) 209 209 u.lock.Unlock() 210 210 211 c.SendMessage(&irc.Message{212 Prefix: c.srv.prefix(),211 dc.SendMessage(&irc.Message{ 212 Prefix: dc.srv.prefix(), 213 213 Command: irc.RPL_WELCOME, 214 Params: []string{ c.nick, "Welcome to jounce, " +c.nick},215 }) 216 c.SendMessage(&irc.Message{217 Prefix: c.srv.prefix(),214 Params: []string{dc.nick, "Welcome to jounce, " + dc.nick}, 215 }) 216 dc.SendMessage(&irc.Message{ 217 Prefix: dc.srv.prefix(), 218 218 Command: irc.RPL_YOURHOST, 219 Params: []string{ c.nick, "Your host is " +c.srv.Hostname},220 }) 221 c.SendMessage(&irc.Message{222 Prefix: c.srv.prefix(),219 Params: []string{dc.nick, "Your host is " + dc.srv.Hostname}, 220 }) 221 dc.SendMessage(&irc.Message{ 222 Prefix: dc.srv.prefix(), 223 223 Command: irc.RPL_CREATED, 224 Params: []string{ c.nick, "Who cares when the server was created?"},225 }) 226 c.SendMessage(&irc.Message{227 Prefix: c.srv.prefix(),224 Params: []string{dc.nick, "Who cares when the server was created?"}, 225 }) 226 dc.SendMessage(&irc.Message{ 227 Prefix: dc.srv.prefix(), 228 228 Command: irc.RPL_MYINFO, 229 Params: []string{ c.nick,c.srv.Hostname, "jounce", "aiwroO", "OovaimnqpsrtklbeI"},230 }) 231 c.SendMessage(&irc.Message{232 Prefix: c.srv.prefix(),229 Params: []string{dc.nick, dc.srv.Hostname, "jounce", "aiwroO", "OovaimnqpsrtklbeI"}, 230 }) 231 dc.SendMessage(&irc.Message{ 232 Prefix: dc.srv.prefix(), 233 233 Command: irc.ERR_NOMOTD, 234 Params: []string{ c.nick, "No MOTD"},234 Params: []string{dc.nick, "No MOTD"}, 235 235 }) 236 236 … … 239 239 for _, ch := range uc.channels { 240 240 if ch.complete { 241 forwardChannel( c, ch)241 forwardChannel(dc, ch) 242 242 } 243 243 } … … 251 251 break 252 252 } 253 c.SendMessage(msg)254 } 255 }) 256 257 return nil 258 } 259 260 func ( c *downstreamConn) handleMessageRegistered(msg *irc.Message) error {253 dc.SendMessage(msg) 254 } 255 }) 256 257 return nil 258 } 259 260 func (dc *downstreamConn) handleMessageRegistered(msg *irc.Message) error { 261 261 switch msg.Command { 262 262 case "USER": 263 263 return ircError{&irc.Message{ 264 264 Command: irc.ERR_ALREADYREGISTERED, 265 Params: []string{ c.nick, "You may not reregister"},265 Params: []string{dc.nick, "You may not reregister"}, 266 266 }} 267 267 case "NICK": 268 c.user.forEachUpstream(func(uc *upstreamConn) {268 dc.user.forEachUpstream(func(uc *upstreamConn) { 269 269 uc.messages <- msg 270 270 }) … … 275 275 } 276 276 277 if ch, _ := c.user.getChannel(name); ch != nil {277 if ch, _ := dc.user.getChannel(name); ch != nil { 278 278 break // already joined 279 279 } … … 290 290 } 291 291 292 ch, err := c.user.getChannel(name)292 ch, err := dc.user.getChannel(name) 293 293 if err != nil { 294 294 return err … … 309 309 310 310 if msg.Prefix.Name != name { 311 ch, err := c.user.getChannel(name)311 ch, err := dc.user.getChannel(name) 312 312 if err != nil { 313 313 return err … … 317 317 ch.conn.messages <- msg 318 318 } else { 319 c.SendMessage(&irc.Message{320 Prefix: c.srv.prefix(),319 dc.SendMessage(&irc.Message{ 320 Prefix: dc.srv.prefix(), 321 321 Command: irc.RPL_CHANNELMODEIS, 322 322 Params: []string{ch.Name, string(ch.modes)}, … … 324 324 } 325 325 } else { 326 if name != c.nick {326 if name != dc.nick { 327 327 return ircError{&irc.Message{ 328 328 Command: irc.ERR_USERSDONTMATCH, 329 Params: []string{ c.nick, "Cannot change mode for other users"},329 Params: []string{dc.nick, "Cannot change mode for other users"}, 330 330 }} 331 331 } 332 332 333 333 if modeStr != "" { 334 c.user.forEachUpstream(func(uc *upstreamConn) {334 dc.user.forEachUpstream(func(uc *upstreamConn) { 335 335 uc.messages <- msg 336 336 }) 337 337 } else { 338 c.SendMessage(&irc.Message{339 Prefix: c.srv.prefix(),338 dc.SendMessage(&irc.Message{ 339 Prefix: dc.srv.prefix(), 340 340 Command: irc.RPL_UMODEIS, 341 341 Params: []string{""}, // TODO … … 344 344 } 345 345 default: 346 c.logger.Printf("unhandled message: %v", msg)346 dc.logger.Printf("unhandled message: %v", msg) 347 347 return newUnknownCommandError(msg.Command) 348 348 } -
trunk/upstream.go
r54 r55 57 57 58 58 msgs := make(chan *irc.Message, 64) 59 conn:= &upstreamConn{59 uc := &upstreamConn{ 60 60 upstream: upstream, 61 61 logger: logger, … … 71 71 go func() { 72 72 for msg := range msgs { 73 if err := conn.irc.WriteMessage(msg); err != nil {74 conn.logger.Printf("failed to write message: %v", err)75 } 76 } 77 if err := conn.net.Close(); err != nil {78 conn.logger.Printf("failed to close connection: %v", err)73 if err := uc.irc.WriteMessage(msg); err != nil { 74 uc.logger.Printf("failed to write message: %v", err) 75 } 76 } 77 if err := uc.net.Close(); err != nil { 78 uc.logger.Printf("failed to close connection: %v", err) 79 79 } else { 80 conn.logger.Printf("connection closed")80 uc.logger.Printf("connection closed") 81 81 } 82 82 }() 83 83 84 return conn, nil85 } 86 87 func ( c *upstreamConn) Close() error {88 if c.closed {84 return uc, nil 85 } 86 87 func (uc *upstreamConn) Close() error { 88 if uc.closed { 89 89 return fmt.Errorf("upstream connection already closed") 90 90 } 91 close( c.messages)92 c.closed = true91 close(uc.messages) 92 uc.closed = true 93 93 return nil 94 94 } 95 95 96 func ( c *upstreamConn) getChannel(name string) (*upstreamChannel, error) {97 ch, ok := c.channels[name]96 func (uc *upstreamConn) getChannel(name string) (*upstreamChannel, error) { 97 ch, ok := uc.channels[name] 98 98 if !ok { 99 99 return nil, fmt.Errorf("unknown channel %q", name) … … 102 102 } 103 103 104 func ( c *upstreamConn) handleMessage(msg *irc.Message) error {104 func (uc *upstreamConn) handleMessage(msg *irc.Message) error { 105 105 switch msg.Command { 106 106 case "PING": 107 107 // TODO: handle params 108 c.messages <- &irc.Message{108 uc.messages <- &irc.Message{ 109 109 Command: "PONG", 110 Params: []string{ c.srv.Hostname},110 Params: []string{uc.srv.Hostname}, 111 111 } 112 112 return nil … … 118 118 119 119 if name == msg.Prefix.Name { // user mode change 120 if name != c.nick {120 if name != uc.nick { 121 121 return fmt.Errorf("received MODE message for unknow nick %q", name) 122 122 } 123 return c.modes.Apply(modeStr)123 return uc.modes.Apply(modeStr) 124 124 } else { // channel mode change 125 ch, err := c.getChannel(name)125 ch, err := uc.getChannel(name) 126 126 if err != nil { 127 127 return err … … 132 132 } 133 133 134 c.user.forEachDownstream(func(dc *downstreamConn) {134 uc.user.forEachDownstream(func(dc *downstreamConn) { 135 135 dc.SendMessage(msg) 136 136 }) 137 137 case "NOTICE": 138 c.logger.Print(msg)138 uc.logger.Print(msg) 139 139 case irc.RPL_WELCOME: 140 c.registered = true141 c.logger.Printf("connection registered")142 143 for _, ch := range c.upstream.Channels {144 c.messages <- &irc.Message{140 uc.registered = true 141 uc.logger.Printf("connection registered") 142 143 for _, ch := range uc.upstream.Channels { 144 uc.messages <- &irc.Message{ 145 145 Command: "JOIN", 146 146 Params: []string{ch}, … … 148 148 } 149 149 case irc.RPL_MYINFO: 150 if err := parseMessageParams(msg, nil, & c.serverName, nil, &c.availableUserModes, &c.availableChannelModes); err != nil {150 if err := parseMessageParams(msg, nil, &uc.serverName, nil, &uc.availableUserModes, &uc.availableChannelModes); err != nil { 151 151 return err 152 152 } 153 153 if len(msg.Params) > 5 { 154 c.channelModesWithParam = msg.Params[5]154 uc.channelModesWithParam = msg.Params[5] 155 155 } 156 156 case "NICK": … … 160 160 } 161 161 162 if msg.Prefix.Name == c.nick {163 c.logger.Printf("changed nick from %q to %q",c.nick, newNick)164 c.nick = newNick165 } 166 167 for _, ch := range c.channels {162 if msg.Prefix.Name == uc.nick { 163 uc.logger.Printf("changed nick from %q to %q", uc.nick, newNick) 164 uc.nick = newNick 165 } 166 167 for _, ch := range uc.channels { 168 168 if membership, ok := ch.Members[msg.Prefix.Name]; ok { 169 169 delete(ch.Members, msg.Prefix.Name) … … 172 172 } 173 173 174 c.user.forEachDownstream(func(dc *downstreamConn) {174 uc.user.forEachDownstream(func(dc *downstreamConn) { 175 175 dc.SendMessage(msg) 176 176 }) … … 182 182 183 183 for _, ch := range strings.Split(channels, ",") { 184 if msg.Prefix.Name == c.nick {185 c.logger.Printf("joined channel %q", ch)186 c.channels[ch] = &upstreamChannel{184 if msg.Prefix.Name == uc.nick { 185 uc.logger.Printf("joined channel %q", ch) 186 uc.channels[ch] = &upstreamChannel{ 187 187 Name: ch, 188 conn: c,188 conn: uc, 189 189 Members: make(map[string]membership), 190 190 } 191 191 } else { 192 ch, err := c.getChannel(ch)192 ch, err := uc.getChannel(ch) 193 193 if err != nil { 194 194 return err … … 198 198 } 199 199 200 c.user.forEachDownstream(func(dc *downstreamConn) {200 uc.user.forEachDownstream(func(dc *downstreamConn) { 201 201 dc.SendMessage(msg) 202 202 }) … … 208 208 209 209 for _, ch := range strings.Split(channels, ",") { 210 if msg.Prefix.Name == c.nick {211 c.logger.Printf("parted channel %q", ch)212 delete( c.channels, ch)210 if msg.Prefix.Name == uc.nick { 211 uc.logger.Printf("parted channel %q", ch) 212 delete(uc.channels, ch) 213 213 } else { 214 ch, err := c.getChannel(ch)214 ch, err := uc.getChannel(ch) 215 215 if err != nil { 216 216 return err … … 220 220 } 221 221 222 c.user.forEachDownstream(func(dc *downstreamConn) {222 uc.user.forEachDownstream(func(dc *downstreamConn) { 223 223 dc.SendMessage(msg) 224 224 }) … … 228 228 return err 229 229 } 230 ch, err := c.getChannel(name)230 ch, err := uc.getChannel(name) 231 231 if err != nil { 232 232 return err … … 242 242 return err 243 243 } 244 ch, err := c.getChannel(name)244 ch, err := uc.getChannel(name) 245 245 if err != nil { 246 246 return err … … 256 256 return err 257 257 } 258 ch, err := c.getChannel(name)258 ch, err := uc.getChannel(name) 259 259 if err != nil { 260 260 return err … … 271 271 return err 272 272 } 273 ch, err := c.getChannel(name)273 ch, err := uc.getChannel(name) 274 274 if err != nil { 275 275 return err … … 291 291 return err 292 292 } 293 ch, err := c.getChannel(name)293 ch, err := uc.getChannel(name) 294 294 if err != nil { 295 295 return err … … 301 301 ch.complete = true 302 302 303 c.user.forEachDownstream(func(dc *downstreamConn) {303 uc.user.forEachDownstream(func(dc *downstreamConn) { 304 304 forwardChannel(dc, ch) 305 305 }) 306 306 case "PRIVMSG": 307 c.ring.Produce(msg)308 c.user.forEachDownstream(func(dc *downstreamConn) {307 uc.ring.Produce(msg) 308 uc.user.forEachDownstream(func(dc *downstreamConn) { 309 309 dc.SendMessage(msg) 310 310 }) … … 320 320 // Ignore 321 321 default: 322 c.logger.Printf("unhandled upstream message: %v", msg)322 uc.logger.Printf("unhandled upstream message: %v", msg) 323 323 } 324 324 return nil 325 325 } 326 326 327 func ( c *upstreamConn) register() {328 c.nick =c.upstream.Nick329 c.messages <- &irc.Message{327 func (uc *upstreamConn) register() { 328 uc.nick = uc.upstream.Nick 329 uc.messages <- &irc.Message{ 330 330 Command: "NICK", 331 Params: []string{ c.upstream.Nick},332 } 333 c.messages <- &irc.Message{331 Params: []string{uc.upstream.Nick}, 332 } 333 uc.messages <- &irc.Message{ 334 334 Command: "USER", 335 Params: []string{ c.upstream.Username, "0", "*",c.upstream.Realname},336 } 337 } 338 339 func ( c *upstreamConn) readMessages() error {335 Params: []string{uc.upstream.Username, "0", "*", uc.upstream.Realname}, 336 } 337 } 338 339 func (uc *upstreamConn) readMessages() error { 340 340 for { 341 msg, err := c.irc.ReadMessage()341 msg, err := uc.irc.ReadMessage() 342 342 if err == io.EOF { 343 343 break … … 346 346 } 347 347 348 if err := c.handleMessage(msg); err != nil {349 c.logger.Printf("failed to handle message %q: %v", msg, err)348 if err := uc.handleMessage(msg); err != nil { 349 uc.logger.Printf("failed to handle message %q: %v", msg, err) 350 350 } 351 351 }
Note:
See TracChangeset
for help on using the changeset viewer.