Browse Source

add schema change for [dk]line refactor

tags/v1.0.0-rc1
Shivaram Lingamneni 5 years ago
parent
commit
854d85a474
1 changed files with 118 additions and 1 deletions
  1. 118
    1
      irc/database.go

+ 118
- 1
irc/database.go View File

@@ -22,7 +22,7 @@ const (
22 22
 	// 'version' of the database schema
23 23
 	keySchemaVersion = "db.version"
24 24
 	// latest schema of the db
25
-	latestDbSchema = "3"
25
+	latestDbSchema = "4"
26 26
 )
27 27
 
28 28
 type SchemaChanger func(*Config, *buntdb.Tx) error
@@ -278,6 +278,118 @@ func schemaChangeV2ToV3(config *Config, tx *buntdb.Tx) error {
278 278
 	return nil
279 279
 }
280 280
 
281
+// 1. ban info format changed (from `legacyBanInfo` below to `IPBanInfo`)
282
+// 2. dlines against individual IPs are normalized into dlines against the appropriate /128 network
283
+func schemaChangeV3ToV4(config *Config, tx *buntdb.Tx) error {
284
+	type ipRestrictTime struct {
285
+		Duration time.Duration
286
+		Expires  time.Time
287
+	}
288
+	type legacyBanInfo struct {
289
+		Reason     string          `json:"reason"`
290
+		OperReason string          `json:"oper_reason"`
291
+		OperName   string          `json:"oper_name"`
292
+		Time       *ipRestrictTime `json:"time"`
293
+	}
294
+
295
+	now := time.Now()
296
+	legacyToNewInfo := func(old legacyBanInfo) (new_ IPBanInfo) {
297
+		new_.Reason = old.Reason
298
+		new_.OperReason = old.OperReason
299
+		new_.OperName = old.OperName
300
+
301
+		if old.Time == nil {
302
+			new_.TimeCreated = now
303
+			new_.Duration = 0
304
+		} else {
305
+			new_.TimeCreated = old.Time.Expires.Add(-1 * old.Time.Duration)
306
+			new_.Duration = old.Time.Duration
307
+		}
308
+		return
309
+	}
310
+
311
+	var keysToDelete []string
312
+
313
+	prefix := "bans.dline "
314
+	dlines := make(map[string]IPBanInfo)
315
+	tx.AscendGreaterOrEqual("", prefix, func(key, value string) bool {
316
+		if !strings.HasPrefix(key, prefix) {
317
+			return false
318
+		}
319
+		keysToDelete = append(keysToDelete, key)
320
+
321
+		var lbinfo legacyBanInfo
322
+		id := strings.TrimPrefix(key, prefix)
323
+		err := json.Unmarshal([]byte(value), &lbinfo)
324
+		if err != nil {
325
+			log.Printf("error unmarshaling legacy dline: %v\n", err)
326
+			return true
327
+		}
328
+		// legacy keys can be either an IP or a CIDR
329
+		hostNet, err := utils.NormalizedNetFromString(id)
330
+		if err != nil {
331
+			log.Printf("error unmarshaling legacy dline network: %v\n", err)
332
+			return true
333
+		}
334
+		dlines[utils.NetToNormalizedString(hostNet)] = legacyToNewInfo(lbinfo)
335
+
336
+		return true
337
+	})
338
+
339
+	setOptions := func(info IPBanInfo) *buntdb.SetOptions {
340
+		if info.Duration == 0 {
341
+			return nil
342
+		}
343
+		ttl := info.TimeCreated.Add(info.Duration).Sub(now)
344
+		return &buntdb.SetOptions{Expires: true, TTL: ttl}
345
+	}
346
+
347
+	// store the new dlines
348
+	for id, info := range dlines {
349
+		b, err := json.Marshal(info)
350
+		if err != nil {
351
+			log.Printf("error marshaling migrated dline: %v\n", err)
352
+			continue
353
+		}
354
+		tx.Set(fmt.Sprintf("bans.dlinev2 %s", id), string(b), setOptions(info))
355
+	}
356
+
357
+	// same operations against klines
358
+	prefix = "bans.kline "
359
+	klines := make(map[string]IPBanInfo)
360
+	tx.AscendGreaterOrEqual("", prefix, func(key, value string) bool {
361
+		if !strings.HasPrefix(key, prefix) {
362
+			return false
363
+		}
364
+		keysToDelete = append(keysToDelete, key)
365
+		mask := strings.TrimPrefix(key, prefix)
366
+		var lbinfo legacyBanInfo
367
+		err := json.Unmarshal([]byte(value), &lbinfo)
368
+		if err != nil {
369
+			log.Printf("error unmarshaling legacy kline: %v\n", err)
370
+			return true
371
+		}
372
+		klines[mask] = legacyToNewInfo(lbinfo)
373
+		return true
374
+	})
375
+
376
+	for mask, info := range klines {
377
+		b, err := json.Marshal(info)
378
+		if err != nil {
379
+			log.Printf("error marshaling migrated kline: %v\n", err)
380
+			continue
381
+		}
382
+		tx.Set(fmt.Sprintf("bans.klinev2 %s", mask), string(b), setOptions(info))
383
+	}
384
+
385
+	// clean up all the old entries
386
+	for _, key := range keysToDelete {
387
+		tx.Delete(key)
388
+	}
389
+
390
+	return nil
391
+}
392
+
281 393
 func init() {
282 394
 	allChanges := []SchemaChange{
283 395
 		{
@@ -290,6 +402,11 @@ func init() {
290 402
 			TargetVersion:  "3",
291 403
 			Changer:        schemaChangeV2ToV3,
292 404
 		},
405
+		{
406
+			InitialVersion: "3",
407
+			TargetVersion:  "4",
408
+			Changer:        schemaChangeV3ToV4,
409
+		},
293 410
 	}
294 411
 
295 412
 	// build the index

Loading…
Cancel
Save