Browse Source

handle connections to non-existent chat rooms

Mike 2 years ago
parent
commit
59a6fafcde
11 changed files with 62 additions and 29 deletions
  1. 1 1
      server/bucp.go
  2. 1 1
      server/buddy.go
  3. 1 1
      server/chat.go
  4. 1 1
      server/chat_nav.go
  5. 1 1
      server/feedbag.go
  6. 1 1
      server/icbm.go
  7. 1 1
      server/locate.go
  8. 3 10
      server/oservice.go
  9. 46 10
      server/oservice_test.go
  10. 1 1
      server/pd.go
  11. 5 1
      server/protocol.go

+ 1 - 1
server/bucp.go

@@ -22,7 +22,7 @@ const (
 )
 
 func routeBUCP(snac oscar.SnacFrame, w io.Writer, sequence *uint32) error {
-	return sendInvalidSNACErr(snac, w, sequence)
+	return handleUnimplementedSNAC(snac, w, sequence)
 }
 
 func ReceiveAndSendAuthChallenge(cfg Config, fm *FeedbagStore, r io.Reader, w io.Writer, sequence *uint32, newUUID func() uuid.UUID) error {

+ 1 - 1
server/buddy.go

@@ -27,7 +27,7 @@ func routeBuddy(snac oscar.SnacFrame, r io.Reader, w io.Writer, sequence *uint32
 	case BuddyRightsQuery:
 		return SendAndReceiveBuddyRights(snac, r, w, sequence)
 	default:
-		return sendInvalidSNACErr(snac, w, sequence)
+		return handleUnimplementedSNAC(snac, w, sequence)
 	}
 }
 

+ 1 - 1
server/chat.go

@@ -55,7 +55,7 @@ func routeChat(sess *Session, sm SessionManager, snac oscar.SnacFrame, r io.Read
 	case ChatChannelMsgTohost:
 		return SendAndReceiveChatChannelMsgTohost(sess, sm, snac, r, w, sequence)
 	default:
-		return sendInvalidSNACErr(snac, w, sequence)
+		return handleUnimplementedSNAC(snac, w, sequence)
 	}
 }
 

+ 1 - 1
server/chat_nav.go

@@ -30,7 +30,7 @@ func routeChatNav(sess *Session, cr *ChatRegistry, snac oscar.SnacFrame, r io.Re
 	case ChatNavCreateRoom:
 		return SendAndReceiveCreateRoom(sess, cr, NewChatRoom, snac, r, w, sequence)
 	default:
-		return sendInvalidSNACErr(snac, w, sequence)
+		return handleUnimplementedSNAC(snac, w, sequence)
 	}
 }
 

+ 1 - 1
server/feedbag.go

@@ -167,7 +167,7 @@ func routeFeedbag(sm SessionManager, sess *Session, fm *FeedbagStore, snac oscar
 	case FeedbagEndCluster:
 		return ReceiveFeedbagEndCluster(snac, r, w, sequence)
 	default:
-		return sendInvalidSNACErr(snac, w, sequence)
+		return handleUnimplementedSNAC(snac, w, sequence)
 	}
 }
 

+ 1 - 1
server/icbm.go

@@ -51,7 +51,7 @@ func routeICBM(sm SessionManager, fm *FeedbagStore, sess *Session, snac oscar.Sn
 	case ICBMClientEvent:
 		return SendAndReceiveClientEvent(sm, fm, sess, snac, r)
 	default:
-		return sendInvalidSNACErr(snac, w, sequence)
+		return handleUnimplementedSNAC(snac, w, sequence)
 	}
 }
 

+ 1 - 1
server/locate.go

@@ -60,7 +60,7 @@ func routeLocate(sess *Session, sm SessionManager, fm *FeedbagStore, snac oscar.
 	case LocateUserInfoQuery2:
 		return SendAndReceiveUserInfoQuery2(sess, sm, fm, fm, snac, r, w, sequence)
 	default:
-		return sendInvalidSNACErr(snac, w, sequence)
+		return handleUnimplementedSNAC(snac, w, sequence)
 	}
 }
 

+ 3 - 10
server/oservice.go

@@ -66,7 +66,7 @@ func routeOService(cfg Config, ready OnReadyCB, cr *ChatRegistry, sm SessionMana
 	case OServiceSetUserinfoFields:
 		return ReceiveSetUserInfoFields(sess, sm, fm, snac, r, w, sequence)
 	default:
-		return sendInvalidSNACErr(snac, w, sequence)
+		return handleUnimplementedSNAC(snac, w, sequence)
 	}
 }
 
@@ -349,21 +349,14 @@ func ReceiveAndSendServiceRequest(cfg Config, cr *ChatRegistry, sess *Session, s
 
 		room, err := cr.Retrieve(string(roomSnac.Cookie))
 		if err != nil {
-			return err
+			return sendInvalidSNACErr(snac, w, sequence)
 		}
 		room.NewSessionWithSN(sess.ID, sess.ScreenName)
 
 		return sendChatRoomServiceInfo(cfg, room, sess, snac, sequence, w)
 	}
 
