Как правильно написать пользовательский слой, когда NextDecoder зависит от предыдущего слоя, а не от текущего? - PullRequest
1 голос
/ 05 июля 2019

Я пишу пользовательские декодеры слоев с 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.

Результат этого кода, как и ожидалось, но я хотел бы знать, есть ли лучший или более идиоматический, чтобы сделать это.

...