Exemple #1
0
// Connect attempts to connect to the given IRC server
func (b *Bot) Connect() error {
	var conn net.Conn
	var err error
	if b.tlsConfig == nil {
		conn, err = net.Dial("tcp", b.Server)
	} else {
		conn, err = tls.Dial("tcp", b.Server, b.tlsConfig)
	}
	if err != nil {
		return err
	}
	b.conn = conn
	b.reader = irc.NewDecoder(conn)
	b.writer = irc.NewEncoder(conn)
	b.sender = ServerSender{writer: &b.writer}
	for _, msg := range b.connectMessages() {
		err := b.writer.Encode(msg)
		if err != nil {
			return err
		}
	}
	log.Println("Connected to", b.Server)
	b.tries = 0
	go b.ReadLoop()
	return nil
}
Exemple #2
0
// NewUserNet creates a *User from a net.Conn connection.
func NewUserNet(c net.Conn) *User {
	return NewUser(&conn{
		Conn:    c,
		Encoder: irc.NewEncoder(c),
		Decoder: irc.NewDecoder(c),
	})
}
Exemple #3
0
// connect attempts to connect to the given IRC server.
func (bot *Bot) connect() error {
	var conn net.Conn
	var err error
	// Establish the connection.
	if bot.Config.TLSConfig == nil {
		bot.Log.Infof("Connecting to %s...", bot.Config.Server)
		conn, err = net.Dial("tcp", bot.Config.Server)
	} else {
		bot.Log.Infof("Connecting to %s using TLS...", bot.Config.Server)
		conn, err = tls.Dial("tcp", bot.Config.Server, bot.Config.TLSConfig)
	}
	if err != nil {
		return err
	}

	// Store connection.
	bot.irc.connection = conn
	bot.irc.decoder = irc.NewDecoder(conn)
	bot.irc.encoder = irc.NewEncoder(conn)

	// Send initial messages.
	if bot.Config.Password != "" {
		bot.SendRawMessage(irc.PASS, []string{bot.Config.Password}, "")
	}
	bot.SendRawMessage(irc.NICK, []string{bot.Config.Name}, "")
	bot.SendRawMessage(irc.USER, []string{bot.Config.User, "0", "*"}, bot.Config.User)

	// Run the message receiver loop.
	go bot.receiverLoop()

	bot.Log.Debugf("Succesfully connected.")
	return nil
}
Exemple #4
0
func NewUserMM(c net.Conn, srv Server, cfg *MmCfg) *User {
	u := NewUser(&conn{
		Conn:    c,
		Encoder: irc.NewEncoder(c),
		Decoder: irc.NewDecoder(c),
	})
	u.Srv = srv
	u.MmInfo.Cfg = cfg
	// used for login
	u.createService("mattermost", "loginservice")
	return u
}
Exemple #5
0
func NewUserMM(c net.Conn, srv Server, cfg *MmCfg) *User {
	u := NewUser(&conn{
		Conn:    c,
		Encoder: irc.NewEncoder(c),
		Decoder: irc.NewDecoder(c),
	})
	u.Srv = srv
	u.MmInfo.Cfg = cfg

	// used for login
	mattermostService := &User{Nick: "mattermost", User: "******", Real: "loginservice", Host: "service", channels: map[Channel]struct{}{}}
	mattermostService.MmGhostUser = true
	srv.Add(mattermostService)
	if _, ok := srv.HasUser("mattermost"); !ok {
		go srv.Handle(mattermostService)
	}

	return u
}
Exemple #6
0
func (self *IrcBot) Connect() error {
	var conn net.Conn
	var err error
	if self.Config.TlsConfig == nil {
		conn, err = net.Dial("tcp", self.Config.Server)
	} else {
		conn, err = tls.Dial("tcp", self.Config.Server, self.Config.TlsConfig)
	}
	if err != nil {
		return err
	}
	self.connection = conn
	self.reader = irc.NewDecoder(conn)
	self.writer = irc.NewEncoder(conn)

	go self.readLoop()

	return nil
}
Exemple #7
0
func (server *Server) Connect() error {
	connection, err := net.Dial("tcp", server.Config.Irc.Server)

	if err != nil {
		return err
	}

	server.connection = connection
	server.Reader = irc.NewDecoder(connection)
	server.Writer = irc.NewEncoder(connection)
	server.Sender = ServerSender{writer: server.Writer}

	err = server.onConnect()
	if err != nil {
		return err
	}

	go server.ReadLoop()

	return nil
}
Exemple #8
0
func CreateIrcChannel(name string, cfg *IrcConfig) (*IrcChannel, error) {
	channel := new(IrcChannel)
	channel.Name = name
	channel.RawIrcMessages = make(chan *irc.Message, 128)
	channel.PostToChannel = make(chan []byte, 128)
	channel.ReadFromChannel = make(chan []byte, 128)
	channel.Config = cfg

	err := channel.Connect()
	if err != nil {
		return nil, err
	}

	channel.Reader = irc.NewDecoder(channel.Conn)
	channel.Writer = irc.NewEncoder(channel.Conn)
	err = channel.Login(cfg)
	go channel.RecvLoop()
	go channel.Sort()
	go channel.SendLoop()
	return channel, err
}
Exemple #9
0
func (b *IrcBot) connect() error {
	log.Print("connecting to IRC")
	b.data = make(chan *irc.Message)
	var err error
	b.conn, err = net.Dial("tcp", b.server)
	if err != nil {
		log.Print("Error connecting", err)
		return err
	}

	b.writer = irc.NewEncoder(b.conn)
	b.reader = irc.NewDecoder(b.conn)

	loginMessages := []irc.Message{
		irc.Message{
			Command: irc.PASS,
			Params:  []string{b.pass},
		},
		irc.Message{
			Command: irc.NICK,
			Params:  []string{b.login},
		},
		irc.Message{
			Command:  irc.USER,
			Params:   []string{b.login, "0", "*"},
			Trailing: b.login,
		},
	}

	for _, v := range loginMessages {
		err := b.writer.Encode(&v)
		if err != nil {
			return err
		}
	}

	go b.loop()

	return nil
}
/**
 * Performs the healthcheck and returns a boolean reporting if all is well.
 * @return boolean
 */