-	snacFrameOut := oscar.SnacFrame{
-		FoodGroup: OSERVICE,
-		SubGroup:  OServiceErr,
-	}
-	snacPayloadOut := oscar.SnacOServiceErr{
-		Code: ErrorCodeNotSupportedByHost,
-	}
-	return writeOutSNAC(snac, snacFrameOut, snacPayloadOut, sequence, w)
+	return sendInvalidSNACErr(snac, w, sequence)
 }
 
 func sendChatRoomServiceInfo(cfg Config, room ChatRoom, sess *Session, snac oscar.SnacFrame, sequence *uint32, w io.Writer) error {

+ 46 - 10
server/oservice_test.go

@@ -16,7 +16,7 @@ func TestReceiveAndSendServiceRequest(t *testing.T) {
 		// cfg is the application config
 		cfg Config
 		// chatRoom is the chat room the user connects to
-		chatRoom ChatRoom
+		chatRoom *ChatRoom
 		// userSession is the session of the user requesting the chat service
 		// info
 		userSession *Session
@@ -30,7 +30,7 @@ func TestReceiveAndSendServiceRequest(t *testing.T) {
 		expectSNACBody any
 	}{
 		{
-			name: "request info for ICBM service, return service not defined error",
+			name: "request info for ICBM service, return invalid SNAC err",
 			userSession: &Session{
 				ScreenName: "user_screen_name",
 			},
@@ -42,7 +42,7 @@ func TestReceiveAndSendServiceRequest(t *testing.T) {
 				SubGroup:  OServiceErr,
 			},
 			expectSNACBody: oscar.SnacOServiceErr{
-				Code: ErrorCodeNotSupportedByHost,
+				Code: ErrorCodeInvalidSnac,
 			},
 		},
 		{
@@ -51,7 +51,7 @@ func TestReceiveAndSendServiceRequest(t *testing.T) {
 				OSCARHost: "127.0.0.1",
 				ChatPort:  1234,
 			},
-			chatRoom: ChatRoom{
+			chatRoom: &ChatRoom{
 				CreateTime:     time.UnixMilli(0),
 				DetailLevel:    4,
 				Exchange:       8,
@@ -112,6 +112,40 @@ func TestReceiveAndSendServiceRequest(t *testing.T) {
 				},
 			},
 		},
+		{
+			name: "request info for connecting to non-existent chat room, return SNAC error",
+			cfg: Config{
+				OSCARHost: "127.0.0.1",
+				ChatPort:  1234,
+			},
+			chatRoom: nil,
+			userSession: &Session{
+				ID:         "user-sess-id",
+				ScreenName: "user_screen_name",
+			},
+			inputSNAC: oscar.SNAC_0x01_0x04_OServiceServiceRequest{
+				FoodGroup: CHAT,
+				TLVRestBlock: oscar.TLVRestBlock{
+					TLVList: oscar.TLVList{
+						{
+							TType: 0x01,
+							Val: oscar.SNAC_0x01_0x04_TLVRoomInfo{
+								Exchange:       8,
+								Cookie:         []byte("the-chat-cookie"),
+								InstanceNumber: 16,
+							},
+						},
+					},
+				},
+			},
+			expectSNACFrame: oscar.SnacFrame{
+				FoodGroup: OSERVICE,
+				SubGroup:  OServiceErr,
+			},
+			expectSNACBody: oscar.SnacOServiceErr{
+				Code: ErrorCodeInvalidSnac,
+			},
+		},
 	}
 
 	for _, tc := range cases {
@@ -120,13 +154,15 @@ func TestReceiveAndSendServiceRequest(t *testing.T) {
 			// initialize dependencies
 			//
 			sm := NewMockSessionManager(t)
-			sm.EXPECT().
-				NewSessionWithSN(tc.userSession.ID, tc.userSession.ScreenName).
-				Return(&Session{}).
-				Maybe()
-			tc.chatRoom.SessionManager = sm
 			cr := NewChatRegistry()
-			cr.Register(tc.chatRoom)
+			if tc.chatRoom != nil {
+				sm.EXPECT().
+					NewSessionWithSN(tc.userSession.ID, tc.userSession.ScreenName).
+					Return(&Session{}).
+					Maybe()
+				tc.chatRoom.SessionManager = sm
+				cr.Register(*tc.chatRoom)
+			}
 
 			//
 			// send input SNAC

+ 1 - 1
server/pd.go

@@ -25,7 +25,7 @@ func routePD(snac oscar.SnacFrame, r io.Reader, w io.Writer, sequence *uint32) e
 	case PDRightsQuery:
 		return SendAndReceivePDRightsQuery(snac, r, w, sequence)
 	default:
-		return sendInvalidSNACErr(snac, w, sequence)
+		return handleUnimplementedSNAC(snac, w, sequence)
 	}
 }
 

+ 5 - 1
server/protocol.go

@@ -199,8 +199,12 @@ const (
 	FlapFrameKeepAlive       = 0x05
 )
 
-func sendInvalidSNACErr(snac oscar.SnacFrame, w io.Writer, sequence *uint32) error {
+func handleUnimplementedSNAC(snac oscar.SnacFrame, w io.Writer, sequence *uint32) error {
 	fmt.Printf("unimplemented SNAC: %+v\n", snac)
+	return sendInvalidSNACErr(snac, w, sequence)
+}
+
+func sendInvalidSNACErr(snac oscar.SnacFrame, w io.Writer, sequence *uint32) error {
 	snacFrameOut := oscar.SnacFrame{
 		FoodGroup: snac.FoodGroup,
 		SubGroup:  0x01, // error subgroup for all SNACs