github.com/keysonZZZ/kmg@v0.0.0-20151121023212-05317bfd7d39/third/kmgRadius/kmgRadius.go (about) 1 package kmgRadius 2 3 import ( 4 "net" 5 6 "github.com/bronze1man/kmg/kmgLog" 7 ) 8 9 type AcctRequest struct { 10 SessionId string //连接id 11 Username string 12 SessionTime uint32 //连接时间 13 InputBytes uint64 //流入字节 14 OutputBytes uint64 //流出字节 15 NasPort uint32 16 } 17 18 type Handler struct { 19 // 有的协议需要明文密码来做各种hash的事情 20 // exist返回false可以踢掉客户端 21 // 同步调用 22 Auth func(username string) (password string, exist bool) 23 // 计费开始,来了一条新连接 24 // 根据协议规定 此处返回给客户端的包,不能发送任何有效信息(比如踢掉客户端,请采用其他办法踢掉客户端) 25 // 异步调用 26 AcctStart func(acctReq AcctRequest) 27 // 计费数据更新 28 // 根据协议规定 此处返回给客户端的包,不能发送任何有效信息(比如踢掉客户端,请采用其他办法踢掉客户端) 29 // 异步调用 30 AcctUpdate func(acctReq AcctRequest) 31 // 计费结束 32 // 根据协议规定 此处返回给客户端的包,不能发送任何有效信息(比如踢掉客户端,请采用其他办法踢掉客户端) 33 // 异步调用 34 AcctStop func(acctReq AcctRequest) 35 } 36 37 //异步运行服务器, 38 // TODO 返回Closer以便可以关闭服务器,所有无法运行的错误panic出来,其他错误丢到kmgLog error里面. 39 // 如果不需要Closer可以直接忽略 40 func RunServer(address string, secret []byte, handler Handler) func() error { 41 s := server{ 42 mschapMap: map[string]mschapStatus{}, 43 handler: handler, 44 } 45 return RunServerWithPacketHandler(address, secret, s.PacketHandler) 46 } 47 48 type PacketHandler func(request *Packet) *Packet 49 50 //异步运行服务器,返回Closer以便可以关闭服务器,所有无法运行的错误panic出来,其他错误丢到kmgLog error里面. 51 func RunServerWithPacketHandler(address string, secret []byte, handler PacketHandler) func() error { 52 connChan := make(chan *net.UDPConn) 53 go func() { 54 var conn *net.UDPConn 55 addr, err := net.ResolveUDPAddr("udp", address) 56 if err != nil { 57 panic(err) 58 } 59 conn, err = net.ListenUDP("udp", addr) 60 if err != nil { 61 panic(err) 62 } 63 connChan <- conn 64 for { 65 b := make([]byte, 4096) 66 n, senderAddress, err := conn.ReadFrom(b) 67 if err != nil { 68 panic(err) 69 } 70 go func(p []byte, senderAddress net.Addr) { 71 pac, err := DecodeRequestPacket(secret, p) 72 if err != nil { 73 kmgLog.Log("error", "radius.Decode", err.Error()) 74 return 75 } 76 77 npac := handler(pac) 78 if npac == nil { 79 // 特殊情况,返回nil,表示抛弃这个包. 80 return 81 } 82 err = npac.Send(conn, senderAddress) 83 if err != nil { 84 kmgLog.Log("error", "radius.Send", err.Error()) 85 return 86 } 87 }(b[:n], senderAddress) 88 } 89 return 90 }() 91 conn := <-connChan 92 close(connChan) 93 return conn.Close 94 }