hid: bringup of what we have this far
This commit is contained in:
		
							
								
								
									
										60
									
								
								hid/main.go
									
									
									
									
									
								
							
							
						
						
									
										60
									
								
								hid/main.go
									
									
									
									
									
								
							@@ -421,7 +421,7 @@ func ircFnmatch(pattern string, s string) bool {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var reMsg = regexp.MustCompile(
 | 
			
		||||
	`^(?:@[^ ]* +)(?::([^! ]*)(?:!([^@]*)@([^ ]*))? +)?([^ ]+)(.*)?$`)
 | 
			
		||||
	`^(@[^ ]* +)?(?::([^! ]*)(?:!([^@]*)@([^ ]*))? +)?([^ ]+)(.*)?$`)
 | 
			
		||||
var reArgs = regexp.MustCompile(`:.*| [^: ][^ ]*`)
 | 
			
		||||
 | 
			
		||||
type message struct {
 | 
			
		||||
@@ -514,7 +514,7 @@ var (
 | 
			
		||||
	// behaviour seems to be unstated in the documentation.
 | 
			
		||||
	reUsername = regexp.MustCompile(`^[^\0\r\n @]+$`)
 | 
			
		||||
 | 
			
		||||
	reChannelName = regexp.MustCompile(`^[^\0\7\r\n ,:]+$`)
 | 
			
		||||
	reChannelName = regexp.MustCompile(`^[^\0\007\r\n ,:]+$`)
 | 
			
		||||
	reKey         = regexp.MustCompile(`^[^\r\n\f\t\v ]{1,23}$`)
 | 
			
		||||
	reUserMask    = regexp.MustCompile(`^[^!@]+![^!@]+@[^@!]+$`)
 | 
			
		||||
	reFingerprint = regexp.MustCompile(`^[a-fA-F0-9]{64}$`)
 | 
			
		||||
@@ -754,17 +754,16 @@ type writeEvent struct {
 | 
			
		||||
var (
 | 
			
		||||
	started time.Time // when has the server been started
 | 
			
		||||
 | 
			
		||||
	users    map[string]*client  // maps nicknames to clients
 | 
			
		||||
	channels map[string]*channel // maps channel names to data
 | 
			
		||||
	users    = make(map[string]*client)     // maps nicknames to clients
 | 
			
		||||
	channels = make(map[string]*channel)    // maps channel names to data
 | 
			
		||||
	whowas   = make(map[string]*whowasInfo) // WHOWAS registry
 | 
			
		||||
 | 
			
		||||
	whowas map[string]*whowasInfo // WHOWAS registry
 | 
			
		||||
 | 
			
		||||
	config         simpleConfig    // server configuration
 | 
			
		||||
	serverName     string          // our server name
 | 
			
		||||
	pingInterval   uint            // ping interval in seconds
 | 
			
		||||
	maxConnections int             // max connections allowed or 0
 | 
			
		||||
	motd           []string        // MOTD (none if empty)
 | 
			
		||||
	operators      map[string]bool // TLS certificate fingerprints for IRCops
 | 
			
		||||
	config         simpleConfig            // server configuration
 | 
			
		||||
	serverName     string                  // our server name
 | 
			
		||||
	pingInterval   uint                    // ping interval in seconds
 | 
			
		||||
	maxConnections int                     // max connections allowed or 0
 | 
			
		||||
	motd           []string                // MOTD (none if empty)
 | 
			
		||||
	operators      = make(map[string]bool) // TLS cert. fingerprints for IRCops
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
@@ -814,8 +813,9 @@ func initiateQuit() {
 | 
			
		||||
func ircChannelCreate(name string) *channel {
 | 
			
		||||
	ch := &channel{
 | 
			
		||||
		name:      name,
 | 
			
		||||
		created:   time.Now(),
 | 
			
		||||
		userLimit: -1,
 | 
			
		||||
		created:   time.Now(),
 | 
			
		||||
		userModes: make(map[*client]uint),
 | 
			
		||||
	}
 | 
			
		||||
	channels[ircToCanon(name)] = ch
 | 
			
		||||
	return ch
 | 
			
		||||
@@ -1046,10 +1046,15 @@ func (c *client) sendReplyVector(id int, items []string, args ...interface{}) {
 | 
			
		||||
 | 
			
		||||
	// We always send at least one message (there might be a client that
 | 
			
		||||
	// expects us to send this message at least once).
 | 
			
		||||
	if len(items) == 0 {
 | 
			
		||||
		items = append(items, "")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for len(items) > 0 {
 | 
			
		||||
		// If not even a single item fits in the limit (which may happen,
 | 
			
		||||
		// in theory) it just gets cropped. We could also skip it.
 | 
			
		||||
		reply := append([]byte(common), items[0]...)
 | 
			
		||||
		items = items[1:]
 | 
			
		||||
 | 
			
		||||
		// Append as many items as fits in a single message.
 | 
			
		||||
		for len(items) > 0 &&
 | 
			
		||||
@@ -1120,10 +1125,10 @@ func isThisMe(target string) bool {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *client) sendISUPPORT() {
 | 
			
		||||
	// Only # channels, +e supported, +I supported, unlimited arguments to MODE
 | 
			
		||||
	c.sendReply(RPL_ISUPPORT, "CHANTYPES=# EXCEPTS INVEX MODES"+
 | 
			
		||||
	// Only # channels, +e supported, +I supported, unlimited arguments to MODE.
 | 
			
		||||
	c.sendReply(RPL_ISUPPORT, fmt.Sprintf("CHANTYPES=# EXCEPTS INVEX MODES"+
 | 
			
		||||
		" TARGMAX=WHOIS:,LIST:,NAMES:,PRIVMSG:1,NOTICE:1,KICK:"+
 | 
			
		||||
		" NICKLEN=%d CHANNELLEN=%d", ircMaxNickname, ircMaxChannelName)
 | 
			
		||||
		" NICKLEN=%d CHANNELLEN=%d", ircMaxNickname, ircMaxChannelName))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *client) tryFinishRegistration() {
 | 
			
		||||
@@ -2170,8 +2175,7 @@ func ircSendWHOISReply(c, target *client) {
 | 
			
		||||
	nick := target.nickname
 | 
			
		||||
	c.sendReply(RPL_WHOISUSER, nick,
 | 
			
		||||
		target.username, target.hostname, target.realname)
 | 
			
		||||
	c.sendReply(RPL_WHOISSERVER, nick,
 | 
			
		||||
		serverName, "TODO server_info from configuration")
 | 
			
		||||
	c.sendReply(RPL_WHOISSERVER, nick, serverName, config["server_info"])
 | 
			
		||||
	if 0 != target.mode&ircUserModeOperator {
 | 
			
		||||
		c.sendReply(RPL_WHOISOPERATOR, nick)
 | 
			
		||||
	}
 | 
			
		||||
@@ -2257,7 +2261,7 @@ func ircHandleWHOWAS(msg *message, c *client) {
 | 
			
		||||
			c.sendReply(RPL_WHOWASUSER, nick,
 | 
			
		||||
				info.username, info.hostname, info.realname)
 | 
			
		||||
			c.sendReply(RPL_WHOISSERVER, nick,
 | 
			
		||||
				serverName, "TODO server_info from configuration")
 | 
			
		||||
				serverName, config["server_info"])
 | 
			
		||||
		}
 | 
			
		||||
		c.sendReply(RPL_ENDOFWHOWAS, nick)
 | 
			
		||||
	}
 | 
			
		||||
@@ -2689,7 +2693,7 @@ func ircHandleLINKS(msg *message, c *client) {
 | 
			
		||||
 | 
			
		||||
	if ircFnmatch(mask, serverName) {
 | 
			
		||||
		c.sendReply(RPL_LINKS, mask, serverName,
 | 
			
		||||
			0 /* hop count */, "TODO server_info from configuration")
 | 
			
		||||
			0 /* hop count */, config["server_info"])
 | 
			
		||||
	}
 | 
			
		||||
	c.sendReply(RPL_ENDOFLINKS, mask)
 | 
			
		||||
}
 | 
			
		||||
@@ -2799,11 +2803,16 @@ func ircProcessMessage(c *client, msg *message, raw string) {
 | 
			
		||||
 | 
			
		||||
// Handle the results from initializing the client's connection.
 | 
			
		||||
func (c *client) onPrepared(host string, isTLS bool) {
 | 
			
		||||
	if isTLS {
 | 
			
		||||
	if !isTLS {
 | 
			
		||||
		c.conn = c.transport.(connCloseWrite)
 | 
			
		||||
	} else if tlsConf != nil {
 | 
			
		||||
		c.tls = tls.Server(c.transport, tlsConf)
 | 
			
		||||
		c.conn = c.tls
 | 
			
		||||
	} else {
 | 
			
		||||
		c.conn = c.transport.(connCloseWrite)
 | 
			
		||||
		log.Printf("could not initialize TLS for %s: TLS support disabled\n",
 | 
			
		||||
			c.address)
 | 
			
		||||
		c.kill("TLS support disabled")
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	c.hostname = host
 | 
			
		||||
@@ -2949,7 +2958,7 @@ func prepare(client *client) {
 | 
			
		||||
		// This is just for the TLS detection and doesn't need to be fatal.
 | 
			
		||||
		log.Println(err)
 | 
			
		||||
	} else {
 | 
			
		||||
		isTLS = tlsConf != nil && detectTLS(sysconn)
 | 
			
		||||
		isTLS = detectTLS(sysconn)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// FIXME: When the client sends no data, we still initialize its conn.
 | 
			
		||||
@@ -2993,7 +3002,7 @@ func processOneEvent() {
 | 
			
		||||
		forceQuit("timeout")
 | 
			
		||||
 | 
			
		||||
	case conn := <-conns:
 | 
			
		||||
		if len(clients) >= maxConnections {
 | 
			
		||||
		if maxConnections > 0 && len(clients) >= maxConnections {
 | 
			
		||||
			log.Println("connection limit reached, refusing connection")
 | 
			
		||||
			conn.Close()
 | 
			
		||||
			break
 | 
			
		||||
@@ -3014,6 +3023,8 @@ func processOneEvent() {
 | 
			
		||||
			hostname:   host,
 | 
			
		||||
			port:       port,
 | 
			
		||||
			capVersion: 301,
 | 
			
		||||
			opened:     time.Now(),
 | 
			
		||||
			lastActive: time.Now(),
 | 
			
		||||
			// TODO: Make this configurable and more fine-grained.
 | 
			
		||||
			antiflood: newFloodDetector(10*time.Second, 20),
 | 
			
		||||
		}
 | 
			
		||||
@@ -3223,6 +3234,7 @@ func main() {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	config = make(simpleConfig)
 | 
			
		||||
	config.loadDefaults(configTable)
 | 
			
		||||
	if err := config.updateFromFile(); err != nil && !os.IsNotExist(err) {
 | 
			
		||||
		log.Println("error loading configuration", err)
 | 
			
		||||
		os.Exit(1)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user