func runHealthcheck(conn net.Conn, err error) bool {
	if err != nil {
		log.Fatalln(err)
	} else {
		conn.SetDeadline(time.Now().Add(30 * time.Second))
		log.Println("Connected to server.")

		// Establish a reader, and a writer.
		writer := irc.NewEncoder(conn)
		reader := irc.NewDecoder(conn)

		// Seed the PRNG source, and use it to generate a random nickname.
		rand.Seed(time.Now().UnixNano())
		nick := healthcheckNameGenerator()

		// Set up a read channel, and look for an 001 RPL as defined by RFC2812.
		authChannel := make(chan error)
		go func() {
			var err error
			for {
				msg, _ := reader.Decode()
				log.Println(msg.String())
				switch msg.Command {

				// Notice is probably an AUTH notice.
				case "NOTICE":
					break

				// Yay, we authenticated successfully!
				case irc.RPL_WELCOME:
					authChannel <- err
					return

				// Oh no, we didn't get an 001. :(
				default:
					authChannel <- errors.New("Received unexpected status")
					return
				}
			}
		}()

		// Send messages to AUTH healthcheck agent with server.
		messages := []*irc.Message{}
		messages = append(messages, &irc.Message{
			Command: irc.NICK,
			Params:  []string{nick},
		})
		messages = append(messages, &irc.Message{
			Command:  irc.USER,
			Params:   []string{nick, "0", "*"},
			Trailing: "https://github.com/StormBit/ircd-healthcheck",
		})
		for _, msg := range messages {
			log.Println(msg)
			if err := writer.Encode(msg); err != nil {
				break
			}
		}

		// Wait for a result from authchannel
		err = <-authChannel
		conn.Close()
	}
	return isError(err)
}
Exemple #11
0
// Reconnect does exactly that and takes a message to be printed as arguments
// can be called concurrently
func (c *IConn) Reconnect(format string, v ...interface{}) {
	c.mu.Lock()

	close(c.quit)
	if c.conn != nil {
		_ = c.conn.Close()
	}
	c.wg.Wait()
	if c.tries > 0 {
		d := time.Duration(math.Pow(2.0, c.tries)*300) * time.Millisecond
		newargs := make([]interface{}, 0, len(v)+1)
		newargs = append(newargs, v...)
		newargs = append(newargs, d)
		debug(format+", reconnecting in %s", v...)
		time.Sleep(d)
	}

	c.quit = make(chan struct{})
	conn, err := net.DialTimeout("tcp", c.cfg.Addr, 5*time.Second)
	if err != nil {
		c.mu.Unlock()
		c.addDelay()
		c.Reconnect("conn error: %+v", err)
		return
	}
	defer c.mu.Unlock()

	c.Loggedin = false
	c.pendingPings = 0
	c.badness = 0
	c.conn = conn
	c.Decoder = irc.NewDecoder(conn)
	c.Encoder = irc.NewEncoder(conn)

	c.wg.Add(2)
	go c.write()
	go c.read()

	if c.Callback != nil {
		ret := c.Callback(c, &irc.Message{
			Command: "CONNECT",
		})
		if ret {
			return
		}
	}

	c.w <- &irc.Message{
		Command: irc.USER,
		Params: []string{
			c.cfg.Nick,
			"0",
			"*",
		},
		Trailing: c.cfg.RealName,
	}
	c.w <- &irc.Message{Command: irc.NICK, Params: []string{c.cfg.Nick}}
	if len(c.cfg.Password) > 0 {
		c.w <- &irc.Message{Command: irc.PASS, Params: []string{c.cfg.Password}}
	}

}