github.com/nats-io/nats-server/v2@v2.11.0-preview.2/server/parser.go (about) 1 // Copyright 2012-2024 The NATS Authors 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package server 15 16 import ( 17 "bufio" 18 "bytes" 19 "fmt" 20 "net/http" 21 "net/textproto" 22 ) 23 24 type parserState int 25 type parseState struct { 26 state parserState 27 op byte 28 as int 29 drop int 30 pa pubArg 31 argBuf []byte 32 msgBuf []byte 33 header http.Header // access via getHeader 34 scratch [MAX_CONTROL_LINE_SIZE]byte 35 } 36 37 type pubArg struct { 38 arg []byte 39 pacache []byte 40 origin []byte 41 account []byte 42 subject []byte 43 deliver []byte 44 mapped []byte 45 reply []byte 46 szb []byte 47 hdb []byte 48 queues [][]byte 49 size int 50 hdr int 51 psi []*serviceImport 52 trace *msgTrace 53 } 54 55 // Parser constants 56 const ( 57 OP_START parserState = iota 58 OP_PLUS 59 OP_PLUS_O 60 OP_PLUS_OK 61 OP_MINUS 62 OP_MINUS_E 63 OP_MINUS_ER 64 OP_MINUS_ERR 65 OP_MINUS_ERR_SPC 66 MINUS_ERR_ARG 67 OP_C 68 OP_CO 69 OP_CON 70 OP_CONN 71 OP_CONNE 72 OP_CONNEC 73 OP_CONNECT 74 CONNECT_ARG 75 OP_H 76 OP_HP 77 OP_HPU 78 OP_HPUB 79 OP_HPUB_SPC 80 HPUB_ARG 81 OP_HM 82 OP_HMS 83 OP_HMSG 84 OP_HMSG_SPC 85 HMSG_ARG 86 OP_P 87 OP_PU 88 OP_PUB 89 OP_PUB_SPC 90 PUB_ARG 91 OP_PI 92 OP_PIN 93 OP_PING 94 OP_PO 95 OP_PON 96 OP_PONG 97 MSG_PAYLOAD 98 MSG_END_R 99 MSG_END_N 100 OP_S 101 OP_SU 102 OP_SUB 103 OP_SUB_SPC 104 SUB_ARG 105 OP_A 106 OP_ASUB 107 OP_ASUB_SPC 108 ASUB_ARG 109 OP_AUSUB 110 OP_AUSUB_SPC 111 AUSUB_ARG 112 OP_L 113 OP_LS 114 OP_R 115 OP_RS 116 OP_U 117 OP_UN 118 OP_UNS 119 OP_UNSU 120 OP_UNSUB 121 OP_UNSUB_SPC 122 UNSUB_ARG 123 OP_M 124 OP_MS 125 OP_MSG 126 OP_MSG_SPC 127 MSG_ARG 128 OP_I 129 OP_IN 130 OP_INF 131 OP_INFO 132 INFO_ARG 133 ) 134 135 func (c *client) parse(buf []byte) error { 136 // Branch out to mqtt clients. c.mqtt is immutable, but should it become 137 // an issue (say data race detection), we could branch outside in readLoop 138 if c.isMqtt() { 139 return c.mqttParse(buf) 140 } 141 var i int 142 var b byte 143 var lmsg bool 144 145 // Snapshots 146 c.mu.Lock() 147 // Snapshot and then reset when we receive a 148 // proper CONNECT if needed. 149 authSet := c.awaitingAuth() 150 // Snapshot max control line as well. 151 s, mcl, trace := c.srv, c.mcl, c.trace 152 c.mu.Unlock() 153 154 // Move to loop instead of range syntax to allow jumping of i 155 for i = 0; i < len(buf); i++ { 156 b = buf[i] 157 158 switch c.state { 159 case OP_START: 160 c.op = b 161 if b != 'C' && b != 'c' { 162 if authSet { 163 if s == nil { 164 goto authErr 165 } 166 var ok bool 167 // Check here for NoAuthUser. If this is set allow non CONNECT protos as our first. 168 // E.g. telnet proto demos. 169 if noAuthUser := s.getOpts().NoAuthUser; noAuthUser != _EMPTY_ { 170 s.mu.Lock() 171 user, exists := s.users[noAuthUser] 172 s.mu.Unlock() 173 if exists { 174 c.RegisterUser(user) 175 c.mu.Lock() 176 c.clearAuthTimer() 177 c.flags.set(connectReceived) 178 c.mu.Unlock() 179 authSet, ok = false, true 180 } 181 } 182 if !ok { 183 goto authErr 184 } 185 } 186 // If the connection is a gateway connection, make sure that 187 // if this is an inbound, it starts with a CONNECT. 188 if c.kind == GATEWAY && !c.gw.outbound && !c.gw.connected { 189 // Use auth violation since no CONNECT was sent. 190 // It could be a parseErr too. 191 goto authErr 192 } 193 } 194 switch b { 195 case 'P', 'p': 196 c.state = OP_P 197 case 'H', 'h': 198 c.state = OP_H 199 case 'S', 's': 200 c.state = OP_S 201 case 'U', 'u': 202 c.state = OP_U 203 case 'R', 'r': 204 if c.kind == CLIENT { 205 goto parseErr 206 } else { 207 c.state = OP_R 208 } 209 case 'L', 'l': 210 if c.kind != LEAF && c.kind != ROUTER { 211 goto parseErr 212 } else { 213 c.state = OP_L 214 } 215 case 'A', 'a': 216 if c.kind == CLIENT { 217 goto parseErr 218 } else { 219 c.state = OP_A 220 } 221 case 'C', 'c': 222 c.state = OP_C 223 case 'I', 'i': 224 c.state = OP_I 225 case '+': 226 c.state = OP_PLUS 227 case '-': 228 c.state = OP_MINUS 229 default: 230 goto parseErr 231 } 232 case OP_H: 233 switch b { 234 case 'P', 'p': 235 c.state = OP_HP 236 case 'M', 'm': 237 c.state = OP_HM 238 default: 239 goto parseErr 240 } 241 case OP_HP: 242 switch b { 243 case 'U', 'u': 244 c.state = OP_HPU 245 default: 246 goto parseErr 247 } 248 case OP_HPU: 249 switch b { 250 case 'B', 'b': 251 c.state = OP_HPUB 252 default: 253 goto parseErr 254 } 255 case OP_HPUB: 256 switch b { 257 case ' ', '\t': 258 c.state = OP_HPUB_SPC 259 default: 260 goto parseErr 261 } 262 case OP_HPUB_SPC: 263 switch b { 264 case ' ', '\t': 265 continue 266 default: 267 c.pa.hdr = 0 268 c.state = HPUB_ARG 269 c.as = i 270 } 271 case HPUB_ARG: 272 switch b { 273 case '\r': 274 c.drop = 1 275 case '\n': 276 var arg []byte 277 if c.argBuf != nil { 278 arg = c.argBuf 279 c.argBuf = nil 280 } else { 281 arg = buf[c.as : i-c.drop] 282 } 283 if err := c.overMaxControlLineLimit(arg, mcl); err != nil { 284 return err 285 } 286 if trace { 287 c.traceInOp("HPUB", arg) 288 } 289 var remaining []byte 290 if i < len(buf) { 291 remaining = buf[i+1:] 292 } 293 if err := c.processHeaderPub(arg, remaining); err != nil { 294 return err 295 } 296 297 c.drop, c.as, c.state = 0, i+1, MSG_PAYLOAD 298 // If we don't have a saved buffer then jump ahead with 299 // the index. If this overruns what is left we fall out 300 // and process split buffer. 301 if c.msgBuf == nil { 302 i = c.as + c.pa.size - LEN_CR_LF 303 } 304 default: 305 if c.argBuf != nil { 306 c.argBuf = append(c.argBuf, b) 307 } 308 } 309 case OP_HM: 310 switch b { 311 case 'S', 's': 312 c.state = OP_HMS 313 default: 314 goto parseErr 315 } 316 case OP_HMS: 317 switch b { 318 case 'G', 'g': 319 c.state = OP_HMSG 320 default: 321 goto parseErr 322 } 323 case OP_HMSG: 324 switch b { 325 case ' ', '\t': 326 c.state = OP_HMSG_SPC 327 default: 328 goto parseErr 329 } 330 case OP_HMSG_SPC: 331 switch b { 332 case ' ', '\t': 333 continue 334 default: 335 c.pa.hdr = 0 336 c.state = HMSG_ARG 337 c.as = i 338 } 339 case HMSG_ARG: 340 switch b { 341 case '\r': 342 c.drop = 1 343 case '\n': 344 var arg []byte 345 if c.argBuf != nil { 346 arg = c.argBuf 347 c.argBuf = nil 348 } else { 349 arg = buf[c.as : i-c.drop] 350 } 351 if err := c.overMaxControlLineLimit(arg, mcl); err != nil { 352 return err 353 } 354 var err error 355 if c.kind == ROUTER || c.kind == GATEWAY { 356 if trace { 357 c.traceInOp("HMSG", arg) 358 } 359 err = c.processRoutedHeaderMsgArgs(arg) 360 } else if c.kind == LEAF { 361 if trace { 362 c.traceInOp("HMSG", arg) 363 } 364 err = c.processLeafHeaderMsgArgs(arg) 365 } 366 if err != nil { 367 return err 368 } 369 c.drop, c.as, c.state = 0, i+1, MSG_PAYLOAD 370 371 // jump ahead with the index. If this overruns 372 // what is left we fall out and process split 373 // buffer. 374 i = c.as + c.pa.size - LEN_CR_LF 375 default: 376 if c.argBuf != nil { 377 c.argBuf = append(c.argBuf, b) 378 } 379 } 380 case OP_P: 381 switch b { 382 case 'U', 'u': 383 c.state = OP_PU 384 case 'I', 'i': 385 c.state = OP_PI 386 case 'O', 'o': 387 c.state = OP_PO 388 default: 389 goto parseErr 390 } 391 case OP_PU: 392 switch b { 393 case 'B', 'b': 394 c.state = OP_PUB 395 default: 396 goto parseErr 397 } 398 case OP_PUB: 399 switch b { 400 case ' ', '\t': 401 c.state = OP_PUB_SPC 402 default: 403 goto parseErr 404 } 405 case OP_PUB_SPC: 406 switch b { 407 case ' ', '\t': 408 continue 409 default: 410 c.pa.hdr = -1 411 c.state = PUB_ARG 412 c.as = i 413 } 414 case PUB_ARG: 415 switch b { 416 case '\r': 417 c.drop = 1 418 case '\n': 419 var arg []byte 420 if c.argBuf != nil { 421 arg = c.argBuf 422 c.argBuf = nil 423 } else { 424 arg = buf[c.as : i-c.drop] 425 } 426 if err := c.overMaxControlLineLimit(arg, mcl); err != nil { 427 return err 428 } 429 if trace { 430 c.traceInOp("PUB", arg) 431 } 432 if err := c.processPub(arg); err != nil { 433 return err 434 } 435 436 c.drop, c.as, c.state = 0, i+1, MSG_PAYLOAD 437 // If we don't have a saved buffer then jump ahead with 438 // the index. If this overruns what is left we fall out 439 // and process split buffer. 440 if c.msgBuf == nil { 441 i = c.as + c.pa.size - LEN_CR_LF 442 } 443 default: 444 if c.argBuf != nil { 445 c.argBuf = append(c.argBuf, b) 446 } 447 } 448 case MSG_PAYLOAD: 449 if c.msgBuf != nil { 450 // copy as much as we can to the buffer and skip ahead. 451 toCopy := c.pa.size - len(c.msgBuf) 452 avail := len(buf) - i 453 if avail < toCopy { 454 toCopy = avail 455 } 456 if toCopy > 0 { 457 start := len(c.msgBuf) 458 // This is needed for copy to work. 459 c.msgBuf = c.msgBuf[:start+toCopy] 460 copy(c.msgBuf[start:], buf[i:i+toCopy]) 461 // Update our index 462 i = (i + toCopy) - 1 463 } else { 464 // Fall back to append if needed. 465 c.msgBuf = append(c.msgBuf, b) 466 } 467 if len(c.msgBuf) >= c.pa.size { 468 c.state = MSG_END_R 469 } 470 } else if i-c.as+1 >= c.pa.size { 471 c.state = MSG_END_R 472 } 473 case MSG_END_R: 474 if b != '\r' { 475 goto parseErr 476 } 477 if c.msgBuf != nil { 478 c.msgBuf = append(c.msgBuf, b) 479 } 480 c.state = MSG_END_N 481 case MSG_END_N: 482 if b != '\n' { 483 goto parseErr 484 } 485 if c.msgBuf != nil { 486 c.msgBuf = append(c.msgBuf, b) 487 } else { 488 c.msgBuf = buf[c.as : i+1] 489 } 490 491 var mt *msgTrace 492 if c.pa.hdr > 0 { 493 mt = c.initMsgTrace() 494 } 495 // Check for mappings. 496 if (c.kind == CLIENT || c.kind == LEAF) && c.in.flags.isSet(hasMappings) { 497 changed := c.selectMappedSubject() 498 if changed { 499 if trace { 500 c.traceInOp("MAPPING", []byte(fmt.Sprintf("%s -> %s", c.pa.mapped, c.pa.subject))) 501 } 502 // c.pa.subject is the subject the original is now mapped to. 503 mt.addSubjectMappingEvent(c.pa.subject) 504 } 505 } 506 if trace { 507 c.traceMsg(c.msgBuf) 508 } 509 510 c.processInboundMsg(c.msgBuf) 511 512 mt.sendEvent() 513 c.argBuf, c.msgBuf, c.header = nil, nil, nil 514 c.drop, c.as, c.state = 0, i+1, OP_START 515 // Drop all pub args 516 c.pa.arg, c.pa.pacache, c.pa.origin, c.pa.account, c.pa.subject, c.pa.mapped = nil, nil, nil, nil, nil, nil 517 c.pa.reply, c.pa.hdr, c.pa.size, c.pa.szb, c.pa.hdb, c.pa.queues = nil, -1, 0, nil, nil, nil 518 c.pa.trace = nil 519 lmsg = false 520 case OP_A: 521 switch b { 522 case '+': 523 c.state = OP_ASUB 524 case '-', 'u': 525 c.state = OP_AUSUB 526 default: 527 goto parseErr 528 } 529 case OP_ASUB: 530 switch b { 531 case ' ', '\t': 532 c.state = OP_ASUB_SPC 533 default: 534 goto parseErr 535 } 536 case OP_ASUB_SPC: 537 switch b { 538 case ' ', '\t': 539 continue 540 default: 541 c.state = ASUB_ARG 542 c.as = i 543 } 544 case ASUB_ARG: 545 switch b { 546 case '\r': 547 c.drop = 1 548 case '\n': 549 var arg []byte 550 if c.argBuf != nil { 551 arg = c.argBuf 552 c.argBuf = nil 553 } else { 554 arg = buf[c.as : i-c.drop] 555 } 556 if err := c.overMaxControlLineLimit(arg, mcl); err != nil { 557 return err 558 } 559 if trace { 560 c.traceInOp("A+", arg) 561 } 562 if err := c.processAccountSub(arg); err != nil { 563 return err 564 } 565 c.drop, c.as, c.state = 0, i+1, OP_START 566 default: 567 if c.argBuf != nil { 568 c.argBuf = append(c.argBuf, b) 569 } 570 } 571 case OP_AUSUB: 572 switch b { 573 case ' ', '\t': 574 c.state = OP_AUSUB_SPC 575 default: 576 goto parseErr 577 } 578 case OP_AUSUB_SPC: 579 switch b { 580 case ' ', '\t': 581 continue 582 default: 583 c.state = AUSUB_ARG 584 c.as = i 585 } 586 case AUSUB_ARG: 587 switch b { 588 case '\r': 589 c.drop = 1 590 case '\n': 591 var arg []byte 592 if c.argBuf != nil { 593 arg = c.argBuf 594 c.argBuf = nil 595 } else { 596 arg = buf[c.as : i-c.drop] 597 } 598 if err := c.overMaxControlLineLimit(arg, mcl); err != nil { 599 return err 600 } 601 if trace { 602 c.traceInOp("A-", arg) 603 } 604 c.processAccountUnsub(arg) 605 c.drop, c.as, c.state = 0, i+1, OP_START 606 default: 607 if c.argBuf != nil { 608 c.argBuf = append(c.argBuf, b) 609 } 610 } 611 case OP_S: 612 switch b { 613 case 'U', 'u': 614 c.state = OP_SU 615 default: 616 goto parseErr 617 } 618 case OP_SU: 619 switch b { 620 case 'B', 'b': 621 c.state = OP_SUB 622 default: 623 goto parseErr 624 } 625 case OP_SUB: 626 switch b { 627 case ' ', '\t': 628 c.state = OP_SUB_SPC 629 default: 630 goto parseErr 631 } 632 case OP_SUB_SPC: 633 switch b { 634 case ' ', '\t': 635 continue 636 default: 637 c.state = SUB_ARG 638 c.as = i 639 } 640 case SUB_ARG: 641 switch b { 642 case '\r': 643 c.drop = 1 644 case '\n': 645 var arg []byte 646 if c.argBuf != nil { 647 arg = c.argBuf 648 c.argBuf = nil 649 } else { 650 arg = buf[c.as : i-c.drop] 651 } 652 if err := c.overMaxControlLineLimit(arg, mcl); err != nil { 653 return err 654 } 655 var err error 656 657 switch c.kind { 658 case CLIENT: 659 if trace { 660 c.traceInOp("SUB", arg) 661 } 662 err = c.parseSub(arg, false) 663 case ROUTER: 664 switch c.op { 665 case 'R', 'r': 666 if trace { 667 c.traceInOp("RS+", arg) 668 } 669 err = c.processRemoteSub(arg, false) 670 case 'L', 'l': 671 if trace { 672 c.traceInOp("LS+", arg) 673 } 674 err = c.processRemoteSub(arg, true) 675 } 676 case GATEWAY: 677 if trace { 678 c.traceInOp("RS+", arg) 679 } 680 err = c.processGatewayRSub(arg) 681 case LEAF: 682 if trace { 683 c.traceInOp("LS+", arg) 684 } 685 err = c.processLeafSub(arg) 686 } 687 if err != nil { 688 return err 689 } 690 c.drop, c.as, c.state = 0, i+1, OP_START 691 default: 692 if c.argBuf != nil { 693 c.argBuf = append(c.argBuf, b) 694 } 695 } 696 case OP_L: 697 switch b { 698 case 'S', 's': 699 c.state = OP_LS 700 case 'M', 'm': 701 c.state = OP_M 702 default: 703 goto parseErr 704 } 705 case OP_LS: 706 switch b { 707 case '+': 708 c.state = OP_SUB 709 case '-': 710 c.state = OP_UNSUB 711 default: 712 goto parseErr 713 } 714 case OP_R: 715 switch b { 716 case 'S', 's': 717 c.state = OP_RS 718 case 'M', 'm': 719 c.state = OP_M 720 default: 721 goto parseErr 722 } 723 case OP_RS: 724 switch b { 725 case '+': 726 c.state = OP_SUB 727 case '-': 728 c.state = OP_UNSUB 729 default: 730 goto parseErr 731 } 732 case OP_U: 733 switch b { 734 case 'N', 'n': 735 c.state = OP_UN 736 default: 737 goto parseErr 738 } 739 case OP_UN: 740 switch b { 741 case 'S', 's': 742 c.state = OP_UNS 743 default: 744 goto parseErr 745 } 746 case OP_UNS: 747 switch b { 748 case 'U', 'u': 749 c.state = OP_UNSU 750 default: 751 goto parseErr 752 } 753 case OP_UNSU: 754 switch b { 755 case 'B', 'b': 756 c.state = OP_UNSUB 757 default: 758 goto parseErr 759 } 760 case OP_UNSUB: 761 switch b { 762 case ' ', '\t': 763 c.state = OP_UNSUB_SPC 764 default: 765 goto parseErr 766 } 767 case OP_UNSUB_SPC: 768 switch b { 769 case ' ', '\t': 770 continue 771 default: 772 c.state = UNSUB_ARG 773 c.as = i 774 } 775 case UNSUB_ARG: 776 switch b { 777 case '\r': 778 c.drop = 1 779 case '\n': 780 var arg []byte 781 if c.argBuf != nil { 782 arg = c.argBuf 783 c.argBuf = nil 784 } else { 785 arg = buf[c.as : i-c.drop] 786 } 787 if err := c.overMaxControlLineLimit(arg, mcl); err != nil { 788 return err 789 } 790 var err error 791 792 switch c.kind { 793 case CLIENT: 794 if trace { 795 c.traceInOp("UNSUB", arg) 796 } 797 err = c.processUnsub(arg) 798 case ROUTER: 799 if trace && c.srv != nil { 800 switch c.op { 801 case 'R', 'r': 802 c.traceInOp("RS-", arg) 803 case 'L', 'l': 804 c.traceInOp("LS-", arg) 805 } 806 } 807 err = c.processRemoteUnsub(arg) 808 case GATEWAY: 809 if trace { 810 c.traceInOp("RS-", arg) 811 } 812 err = c.processGatewayRUnsub(arg) 813 case LEAF: 814 if trace { 815 c.traceInOp("LS-", arg) 816 } 817 err = c.processLeafUnsub(arg) 818 } 819 if err != nil { 820 return err 821 } 822 c.drop, c.as, c.state = 0, i+1, OP_START 823 default: 824 if c.argBuf != nil { 825 c.argBuf = append(c.argBuf, b) 826 } 827 } 828 case OP_PI: 829 switch b { 830 case 'N', 'n': 831 c.state = OP_PIN 832 default: 833 goto parseErr 834 } 835 case OP_PIN: 836 switch b { 837 case 'G', 'g': 838 c.state = OP_PING 839 default: 840 goto parseErr 841 } 842 case OP_PING: 843 switch b { 844 case '\n': 845 if trace { 846 c.traceInOp("PING", nil) 847 } 848 c.processPing() 849 c.drop, c.state = 0, OP_START 850 } 851 case OP_PO: 852 switch b { 853 case 'N', 'n': 854 c.state = OP_PON 855 default: 856 goto parseErr 857 } 858 case OP_PON: 859 switch b { 860 case 'G', 'g': 861 c.state = OP_PONG 862 default: 863 goto parseErr 864 } 865 case OP_PONG: 866 switch b { 867 case '\n': 868 if trace { 869 c.traceInOp("PONG", nil) 870 } 871 c.processPong() 872 c.drop, c.state = 0, OP_START 873 } 874 case OP_C: 875 switch b { 876 case 'O', 'o': 877 c.state = OP_CO 878 default: 879 goto parseErr 880 } 881 case OP_CO: 882 switch b { 883 case 'N', 'n': 884 c.state = OP_CON 885 default: 886 goto parseErr 887 } 888 case OP_CON: 889 switch b { 890 case 'N', 'n': 891 c.state = OP_CONN 892 default: 893 goto parseErr 894 } 895 case OP_CONN: 896 switch b { 897 case 'E', 'e': 898 c.state = OP_CONNE 899 default: 900 goto parseErr 901 } 902 case OP_CONNE: 903 switch b { 904 case 'C', 'c': 905 c.state = OP_CONNEC 906 default: 907 goto parseErr 908 } 909 case OP_CONNEC: 910 switch b { 911 case 'T', 't': 912 c.state = OP_CONNECT 913 default: 914 goto parseErr 915 } 916 case OP_CONNECT: 917 switch b { 918 case ' ', '\t': 919 continue 920 default: 921 c.state = CONNECT_ARG 922 c.as = i 923 } 924 case CONNECT_ARG: 925 switch b { 926 case '\r': 927 c.drop = 1 928 case '\n': 929 var arg []byte 930 if c.argBuf != nil { 931 arg = c.argBuf 932 c.argBuf = nil 933 } else { 934 arg = buf[c.as : i-c.drop] 935 } 936 if err := c.overMaxControlLineLimit(arg, mcl); err != nil { 937 return err 938 } 939 if trace { 940 c.traceInOp("CONNECT", removePassFromTrace(arg)) 941 } 942 if err := c.processConnect(arg); err != nil { 943 return err 944 } 945 c.drop, c.state = 0, OP_START 946 // Reset notion on authSet 947 c.mu.Lock() 948 authSet = c.awaitingAuth() 949 c.mu.Unlock() 950 default: 951 if c.argBuf != nil { 952 c.argBuf = append(c.argBuf, b) 953 } 954 } 955 case OP_M: 956 switch b { 957 case 'S', 's': 958 c.state = OP_MS 959 default: 960 goto parseErr 961 } 962 case OP_MS: 963 switch b { 964 case 'G', 'g': 965 c.state = OP_MSG 966 default: 967 goto parseErr 968 } 969 case OP_MSG: 970 switch b { 971 case ' ', '\t': 972 c.state = OP_MSG_SPC 973 default: 974 goto parseErr 975 } 976 case OP_MSG_SPC: 977 switch b { 978 case ' ', '\t': 979 continue 980 default: 981 c.pa.hdr = -1 982 c.state = MSG_ARG 983 c.as = i 984 } 985 case MSG_ARG: 986 switch b { 987 case '\r': 988 c.drop = 1 989 case '\n': 990 var arg []byte 991 if c.argBuf != nil { 992 arg = c.argBuf 993 c.argBuf = nil 994 } else { 995 arg = buf[c.as : i-c.drop] 996 } 997 if err := c.overMaxControlLineLimit(arg, mcl); err != nil { 998 return err 999 } 1000 var err error 1001 if c.kind == ROUTER || c.kind == GATEWAY { 1002 switch c.op { 1003 case 'R', 'r': 1004 if trace { 1005 c.traceInOp("RMSG", arg) 1006 } 1007 err = c.processRoutedMsgArgs(arg) 1008 case 'L', 'l': 1009 if trace { 1010 c.traceInOp("LMSG", arg) 1011 } 1012 lmsg = true 1013 err = c.processRoutedOriginClusterMsgArgs(arg) 1014 } 1015 } else if c.kind == LEAF { 1016 if trace { 1017 c.traceInOp("LMSG", arg) 1018 } 1019 err = c.processLeafMsgArgs(arg) 1020 } 1021 if err != nil { 1022 return err 1023 } 1024 c.drop, c.as, c.state = 0, i+1, MSG_PAYLOAD 1025 1026 // jump ahead with the index. If this overruns 1027 // what is left we fall out and process split 1028 // buffer. 1029 i = c.as + c.pa.size - LEN_CR_LF 1030 default: 1031 if c.argBuf != nil { 1032 c.argBuf = append(c.argBuf, b) 1033 } 1034 } 1035 case OP_I: 1036 switch b { 1037 case 'N', 'n': 1038 c.state = OP_IN 1039 default: 1040 goto parseErr 1041 } 1042 case OP_IN: 1043 switch b { 1044 case 'F', 'f': 1045 c.state = OP_INF 1046 default: 1047 goto parseErr 1048 } 1049 case OP_INF: 1050 switch b { 1051 case 'O', 'o': 1052 c.state = OP_INFO 1053 default: 1054 goto parseErr 1055 } 1056 case OP_INFO: 1057 switch b { 1058 case ' ', '\t': 1059 continue 1060 default: 1061 c.state = INFO_ARG 1062 c.as = i 1063 } 1064 case INFO_ARG: 1065 switch b { 1066 case '\r': 1067 c.drop = 1 1068 case '\n': 1069 var arg []byte 1070 if c.argBuf != nil { 1071 arg = c.argBuf 1072 c.argBuf = nil 1073 } else { 1074 arg = buf[c.as : i-c.drop] 1075 } 1076 if err := c.overMaxControlLineLimit(arg, mcl); err != nil { 1077 return err 1078 } 1079 if err := c.processInfo(arg); err != nil { 1080 return err 1081 } 1082 c.drop, c.as, c.state = 0, i+1, OP_START 1083 default: 1084 if c.argBuf != nil { 1085 c.argBuf = append(c.argBuf, b) 1086 } 1087 } 1088 case OP_PLUS: 1089 switch b { 1090 case 'O', 'o': 1091 c.state = OP_PLUS_O 1092 default: 1093 goto parseErr 1094 } 1095 case OP_PLUS_O: 1096 switch b { 1097 case 'K', 'k': 1098 c.state = OP_PLUS_OK 1099 default: 1100 goto parseErr 1101 } 1102 case OP_PLUS_OK: 1103 switch b { 1104 case '\n': 1105 c.drop, c.state = 0, OP_START 1106 } 1107 case OP_MINUS: 1108 switch b { 1109 case 'E', 'e': 1110 c.state = OP_MINUS_E 1111 default: 1112 goto parseErr 1113 } 1114 case OP_MINUS_E: 1115 switch b { 1116 case 'R', 'r': 1117 c.state = OP_MINUS_ER 1118 default: 1119 goto parseErr 1120 } 1121 case OP_MINUS_ER: 1122 switch b { 1123 case 'R', 'r': 1124 c.state = OP_MINUS_ERR 1125 default: 1126 goto parseErr 1127 } 1128 case OP_MINUS_ERR: 1129 switch b { 1130 case ' ', '\t': 1131 c.state = OP_MINUS_ERR_SPC 1132 default: 1133 goto parseErr 1134 } 1135 case OP_MINUS_ERR_SPC: 1136 switch b { 1137 case ' ', '\t': 1138 continue 1139 default: 1140 c.state = MINUS_ERR_ARG 1141 c.as = i 1142 } 1143 case MINUS_ERR_ARG: 1144 switch b { 1145 case '\r': 1146 c.drop = 1 1147 case '\n': 1148 var arg []byte 1149 if c.argBuf != nil { 1150 arg = c.argBuf 1151 c.argBuf = nil 1152 } else { 1153 arg = buf[c.as : i-c.drop] 1154 } 1155 if err := c.overMaxControlLineLimit(arg, mcl); err != nil { 1156 return err 1157 } 1158 c.processErr(string(arg)) 1159 c.drop, c.as, c.state = 0, i+1, OP_START 1160 default: 1161 if c.argBuf != nil { 1162 c.argBuf = append(c.argBuf, b) 1163 } 1164 } 1165 default: 1166 goto parseErr 1167 } 1168 } 1169 1170 // Check for split buffer scenarios for any ARG state. 1171 if c.state == SUB_ARG || c.state == UNSUB_ARG || 1172 c.state == PUB_ARG || c.state == HPUB_ARG || 1173 c.state == ASUB_ARG || c.state == AUSUB_ARG || 1174 c.state == MSG_ARG || c.state == HMSG_ARG || 1175 c.state == MINUS_ERR_ARG || c.state == CONNECT_ARG || c.state == INFO_ARG { 1176 1177 // Setup a holder buffer to deal with split buffer scenario. 1178 if c.argBuf == nil { 1179 c.argBuf = c.scratch[:0] 1180 c.argBuf = append(c.argBuf, buf[c.as:i-c.drop]...) 1181 } 1182 // Check for violations of control line length here. Note that this is not 1183 // exact at all but the performance hit is too great to be precise, and 1184 // catching here should prevent memory exhaustion attacks. 1185 if err := c.overMaxControlLineLimit(c.argBuf, mcl); err != nil { 1186 return err 1187 } 1188 } 1189 1190 // Check for split msg 1191 if (c.state == MSG_PAYLOAD || c.state == MSG_END_R || c.state == MSG_END_N) && c.msgBuf == nil { 1192 // We need to clone the pubArg if it is still referencing the 1193 // read buffer and we are not able to process the msg. 1194 1195 if c.argBuf == nil { 1196 // Works also for MSG_ARG, when message comes from ROUTE or GATEWAY. 1197 if err := c.clonePubArg(lmsg); err != nil { 1198 goto parseErr 1199 } 1200 } 1201 1202 // If we will overflow the scratch buffer, just create a 1203 // new buffer to hold the split message. 1204 if c.pa.size > cap(c.scratch)-len(c.argBuf) { 1205 lrem := len(buf[c.as:]) 1206 // Consider it a protocol error when the remaining payload 1207 // is larger than the reported size for PUB. It can happen 1208 // when processing incomplete messages from rogue clients. 1209 if lrem > c.pa.size+LEN_CR_LF { 1210 goto parseErr 1211 } 1212 c.msgBuf = make([]byte, lrem, c.pa.size+LEN_CR_LF) 1213 copy(c.msgBuf, buf[c.as:]) 1214 } else { 1215 c.msgBuf = c.scratch[len(c.argBuf):len(c.argBuf)] 1216 c.msgBuf = append(c.msgBuf, (buf[c.as:])...) 1217 } 1218 } 1219 1220 return nil 1221 1222 authErr: 1223 c.authViolation() 1224 return ErrAuthentication 1225 1226 parseErr: 1227 c.sendErr("Unknown Protocol Operation") 1228 snip := protoSnippet(i, PROTO_SNIPPET_SIZE, buf) 1229 err := fmt.Errorf("%s parser ERROR, state=%d, i=%d: proto='%s...'", c.kindString(), c.state, i, snip) 1230 return err 1231 } 1232 1233 func protoSnippet(start, max int, buf []byte) string { 1234 stop := start + max 1235 bufSize := len(buf) 1236 if start >= bufSize { 1237 return `""` 1238 } 1239 if stop > bufSize { 1240 stop = bufSize - 1 1241 } 1242 return fmt.Sprintf("%q", buf[start:stop]) 1243 } 1244 1245 // Check if the length of buffer `arg` is over the max control line limit `mcl`. 1246 // If so, an error is sent to the client and the connection is closed. 1247 // The error ErrMaxControlLine is returned. 1248 func (c *client) overMaxControlLineLimit(arg []byte, mcl int32) error { 1249 if c.kind != CLIENT { 1250 return nil 1251 } 1252 if len(arg) > int(mcl) { 1253 err := NewErrorCtx(ErrMaxControlLine, "State %d, max_control_line %d, Buffer len %d (snip: %s...)", 1254 c.state, int(mcl), len(c.argBuf), protoSnippet(0, MAX_CONTROL_LINE_SNIPPET_SIZE, arg)) 1255 c.sendErr(err.Error()) 1256 c.closeConnection(MaxControlLineExceeded) 1257 return err 1258 } 1259 return nil 1260 } 1261 1262 // clonePubArg is used when the split buffer scenario has the pubArg in the existing read buffer, but 1263 // we need to hold onto it into the next read. 1264 func (c *client) clonePubArg(lmsg bool) error { 1265 // Just copy and re-process original arg buffer. 1266 c.argBuf = c.scratch[:0] 1267 c.argBuf = append(c.argBuf, c.pa.arg...) 1268 1269 switch c.kind { 1270 case ROUTER, GATEWAY: 1271 if lmsg { 1272 return c.processRoutedOriginClusterMsgArgs(c.argBuf) 1273 } 1274 if c.pa.hdr < 0 { 1275 return c.processRoutedMsgArgs(c.argBuf) 1276 } else { 1277 return c.processRoutedHeaderMsgArgs(c.argBuf) 1278 } 1279 case LEAF: 1280 if c.pa.hdr < 0 { 1281 return c.processLeafMsgArgs(c.argBuf) 1282 } else { 1283 return c.processLeafHeaderMsgArgs(c.argBuf) 1284 } 1285 default: 1286 if c.pa.hdr < 0 { 1287 return c.processPub(c.argBuf) 1288 } else { 1289 return c.processHeaderPub(c.argBuf, nil) 1290 } 1291 } 1292 } 1293 1294 func (ps *parseState) getHeader() http.Header { 1295 if ps.header == nil { 1296 if hdr := ps.pa.hdr; hdr > 0 { 1297 reader := bufio.NewReader(bytes.NewReader(ps.msgBuf[0:hdr])) 1298 tp := textproto.NewReader(reader) 1299 tp.ReadLine() // skip over first line, contains version 1300 if mimeHeader, err := tp.ReadMIMEHeader(); err == nil { 1301 ps.header = http.Header(mimeHeader) 1302 } 1303 } 1304 } 1305 return ps.header 1306 }