...
This commit is contained in:
parent
d21b5cccfe
commit
4dff342b70
46
client.go
46
client.go
|
@ -3,7 +3,7 @@
|
|||
package ircd
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
|
@ -119,7 +119,7 @@ func (cl *RemoteClient) Destroy() {
|
|||
|
||||
func (cl *RemoteClient) dispatcher() {
|
||||
for {
|
||||
time.Sleep(1 * time.Millisecond)
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
if cl.isClosed {
|
||||
return
|
||||
}
|
||||
|
@ -140,34 +140,56 @@ func (cl *RemoteClient) dispatcher() {
|
|||
}
|
||||
}
|
||||
|
||||
func (cl *RemoteClient) connReader() {
|
||||
input := bufio.NewReader(cl.conn)
|
||||
/*func (cl *RemoteClient) pinger() {
|
||||
for {
|
||||
time.Sleep(30 * time.Second)
|
||||
if cl.isClosed {
|
||||
return
|
||||
}
|
||||
cl.writeLine("PING %s", cl.server.host)
|
||||
}
|
||||
}*/
|
||||
|
||||
func (cl *RemoteClient) connReader() {
|
||||
for {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
buf := make([]byte, 4096)
|
||||
if cl.isClosed {
|
||||
xlog.Debug("connReader: exiting")
|
||||
return
|
||||
}
|
||||
s, err := input.ReadString('\n')
|
||||
cl.conn.SetReadDeadline(time.Now().Add(time.Second * 5))
|
||||
n, err := cl.conn.Read(buf)
|
||||
if err == io.EOF {
|
||||
xlog.Info("connReader: Connection closed by peer")
|
||||
cl.server.DelClient(cl)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
xlog.Error("connReader: %s", err.Error())
|
||||
cl.server.DelClient(cl)
|
||||
return
|
||||
continue
|
||||
}
|
||||
raw := buf[:n]
|
||||
raw = bytes.Replace(raw, []byte("\r\n"), []byte("\n"), -1)
|
||||
raw = bytes.Replace(raw, []byte("\r"), []byte("\n"), -1)
|
||||
lines := bytes.Split(raw, []byte("\n"))
|
||||
for _, line := range lines {
|
||||
if len(line) > 0 {
|
||||
cl.handleCmd(string(line))
|
||||
}
|
||||
}
|
||||
s = strings.Trim(s, "\r\n")
|
||||
cl.handleCmd(s)
|
||||
}
|
||||
}
|
||||
|
||||
func (cl *RemoteClient) connWriter() {
|
||||
for line := range cl.writeq {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
if cl.isClosed {
|
||||
return
|
||||
}
|
||||
written := 0
|
||||
bytes := []byte(line + "\r\n")
|
||||
for written < len(line) {
|
||||
cl.conn.SetWriteDeadline(time.Now().Add(time.Second * 5))
|
||||
n, err := cl.conn.Write(bytes[written:])
|
||||
if err == io.EOF {
|
||||
xlog.Info("connWriter: Connection closed by peer")
|
||||
|
@ -185,6 +207,10 @@ func (cl *RemoteClient) connWriter() {
|
|||
}
|
||||
|
||||
func (cl *RemoteClient) writeMsg(msg *irc.Message) {
|
||||
clid := strings.ToLower(msg.Pre)
|
||||
if _, exists := cl.server.clients[clid]; exists {
|
||||
msg.Pre = msg.Pre + "!" + msg.Pre + "@" + cl.server.clHosts[clid]
|
||||
}
|
||||
cl.writeLine(msg.String())
|
||||
}
|
||||
|
||||
|
|
34
handlers.go
34
handlers.go
|
@ -3,6 +3,7 @@
|
|||
package ircd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"code.dnix.de/an/irc"
|
||||
|
@ -25,8 +26,10 @@ var svCommandHooks = map[string]commandHook{
|
|||
"TOPIC": {handleCmdTopic, 1, false, ""},
|
||||
"KICK": {handleCmdKick, 2, false, ""},
|
||||
"NAMES": {handleCmdNames, 1, false, ""},
|
||||
"WHO": {handleCmdWho, 1, false, ""},
|
||||
"WHOIS": {handleCmdWhois, 0, false, ""},
|
||||
"PING": {handleCmdPing, 1, false, ""},
|
||||
"PONG": {handleCmdPong, 0, false, ""},
|
||||
"REHASH": {handleCmdRehash, 0, false, "ao"},
|
||||
"KILL": {handleCmdKill, 0, false, "ao"},
|
||||
/*
|
||||
|
@ -235,14 +238,43 @@ func handleCmdNames(sv *Server, msg *irc.Message) {
|
|||
sv.channelNames(msg.Pre, chid)
|
||||
}
|
||||
|
||||
func handleCmdWho(sv *Server, msg *irc.Message) {
|
||||
clid := strings.ToLower(msg.Args[0])
|
||||
if _, exists := sv.clients[clid]; exists {
|
||||
// :irc.dnix.de 352 Anydin #northbrigade webuser369 -anon/guest irc.dnix.de webuser36968 H :0 webuser36968
|
||||
sv.sendReply(msg.Pre, RPL_WHOREPLY,
|
||||
fmt.Sprintf("* %s %s %s %s %s%s", clid, sv.clHosts[clid], sv.host, clid, "H", ""), "0 "+msg.Args[0])
|
||||
}
|
||||
sv.sendReply(msg.Pre, RPL_ENDOFWHO, clid, "End of /WHO list.")
|
||||
}
|
||||
|
||||
func handleCmdWhois(sv *Server, msg *irc.Message) {
|
||||
sv.sendReply(msg.Pre, RPL_WHOISUSER, "nick user host *", "real name")
|
||||
clid := strings.ToLower(msg.Args[0])
|
||||
if _, exists := sv.clients[clid]; !exists {
|
||||
sv.sendReply(msg.Pre, ERR_NOSUCHNICK, clid, "No such nick")
|
||||
return
|
||||
}
|
||||
sv.sendReply(msg.Pre, RPL_WHOISUSER, fmt.Sprintf("%s %s %s *", clid, clid, sv.clHosts[clid]), msg.Args[0])
|
||||
m, isoper := sv.opers[clid]
|
||||
if isoper {
|
||||
if m == "a" {
|
||||
sv.sendReply(msg.Pre, RPL_WHOISOPERATOR, clid, "is a server administrator")
|
||||
}
|
||||
if m == "o" {
|
||||
sv.sendReply(msg.Pre, RPL_WHOISOPERATOR, clid, "is a server operator")
|
||||
}
|
||||
}
|
||||
sv.sendReply(msg.Pre, RPL_ENDOFWHOIS, "", "End of /WHOIS list")
|
||||
|
||||
}
|
||||
|
||||
func handleCmdPing(sv *Server, msg *irc.Message) {
|
||||
sv.sendReply(msg.Pre, "PONG", msg.Args[0], "")
|
||||
}
|
||||
|
||||
func handleCmdPong(sv *Server, msg *irc.Message) {
|
||||
}
|
||||
|
||||
func handleCmdRehash(sv *Server, msg *irc.Message) {
|
||||
sv.loadConfig()
|
||||
sv.sendReply(msg.Pre, RPL_REHASHING, "", "Rehashing")
|
||||
|
|
|
@ -58,7 +58,7 @@ func monitoringRun(sv *Server) {
|
|||
|
||||
func monitoringUpdater(sv *Server) {
|
||||
for {
|
||||
time.Sleep(5 * time.Second)
|
||||
time.Sleep(10 * time.Second)
|
||||
gaugeGoroutinesRunning.Set(float64(runtime.NumGoroutine()))
|
||||
gaugePacketsTransferred.Set(sv.packetsTransferred)
|
||||
gaugeConnectionsCurrent.Set(float64(len(sv.clients)))
|
||||
|
|
28
server.go
28
server.go
|
@ -46,6 +46,7 @@ type Server struct {
|
|||
|
||||
clients map[string]Client
|
||||
clModes map[string]string
|
||||
clHosts map[string]string
|
||||
|
||||
services map[string]*Service
|
||||
|
||||
|
@ -59,7 +60,7 @@ type Server struct {
|
|||
packetsTransferred float64
|
||||
connectionsCount float64
|
||||
|
||||
authCallback func(name, pass string) bool
|
||||
authCallback func(name, pass string) (string, bool)
|
||||
}
|
||||
|
||||
func NewServer(configPath, software, version string) *Server {
|
||||
|
@ -76,6 +77,7 @@ func NewServer(configPath, software, version string) *Server {
|
|||
|
||||
sv.clients = make(map[string]Client)
|
||||
sv.clModes = make(map[string]string)
|
||||
sv.clHosts = make(map[string]string)
|
||||
|
||||
sv.services = make(map[string]*Service, 0)
|
||||
|
||||
|
@ -98,11 +100,11 @@ func NewServer(configPath, software, version string) *Server {
|
|||
|
||||
nicks, _ := sv.config.GetString("control", "a")
|
||||
for _, nick := range strings.Split(nicks, ",") {
|
||||
sv.opers[nick] = "a"
|
||||
sv.opers[strings.ToLower(nick)] = "a"
|
||||
}
|
||||
nicks, _ = sv.config.GetString("control", "o")
|
||||
for _, nick := range strings.Split(nicks, ",") {
|
||||
sv.opers[nick] = "o"
|
||||
sv.opers[strings.ToLower(nick)] = "o"
|
||||
}
|
||||
|
||||
sv.packetsTransferred = 0
|
||||
|
@ -111,7 +113,7 @@ func NewServer(configPath, software, version string) *Server {
|
|||
return sv
|
||||
}
|
||||
|
||||
func (sv *Server) SetAuthCallback(authCB func(name, pass string) bool) {
|
||||
func (sv *Server) SetAuthCallback(authCB func(name, pass string) (string, bool)) {
|
||||
sv.authCallback = authCB
|
||||
}
|
||||
|
||||
|
@ -232,7 +234,7 @@ func (sv *Server) dispatcher() (err error) {
|
|||
case cl := <-sv.delq:
|
||||
sv.delClient(cl)
|
||||
default:
|
||||
time.Sleep(100 * time.Microsecond)
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
return
|
||||
|
@ -258,7 +260,15 @@ func (sv *Server) addClient(cl Client) {
|
|||
xlog.Info("Client registration failed: '%s' (client exists)", clid)
|
||||
return
|
||||
}
|
||||
if !sv.authCallback(cl.Name(), cl.Password()) {
|
||||
if host, success := sv.authCallback(cl.Name(), cl.Password()); success {
|
||||
sv.clients[clid] = cl
|
||||
sv.clHosts[clid] = host
|
||||
sv.sendLogon(cl.Name())
|
||||
cl.Register(true)
|
||||
sv.cluster.Subscribe(clid, sv.remoteq)
|
||||
xlog.Info("Client registered: '%s'", clid)
|
||||
xlog.Info("Server has %d client(s)", len(sv.clients))
|
||||
} else {
|
||||
cl.Receive(irc.M(sv.host, ERR_PASSWDMISMATCH, "", "Password incorrect"))
|
||||
go func() {
|
||||
time.Sleep(5 * time.Second)
|
||||
|
@ -267,12 +277,6 @@ func (sv *Server) addClient(cl Client) {
|
|||
xlog.Info("Client registration failed: '%s' (wrong password)", clid)
|
||||
return
|
||||
}
|
||||
sv.clients[clid] = cl
|
||||
sv.sendLogon(cl.Name())
|
||||
cl.Register(true)
|
||||
sv.cluster.Subscribe(clid, sv.remoteq)
|
||||
xlog.Info("Client registered: '%s'", clid)
|
||||
xlog.Info("Server has %d client(s)", len(sv.clients))
|
||||
}
|
||||
|
||||
func (sv *Server) delClient(cl Client) {
|
||||
|
|
|
@ -23,6 +23,9 @@ func (svc *Service) Run() {
|
|||
go svc.dispatcher()
|
||||
}
|
||||
|
||||
func (svc *Service) Stop() {
|
||||
}
|
||||
|
||||
func (svc *Service) Dispatch(msg *irc.Message) {
|
||||
svc.recvq <- msg
|
||||
}
|
||||
|
@ -33,13 +36,13 @@ func (svc *Service) Handler(cmd string, fn func(*irc.Message)) {
|
|||
|
||||
func (svc *Service) dispatcher() {
|
||||
for {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
select {
|
||||
case msg := <-svc.recvq:
|
||||
if fn, exists := sv.handlers[msg.Pre]; exists {
|
||||
if fn, exists := svc.handlers[msg.Pre]; exists {
|
||||
fn(msg)
|
||||
}
|
||||
default:
|
||||
time.Sleep(100 * time.Microsecond)
|
||||
}
|
||||
}
|
||||
return
|
||||
|
|
Loading…
Reference in New Issue