Changeset 69 in code


Ignore:
Timestamp:
Feb 19, 2020, 5:25:19 PM (5 years ago)
Author:
contact
Message:

Add functions to translate between upstream and downstream names

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/bridge.go

    r54 r69  
    1010        }
    1111
     12        downstreamName := dc.marshalChannel(ch.conn, ch.Name)
     13
    1214        dc.SendMessage(&irc.Message{
    1315                Prefix:  dc.prefix(),
    1416                Command: "JOIN",
    15                 Params:  []string{ch.Name},
     17                Params:  []string{downstreamName},
    1618        })
    1719
     
    2022                        Prefix:  dc.srv.prefix(),
    2123                        Command: irc.RPL_TOPIC,
    22                         Params:  []string{dc.nick, ch.Name, ch.Topic},
     24                        Params:  []string{dc.nick, downstreamName, ch.Topic},
    2325                })
    2426        } else {
     
    2628                        Prefix:  dc.srv.prefix(),
    2729                        Command: irc.RPL_NOTOPIC,
    28                         Params:  []string{dc.nick, ch.Name, "No topic is set"},
     30                        Params:  []string{dc.nick, downstreamName, "No topic is set"},
    2931                })
    3032        }
     
    3436        // TODO: send multiple members in each message
    3537        for nick, membership := range ch.Members {
    36                 s := nick
     38                s := dc.marshalNick(ch.conn, nick)
    3739                if membership != 0 {
    38                         s = string(membership) + nick
     40                        s = string(membership) + s
    3941                }
    4042
     
    4244                        Prefix:  dc.srv.prefix(),
    4345                        Command: irc.RPL_NAMREPLY,
    44                         Params:  []string{dc.nick, string(ch.Status), ch.Name, s},
     46                        Params:  []string{dc.nick, string(ch.Status), downstreamName, s},
    4547                })
    4648        }
     
    4951                Prefix:  dc.srv.prefix(),
    5052                Command: irc.RPL_ENDOFNAMES,
    51                 Params:  []string{dc.nick, ch.Name, "End of /NAMES list"},
     53                Params:  []string{dc.nick, downstreamName, "End of /NAMES list"},
    5254        })
    5355}
  • trunk/downstream.go

    r68 r69  
    4040}
    4141
     42type consumption struct {
     43        consumer     *RingConsumer
     44        upstreamConn *upstreamConn
     45}
     46
    4247type downstreamConn struct {
    43         net       net.Conn
    44         irc       *irc.Conn
    45         srv       *Server
    46         logger    Logger
    47         messages  chan *irc.Message
    48         consumers chan *RingConsumer
    49         closed    chan struct{}
     48        net          net.Conn
     49        irc          *irc.Conn
     50        srv          *Server
     51        logger       Logger
     52        messages     chan *irc.Message
     53        consumptions chan consumption
     54        closed       chan struct{}
    5055
    5156        registered bool
     
    5863func newDownstreamConn(srv *Server, netConn net.Conn) *downstreamConn {
    5964        dc := &downstreamConn{
    60                 net:       netConn,
    61                 irc:       irc.NewConn(netConn),
    62                 srv:       srv,
    63                 logger:    &prefixLogger{srv.Logger, fmt.Sprintf("downstream %q: ", netConn.RemoteAddr())},
    64                 messages:  make(chan *irc.Message, 64),
    65                 consumers: make(chan *RingConsumer),
    66                 closed:    make(chan struct{}),
     65                net:          netConn,
     66                irc:          irc.NewConn(netConn),
     67                srv:          srv,
     68                logger:       &prefixLogger{srv.Logger, fmt.Sprintf("downstream %q: ", netConn.RemoteAddr())},
     69                messages:     make(chan *irc.Message, 64),
     70                consumptions: make(chan consumption),
     71                closed:       make(chan struct{}),
    6772        }
    6873
     
    8792                // TODO: fill the host?
    8893        }
     94}
     95
     96func (dc *downstreamConn) marshalChannel(uc *upstreamConn, name string) string {
     97        return name
     98}
     99
     100func (dc *downstreamConn) unmarshalChannel(name string) (*upstreamConn, string, error) {
     101        // TODO: extract network name from channel name
     102        ch, err := dc.user.getChannel(name)
     103        if err != nil {
     104                return nil, "", err
     105        }
     106        return ch.conn, ch.Name, nil
     107}
     108
     109func (dc *downstreamConn) marshalNick(uc *upstreamConn, nick string) string {
     110        if nick == uc.nick {
     111                return dc.nick
     112        }
     113        return nick
     114}
     115
     116func (dc *downstreamConn) marshalUserPrefix(uc *upstreamConn, prefix *irc.Prefix) *irc.Prefix {
     117        if prefix.Name == uc.nick {
     118                return dc.prefix()
     119        }
     120        return prefix
    89121}
    90122
     
    139171                        }
    140172                        err = dc.irc.WriteMessage(msg)
    141                 case consumer := <-dc.consumers:
     173                case consumption := <-dc.consumptions:
     174                        consumer, uc := consumption.consumer, consumption.upstreamConn
    142175                        for {
    143176                                msg := consumer.Peek()
    144177                                if msg == nil {
    145178                                        break
     179                                }
     180                                msg = msg.Copy()
     181                                switch msg.Command {
     182                                case "PRIVMSG":
     183                                        // TODO: detect whether it's a user or a channel
     184                                        msg.Params[0] = dc.marshalChannel(uc, msg.Params[0])
     185                                default:
     186                                        panic("expected to consume a PRIVMSG message")
    146187                                }
    147188                                if dc.srv.Debug {
     
    304345                                select {
    305346                                case <-ch:
    306                                         dc.consumers <- consumer
     347                                        dc.consumptions <- consumption{consumer, uc}
    307348                                case <-dc.closed:
    308349                                        closed = true
     
    339380                        uc.SendMessage(msg)
    340381                })
    341         case "JOIN":
     382        case "JOIN", "PART":
    342383                var name string
    343384                if err := parseMessageParams(msg, &name); err != nil {
     
    345386                }
    346387
    347                 if ch, _ := dc.user.getChannel(name); ch != nil {
    348                         break // already joined
    349                 }
    350 
    351                 // TODO: extract network name from channel name
    352                 return ircError{&irc.Message{
    353                         Command: irc.ERR_NOSUCHCHANNEL,
    354                         Params:  []string{name, "Channel name ambiguous"},
    355                 }}
    356         case "PART":
    357                 var name string
    358                 if err := parseMessageParams(msg, &name); err != nil {
    359                         return err
    360                 }
    361 
    362                 ch, err := dc.user.getChannel(name)
     388                uc, upstreamName, err := dc.unmarshalChannel(name)
    363389                if err != nil {
    364                         return err
    365                 }
    366 
    367                 ch.conn.SendMessage(msg)
    368                 // TODO: remove channel from upstream config
     390                        return ircError{&irc.Message{
     391                                Command: irc.ERR_NOSUCHCHANNEL,
     392                                Params:  []string{name, err.Error()},
     393                        }}
     394                }
     395
     396                uc.SendMessage(&irc.Message{
     397                        Command: msg.Command,
     398                        Params:  []string{upstreamName},
     399                })
     400                // TODO: add/remove channel from upstream config
    369401        case "MODE":
     402                if msg.Prefix == nil {
     403                        return fmt.Errorf("missing prefix")
     404                }
     405
    370406                var name string
    371407                if err := parseMessageParams(msg, &name); err != nil {
     
    379415
    380416                if msg.Prefix.Name != name {
    381                         ch, err := dc.user.getChannel(name)
     417                        uc, upstreamName, err := dc.unmarshalChannel(name)
    382418                        if err != nil {
    383419                                return err
     
    385421
    386422                        if modeStr != "" {
    387                                 ch.conn.SendMessage(msg)
     423                                uc.SendMessage(&irc.Message{
     424                                        Prefix:  uc.prefix(),
     425                                        Command: "MODE",
     426                                        Params:  []string{upstreamName, modeStr},
     427                                })
    388428                        } else {
     429                                ch, ok := uc.channels[upstreamName]
     430                                if !ok {
     431                                        return ircError{&irc.Message{
     432                                                Command: irc.ERR_NOSUCHCHANNEL,
     433                                                Params:  []string{name, "No such channel"},
     434                                        }}
     435                                }
     436
    389437                                dc.SendMessage(&irc.Message{
    390438                                        Prefix:  dc.srv.prefix(),
    391439                                        Command: irc.RPL_CHANNELMODEIS,
    392                                         Params:  []string{ch.Name, string(ch.modes)},
     440                                        Params:  []string{name, string(ch.modes)},
    393441                                })
    394442                        }
     
    403451                        if modeStr != "" {
    404452                                dc.user.forEachUpstream(func(uc *upstreamConn) {
    405                                         uc.SendMessage(msg)
     453                                        uc.SendMessage(&irc.Message{
     454                                                Prefix:  uc.prefix(),
     455                                                Command: "MODE",
     456                                                Params:  []string{uc.nick, modeStr},
     457                                        })
    406458                                })
    407459                        } else {
     
    420472
    421473                for _, name := range strings.Split(targetsStr, ",") {
    422                         ch, err := dc.user.getChannel(name)
     474                        uc, upstreamName, err := dc.unmarshalChannel(name)
    423475                        if err != nil {
    424476                                return err
    425477                        }
    426478
    427                         ch.conn.SendMessage(&irc.Message{
    428                                 Prefix:  msg.Prefix,
     479                        uc.SendMessage(&irc.Message{
     480                                Prefix:  uc.prefix(),
    429481                                Command: "PRIVMSG",
    430                                 Params:  []string{name, text},
     482                                Params:  []string{upstreamName, text},
    431483                        })
    432484                }
  • trunk/upstream.go

    r68 r69  
    9292}
    9393
     94func (uc *upstreamConn) prefix() *irc.Prefix {
     95        return &irc.Prefix{
     96                Name: uc.nick,
     97                User: uc.upstream.Username,
     98                // TODO: fill the host?
     99        }
     100}
     101
    94102func (uc *upstreamConn) Close() error {
    95103        if uc.closed {
     
    118126                return nil
    119127        case "MODE":
     128                if msg.Prefix == nil {
     129                        return fmt.Errorf("missing prefix")
     130                }
     131
    120132                var name, modeStr string
    121133                if err := parseMessageParams(msg, &name, &modeStr); err != nil {
     
    136148                                return err
    137149                        }
    138                 }
    139 
    140                 uc.user.forEachDownstream(func(dc *downstreamConn) {
    141                         dc.SendMessage(msg)
    142                 })
     150
     151                        uc.user.forEachDownstream(func(dc *downstreamConn) {
     152                                dc.SendMessage(&irc.Message{
     153                                        Prefix:  dc.marshalUserPrefix(uc, msg.Prefix),
     154                                        Command: "MODE",
     155                                        Params:  []string{dc.marshalChannel(uc, name), modeStr},
     156                                })
     157                        })
     158                }
    143159        case "NOTICE":
    144160                uc.logger.Print(msg)
     
    177193                        }
    178194                }
    179 
    180                 uc.user.forEachDownstream(func(dc *downstreamConn) {
    181                         dc.SendMessage(msg)
    182                 })
    183195        case "JOIN":
     196                if msg.Prefix == nil {
     197                        return fmt.Errorf("expected a prefix")
     198                }
     199
    184200                var channels string
    185201                if err := parseMessageParams(msg, &channels); err != nil {
     
    202218                                ch.Members[msg.Prefix.Name] = 0
    203219                        }
    204                 }
    205 
    206                 uc.user.forEachDownstream(func(dc *downstreamConn) {
    207                         dc.SendMessage(msg)
    208                 })
     220
     221                        uc.user.forEachDownstream(func(dc *downstreamConn) {
     222                                dc.SendMessage(&irc.Message{
     223                                        Prefix:  dc.marshalUserPrefix(uc, msg.Prefix),
     224                                        Command: "JOIN",
     225                                        Params:  []string{dc.marshalChannel(uc, ch)},
     226                                })
     227                        })
     228                }
    209229        case "PART":
     230                if msg.Prefix == nil {
     231                        return fmt.Errorf("expected a prefix")
     232                }
     233
    210234                var channels string
    211235                if err := parseMessageParams(msg, &channels); err != nil {
     
    224248                                delete(ch.Members, msg.Prefix.Name)
    225249                        }
    226                 }
    227 
    228                 uc.user.forEachDownstream(func(dc *downstreamConn) {
    229                         dc.SendMessage(msg)
    230                 })
     250
     251                        uc.user.forEachDownstream(func(dc *downstreamConn) {
     252                                dc.SendMessage(&irc.Message{
     253                                        Prefix:  dc.marshalUserPrefix(uc, msg.Prefix),
     254                                        Command: "PART",
     255                                        Params:  []string{dc.marshalChannel(uc, ch)},
     256                                })
     257                        })
     258                }
    231259        case irc.RPL_TOPIC, irc.RPL_NOTOPIC:
    232260                var name, topic string
     
    311339                })
    312340        case "PRIVMSG":
     341                if err := parseMessageParams(msg, nil, nil); err != nil {
     342                        return err
     343                }
    313344                uc.ring.Produce(msg)
    314345        case irc.RPL_YOURHOST, irc.RPL_CREATED:
     
    332363        uc.SendMessage(&irc.Message{
    333364                Command: "NICK",
    334                 Params:  []string{uc.upstream.Nick},
     365                Params:  []string{uc.nick},
    335366        })
    336367        uc.SendMessage(&irc.Message{
Note: See TracChangeset for help on using the changeset viewer.