xref: /trafficserver/src/tscore/ink_uuid.cc (revision 4cfd5a73)
1 /** @file
2  *
3  *  Basic implementation of RFC 4122, see
4  *      https://www.ietf.org/rfc/rfc4122.txt
5  *
6  *  @section license License
7  *
8  *  Licensed to the Apache Software Foundation (ASF) under one
9  *  or more contributor license agreements.  See the NOTICE file
10  *  distributed with this work for additional information
11  *  regarding copyright ownership.  The ASF licenses this file
12  *  to you under the Apache License, Version 2.0 (the
13  *  "License"); you may not use this file except in compliance
14  *  with the License.  You may obtain a copy of the License at
15  *
16  *      http://www.apache.org/licenses/LICENSE-2.0
17  *
18  *  Unless required by applicable law or agreed to in writing, software
19  *  distributed under the License is distributed on an "AS IS" BASIS,
20  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21  *  See the License for the specific language governing permissions and
22  *  limitations under the License.
23  */
24 #include <openssl/rand.h>
25 
26 #include "tscore/ink_error.h"
27 #include "tscore/ink_uuid.h"
28 
29 void
initialize(TSUuidVersion v)30 ATSUuid::initialize(TSUuidVersion v)
31 {
32   switch (v) {
33   case TS_UUID_UNDEFINED:
34     ink_abort("Don't initialize to undefined UUID variant!");
35     break;
36   case TS_UUID_V1:
37   case TS_UUID_V2:
38   case TS_UUID_V3:
39   case TS_UUID_V5:
40     ink_zero(_uuid.data); // Not properly implemented yet, so set it to the Nil UUID
41     break;
42   case TS_UUID_V4:
43     RAND_bytes(_uuid.data, sizeof(_uuid.data));
44     _uuid.clockSeqAndReserved = static_cast<uint8_t>((_uuid.clockSeqAndReserved & 0x3F) | 0x80);
45     _uuid.timeHighAndVersion  = static_cast<uint16_t>((_uuid.timeHighAndVersion & 0x0FFF) | 0x4000);
46 
47     break;
48   }
49 
50   _version = _toString(_string) ? v : TS_UUID_UNDEFINED;
51 }
52 
53 // Copy assignment
54 ATSUuid &
operator =(const ATSUuid & other)55 ATSUuid::operator=(const ATSUuid &other)
56 {
57   if (this != &other) { // Self assignment guard
58     memcpy(_uuid.data, other._uuid.data, sizeof(_uuid.data));
59     memcpy(_string, other._string, sizeof(_string));
60     _version = other._version;
61   }
62 
63   return *this;
64 }
65 
66 bool
parseString(const char * str)67 ATSUuid::parseString(const char *str)
68 {
69   int cnt = sscanf(str, "%08x-%04hx-%04hx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", &_uuid.timeLow, &_uuid.timeMid,
70                    &_uuid.timeHighAndVersion, &_uuid.clockSeqAndReserved, &_uuid.clockSeqLow, &_uuid.node[0], &_uuid.node[1],
71                    &_uuid.node[2], &_uuid.node[3], &_uuid.node[4], &_uuid.node[5]);
72 
73   if ((11 == cnt) && _toString(_string)) {
74     switch (_uuid.timeHighAndVersion >> 12) {
75     case 1:
76       _version = TS_UUID_V1;
77       break;
78     case 2:
79       _version = TS_UUID_V2;
80       break;
81     case 3:
82       _version = TS_UUID_V3;
83       break;
84     case 4:
85       _version = TS_UUID_V4;
86       break;
87     case 5:
88       _version = TS_UUID_V5;
89       break;
90     default:
91       _version = TS_UUID_UNDEFINED;
92       break;
93     }
94   } else {
95     _version = TS_UUID_UNDEFINED;
96   }
97 
98   return (TS_UUID_UNDEFINED != _version);
99 }
100