Я пишу пользовательские декодеры слоев с gopacket .
LayerA содержит поле Type
, которое может принимать одно из следующих значений:
- только для B , следующий уровень - LayerB , за которым следует необработанная полезная нагрузка
- C-only , следующийслой LayerC , за которым следует необработанная полезная нагрузка
- BC , следующий слой - LayerB , за которым следует LayerC затем необработанная полезная нагрузка
В LayerB нет поля, которое можно использовать для определения, является ли LayerC следующим или нет. LayerB и LayerC декодирование не зависит от того, присутствует ли другой слой или нет.
Каким будет правильный способ записи функции декодирования LayerA , так как это тот, который знает, каковы следующие слои?
Существует не так много учебников по пользовательским слоям с gopacket , и этот случай не похож на основной
Кажется, что логика должна быть вставлена в LayerA функцию декодирования, непосредственно перед вызовом p.NextDecoder
.
Я подумал о двух способах добиться этого:
1.Используйте замыкание
Добавьте поле nextDecoder Decoder
в структуру LayerB .В декодере LayerA , когда Type
равен C-only , просто используйте декодер LayerC .В противном случае создайте структуру LayerB и заполните поле nextDecoder
соответственно.Затем используйте эту структуру в замыкании, которая будет использоваться в качестве следующего декодера.
Проблемы
Логика декодирования LayerB будет в LayerA функция декодирования (см. Код в Palyground ниже).Кроме того, какую функцию декодирования использовать при регистрации LayerB с помощью gopacket.RegisterLayer
?
2.Имеют два отдельных слоя LayerB-C и LayerB-only
LayerB-C , следующий декодер будет LayerC
, LayerB-only будет простоуровень полезной нагрузки.
Проблемы
Функция декодирования Только LayerB и LayerB-C такая же, ожидайте вызова p.NextDecoder
.Поскольку в go нет понятия «наследование», я не уверен, как его спроектировать, чтобы избежать дублирования.Может быть, создать интерфейс LayerB-base с функцией nextDecoder() LayerType
и заставить LayerB-C и LayerB-only реализовать его?Или внедрить тип LayerB-base , который имеет функцию Decode
?Но ни один из них не чувствует себя хорошо.
Код
Вот код для каждого описанного способа: https://play.golang.org/p/N9ZpYqFb16Q. Фактическое содержание слоев не имеет значения, кроме LayerA.Type
.
Результат этого кода, как и ожидалось, но я хотел бы знать, есть ли лучший или более идиоматический, чтобы сделать это.