Print this page
    
dccp: getting kernel segfaults, back out recent added features
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/common/inet/dccp/dccp_options.c
          +++ new/usr/src/uts/common/inet/dccp/dccp_options.c
   1    1  /*
   2    2   * This file and its contents are supplied under the terms of the
   3    3   * Common Development and Distribution License ("CDDL"), version 1.0.
   4    4   * You may only use this file in accordance with the terms of version
   5    5   * 1.0 of the CDDL.
   6    6   *
   7    7   * A full copy of the text of the CDDL should have accompanied this
   8    8   * source.  A copy of the CDDL is also available via the Internet at
   9    9   * http://www.illumos.org/license/CDDL.
  
    | 
      ↓ open down ↓ | 
    9 lines elided | 
    
      ↑ open up ↑ | 
  
  10   10   */
  11   11  
  12   12  /*
  13   13   * Copyright 2012 David Hoeppner. All rights reserved.
  14   14   */
  15   15  
  16   16  #include <sys/types.h> 
  17   17  #include <sys/stream.h> 
  18   18  #include <sys/debug.h> 
  19   19  #include <sys/cmn_err.h>
       20 +
  20   21  #include <inet/dccp_impl.h>
  21   22  #include <inet/dccp_stack.h>
  22   23  
  23   24  /*
  24   25   * This file contains functions to parse and process DCCP options.
  25   26   */
  26   27  
  27   28  
  28   29  /*
  29   30   * Parse the options in a DCCP header.
  30   31   */
  31   32  int
  32   33  dccp_parse_options(dccp_t *dccp, dccpha_t *dccpha)
  33   34  {
  34   35          uchar_t         *end;
  35   36          uchar_t         *up;
  36   37          uint8_t         dccp_type;
  37   38          uint32_t        option_value;
  38   39          uint8_t         option_type;
  39   40          uint8_t         option_length;
  40   41          int             len;
  41   42          int             i;
  42   43          uchar_t         *value;
  43   44          boolean_t       mandatory = B_FALSE;
  44   45          int             error;
  45   46  
  46   47          cmn_err(CE_NOTE, "dccp_features.c: dccp_parse_options");
  47   48  
  48   49          dccp_type = dccpha->dha_type;
  49   50  
  50   51          up = (uchar_t *)dccpha;
  51   52          end = up + DCCP_HDR_LENGTH(dccpha);
  52   53          up += 20;
  53   54  
  54   55          while (up != end) {
  55   56                  option_length = 0;
  56   57                  option_type = *up++;
  57   58  
  58   59                  if (option_type > 31) {
  59   60                          if (up == end) {
  60   61                                  goto length_error;
  61   62                          }
  62   63  
  63   64                          option_length = *up++;
  64   65                          if (option_length < 2) {
  65   66                                  goto length_error;
  66   67                          }
  67   68  
  68   69                          option_length -= 2;
  69   70                          value = up;
  70   71  
  71   72                          up += option_length;
  72   73  
  73   74                          /* Ignore options with greater length then header */
  74   75                          if (up > end) {
  75   76                                  goto length_error;
  76   77                          }
  77   78                  }
  78   79  
  79   80                  switch (option_type) {
  80   81                  case DCCP_OPTION_PADDING:
  81   82                          cmn_err(CE_NOTE, "PADDING");
  82   83                          break;
  83   84                  case DCCP_OPTION_MANDATORY:
  84   85                          cmn_err(CE_NOTE, "MANDATORY");
  85   86                          if (mandatory)
  86   87                                  goto option_error;
  87   88  
  88   89                          if (dccp_type != DCCP_PKT_DATA)
  89   90                                  mandatory = B_TRUE;
  90   91                          break;
  91   92                  case DCCP_OPTION_SLOW_RECEIVER:
  92   93                          cmn_err(CE_NOTE, "SLOW RECEIVER");
  93   94                          break;
  94   95                  case DCCP_OPTION_CHANGE_L:
  95   96                  case DCCP_OPTION_CONFIRM_L:
  96   97                  case DCCP_OPTION_CHANGE_R:
  97   98                  case DCCP_OPTION_CONFIRM_R:
  98   99                          if (dccp_type == DCCP_PKT_DATA)
  99  100                                  break;
 100  101  
 101  102                          if (option_length == 0)
 102  103                                  goto option_error;
 103  104  
 104  105                          dccp_parse_feature(dccp, option_type, option_length,
 105  106                              value, mandatory);
 106  107                          break;
 107  108                  case DCCP_OPTION_INIT_COOKIE:
 108  109                          cmn_err(CE_NOTE, "INIT COOKIE");
 109  110                          break;
 110  111                  case DCCP_OPTION_NDP_COUNT:
 111  112                          cmn_err(CE_NOTE, "NDP COUNT");
 112  113                          if (option_length > 6)
 113  114                                  goto option_error;
 114  115                          break;
 115  116                  case DCCP_OPTION_ACK_VECTOR_1:
 116  117                          cmn_err(CE_NOTE, "ACK VECTOR 1");
 117  118                          break;
 118  119                  case DCCP_OPTION_ACK_VECTOR_2:
 119  120                          cmn_err(CE_NOTE, "ACK VECTOR 2");
  
    | 
      ↓ open down ↓ | 
    90 lines elided | 
    
      ↑ open up ↑ | 
  
 120  121                          break;
 121  122                  case DCCP_OPTION_DATA_DROPPED:
 122  123                          cmn_err(CE_NOTE, "DATA DROPPED");
 123  124                          break;
 124  125                  case DCCP_OPTION_TIMESTAMP:
 125  126                          cmn_err(CE_NOTE, "TIMESTAMP");
 126  127                          if (option_length != 4)
 127  128                                  goto option_error;
 128  129  
 129  130                          /* XXX read unaligned big endian */
 130      -                        option_value = ((uint8_t)value[0] << 31);
      131 +                        option_value = ((uint8_t)value[0] << 24);
      132 +                        option_value += ((uint8_t)value[1] << 16);
      133 +                        option_value += ((uint8_t)value[2] << 8);
      134 +                        option_value += (uint8_t)value[3];
 131  135                          if (option_value) {
 132  136                                  cmn_err(CE_NOTE, "Zero timestamp");
 133  137                                  break;
 134  138                          }
 135  139  
 136  140                          dccp->dccp_timestamp_echo = ntohs(option_value);
 137      -                        dccp->dccp_timestamp = gethrtime();
      141 +                        dccp->dccp_timestamp = TICK_TO_MSEC(LBOLT_FASTPATH);
 138  142                          break;
 139  143                  case DCCP_OPTION_TIMESTAMP_ECHO:
 140  144                          cmn_err(CE_NOTE, "TIMESTAMP ECHO");
 141  145                          if (option_length != 4 &&
 142  146                              option_length != 6 &&
 143  147                              option_length != 8) {
 144  148                                  goto option_error;
 145  149                          }
 146  150  
 147  151                          break;
 148  152                  case DCCP_OPTION_ELAPSED_TIME:
 149  153                          cmn_err(CE_NOTE, "ELAPSES TIME");
 150  154                          switch (option_length) {
 151  155                          case 2:
 152  156                                  break;
 153  157                          case 4:
 154  158                                  break;
 155  159                          default:
 156  160                                  goto option_error;
 157  161                          }
 158  162                          break;
 159  163                  case DCCP_OPTION_DATA_CHECKSUM:
 160  164                          cmn_err(CE_NOTE, "DATA CHECKSUM");
 161  165                          break;
 162  166  
 163  167                  default:
 164  168                          cmn_err(CE_NOTE, "DEFAULT");
 165  169                          break;
 166  170                  }
 167  171  
 168  172                  if (option_type != DCCP_OPTION_MANDATORY) {
 169  173                          mandatory = B_FALSE;
 170  174                  }
 171  175          }
 172  176  
 173  177          if (mandatory)
 174  178                  goto option_error;
 175  179  
 176  180  length_error:
 177  181          return (0);
 178  182  
 179  183  option_error:
 180  184          error = DCCP_RESET_OPTION_ERROR;
 181  185  
 182  186          cmn_err(CE_NOTE, "setting error code");
 183  187  
 184  188          dccp->dccp_reset_code = error;
 185  189          dccp->dccp_reset_data[0] = option_type;
 186  190          dccp->dccp_reset_data[1] = option_length > 0 ? value[0] : 0;
 187  191          dccp->dccp_reset_data[2] = option_length > 1 ? value[1] : 0;
 188  192  
 189  193          return (-1);
 190  194  }
 191  195  
 192  196  void
 193  197  dccp_process_options(dccp_t *dccp, dccpha_t *dccpha)
 194  198  {
 195  199          cmn_err(CE_NOTE, "dccp_features.c: dccp_process_features");
 196  200  
 197  201          dccp_parse_options(dccp, dccpha);
 198  202  }
 199  203  
 200  204  int
 201  205  dccp_generate_options(dccp_t *dccp, void **opt, size_t *opt_len)
 202  206  {
 203  207          dccp_feature_t  *feature = NULL;
 204  208          uint8_t         buf[1024];      /* XXX */
 205  209          uint8_t         option_type;
 206  210          uint_t          len = 0;
 207  211          uint_t          total_len;
 208  212          void            *options;
 209  213          int             rest;
 210  214  
 211  215          cmn_err(CE_NOTE, "dccp_features.c: dccp_generate_options");
 212  216  
 213  217          for (feature = list_head(&dccp->dccp_features); feature;
 214  218              feature = list_next(&dccp->dccp_features, feature)) {
 215  219                  if (feature->df_option == DCCP_OPTION_CHANGE_L) {
 216  220                          option_type = DCCP_OPTION_CONFIRM_R;
 217  221                  } else {
 218  222                          option_type = DCCP_OPTION_CONFIRM_L;
 219  223                  }
 220  224  /*
 221  225                  if (feature->df_mandatory == B_TRUE) {
 222  226                          buf[len] = DCCP_OPTION_MANDATORY;
 223  227                          len++;
 224  228                  }
 225  229  */
 226  230                  if (feature->df_type == DCCP_FEATURE_CCID) {
 227  231                          cmn_err(CE_NOTE, "FOUND DCCP_FEATURE_CCID");
 228  232  
 229  233                          buf[len] = option_type;
 230  234                          len++;
 231  235                          buf[len] = 4;
 232  236                          len++;
 233  237                          buf[len] = DCCP_FEATURE_CCID;
 234  238                          len++;
 235  239                          buf[len] = 2;
 236  240                          len++;
 237  241                  }
 238  242  
 239  243                  if (feature->df_type == DCCP_FEATURE_ALLOW_SHORT_SEQNOS) {
 240  244                          buf[len] = option_type;
 241  245                          len++;
 242  246                          buf[len] = 4;
 243  247                          len++;
 244  248                          buf[len] = feature->df_type;
 245  249                          len++;
 246  250                          buf[len] = 0;
 247  251                          len++;
 248  252                  }
 249  253  
 250  254                  if (feature->df_type == DCCP_FEATURE_ECN_INCAPABLE) {
 251  255                          buf[len] = option_type;
 252  256                          len++;
 253  257                          buf[len] = 4;
 254  258                          len++;
  
    | 
      ↓ open down ↓ | 
    107 lines elided | 
    
      ↑ open up ↑ | 
  
 255  259                          buf[len] = feature->df_type;
 256  260                          len++;
 257  261                          buf[len] = 1;
 258  262                          len++;
 259  263                  }
 260  264          }
 261  265  
 262  266          if (dccp->dccp_timestamp_echo != 0) {
 263  267                  uint32_t        elapsed;
 264  268                  int             elapsed_length;
      269 +                clock_t         now;
 265  270  
 266  271                  buf[len] = DCCP_OPTION_TIMESTAMP_ECHO;
 267  272                  len++;
      273 +                buf[len] = 10;
      274 +                len++;
      275 +
      276 +                now = TICK_TO_MSEC(LBOLT_FASTPATH);
      277 +                elapsed =  now - dccp->dccp_timestamp;
 268  278  
 269      -                elapsed = gethrtime() - dccp->dccp_timestamp;
 270  279  
 271  280                  dccp->dccp_timestamp_echo = 0;
 272  281          }
 273  282  
 274  283          total_len = ((len + (4 - 1)) / 4) * 4;
 275  284          options = kmem_zalloc(total_len, KM_SLEEP);
 276  285          if (options == NULL) {
 277  286                  cmn_err(CE_NOTE, "kmem_zalloc failed");
 278  287                  return (ENOMEM);
 279  288          }
 280  289          memcpy(options, buf, len);
 281  290  
 282  291          *opt = options;
 283  292          *opt_len = len;
 284  293  
 285  294          return (0);
 286  295  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX