get.pme.sh/pnats@v0.0.0-20240304004023-26bb5a137ed0/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 (trace || mt != nil) && changed { 499 c.traceInOp("MAPPING", []byte(fmt.Sprintf("%s -> %s", c.pa.mapped, c.pa.subject))) 500 // c.pa.subject is the subject the original is now mapped to. 501 mt.addSubjectMappingEvent(c.pa.subject) 502 } 503 } 504 if trace { 505 c.traceMsg(c.msgBuf) 506 } 507 508 c.processInboundMsg(c.msgBuf) 509 510 mt.sendEvent() 511 c.argBuf, c.msgBuf, c.header = nil, nil, nil 512 c.drop, c.as, c.state = 0, i+1, OP_START 513 // Drop all pub args 514 c.pa.arg, c.pa.pacache, c.pa.origin, c.pa.account, c.pa.subject, c.pa.mapped = nil, nil, nil, nil, nil, nil 515 c.pa.reply, c.pa.hdr, c.pa.size, c.pa.szb, c.pa.hdb, c.pa.queues = nil, -1, 0, nil, nil, nil 516 c.pa.trace = nil 517 lmsg = false 518 case OP_A: 519 switch b { 520 case '+': 521 c.state = OP_ASUB 522 case '-', 'u': 523 c.state = OP_AUSUB 524 default: 525 goto parseErr 526 } 527 case OP_ASUB: 528 switch b { 529 case ' ', '\t': 530 c.state = OP_ASUB_SPC 531 default: 532 goto parseErr 533 } 534 case OP_ASUB_SPC: 535 switch b { 536 case ' ', '\t': 537 continue 538 default: 539 c.state = ASUB_ARG 540 c.as = i 541 } 542 case ASUB_ARG: 543 switch b { 544 case '\r': 545 c.drop = 1 546 case '\n': 547 var arg []byte 548 if c.argBuf != nil { 549 arg = c.argBuf 550 c.argBuf = nil 551 } else { 552 arg = buf[c.as : i-c.drop] 553 } 554 if err := c.overMaxControlLineLimit(arg, mcl); err != nil { 555 return err 556 } 557 if trace { 558 c.traceInOp("A+", arg) 559 } 560 if err := c.processAccountSub(arg); err != nil { 561 return err 562 } 563 c.drop, c.as, c.state = 0, i+1, OP_START 564 default: 565 if c.argBuf != nil { 566 c.argBuf = append(c.argBuf, b) 567 } 568 } 569 case OP_AUSUB: 570 switch b { 571 case ' ', '\t': 572 c.state = OP_AUSUB_SPC 573 default: 574 goto parseErr 575 } 576 case OP_AUSUB_SPC: 577 switch b { 578 case ' ', '\t': 579 continue 580 default: 581 c.state = AUSUB_ARG 582 c.as = i 583 } 584 case AUSUB_ARG: 585 switch b { 586 case '\r': 587 c.drop = 1 588 case '\n': 589 var arg []byte 590 if c.argBuf != nil { 591 arg = c.argBuf 592 c.argBuf = nil 593 } else { 594 arg = buf[c.as : i-c.drop] 595 } 596 if err := c.overMaxControlLineLimit(arg, mcl); err != nil { 597 return err 598 } 599 if trace { 600 c.traceInOp("A-", arg) 601 } 602 c.processAccountUnsub(arg) 603 c.drop, c.as, c.state = 0, i+1, OP_START 604 default: 605 if c.argBuf != nil { 606 c.argBuf = append(c.argBuf, b) 607 } 608 } 609 case OP_S: 610 switch b { 611 case 'U', 'u': 612 c.state = OP_SU 613 default: 614 goto parseErr 615 } 616 case OP_SU: 617 switch b { 618 case 'B', 'b': 619 c.state = OP_SUB 620 default: 621 goto parseErr 622 } 623 case OP_SUB: 624 switch b { 625 case ' ', '\t': 626 c.state = OP_SUB_SPC 627 default: 628 goto parseErr 629 } 630 case OP_SUB_SPC: 631 switch b { 632 case ' ', '\t': 633 continue 634 default: 635 c.state = SUB_ARG 636 c.as = i 637 } 638 case SUB_ARG: 639 switch b { 640 case '\r': 641 c.drop = 1 642 case '\n': 643 var arg []byte 644 if c.argBuf != nil { 645 arg = c.argBuf 646 c.argBuf = nil 647 } else { 648 arg = buf[c.as : i-c.drop] 649 } 650 if err := c.overMaxControlLineLimit(arg, mcl); err != nil { 651 return err 652 } 653 var err error 654 655 switch c.kind { 656 case CLIENT: 657 if trace { 658 c.traceInOp("SUB", arg) 659 } 660 err = c.parseSub(arg, false) 661 case ROUTER: 662 switch c.op { 663 case 'R', 'r': 664 if trace { 665 c.traceInOp("RS+", arg) 666 } 667 err = c.processRemoteSub(arg, false) 668 case 'L', 'l': 669 if trace { 670 c.traceInOp("LS+", arg) 671 } 672 err = c.processRemoteSub(arg, true) 673 } 674 case GATEWAY: 675 if trace { 676 c.traceInOp("RS+", arg) 677 } 678 err = c.processGatewayRSub(arg) 679 case LEAF: 680 if trace { 681 c.traceInOp("LS+", arg) 682 } 683 err = c.processLeafSub(arg) 684 } 685 if err != nil { 686 return err 687 } 688 c.drop, c.as, c.state = 0, i+1, OP_START 689 default: 690 if c.argBuf != nil { 691 c.argBuf = append(c.argBuf, b) 692 } 693 } 694 case OP_L: 695 switch b { 696 case 'S', 's': 697 c.state = OP_LS 698 case 'M', 'm': 699 c.state = OP_M 700 default: 701 goto parseErr 702 } 703 case OP_LS: 704 switch b { 705 case '+': 706 c.state = OP_SUB 707 case '-': 708 c.state = OP_UNSUB 709 default: 710 goto parseErr 711 } 712 case OP_R: 713 switch b { 714 case 'S', 's': 715 c.state = OP_RS 716 case 'M', 'm': 717 c.state = OP_M 718 default: 719 goto parseErr 720 } 721 case OP_RS: 722 switch b { 723 case '+': 724 c.state = OP_SUB 725 case '-': 726 c.state = OP_UNSUB 727 default: 728 goto parseErr 729 } 730 case OP_U: 731 switch b { 732 case 'N', 'n': 733 c.state = OP_UN 734 default: 735 goto parseErr 736 } 737 case OP_UN: 738 switch b { 739 case 'S', 's': 740 c.state = OP_UNS 741 default: 742 goto parseErr 743 } 744 case OP_UNS: 745 switch b { 746 case 'U', 'u': 747 c.state = OP_UNSU 748 default: 749 goto parseErr 750 } 751 case OP_UNSU: 752 switch b { 753 case 'B', 'b': 754 c.state = OP_UNSUB 755 default: 756 goto parseErr 757 } 758 case OP_UNSUB: 759 switch b { 760 case ' ', '\t': 761 c.state = OP_UNSUB_SPC 762 default: 763 goto parseErr 764 } 765 case OP_UNSUB_SPC: 766 switch b { 767 case ' ', '\t': 768 continue 769 default: 770 c.state = UNSUB_ARG 771 c.as = i 772 } 773 case UNSUB_ARG: 774 switch b { 775 case '\r': 776 c.drop = 1 777 case '\n': 778 var arg []byte 779 if c.argBuf != nil { 780 arg = c.argBuf 781 c.argBuf = nil 782 } else { 783 arg = buf[c.as : i-c.drop] 784 } 785 if err := c.overMaxControlLineLimit(arg, mcl); err != nil { 786 return err 787 } 788 var err error 789 790 switch c.kind { 791 case CLIENT: 792 if trace { 793 c.traceInOp("UNSUB", arg) 794 } 795 err = c.processUnsub(arg) 796 case ROUTER: 797 if trace && c.srv != nil { 798 switch c.op { 799 case 'R', 'r': 800 c.traceInOp("RS-", arg) 801 case 'L', 'l': 802 c.traceInOp("LS-", arg) 803 } 804 } 805 err = c.processRemoteUnsub(arg) 806 case GATEWAY: 807 if trace { 808 c.traceInOp("RS-", arg) 809 } 810 err = c.processGatewayRUnsub(arg) 811 case LEAF: 812 if trace { 813 c.traceInOp("LS-", arg) 814 } 815 err = c.processLeafUnsub(arg) 816 } 817 if err != nil { 818 return err 819 } 820 c.drop, c.as, c.state = 0, i+1, OP_START 821 default: 822 if c.argBuf != nil { 823 c.argBuf = append(c.argBuf, b) 824 } 825 } 826 case OP_PI: 827 switch b { 828 case 'N', 'n': 829 c.state = OP_PIN 830 default: 831 goto parseErr 832 } 833 case OP_PIN: 834 switch b { 835 case 'G', 'g': 836 c.state = OP_PING 837 default: 838 goto parseErr 839 } 840 case OP_PING: 841 switch b { 842 case '\n': 843 if trace { 844 c.traceInOp("PING", nil) 845 } 846 c.processPing() 847 c.drop, c.state = 0, OP_START 848 } 849 case OP_PO: 850 switch b { 851 case 'N', 'n': 852 c.state = OP_PON 853 default: 854 goto parseErr 855 } 856 case OP_PON: 857 switch b { 858 case 'G', 'g': 859 c.state = OP_PONG 860 default: 861 goto parseErr 862 } 863 case OP_PONG: 864 switch b { 865 case '\n': 866 if trace { 867 c.traceInOp("PONG", nil) 868 } 869 c.processPong() 870 c.drop, c.state = 0, OP_START 871 } 872 case OP_C: 873 switch b { 874 case 'O', 'o': 875 c.state = OP_CO 876 default: 877 goto parseErr 878 } 879 case OP_CO: 880 switch b { 881 case 'N', 'n': 882 c.state = OP_CON 883 default: 884 goto parseErr 885 } 886 case OP_CON: 887 switch b { 888 case 'N', 'n': 889 c.state = OP_CONN 890 default: 891 goto parseErr 892 } 893 case OP_CONN: 894 switch b { 895 case 'E', 'e': 896 c.state = OP_CONNE 897 default: 898 goto parseErr 899 } 900 case OP_CONNE: 901 switch b { 902 case 'C', 'c': 903 c.state = OP_CONNEC 904 default: 905 goto parseErr 906 } 907 case OP_CONNEC: 908 switch b { 909 case 'T', 't': 910 c.state = OP_CONNECT 911 default: 912 goto parseErr 913 } 914 case OP_CONNECT: 915 switch b { 916 case ' ', '\t': 917 continue 918 default: 919 c.state = CONNECT_ARG 920 c.as = i 921 } 922 case CONNECT_ARG: 923 switch b { 924 case '\r': 925 c.drop = 1 926 case '\n': 927 var arg []byte 928 if c.argBuf != nil { 929 arg = c.argBuf 930 c.argBuf = nil 931 } else { 932 arg = buf[c.as : i-c.drop] 933 } 934 if err := c.overMaxControlLineLimit(arg, mcl); err != nil { 935 return err 936 } 937 if trace { 938 c.traceInOp("CONNECT", removePassFromTrace(arg)) 939 } 940 if err := c.processConnect(arg); err != nil { 941 return err 942 } 943 c.drop, c.state = 0, OP_START 944 // Reset notion on authSet 945 c.mu.Lock() 946 authSet = c.awaitingAuth() 947 c.mu.Unlock() 948 default: 949 if c.argBuf != nil { 950 c.argBuf = append(c.argBuf, b) 951 } 952 } 953 case OP_M: 954 switch b { 955 case 'S', 's': 956 c.state = OP_MS 957 default: 958 goto parseErr 959 } 960 case OP_MS: 961 switch b { 962 case 'G', 'g': 963 c.state = OP_MSG 964 default: 965 goto parseErr 966 } 967 case OP_MSG: 968 switch b { 969 case ' ', '\t': 970 c.state = OP_MSG_SPC 971 default: 972 goto parseErr 973 } 974 case OP_MSG_SPC: 975 switch b { 976 case ' ', '\t': 977 continue 978 default: 979 c.pa.hdr = -1 980 c.state = MSG_ARG 981 c.as = i 982 } 983 case MSG_ARG: 984 switch b { 985 case '\r': 986 c.drop = 1 987 case '\n': 988 var arg []byte 989 if c.argBuf != nil { 990 arg = c.argBuf 991 c.argBuf = nil 992 } else { 993 arg = buf[c.as : i-c.drop] 994 } 995 if err := c.overMaxControlLineLimit(arg, mcl); err != nil { 996 return err 997 } 998 var err error 999 if c.kind == ROUTER || c.kind == GATEWAY { 1000 switch c.op { 1001 case 'R', 'r': 1002 if trace { 1003 c.traceInOp("RMSG", arg) 1004 } 1005 err = c.processRoutedMsgArgs(arg) 1006 case 'L', 'l': 1007 if trace { 1008 c.traceInOp("LMSG", arg) 1009 } 1010 lmsg = true 1011 err = c.processRoutedOriginClusterMsgArgs(arg) 1012 } 1013 } else if c.kind == LEAF { 1014 if trace { 1015 c.traceInOp("LMSG", arg) 1016 } 1017 err = c.processLeafMsgArgs(arg) 1018 } 1019 if err != nil { 1020 return err 1021 } 1022 c.drop, c.as, c.state = 0, i+1, MSG_PAYLOAD 1023 1024 // jump ahead with the index. If this overruns 1025 // what is left we fall out and process split 1026 // buffer. 1027 i = c.as + c.pa.size - LEN_CR_LF 1028 default: 1029 if c.argBuf != nil { 1030 c.argBuf = append(c.argBuf, b) 1031 } 1032 } 1033 case OP_I: 1034 switch b { 1035 case 'N', 'n': 1036 c.state = OP_IN 1037 default: 1038 goto parseErr 1039 } 1040 case OP_IN: 1041 switch b { 1042 case 'F', 'f': 1043 c.state = OP_INF 1044 default: 1045 goto parseErr 1046 } 1047 case OP_INF: 1048 switch b { 1049 case 'O', 'o': 1050 c.state = OP_INFO 1051 default: 1052 goto parseErr 1053 } 1054 case OP_INFO: 1055 switch b { 1056 case ' ', '\t': 1057 continue 1058 default: 1059 c.state = INFO_ARG 1060 c.as = i 1061 } 1062 case INFO_ARG: 1063 switch b { 1064 case '\r': 1065 c.drop = 1 1066 case '\n': 1067 var arg []byte 1068 if c.argBuf != nil { 1069 arg = c.argBuf 1070 c.argBuf = nil 1071 } else { 1072 arg = buf[c.as : i-c.drop] 1073 } 1074 if err := c.overMaxControlLineLimit(arg, mcl); err != nil { 1075 return err 1076 } 1077 if err := c.processInfo(arg); err != nil { 1078 return err 1079 } 1080 c.drop, c.as, c.state = 0, i+1, OP_START 1081 default: 1082 if c.argBuf != nil { 1083 c.argBuf = append(c.argBuf, b) 1084 } 1085 } 1086 case OP_PLUS: 1087 switch b { 1088 case 'O', 'o': 1089 c.state = OP_PLUS_O 1090 default: 1091 goto parseErr 1092 } 1093 case OP_PLUS_O: 1094 switch b { 1095 case 'K', 'k': 1096 c.state = OP_PLUS_OK 1097 default: 1098 goto parseErr 1099 } 1100 case OP_PLUS_OK: 1101 switch b { 1102 case '\n': 1103 c.drop, c.state = 0, OP_START 1104 } 1105 case OP_MINUS: 1106 switch b { 1107 case 'E', 'e': 1108 c.state = OP_MINUS_E 1109 default: 1110 goto parseErr 1111 } 1112 case OP_MINUS_E: 1113 switch b { 1114 case 'R', 'r': 1115 c.state = OP_MINUS_ER 1116 default: 1117 goto parseErr 1118 } 1119 case OP_MINUS_ER: 1120 switch b { 1121 case 'R', 'r': 1122 c.state = OP_MINUS_ERR 1123 default: 1124 goto parseErr 1125 } 1126 case OP_MINUS_ERR: 1127 switch b { 1128 case ' ', '\t': 1129 c.state = OP_MINUS_ERR_SPC 1130 default: 1131 goto parseErr 1132 } 1133 case OP_MINUS_ERR_SPC: 1134 switch b { 1135 case ' ', '\t': 1136 continue 1137 default: 1138 c.state = MINUS_ERR_ARG 1139 c.as = i 1140 } 1141 case MINUS_ERR_ARG: 1142 switch b { 1143 case '\r': 1144 c.drop = 1 1145 case '\n': 1146 var arg []byte 1147 if c.argBuf != nil { 1148 arg = c.argBuf 1149 c.argBuf = nil 1150 } else { 1151 arg = buf[c.as : i-c.drop] 1152 } 1153 if err := c.overMaxControlLineLimit(arg, mcl); err != nil { 1154 return err 1155 } 1156 c.processErr(string(arg)) 1157 c.drop, c.as, c.state = 0, i+1, OP_START 1158 default: 1159 if c.argBuf != nil { 1160 c.argBuf = append(c.argBuf, b) 1161 } 1162 } 1163 default: 1164 goto parseErr 1165 } 1166 } 1167 1168 // Check for split buffer scenarios for any ARG state. 1169 if c.state == SUB_ARG || c.state == UNSUB_ARG || 1170 c.state == PUB_ARG || c.state == HPUB_ARG || 1171 c.state == ASUB_ARG || c.state == AUSUB_ARG || 1172 c.state == MSG_ARG || c.state == HMSG_ARG || 1173 c.state == MINUS_ERR_ARG || c.state == CONNECT_ARG || c.state == INFO_ARG { 1174 1175 // Setup a holder buffer to deal with split buffer scenario. 1176 if c.argBuf == nil { 1177 c.argBuf = c.scratch[:0] 1178 c.argBuf = append(c.argBuf, buf[c.as:i-c.drop]...) 1179 } 1180 // Check for violations of control line length here. Note that this is not 1181 // exact at all but the performance hit is too great to be precise, and 1182 // catching here should prevent memory exhaustion attacks. 1183 if err := c.overMaxControlLineLimit(c.argBuf, mcl); err != nil { 1184 return err 1185 } 1186 } 1187 1188 // Check for split msg 1189 if (c.state == MSG_PAYLOAD || c.state == MSG_END_R || c.state == MSG_END_N) && c.msgBuf == nil { 1190 // We need to clone the pubArg if it is still referencing the 1191 // read buffer and we are not able to process the msg. 1192 1193 if c.argBuf == nil { 1194 // Works also for MSG_ARG, when message comes from ROUTE or GATEWAY. 1195 if err := c.clonePubArg(lmsg); err != nil { 1196 goto parseErr 1197 } 1198 } 1199 1200 // If we will overflow the scratch buffer, just create a 1201 // new buffer to hold the split message. 1202 if c.pa.size > cap(c.scratch)-len(c.argBuf) { 1203 lrem := len(buf[c.as:]) 1204 // Consider it a protocol error when the remaining payload 1205 // is larger than the reported size for PUB. It can happen 1206 // when processing incomplete messages from rogue clients. 1207 if lrem > c.pa.size+LEN_CR_LF { 1208 goto parseErr 1209 } 1210 c.msgBuf = make([]byte, lrem, c.pa.size+LEN_CR_LF) 1211 copy(c.msgBuf, buf[c.as:]) 1212 } else { 1213 c.msgBuf = c.scratch[len(c.argBuf):len(c.argBuf)] 1214 c.msgBuf = append(c.msgBuf, (buf[c.as:])...) 1215 } 1216 } 1217 1218 return nil 1219 1220 authErr: 1221 c.authViolation() 1222 return ErrAuthentication 1223 1224 parseErr: 1225 c.sendErr("Unknown Protocol Operation") 1226 snip := protoSnippet(i, PROTO_SNIPPET_SIZE, buf) 1227 err := fmt.Errorf("%s parser ERROR, state=%d, i=%d: proto='%s...'", c.kindString(), c.state, i, snip) 1228 return err 1229 } 1230 1231 func protoSnippet(start, max int, buf []byte) string { 1232 stop := start + max 1233 bufSize := len(buf) 1234 if start >= bufSize { 1235 return `""` 1236 } 1237 if stop > bufSize { 1238 stop = bufSize - 1 1239 } 1240 return fmt.Sprintf("%q", buf[start:stop]) 1241 } 1242 1243 // Check if the length of buffer `arg` is over the max control line limit `mcl`. 1244 // If so, an error is sent to the client and the connection is closed. 1245 // The error ErrMaxControlLine is returned. 1246 func (c *client) overMaxControlLineLimit(arg []byte, mcl int32) error { 1247 if c.kind != CLIENT { 1248 return nil 1249 } 1250 if len(arg) > int(mcl) { 1251 err := NewErrorCtx(ErrMaxControlLine, "State %d, max_control_line %d, Buffer len %d (snip: %s...)", 1252 c.state, int(mcl), len(c.argBuf), protoSnippet(0, MAX_CONTROL_LINE_SNIPPET_SIZE, arg)) 1253 c.sendErr(err.Error()) 1254 c.closeConnection(MaxControlLineExceeded) 1255 return err 1256 } 1257 return nil 1258 } 1259 1260 // clonePubArg is used when the split buffer scenario has the pubArg in the existing read buffer, but 1261 // we need to hold onto it into the next read. 1262 func (c *client) clonePubArg(lmsg bool) error { 1263 // Just copy and re-process original arg buffer. 1264 c.argBuf = c.scratch[:0] 1265 c.argBuf = append(c.argBuf, c.pa.arg...) 1266 1267 switch c.kind { 1268 case ROUTER, GATEWAY: 1269 if lmsg { 1270 return c.processRoutedOriginClusterMsgArgs(c.argBuf) 1271 } 1272 if c.pa.hdr < 0 { 1273 return c.processRoutedMsgArgs(c.argBuf) 1274 } else { 1275 return c.processRoutedHeaderMsgArgs(c.argBuf) 1276 } 1277 case LEAF: 1278 if c.pa.hdr < 0 { 1279 return c.processLeafMsgArgs(c.argBuf) 1280 } else { 1281 return c.processLeafHeaderMsgArgs(c.argBuf) 1282 } 1283 default: 1284 if c.pa.hdr < 0 { 1285 return c.processPub(c.argBuf) 1286 } else { 1287 return c.processHeaderPub(c.argBuf, nil) 1288 } 1289 } 1290 } 1291 1292 func (ps *parseState) getHeader() http.Header { 1293 if ps.header == nil { 1294 if hdr := ps.pa.hdr; hdr > 0 { 1295 reader := bufio.NewReader(bytes.NewReader(ps.msgBuf[0:hdr])) 1296 tp := textproto.NewReader(reader) 1297 tp.ReadLine() // skip over first line, contains version 1298 if mimeHeader, err := tp.ReadMIMEHeader(); err == nil { 1299 ps.header = http.Header(mimeHeader) 1300 } 1301 } 1302 } 1303 return ps.header 1304 }